1//===-- ARMInstrNEON.td - NEON support for ARM -------------*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the ARM NEON instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14 15//===----------------------------------------------------------------------===// 16// NEON-specific Operands. 17//===----------------------------------------------------------------------===// 18def nModImm : Operand<i32> { 19 let PrintMethod = "printNEONModImmOperand"; 20} 21 22def nImmSplatI8AsmOperand : AsmOperandClass { let Name = "NEONi8splat"; } 23def nImmSplatI8 : Operand<i32> { 24 let PrintMethod = "printNEONModImmOperand"; 25 let ParserMatchClass = nImmSplatI8AsmOperand; 26} 27def nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; } 28def nImmSplatI16 : Operand<i32> { 29 let PrintMethod = "printNEONModImmOperand"; 30 let ParserMatchClass = nImmSplatI16AsmOperand; 31} 32def nImmSplatI32AsmOperand : AsmOperandClass { let Name = "NEONi32splat"; } 33def nImmSplatI32 : Operand<i32> { 34 let PrintMethod = "printNEONModImmOperand"; 35 let ParserMatchClass = nImmSplatI32AsmOperand; 36} 37def nImmVMOVI32AsmOperand : AsmOperandClass { let Name = "NEONi32vmov"; } 38def nImmVMOVI32 : Operand<i32> { 39 let PrintMethod = "printNEONModImmOperand"; 40 let ParserMatchClass = nImmVMOVI32AsmOperand; 41} 42def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; } 43def nImmVMOVI32Neg : Operand<i32> { 44 let PrintMethod = "printNEONModImmOperand"; 45 let ParserMatchClass = nImmVMOVI32NegAsmOperand; 46} 47def nImmVMOVF32 : Operand<i32> { 48 let PrintMethod = "printFPImmOperand"; 49 let ParserMatchClass = FPImmOperand; 50} 51def nImmSplatI64AsmOperand : AsmOperandClass { let Name = "NEONi64splat"; } 52def nImmSplatI64 : Operand<i32> { 53 let PrintMethod = "printNEONModImmOperand"; 54 let ParserMatchClass = nImmSplatI64AsmOperand; 55} 56 57def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; } 58def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; } 59def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; } 60def VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{ 61 return ((uint64_t)Imm) < 8; 62}]> { 63 let ParserMatchClass = VectorIndex8Operand; 64 let PrintMethod = "printVectorIndex"; 65 let MIOperandInfo = (ops i32imm); 66} 67def VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{ 68 return ((uint64_t)Imm) < 4; 69}]> { 70 let ParserMatchClass = VectorIndex16Operand; 71 let PrintMethod = "printVectorIndex"; 72 let MIOperandInfo = (ops i32imm); 73} 74def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{ 75 return ((uint64_t)Imm) < 2; 76}]> { 77 let ParserMatchClass = VectorIndex32Operand; 78 let PrintMethod = "printVectorIndex"; 79 let MIOperandInfo = (ops i32imm); 80} 81 82// Register list of one D register. 83def VecListOneDAsmOperand : AsmOperandClass { 84 let Name = "VecListOneD"; 85 let ParserMethod = "parseVectorList"; 86 let RenderMethod = "addVecListOperands"; 87} 88def VecListOneD : RegisterOperand<DPR, "printVectorListOne"> { 89 let ParserMatchClass = VecListOneDAsmOperand; 90} 91// Register list of two sequential D registers. 92def VecListDPairAsmOperand : AsmOperandClass { 93 let Name = "VecListDPair"; 94 let ParserMethod = "parseVectorList"; 95 let RenderMethod = "addVecListOperands"; 96} 97def VecListDPair : RegisterOperand<DPair, "printVectorListTwo"> { 98 let ParserMatchClass = VecListDPairAsmOperand; 99} 100// Register list of three sequential D registers. 101def VecListThreeDAsmOperand : AsmOperandClass { 102 let Name = "VecListThreeD"; 103 let ParserMethod = "parseVectorList"; 104 let RenderMethod = "addVecListOperands"; 105} 106def VecListThreeD : RegisterOperand<DPR, "printVectorListThree"> { 107 let ParserMatchClass = VecListThreeDAsmOperand; 108} 109// Register list of four sequential D registers. 110def VecListFourDAsmOperand : AsmOperandClass { 111 let Name = "VecListFourD"; 112 let ParserMethod = "parseVectorList"; 113 let RenderMethod = "addVecListOperands"; 114} 115def VecListFourD : RegisterOperand<DPR, "printVectorListFour"> { 116 let ParserMatchClass = VecListFourDAsmOperand; 117} 118// Register list of two D registers spaced by 2 (two sequential Q registers). 119def VecListDPairSpacedAsmOperand : AsmOperandClass { 120 let Name = "VecListDPairSpaced"; 121 let ParserMethod = "parseVectorList"; 122 let RenderMethod = "addVecListOperands"; 123} 124def VecListDPairSpaced : RegisterOperand<DPair, "printVectorListTwoSpaced"> { 125 let ParserMatchClass = VecListDPairSpacedAsmOperand; 126} 127// Register list of three D registers spaced by 2 (three Q registers). 128def VecListThreeQAsmOperand : AsmOperandClass { 129 let Name = "VecListThreeQ"; 130 let ParserMethod = "parseVectorList"; 131 let RenderMethod = "addVecListOperands"; 132} 133def VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> { 134 let ParserMatchClass = VecListThreeQAsmOperand; 135} 136// Register list of three D registers spaced by 2 (three Q registers). 137def VecListFourQAsmOperand : AsmOperandClass { 138 let Name = "VecListFourQ"; 139 let ParserMethod = "parseVectorList"; 140 let RenderMethod = "addVecListOperands"; 141} 142def VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> { 143 let ParserMatchClass = VecListFourQAsmOperand; 144} 145 146// Register list of one D register, with "all lanes" subscripting. 147def VecListOneDAllLanesAsmOperand : AsmOperandClass { 148 let Name = "VecListOneDAllLanes"; 149 let ParserMethod = "parseVectorList"; 150 let RenderMethod = "addVecListOperands"; 151} 152def VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> { 153 let ParserMatchClass = VecListOneDAllLanesAsmOperand; 154} 155// Register list of two D registers, with "all lanes" subscripting. 156def VecListDPairAllLanesAsmOperand : AsmOperandClass { 157 let Name = "VecListDPairAllLanes"; 158 let ParserMethod = "parseVectorList"; 159 let RenderMethod = "addVecListOperands"; 160} 161def VecListDPairAllLanes : RegisterOperand<DPair, 162 "printVectorListTwoAllLanes"> { 163 let ParserMatchClass = VecListDPairAllLanesAsmOperand; 164} 165// Register list of two D registers spaced by 2 (two sequential Q registers). 166def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass { 167 let Name = "VecListDPairSpacedAllLanes"; 168 let ParserMethod = "parseVectorList"; 169 let RenderMethod = "addVecListOperands"; 170} 171def VecListDPairSpacedAllLanes : RegisterOperand<DPair, 172 "printVectorListTwoSpacedAllLanes"> { 173 let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand; 174} 175// Register list of three D registers, with "all lanes" subscripting. 176def VecListThreeDAllLanesAsmOperand : AsmOperandClass { 177 let Name = "VecListThreeDAllLanes"; 178 let ParserMethod = "parseVectorList"; 179 let RenderMethod = "addVecListOperands"; 180} 181def VecListThreeDAllLanes : RegisterOperand<DPR, 182 "printVectorListThreeAllLanes"> { 183 let ParserMatchClass = VecListThreeDAllLanesAsmOperand; 184} 185// Register list of three D registers spaced by 2 (three sequential Q regs). 186def VecListThreeQAllLanesAsmOperand : AsmOperandClass { 187 let Name = "VecListThreeQAllLanes"; 188 let ParserMethod = "parseVectorList"; 189 let RenderMethod = "addVecListOperands"; 190} 191def VecListThreeQAllLanes : RegisterOperand<DPR, 192 "printVectorListThreeSpacedAllLanes"> { 193 let ParserMatchClass = VecListThreeQAllLanesAsmOperand; 194} 195// Register list of four D registers, with "all lanes" subscripting. 196def VecListFourDAllLanesAsmOperand : AsmOperandClass { 197 let Name = "VecListFourDAllLanes"; 198 let ParserMethod = "parseVectorList"; 199 let RenderMethod = "addVecListOperands"; 200} 201def VecListFourDAllLanes : RegisterOperand<DPR, "printVectorListFourAllLanes"> { 202 let ParserMatchClass = VecListFourDAllLanesAsmOperand; 203} 204// Register list of four D registers spaced by 2 (four sequential Q regs). 205def VecListFourQAllLanesAsmOperand : AsmOperandClass { 206 let Name = "VecListFourQAllLanes"; 207 let ParserMethod = "parseVectorList"; 208 let RenderMethod = "addVecListOperands"; 209} 210def VecListFourQAllLanes : RegisterOperand<DPR, 211 "printVectorListFourSpacedAllLanes"> { 212 let ParserMatchClass = VecListFourQAllLanesAsmOperand; 213} 214 215 216// Register list of one D register, with byte lane subscripting. 217def VecListOneDByteIndexAsmOperand : AsmOperandClass { 218 let Name = "VecListOneDByteIndexed"; 219 let ParserMethod = "parseVectorList"; 220 let RenderMethod = "addVecListIndexedOperands"; 221} 222def VecListOneDByteIndexed : Operand<i32> { 223 let ParserMatchClass = VecListOneDByteIndexAsmOperand; 224 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 225} 226// ...with half-word lane subscripting. 227def VecListOneDHWordIndexAsmOperand : AsmOperandClass { 228 let Name = "VecListOneDHWordIndexed"; 229 let ParserMethod = "parseVectorList"; 230 let RenderMethod = "addVecListIndexedOperands"; 231} 232def VecListOneDHWordIndexed : Operand<i32> { 233 let ParserMatchClass = VecListOneDHWordIndexAsmOperand; 234 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 235} 236// ...with word lane subscripting. 237def VecListOneDWordIndexAsmOperand : AsmOperandClass { 238 let Name = "VecListOneDWordIndexed"; 239 let ParserMethod = "parseVectorList"; 240 let RenderMethod = "addVecListIndexedOperands"; 241} 242def VecListOneDWordIndexed : Operand<i32> { 243 let ParserMatchClass = VecListOneDWordIndexAsmOperand; 244 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 245} 246 247// Register list of two D registers with byte lane subscripting. 248def VecListTwoDByteIndexAsmOperand : AsmOperandClass { 249 let Name = "VecListTwoDByteIndexed"; 250 let ParserMethod = "parseVectorList"; 251 let RenderMethod = "addVecListIndexedOperands"; 252} 253def VecListTwoDByteIndexed : Operand<i32> { 254 let ParserMatchClass = VecListTwoDByteIndexAsmOperand; 255 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 256} 257// ...with half-word lane subscripting. 258def VecListTwoDHWordIndexAsmOperand : AsmOperandClass { 259 let Name = "VecListTwoDHWordIndexed"; 260 let ParserMethod = "parseVectorList"; 261 let RenderMethod = "addVecListIndexedOperands"; 262} 263def VecListTwoDHWordIndexed : Operand<i32> { 264 let ParserMatchClass = VecListTwoDHWordIndexAsmOperand; 265 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 266} 267// ...with word lane subscripting. 268def VecListTwoDWordIndexAsmOperand : AsmOperandClass { 269 let Name = "VecListTwoDWordIndexed"; 270 let ParserMethod = "parseVectorList"; 271 let RenderMethod = "addVecListIndexedOperands"; 272} 273def VecListTwoDWordIndexed : Operand<i32> { 274 let ParserMatchClass = VecListTwoDWordIndexAsmOperand; 275 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 276} 277// Register list of two Q registers with half-word lane subscripting. 278def VecListTwoQHWordIndexAsmOperand : AsmOperandClass { 279 let Name = "VecListTwoQHWordIndexed"; 280 let ParserMethod = "parseVectorList"; 281 let RenderMethod = "addVecListIndexedOperands"; 282} 283def VecListTwoQHWordIndexed : Operand<i32> { 284 let ParserMatchClass = VecListTwoQHWordIndexAsmOperand; 285 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 286} 287// ...with word lane subscripting. 288def VecListTwoQWordIndexAsmOperand : AsmOperandClass { 289 let Name = "VecListTwoQWordIndexed"; 290 let ParserMethod = "parseVectorList"; 291 let RenderMethod = "addVecListIndexedOperands"; 292} 293def VecListTwoQWordIndexed : Operand<i32> { 294 let ParserMatchClass = VecListTwoQWordIndexAsmOperand; 295 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 296} 297 298 299// Register list of three D registers with byte lane subscripting. 300def VecListThreeDByteIndexAsmOperand : AsmOperandClass { 301 let Name = "VecListThreeDByteIndexed"; 302 let ParserMethod = "parseVectorList"; 303 let RenderMethod = "addVecListIndexedOperands"; 304} 305def VecListThreeDByteIndexed : Operand<i32> { 306 let ParserMatchClass = VecListThreeDByteIndexAsmOperand; 307 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 308} 309// ...with half-word lane subscripting. 310def VecListThreeDHWordIndexAsmOperand : AsmOperandClass { 311 let Name = "VecListThreeDHWordIndexed"; 312 let ParserMethod = "parseVectorList"; 313 let RenderMethod = "addVecListIndexedOperands"; 314} 315def VecListThreeDHWordIndexed : Operand<i32> { 316 let ParserMatchClass = VecListThreeDHWordIndexAsmOperand; 317 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 318} 319// ...with word lane subscripting. 320def VecListThreeDWordIndexAsmOperand : AsmOperandClass { 321 let Name = "VecListThreeDWordIndexed"; 322 let ParserMethod = "parseVectorList"; 323 let RenderMethod = "addVecListIndexedOperands"; 324} 325def VecListThreeDWordIndexed : Operand<i32> { 326 let ParserMatchClass = VecListThreeDWordIndexAsmOperand; 327 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 328} 329// Register list of three Q registers with half-word lane subscripting. 330def VecListThreeQHWordIndexAsmOperand : AsmOperandClass { 331 let Name = "VecListThreeQHWordIndexed"; 332 let ParserMethod = "parseVectorList"; 333 let RenderMethod = "addVecListIndexedOperands"; 334} 335def VecListThreeQHWordIndexed : Operand<i32> { 336 let ParserMatchClass = VecListThreeQHWordIndexAsmOperand; 337 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 338} 339// ...with word lane subscripting. 340def VecListThreeQWordIndexAsmOperand : AsmOperandClass { 341 let Name = "VecListThreeQWordIndexed"; 342 let ParserMethod = "parseVectorList"; 343 let RenderMethod = "addVecListIndexedOperands"; 344} 345def VecListThreeQWordIndexed : Operand<i32> { 346 let ParserMatchClass = VecListThreeQWordIndexAsmOperand; 347 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 348} 349 350// Register list of four D registers with byte lane subscripting. 351def VecListFourDByteIndexAsmOperand : AsmOperandClass { 352 let Name = "VecListFourDByteIndexed"; 353 let ParserMethod = "parseVectorList"; 354 let RenderMethod = "addVecListIndexedOperands"; 355} 356def VecListFourDByteIndexed : Operand<i32> { 357 let ParserMatchClass = VecListFourDByteIndexAsmOperand; 358 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 359} 360// ...with half-word lane subscripting. 361def VecListFourDHWordIndexAsmOperand : AsmOperandClass { 362 let Name = "VecListFourDHWordIndexed"; 363 let ParserMethod = "parseVectorList"; 364 let RenderMethod = "addVecListIndexedOperands"; 365} 366def VecListFourDHWordIndexed : Operand<i32> { 367 let ParserMatchClass = VecListFourDHWordIndexAsmOperand; 368 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 369} 370// ...with word lane subscripting. 371def VecListFourDWordIndexAsmOperand : AsmOperandClass { 372 let Name = "VecListFourDWordIndexed"; 373 let ParserMethod = "parseVectorList"; 374 let RenderMethod = "addVecListIndexedOperands"; 375} 376def VecListFourDWordIndexed : Operand<i32> { 377 let ParserMatchClass = VecListFourDWordIndexAsmOperand; 378 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 379} 380// Register list of four Q registers with half-word lane subscripting. 381def VecListFourQHWordIndexAsmOperand : AsmOperandClass { 382 let Name = "VecListFourQHWordIndexed"; 383 let ParserMethod = "parseVectorList"; 384 let RenderMethod = "addVecListIndexedOperands"; 385} 386def VecListFourQHWordIndexed : Operand<i32> { 387 let ParserMatchClass = VecListFourQHWordIndexAsmOperand; 388 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 389} 390// ...with word lane subscripting. 391def VecListFourQWordIndexAsmOperand : AsmOperandClass { 392 let Name = "VecListFourQWordIndexed"; 393 let ParserMethod = "parseVectorList"; 394 let RenderMethod = "addVecListIndexedOperands"; 395} 396def VecListFourQWordIndexed : Operand<i32> { 397 let ParserMatchClass = VecListFourQWordIndexAsmOperand; 398 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 399} 400 401def hword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 402 return cast<LoadSDNode>(N)->getAlignment() == 2; 403}]>; 404def hword_alignedstore : PatFrag<(ops node:$val, node:$ptr), 405 (store node:$val, node:$ptr), [{ 406 return cast<StoreSDNode>(N)->getAlignment() == 2; 407}]>; 408def byte_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 409 return cast<LoadSDNode>(N)->getAlignment() == 1; 410}]>; 411def byte_alignedstore : PatFrag<(ops node:$val, node:$ptr), 412 (store node:$val, node:$ptr), [{ 413 return cast<StoreSDNode>(N)->getAlignment() == 1; 414}]>; 415def non_word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 416 return cast<LoadSDNode>(N)->getAlignment() < 4; 417}]>; 418def non_word_alignedstore : PatFrag<(ops node:$val, node:$ptr), 419 (store node:$val, node:$ptr), [{ 420 return cast<StoreSDNode>(N)->getAlignment() < 4; 421}]>; 422 423//===----------------------------------------------------------------------===// 424// NEON-specific DAG Nodes. 425//===----------------------------------------------------------------------===// 426 427def SDTARMVCMP : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>; 428def SDTARMVCMPZ : SDTypeProfile<1, 1, []>; 429 430def NEONvceq : SDNode<"ARMISD::VCEQ", SDTARMVCMP>; 431def NEONvceqz : SDNode<"ARMISD::VCEQZ", SDTARMVCMPZ>; 432def NEONvcge : SDNode<"ARMISD::VCGE", SDTARMVCMP>; 433def NEONvcgez : SDNode<"ARMISD::VCGEZ", SDTARMVCMPZ>; 434def NEONvclez : SDNode<"ARMISD::VCLEZ", SDTARMVCMPZ>; 435def NEONvcgeu : SDNode<"ARMISD::VCGEU", SDTARMVCMP>; 436def NEONvcgt : SDNode<"ARMISD::VCGT", SDTARMVCMP>; 437def NEONvcgtz : SDNode<"ARMISD::VCGTZ", SDTARMVCMPZ>; 438def NEONvcltz : SDNode<"ARMISD::VCLTZ", SDTARMVCMPZ>; 439def NEONvcgtu : SDNode<"ARMISD::VCGTU", SDTARMVCMP>; 440def NEONvtst : SDNode<"ARMISD::VTST", SDTARMVCMP>; 441 442// Types for vector shift by immediates. The "SHX" version is for long and 443// narrow operations where the source and destination vectors have different 444// types. The "SHINS" version is for shift and insert operations. 445def SDTARMVSH : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 446 SDTCisVT<2, i32>]>; 447def SDTARMVSHX : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 448 SDTCisVT<2, i32>]>; 449def SDTARMVSHINS : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 450 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; 451 452def NEONvshl : SDNode<"ARMISD::VSHL", SDTARMVSH>; 453def NEONvshrs : SDNode<"ARMISD::VSHRs", SDTARMVSH>; 454def NEONvshru : SDNode<"ARMISD::VSHRu", SDTARMVSH>; 455def NEONvshlls : SDNode<"ARMISD::VSHLLs", SDTARMVSHX>; 456def NEONvshllu : SDNode<"ARMISD::VSHLLu", SDTARMVSHX>; 457def NEONvshlli : SDNode<"ARMISD::VSHLLi", SDTARMVSHX>; 458def NEONvshrn : SDNode<"ARMISD::VSHRN", SDTARMVSHX>; 459 460def NEONvrshrs : SDNode<"ARMISD::VRSHRs", SDTARMVSH>; 461def NEONvrshru : SDNode<"ARMISD::VRSHRu", SDTARMVSH>; 462def NEONvrshrn : SDNode<"ARMISD::VRSHRN", SDTARMVSHX>; 463 464def NEONvqshls : SDNode<"ARMISD::VQSHLs", SDTARMVSH>; 465def NEONvqshlu : SDNode<"ARMISD::VQSHLu", SDTARMVSH>; 466def NEONvqshlsu : SDNode<"ARMISD::VQSHLsu", SDTARMVSH>; 467def NEONvqshrns : SDNode<"ARMISD::VQSHRNs", SDTARMVSHX>; 468def NEONvqshrnu : SDNode<"ARMISD::VQSHRNu", SDTARMVSHX>; 469def NEONvqshrnsu : SDNode<"ARMISD::VQSHRNsu", SDTARMVSHX>; 470 471def NEONvqrshrns : SDNode<"ARMISD::VQRSHRNs", SDTARMVSHX>; 472def NEONvqrshrnu : SDNode<"ARMISD::VQRSHRNu", SDTARMVSHX>; 473def NEONvqrshrnsu : SDNode<"ARMISD::VQRSHRNsu", SDTARMVSHX>; 474 475def NEONvsli : SDNode<"ARMISD::VSLI", SDTARMVSHINS>; 476def NEONvsri : SDNode<"ARMISD::VSRI", SDTARMVSHINS>; 477 478def SDTARMVGETLN : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>, 479 SDTCisVT<2, i32>]>; 480def NEONvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>; 481def NEONvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>; 482 483def SDTARMVMOVIMM : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>; 484def NEONvmovImm : SDNode<"ARMISD::VMOVIMM", SDTARMVMOVIMM>; 485def NEONvmvnImm : SDNode<"ARMISD::VMVNIMM", SDTARMVMOVIMM>; 486def NEONvmovFPImm : SDNode<"ARMISD::VMOVFPIMM", SDTARMVMOVIMM>; 487 488def SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 489 SDTCisVT<2, i32>]>; 490def NEONvorrImm : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>; 491def NEONvbicImm : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>; 492 493def NEONvbsl : SDNode<"ARMISD::VBSL", 494 SDTypeProfile<1, 3, [SDTCisVec<0>, 495 SDTCisSameAs<0, 1>, 496 SDTCisSameAs<0, 2>, 497 SDTCisSameAs<0, 3>]>>; 498 499def NEONvdup : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>; 500 501// VDUPLANE can produce a quad-register result from a double-register source, 502// so the result is not constrained to match the source. 503def NEONvduplane : SDNode<"ARMISD::VDUPLANE", 504 SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, 505 SDTCisVT<2, i32>]>>; 506 507def SDTARMVEXT : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 508 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; 509def NEONvext : SDNode<"ARMISD::VEXT", SDTARMVEXT>; 510 511def SDTARMVSHUF : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>; 512def NEONvrev64 : SDNode<"ARMISD::VREV64", SDTARMVSHUF>; 513def NEONvrev32 : SDNode<"ARMISD::VREV32", SDTARMVSHUF>; 514def NEONvrev16 : SDNode<"ARMISD::VREV16", SDTARMVSHUF>; 515 516def SDTARMVSHUF2 : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 517 SDTCisSameAs<0, 2>, 518 SDTCisSameAs<0, 3>]>; 519def NEONzip : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>; 520def NEONuzp : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>; 521def NEONtrn : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>; 522 523def SDTARMVMULL : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 524 SDTCisSameAs<1, 2>]>; 525def NEONvmulls : SDNode<"ARMISD::VMULLs", SDTARMVMULL>; 526def NEONvmullu : SDNode<"ARMISD::VMULLu", SDTARMVMULL>; 527 528def SDTARMFMAX : SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisSameAs<0, 1>, 529 SDTCisSameAs<0, 2>]>; 530def NEONfmax : SDNode<"ARMISD::FMAX", SDTARMFMAX>; 531def NEONfmin : SDNode<"ARMISD::FMIN", SDTARMFMAX>; 532 533def NEONimmAllZerosV: PatLeaf<(NEONvmovImm (i32 timm)), [{ 534 ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0)); 535 unsigned EltBits = 0; 536 uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits); 537 return (EltBits == 32 && EltVal == 0); 538}]>; 539 540def NEONimmAllOnesV: PatLeaf<(NEONvmovImm (i32 timm)), [{ 541 ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0)); 542 unsigned EltBits = 0; 543 uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits); 544 return (EltBits == 8 && EltVal == 0xff); 545}]>; 546 547//===----------------------------------------------------------------------===// 548// NEON load / store instructions 549//===----------------------------------------------------------------------===// 550 551// Use VLDM to load a Q register as a D register pair. 552// This is a pseudo instruction that is expanded to VLDMD after reg alloc. 553def VLDMQIA 554 : PseudoVFPLdStM<(outs DPair:$dst), (ins GPR:$Rn), 555 IIC_fpLoad_m, "", 556 [(set DPair:$dst, (v2f64 (load GPR:$Rn)))]>; 557 558// Use VSTM to store a Q register as a D register pair. 559// This is a pseudo instruction that is expanded to VSTMD after reg alloc. 560def VSTMQIA 561 : PseudoVFPLdStM<(outs), (ins DPair:$src, GPR:$Rn), 562 IIC_fpStore_m, "", 563 [(store (v2f64 DPair:$src), GPR:$Rn)]>; 564 565// Classes for VLD* pseudo-instructions with multi-register operands. 566// These are expanded to real instructions after register allocation. 567class VLDQPseudo<InstrItinClass itin> 568 : PseudoNLdSt<(outs QPR:$dst), (ins addrmode6:$addr), itin, "">; 569class VLDQWBPseudo<InstrItinClass itin> 570 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 571 (ins addrmode6:$addr, am6offset:$offset), itin, 572 "$addr.addr = $wb">; 573class VLDQWBfixedPseudo<InstrItinClass itin> 574 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 575 (ins addrmode6:$addr), itin, 576 "$addr.addr = $wb">; 577class VLDQWBregisterPseudo<InstrItinClass itin> 578 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 579 (ins addrmode6:$addr, rGPR:$offset), itin, 580 "$addr.addr = $wb">; 581 582class VLDQQPseudo<InstrItinClass itin> 583 : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">; 584class VLDQQWBPseudo<InstrItinClass itin> 585 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 586 (ins addrmode6:$addr, am6offset:$offset), itin, 587 "$addr.addr = $wb">; 588class VLDQQWBfixedPseudo<InstrItinClass itin> 589 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 590 (ins addrmode6:$addr), itin, 591 "$addr.addr = $wb">; 592class VLDQQWBregisterPseudo<InstrItinClass itin> 593 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 594 (ins addrmode6:$addr, rGPR:$offset), itin, 595 "$addr.addr = $wb">; 596 597 598class VLDQQQQPseudo<InstrItinClass itin> 599 : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin, 600 "$src = $dst">; 601class VLDQQQQWBPseudo<InstrItinClass itin> 602 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb), 603 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin, 604 "$addr.addr = $wb, $src = $dst">; 605 606let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 607 608// VLD1 : Vector Load (multiple single elements) 609class VLD1D<bits<4> op7_4, string Dt> 610 : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd), 611 (ins addrmode6:$Rn), IIC_VLD1, 612 "vld1", Dt, "$Vd, $Rn", "", []> { 613 let Rm = 0b1111; 614 let Inst{4} = Rn{4}; 615 let DecoderMethod = "DecodeVLDInstruction"; 616} 617class VLD1Q<bits<4> op7_4, string Dt> 618 : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd), 619 (ins addrmode6:$Rn), IIC_VLD1x2, 620 "vld1", Dt, "$Vd, $Rn", "", []> { 621 let Rm = 0b1111; 622 let Inst{5-4} = Rn{5-4}; 623 let DecoderMethod = "DecodeVLDInstruction"; 624} 625 626def VLD1d8 : VLD1D<{0,0,0,?}, "8">; 627def VLD1d16 : VLD1D<{0,1,0,?}, "16">; 628def VLD1d32 : VLD1D<{1,0,0,?}, "32">; 629def VLD1d64 : VLD1D<{1,1,0,?}, "64">; 630 631def VLD1q8 : VLD1Q<{0,0,?,?}, "8">; 632def VLD1q16 : VLD1Q<{0,1,?,?}, "16">; 633def VLD1q32 : VLD1Q<{1,0,?,?}, "32">; 634def VLD1q64 : VLD1Q<{1,1,?,?}, "64">; 635 636// ...with address register writeback: 637multiclass VLD1DWB<bits<4> op7_4, string Dt> { 638 def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb), 639 (ins addrmode6:$Rn), IIC_VLD1u, 640 "vld1", Dt, "$Vd, $Rn!", 641 "$Rn.addr = $wb", []> { 642 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 643 let Inst{4} = Rn{4}; 644 let DecoderMethod = "DecodeVLDInstruction"; 645 let AsmMatchConverter = "cvtVLDwbFixed"; 646 } 647 def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb), 648 (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1u, 649 "vld1", Dt, "$Vd, $Rn, $Rm", 650 "$Rn.addr = $wb", []> { 651 let Inst{4} = Rn{4}; 652 let DecoderMethod = "DecodeVLDInstruction"; 653 let AsmMatchConverter = "cvtVLDwbRegister"; 654 } 655} 656multiclass VLD1QWB<bits<4> op7_4, string Dt> { 657 def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb), 658 (ins addrmode6:$Rn), IIC_VLD1x2u, 659 "vld1", Dt, "$Vd, $Rn!", 660 "$Rn.addr = $wb", []> { 661 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 662 let Inst{5-4} = Rn{5-4}; 663 let DecoderMethod = "DecodeVLDInstruction"; 664 let AsmMatchConverter = "cvtVLDwbFixed"; 665 } 666 def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb), 667 (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u, 668 "vld1", Dt, "$Vd, $Rn, $Rm", 669 "$Rn.addr = $wb", []> { 670 let Inst{5-4} = Rn{5-4}; 671 let DecoderMethod = "DecodeVLDInstruction"; 672 let AsmMatchConverter = "cvtVLDwbRegister"; 673 } 674} 675 676defm VLD1d8wb : VLD1DWB<{0,0,0,?}, "8">; 677defm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16">; 678defm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32">; 679defm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64">; 680defm VLD1q8wb : VLD1QWB<{0,0,?,?}, "8">; 681defm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16">; 682defm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32">; 683defm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64">; 684 685// ...with 3 registers 686class VLD1D3<bits<4> op7_4, string Dt> 687 : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd), 688 (ins addrmode6:$Rn), IIC_VLD1x3, "vld1", Dt, 689 "$Vd, $Rn", "", []> { 690 let Rm = 0b1111; 691 let Inst{4} = Rn{4}; 692 let DecoderMethod = "DecodeVLDInstruction"; 693} 694multiclass VLD1D3WB<bits<4> op7_4, string Dt> { 695 def _fixed : NLdSt<0,0b10,0b0110, op7_4, (outs VecListThreeD:$Vd, GPR:$wb), 696 (ins addrmode6:$Rn), IIC_VLD1x2u, 697 "vld1", Dt, "$Vd, $Rn!", 698 "$Rn.addr = $wb", []> { 699 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 700 let Inst{4} = Rn{4}; 701 let DecoderMethod = "DecodeVLDInstruction"; 702 let AsmMatchConverter = "cvtVLDwbFixed"; 703 } 704 def _register : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd, GPR:$wb), 705 (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u, 706 "vld1", Dt, "$Vd, $Rn, $Rm", 707 "$Rn.addr = $wb", []> { 708 let Inst{4} = Rn{4}; 709 let DecoderMethod = "DecodeVLDInstruction"; 710 let AsmMatchConverter = "cvtVLDwbRegister"; 711 } 712} 713 714def VLD1d8T : VLD1D3<{0,0,0,?}, "8">; 715def VLD1d16T : VLD1D3<{0,1,0,?}, "16">; 716def VLD1d32T : VLD1D3<{1,0,0,?}, "32">; 717def VLD1d64T : VLD1D3<{1,1,0,?}, "64">; 718 719defm VLD1d8Twb : VLD1D3WB<{0,0,0,?}, "8">; 720defm VLD1d16Twb : VLD1D3WB<{0,1,0,?}, "16">; 721defm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32">; 722defm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64">; 723 724def VLD1d64TPseudo : VLDQQPseudo<IIC_VLD1x3>; 725 726// ...with 4 registers 727class VLD1D4<bits<4> op7_4, string Dt> 728 : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd), 729 (ins addrmode6:$Rn), IIC_VLD1x4, "vld1", Dt, 730 "$Vd, $Rn", "", []> { 731 let Rm = 0b1111; 732 let Inst{5-4} = Rn{5-4}; 733 let DecoderMethod = "DecodeVLDInstruction"; 734} 735multiclass VLD1D4WB<bits<4> op7_4, string Dt> { 736 def _fixed : NLdSt<0,0b10,0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb), 737 (ins addrmode6:$Rn), IIC_VLD1x2u, 738 "vld1", Dt, "$Vd, $Rn!", 739 "$Rn.addr = $wb", []> { 740 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 741 let Inst{5-4} = Rn{5-4}; 742 let DecoderMethod = "DecodeVLDInstruction"; 743 let AsmMatchConverter = "cvtVLDwbFixed"; 744 } 745 def _register : NLdSt<0,0b10,0b0010,op7_4, (outs VecListFourD:$Vd, GPR:$wb), 746 (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u, 747 "vld1", Dt, "$Vd, $Rn, $Rm", 748 "$Rn.addr = $wb", []> { 749 let Inst{5-4} = Rn{5-4}; 750 let DecoderMethod = "DecodeVLDInstruction"; 751 let AsmMatchConverter = "cvtVLDwbRegister"; 752 } 753} 754 755def VLD1d8Q : VLD1D4<{0,0,?,?}, "8">; 756def VLD1d16Q : VLD1D4<{0,1,?,?}, "16">; 757def VLD1d32Q : VLD1D4<{1,0,?,?}, "32">; 758def VLD1d64Q : VLD1D4<{1,1,?,?}, "64">; 759 760defm VLD1d8Qwb : VLD1D4WB<{0,0,?,?}, "8">; 761defm VLD1d16Qwb : VLD1D4WB<{0,1,?,?}, "16">; 762defm VLD1d32Qwb : VLD1D4WB<{1,0,?,?}, "32">; 763defm VLD1d64Qwb : VLD1D4WB<{1,1,?,?}, "64">; 764 765def VLD1d64QPseudo : VLDQQPseudo<IIC_VLD1x4>; 766 767// VLD2 : Vector Load (multiple 2-element structures) 768class VLD2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, 769 InstrItinClass itin> 770 : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd), 771 (ins addrmode6:$Rn), itin, 772 "vld2", Dt, "$Vd, $Rn", "", []> { 773 let Rm = 0b1111; 774 let Inst{5-4} = Rn{5-4}; 775 let DecoderMethod = "DecodeVLDInstruction"; 776} 777 778def VLD2d8 : VLD2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2>; 779def VLD2d16 : VLD2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2>; 780def VLD2d32 : VLD2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2>; 781 782def VLD2q8 : VLD2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2>; 783def VLD2q16 : VLD2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2>; 784def VLD2q32 : VLD2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2>; 785 786def VLD2q8Pseudo : VLDQQPseudo<IIC_VLD2x2>; 787def VLD2q16Pseudo : VLDQQPseudo<IIC_VLD2x2>; 788def VLD2q32Pseudo : VLDQQPseudo<IIC_VLD2x2>; 789 790// ...with address register writeback: 791multiclass VLD2WB<bits<4> op11_8, bits<4> op7_4, string Dt, 792 RegisterOperand VdTy, InstrItinClass itin> { 793 def _fixed : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb), 794 (ins addrmode6:$Rn), itin, 795 "vld2", Dt, "$Vd, $Rn!", 796 "$Rn.addr = $wb", []> { 797 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 798 let Inst{5-4} = Rn{5-4}; 799 let DecoderMethod = "DecodeVLDInstruction"; 800 let AsmMatchConverter = "cvtVLDwbFixed"; 801 } 802 def _register : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb), 803 (ins addrmode6:$Rn, rGPR:$Rm), itin, 804 "vld2", Dt, "$Vd, $Rn, $Rm", 805 "$Rn.addr = $wb", []> { 806 let Inst{5-4} = Rn{5-4}; 807 let DecoderMethod = "DecodeVLDInstruction"; 808 let AsmMatchConverter = "cvtVLDwbRegister"; 809 } 810} 811 812defm VLD2d8wb : VLD2WB<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2u>; 813defm VLD2d16wb : VLD2WB<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2u>; 814defm VLD2d32wb : VLD2WB<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2u>; 815 816defm VLD2q8wb : VLD2WB<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2u>; 817defm VLD2q16wb : VLD2WB<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2u>; 818defm VLD2q32wb : VLD2WB<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2u>; 819 820def VLD2q8PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>; 821def VLD2q16PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>; 822def VLD2q32PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>; 823def VLD2q8PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>; 824def VLD2q16PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>; 825def VLD2q32PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>; 826 827// ...with double-spaced registers 828def VLD2b8 : VLD2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2>; 829def VLD2b16 : VLD2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2>; 830def VLD2b32 : VLD2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2>; 831defm VLD2b8wb : VLD2WB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2u>; 832defm VLD2b16wb : VLD2WB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2u>; 833defm VLD2b32wb : VLD2WB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2u>; 834 835// VLD3 : Vector Load (multiple 3-element structures) 836class VLD3D<bits<4> op11_8, bits<4> op7_4, string Dt> 837 : NLdSt<0, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 838 (ins addrmode6:$Rn), IIC_VLD3, 839 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> { 840 let Rm = 0b1111; 841 let Inst{4} = Rn{4}; 842 let DecoderMethod = "DecodeVLDInstruction"; 843} 844 845def VLD3d8 : VLD3D<0b0100, {0,0,0,?}, "8">; 846def VLD3d16 : VLD3D<0b0100, {0,1,0,?}, "16">; 847def VLD3d32 : VLD3D<0b0100, {1,0,0,?}, "32">; 848 849def VLD3d8Pseudo : VLDQQPseudo<IIC_VLD3>; 850def VLD3d16Pseudo : VLDQQPseudo<IIC_VLD3>; 851def VLD3d32Pseudo : VLDQQPseudo<IIC_VLD3>; 852 853// ...with address register writeback: 854class VLD3DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 855 : NLdSt<0, 0b10, op11_8, op7_4, 856 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 857 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD3u, 858 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm", 859 "$Rn.addr = $wb", []> { 860 let Inst{4} = Rn{4}; 861 let DecoderMethod = "DecodeVLDInstruction"; 862} 863 864def VLD3d8_UPD : VLD3DWB<0b0100, {0,0,0,?}, "8">; 865def VLD3d16_UPD : VLD3DWB<0b0100, {0,1,0,?}, "16">; 866def VLD3d32_UPD : VLD3DWB<0b0100, {1,0,0,?}, "32">; 867 868def VLD3d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>; 869def VLD3d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>; 870def VLD3d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>; 871 872// ...with double-spaced registers: 873def VLD3q8 : VLD3D<0b0101, {0,0,0,?}, "8">; 874def VLD3q16 : VLD3D<0b0101, {0,1,0,?}, "16">; 875def VLD3q32 : VLD3D<0b0101, {1,0,0,?}, "32">; 876def VLD3q8_UPD : VLD3DWB<0b0101, {0,0,0,?}, "8">; 877def VLD3q16_UPD : VLD3DWB<0b0101, {0,1,0,?}, "16">; 878def VLD3q32_UPD : VLD3DWB<0b0101, {1,0,0,?}, "32">; 879 880def VLD3q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 881def VLD3q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 882def VLD3q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 883 884// ...alternate versions to be allocated odd register numbers: 885def VLD3q8oddPseudo : VLDQQQQPseudo<IIC_VLD3>; 886def VLD3q16oddPseudo : VLDQQQQPseudo<IIC_VLD3>; 887def VLD3q32oddPseudo : VLDQQQQPseudo<IIC_VLD3>; 888 889def VLD3q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 890def VLD3q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 891def VLD3q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>; 892 893// VLD4 : Vector Load (multiple 4-element structures) 894class VLD4D<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, DPR:$dst4), 897 (ins addrmode6:$Rn), IIC_VLD4, 898 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> { 899 let Rm = 0b1111; 900 let Inst{5-4} = Rn{5-4}; 901 let DecoderMethod = "DecodeVLDInstruction"; 902} 903 904def VLD4d8 : VLD4D<0b0000, {0,0,?,?}, "8">; 905def VLD4d16 : VLD4D<0b0000, {0,1,?,?}, "16">; 906def VLD4d32 : VLD4D<0b0000, {1,0,?,?}, "32">; 907 908def VLD4d8Pseudo : VLDQQPseudo<IIC_VLD4>; 909def VLD4d16Pseudo : VLDQQPseudo<IIC_VLD4>; 910def VLD4d32Pseudo : VLDQQPseudo<IIC_VLD4>; 911 912// ...with address register writeback: 913class VLD4DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 914 : NLdSt<0, 0b10, op11_8, op7_4, 915 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 916 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD4u, 917 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", 918 "$Rn.addr = $wb", []> { 919 let Inst{5-4} = Rn{5-4}; 920 let DecoderMethod = "DecodeVLDInstruction"; 921} 922 923def VLD4d8_UPD : VLD4DWB<0b0000, {0,0,?,?}, "8">; 924def VLD4d16_UPD : VLD4DWB<0b0000, {0,1,?,?}, "16">; 925def VLD4d32_UPD : VLD4DWB<0b0000, {1,0,?,?}, "32">; 926 927def VLD4d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>; 928def VLD4d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>; 929def VLD4d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>; 930 931// ...with double-spaced registers: 932def VLD4q8 : VLD4D<0b0001, {0,0,?,?}, "8">; 933def VLD4q16 : VLD4D<0b0001, {0,1,?,?}, "16">; 934def VLD4q32 : VLD4D<0b0001, {1,0,?,?}, "32">; 935def VLD4q8_UPD : VLD4DWB<0b0001, {0,0,?,?}, "8">; 936def VLD4q16_UPD : VLD4DWB<0b0001, {0,1,?,?}, "16">; 937def VLD4q32_UPD : VLD4DWB<0b0001, {1,0,?,?}, "32">; 938 939def VLD4q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 940def VLD4q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 941def VLD4q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 942 943// ...alternate versions to be allocated odd register numbers: 944def VLD4q8oddPseudo : VLDQQQQPseudo<IIC_VLD4>; 945def VLD4q16oddPseudo : VLDQQQQPseudo<IIC_VLD4>; 946def VLD4q32oddPseudo : VLDQQQQPseudo<IIC_VLD4>; 947 948def VLD4q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 949def VLD4q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 950def VLD4q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>; 951 952} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 953 954// Classes for VLD*LN pseudo-instructions with multi-register operands. 955// These are expanded to real instructions after register allocation. 956class VLDQLNPseudo<InstrItinClass itin> 957 : PseudoNLdSt<(outs QPR:$dst), 958 (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane), 959 itin, "$src = $dst">; 960class VLDQLNWBPseudo<InstrItinClass itin> 961 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 962 (ins addrmode6:$addr, am6offset:$offset, QPR:$src, 963 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 964class VLDQQLNPseudo<InstrItinClass itin> 965 : PseudoNLdSt<(outs QQPR:$dst), 966 (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane), 967 itin, "$src = $dst">; 968class VLDQQLNWBPseudo<InstrItinClass itin> 969 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 970 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src, 971 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 972class VLDQQQQLNPseudo<InstrItinClass itin> 973 : PseudoNLdSt<(outs QQQQPR:$dst), 974 (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane), 975 itin, "$src = $dst">; 976class VLDQQQQLNWBPseudo<InstrItinClass itin> 977 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb), 978 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src, 979 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 980 981// VLD1LN : Vector Load (single element to one lane) 982class VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 983 PatFrag LoadOp> 984 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd), 985 (ins addrmode6:$Rn, DPR:$src, nohash_imm:$lane), 986 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn", 987 "$src = $Vd", 988 [(set DPR:$Vd, (vector_insert (Ty DPR:$src), 989 (i32 (LoadOp addrmode6:$Rn)), 990 imm:$lane))]> { 991 let Rm = 0b1111; 992 let DecoderMethod = "DecodeVLD1LN"; 993} 994class VLD1LN32<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 995 PatFrag LoadOp> 996 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd), 997 (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane), 998 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn", 999 "$src = $Vd", 1000 [(set DPR:$Vd, (vector_insert (Ty DPR:$src), 1001 (i32 (LoadOp addrmode6oneL32:$Rn)), 1002 imm:$lane))]> { 1003 let Rm = 0b1111; 1004 let DecoderMethod = "DecodeVLD1LN"; 1005} 1006class VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln> { 1007 let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src), 1008 (i32 (LoadOp addrmode6:$addr)), 1009 imm:$lane))]; 1010} 1011 1012def VLD1LNd8 : VLD1LN<0b0000, {?,?,?,0}, "8", v8i8, extloadi8> { 1013 let Inst{7-5} = lane{2-0}; 1014} 1015def VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> { 1016 let Inst{7-6} = lane{1-0}; 1017 let Inst{5-4} = Rn{5-4}; 1018} 1019def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> { 1020 let Inst{7} = lane{0}; 1021 let Inst{5-4} = Rn{5-4}; 1022} 1023 1024def VLD1LNq8Pseudo : VLD1QLNPseudo<v16i8, extloadi8>; 1025def VLD1LNq16Pseudo : VLD1QLNPseudo<v8i16, extloadi16>; 1026def VLD1LNq32Pseudo : VLD1QLNPseudo<v4i32, load>; 1027 1028def : Pat<(vector_insert (v2f32 DPR:$src), 1029 (f32 (load addrmode6:$addr)), imm:$lane), 1030 (VLD1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>; 1031def : Pat<(vector_insert (v4f32 QPR:$src), 1032 (f32 (load addrmode6:$addr)), imm:$lane), 1033 (VLD1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 1034 1035let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1036 1037// ...with address register writeback: 1038class VLD1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1039 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, GPR:$wb), 1040 (ins addrmode6:$Rn, am6offset:$Rm, 1041 DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt, 1042 "\\{$Vd[$lane]\\}, $Rn$Rm", 1043 "$src = $Vd, $Rn.addr = $wb", []> { 1044 let DecoderMethod = "DecodeVLD1LN"; 1045} 1046 1047def VLD1LNd8_UPD : VLD1LNWB<0b0000, {?,?,?,0}, "8"> { 1048 let Inst{7-5} = lane{2-0}; 1049} 1050def VLD1LNd16_UPD : VLD1LNWB<0b0100, {?,?,0,?}, "16"> { 1051 let Inst{7-6} = lane{1-0}; 1052 let Inst{4} = Rn{4}; 1053} 1054def VLD1LNd32_UPD : VLD1LNWB<0b1000, {?,0,?,?}, "32"> { 1055 let Inst{7} = lane{0}; 1056 let Inst{5} = Rn{4}; 1057 let Inst{4} = Rn{4}; 1058} 1059 1060def VLD1LNq8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>; 1061def VLD1LNq16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>; 1062def VLD1LNq32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>; 1063 1064// VLD2LN : Vector Load (single 2-element structure to one lane) 1065class VLD2LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1066 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2), 1067 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, nohash_imm:$lane), 1068 IIC_VLD2ln, "vld2", Dt, "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn", 1069 "$src1 = $Vd, $src2 = $dst2", []> { 1070 let Rm = 0b1111; 1071 let Inst{4} = Rn{4}; 1072 let DecoderMethod = "DecodeVLD2LN"; 1073} 1074 1075def VLD2LNd8 : VLD2LN<0b0001, {?,?,?,?}, "8"> { 1076 let Inst{7-5} = lane{2-0}; 1077} 1078def VLD2LNd16 : VLD2LN<0b0101, {?,?,0,?}, "16"> { 1079 let Inst{7-6} = lane{1-0}; 1080} 1081def VLD2LNd32 : VLD2LN<0b1001, {?,0,0,?}, "32"> { 1082 let Inst{7} = lane{0}; 1083} 1084 1085def VLD2LNd8Pseudo : VLDQLNPseudo<IIC_VLD2ln>; 1086def VLD2LNd16Pseudo : VLDQLNPseudo<IIC_VLD2ln>; 1087def VLD2LNd32Pseudo : VLDQLNPseudo<IIC_VLD2ln>; 1088 1089// ...with double-spaced registers: 1090def VLD2LNq16 : VLD2LN<0b0101, {?,?,1,?}, "16"> { 1091 let Inst{7-6} = lane{1-0}; 1092} 1093def VLD2LNq32 : VLD2LN<0b1001, {?,1,0,?}, "32"> { 1094 let Inst{7} = lane{0}; 1095} 1096 1097def VLD2LNq16Pseudo : VLDQQLNPseudo<IIC_VLD2ln>; 1098def VLD2LNq32Pseudo : VLDQQLNPseudo<IIC_VLD2ln>; 1099 1100// ...with address register writeback: 1101class VLD2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1102 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb), 1103 (ins addrmode6:$Rn, am6offset:$Rm, 1104 DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2lnu, "vld2", Dt, 1105 "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm", 1106 "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> { 1107 let Inst{4} = Rn{4}; 1108 let DecoderMethod = "DecodeVLD2LN"; 1109} 1110 1111def VLD2LNd8_UPD : VLD2LNWB<0b0001, {?,?,?,?}, "8"> { 1112 let Inst{7-5} = lane{2-0}; 1113} 1114def VLD2LNd16_UPD : VLD2LNWB<0b0101, {?,?,0,?}, "16"> { 1115 let Inst{7-6} = lane{1-0}; 1116} 1117def VLD2LNd32_UPD : VLD2LNWB<0b1001, {?,0,0,?}, "32"> { 1118 let Inst{7} = lane{0}; 1119} 1120 1121def VLD2LNd8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>; 1122def VLD2LNd16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>; 1123def VLD2LNd32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>; 1124 1125def VLD2LNq16_UPD : VLD2LNWB<0b0101, {?,?,1,?}, "16"> { 1126 let Inst{7-6} = lane{1-0}; 1127} 1128def VLD2LNq32_UPD : VLD2LNWB<0b1001, {?,1,0,?}, "32"> { 1129 let Inst{7} = lane{0}; 1130} 1131 1132def VLD2LNq16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>; 1133def VLD2LNq32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>; 1134 1135// VLD3LN : Vector Load (single 3-element structure to one lane) 1136class VLD3LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1137 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 1138 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, 1139 nohash_imm:$lane), IIC_VLD3ln, "vld3", Dt, 1140 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn", 1141 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []> { 1142 let Rm = 0b1111; 1143 let DecoderMethod = "DecodeVLD3LN"; 1144} 1145 1146def VLD3LNd8 : VLD3LN<0b0010, {?,?,?,0}, "8"> { 1147 let Inst{7-5} = lane{2-0}; 1148} 1149def VLD3LNd16 : VLD3LN<0b0110, {?,?,0,0}, "16"> { 1150 let Inst{7-6} = lane{1-0}; 1151} 1152def VLD3LNd32 : VLD3LN<0b1010, {?,0,0,0}, "32"> { 1153 let Inst{7} = lane{0}; 1154} 1155 1156def VLD3LNd8Pseudo : VLDQQLNPseudo<IIC_VLD3ln>; 1157def VLD3LNd16Pseudo : VLDQQLNPseudo<IIC_VLD3ln>; 1158def VLD3LNd32Pseudo : VLDQQLNPseudo<IIC_VLD3ln>; 1159 1160// ...with double-spaced registers: 1161def VLD3LNq16 : VLD3LN<0b0110, {?,?,1,0}, "16"> { 1162 let Inst{7-6} = lane{1-0}; 1163} 1164def VLD3LNq32 : VLD3LN<0b1010, {?,1,0,0}, "32"> { 1165 let Inst{7} = lane{0}; 1166} 1167 1168def VLD3LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>; 1169def VLD3LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>; 1170 1171// ...with address register writeback: 1172class VLD3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1173 : NLdStLn<1, 0b10, op11_8, op7_4, 1174 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 1175 (ins addrmode6:$Rn, am6offset:$Rm, 1176 DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane), 1177 IIC_VLD3lnu, "vld3", Dt, 1178 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm", 1179 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb", 1180 []> { 1181 let DecoderMethod = "DecodeVLD3LN"; 1182} 1183 1184def VLD3LNd8_UPD : VLD3LNWB<0b0010, {?,?,?,0}, "8"> { 1185 let Inst{7-5} = lane{2-0}; 1186} 1187def VLD3LNd16_UPD : VLD3LNWB<0b0110, {?,?,0,0}, "16"> { 1188 let Inst{7-6} = lane{1-0}; 1189} 1190def VLD3LNd32_UPD : VLD3LNWB<0b1010, {?,0,0,0}, "32"> { 1191 let Inst{7} = lane{0}; 1192} 1193 1194def VLD3LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>; 1195def VLD3LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>; 1196def VLD3LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>; 1197 1198def VLD3LNq16_UPD : VLD3LNWB<0b0110, {?,?,1,0}, "16"> { 1199 let Inst{7-6} = lane{1-0}; 1200} 1201def VLD3LNq32_UPD : VLD3LNWB<0b1010, {?,1,0,0}, "32"> { 1202 let Inst{7} = lane{0}; 1203} 1204 1205def VLD3LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>; 1206def VLD3LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>; 1207 1208// VLD4LN : Vector Load (single 4-element structure to one lane) 1209class VLD4LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1210 : NLdStLn<1, 0b10, op11_8, op7_4, 1211 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), 1212 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, 1213 nohash_imm:$lane), IIC_VLD4ln, "vld4", Dt, 1214 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn", 1215 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []> { 1216 let Rm = 0b1111; 1217 let Inst{4} = Rn{4}; 1218 let DecoderMethod = "DecodeVLD4LN"; 1219} 1220 1221def VLD4LNd8 : VLD4LN<0b0011, {?,?,?,?}, "8"> { 1222 let Inst{7-5} = lane{2-0}; 1223} 1224def VLD4LNd16 : VLD4LN<0b0111, {?,?,0,?}, "16"> { 1225 let Inst{7-6} = lane{1-0}; 1226} 1227def VLD4LNd32 : VLD4LN<0b1011, {?,0,?,?}, "32"> { 1228 let Inst{7} = lane{0}; 1229 let Inst{5} = Rn{5}; 1230} 1231 1232def VLD4LNd8Pseudo : VLDQQLNPseudo<IIC_VLD4ln>; 1233def VLD4LNd16Pseudo : VLDQQLNPseudo<IIC_VLD4ln>; 1234def VLD4LNd32Pseudo : VLDQQLNPseudo<IIC_VLD4ln>; 1235 1236// ...with double-spaced registers: 1237def VLD4LNq16 : VLD4LN<0b0111, {?,?,1,?}, "16"> { 1238 let Inst{7-6} = lane{1-0}; 1239} 1240def VLD4LNq32 : VLD4LN<0b1011, {?,1,?,?}, "32"> { 1241 let Inst{7} = lane{0}; 1242 let Inst{5} = Rn{5}; 1243} 1244 1245def VLD4LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>; 1246def VLD4LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>; 1247 1248// ...with address register writeback: 1249class VLD4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1250 : NLdStLn<1, 0b10, op11_8, op7_4, 1251 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 1252 (ins addrmode6:$Rn, am6offset:$Rm, 1253 DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), 1254 IIC_VLD4lnu, "vld4", Dt, 1255"\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn$Rm", 1256"$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb", 1257 []> { 1258 let Inst{4} = Rn{4}; 1259 let DecoderMethod = "DecodeVLD4LN" ; 1260} 1261 1262def VLD4LNd8_UPD : VLD4LNWB<0b0011, {?,?,?,?}, "8"> { 1263 let Inst{7-5} = lane{2-0}; 1264} 1265def VLD4LNd16_UPD : VLD4LNWB<0b0111, {?,?,0,?}, "16"> { 1266 let Inst{7-6} = lane{1-0}; 1267} 1268def VLD4LNd32_UPD : VLD4LNWB<0b1011, {?,0,?,?}, "32"> { 1269 let Inst{7} = lane{0}; 1270 let Inst{5} = Rn{5}; 1271} 1272 1273def VLD4LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>; 1274def VLD4LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>; 1275def VLD4LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>; 1276 1277def VLD4LNq16_UPD : VLD4LNWB<0b0111, {?,?,1,?}, "16"> { 1278 let Inst{7-6} = lane{1-0}; 1279} 1280def VLD4LNq32_UPD : VLD4LNWB<0b1011, {?,1,?,?}, "32"> { 1281 let Inst{7} = lane{0}; 1282 let Inst{5} = Rn{5}; 1283} 1284 1285def VLD4LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>; 1286def VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>; 1287 1288} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1289 1290// VLD1DUP : Vector Load (single element to all lanes) 1291class VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp> 1292 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd), 1293 (ins addrmode6dup:$Rn), 1294 IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "", 1295 [(set VecListOneDAllLanes:$Vd, 1296 (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> { 1297 let Rm = 0b1111; 1298 let Inst{4} = Rn{4}; 1299 let DecoderMethod = "DecodeVLD1DupInstruction"; 1300} 1301def VLD1DUPd8 : VLD1DUP<{0,0,0,?}, "8", v8i8, extloadi8>; 1302def VLD1DUPd16 : VLD1DUP<{0,1,0,?}, "16", v4i16, extloadi16>; 1303def VLD1DUPd32 : VLD1DUP<{1,0,0,?}, "32", v2i32, load>; 1304 1305def : Pat<(v2f32 (NEONvdup (f32 (load addrmode6dup:$addr)))), 1306 (VLD1DUPd32 addrmode6:$addr)>; 1307 1308class VLD1QDUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp> 1309 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListDPairAllLanes:$Vd), 1310 (ins addrmode6dup:$Rn), IIC_VLD1dup, 1311 "vld1", Dt, "$Vd, $Rn", "", 1312 [(set VecListDPairAllLanes:$Vd, 1313 (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> { 1314 let Rm = 0b1111; 1315 let Inst{4} = Rn{4}; 1316 let DecoderMethod = "DecodeVLD1DupInstruction"; 1317} 1318 1319def VLD1DUPq8 : VLD1QDUP<{0,0,1,0}, "8", v16i8, extloadi8>; 1320def VLD1DUPq16 : VLD1QDUP<{0,1,1,?}, "16", v8i16, extloadi16>; 1321def VLD1DUPq32 : VLD1QDUP<{1,0,1,?}, "32", v4i32, load>; 1322 1323def : Pat<(v4f32 (NEONvdup (f32 (load addrmode6dup:$addr)))), 1324 (VLD1DUPq32 addrmode6:$addr)>; 1325 1326let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1327// ...with address register writeback: 1328multiclass VLD1DUPWB<bits<4> op7_4, string Dt> { 1329 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4, 1330 (outs VecListOneDAllLanes:$Vd, GPR:$wb), 1331 (ins addrmode6dup:$Rn), IIC_VLD1dupu, 1332 "vld1", Dt, "$Vd, $Rn!", 1333 "$Rn.addr = $wb", []> { 1334 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1335 let Inst{4} = Rn{4}; 1336 let DecoderMethod = "DecodeVLD1DupInstruction"; 1337 let AsmMatchConverter = "cvtVLDwbFixed"; 1338 } 1339 def _register : NLdSt<1, 0b10, 0b1100, op7_4, 1340 (outs VecListOneDAllLanes:$Vd, GPR:$wb), 1341 (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD1dupu, 1342 "vld1", Dt, "$Vd, $Rn, $Rm", 1343 "$Rn.addr = $wb", []> { 1344 let Inst{4} = Rn{4}; 1345 let DecoderMethod = "DecodeVLD1DupInstruction"; 1346 let AsmMatchConverter = "cvtVLDwbRegister"; 1347 } 1348} 1349multiclass VLD1QDUPWB<bits<4> op7_4, string Dt> { 1350 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4, 1351 (outs VecListDPairAllLanes:$Vd, GPR:$wb), 1352 (ins addrmode6dup:$Rn), IIC_VLD1dupu, 1353 "vld1", Dt, "$Vd, $Rn!", 1354 "$Rn.addr = $wb", []> { 1355 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1356 let Inst{4} = Rn{4}; 1357 let DecoderMethod = "DecodeVLD1DupInstruction"; 1358 let AsmMatchConverter = "cvtVLDwbFixed"; 1359 } 1360 def _register : NLdSt<1, 0b10, 0b1100, op7_4, 1361 (outs VecListDPairAllLanes:$Vd, GPR:$wb), 1362 (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD1dupu, 1363 "vld1", Dt, "$Vd, $Rn, $Rm", 1364 "$Rn.addr = $wb", []> { 1365 let Inst{4} = Rn{4}; 1366 let DecoderMethod = "DecodeVLD1DupInstruction"; 1367 let AsmMatchConverter = "cvtVLDwbRegister"; 1368 } 1369} 1370 1371defm VLD1DUPd8wb : VLD1DUPWB<{0,0,0,0}, "8">; 1372defm VLD1DUPd16wb : VLD1DUPWB<{0,1,0,?}, "16">; 1373defm VLD1DUPd32wb : VLD1DUPWB<{1,0,0,?}, "32">; 1374 1375defm VLD1DUPq8wb : VLD1QDUPWB<{0,0,1,0}, "8">; 1376defm VLD1DUPq16wb : VLD1QDUPWB<{0,1,1,?}, "16">; 1377defm VLD1DUPq32wb : VLD1QDUPWB<{1,0,1,?}, "32">; 1378 1379// VLD2DUP : Vector Load (single 2-element structure to all lanes) 1380class VLD2DUP<bits<4> op7_4, string Dt, RegisterOperand VdTy> 1381 : NLdSt<1, 0b10, 0b1101, op7_4, (outs VdTy:$Vd), 1382 (ins addrmode6dup:$Rn), IIC_VLD2dup, 1383 "vld2", Dt, "$Vd, $Rn", "", []> { 1384 let Rm = 0b1111; 1385 let Inst{4} = Rn{4}; 1386 let DecoderMethod = "DecodeVLD2DupInstruction"; 1387} 1388 1389def VLD2DUPd8 : VLD2DUP<{0,0,0,?}, "8", VecListDPairAllLanes>; 1390def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes>; 1391def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes>; 1392 1393// ...with double-spaced registers 1394def VLD2DUPd8x2 : VLD2DUP<{0,0,1,?}, "8", VecListDPairSpacedAllLanes>; 1395def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>; 1396def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>; 1397 1398// ...with address register writeback: 1399multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy> { 1400 def _fixed : NLdSt<1, 0b10, 0b1101, op7_4, 1401 (outs VdTy:$Vd, GPR:$wb), 1402 (ins addrmode6dup:$Rn), IIC_VLD2dupu, 1403 "vld2", Dt, "$Vd, $Rn!", 1404 "$Rn.addr = $wb", []> { 1405 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1406 let Inst{4} = Rn{4}; 1407 let DecoderMethod = "DecodeVLD2DupInstruction"; 1408 let AsmMatchConverter = "cvtVLDwbFixed"; 1409 } 1410 def _register : NLdSt<1, 0b10, 0b1101, op7_4, 1411 (outs VdTy:$Vd, GPR:$wb), 1412 (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD2dupu, 1413 "vld2", Dt, "$Vd, $Rn, $Rm", 1414 "$Rn.addr = $wb", []> { 1415 let Inst{4} = Rn{4}; 1416 let DecoderMethod = "DecodeVLD2DupInstruction"; 1417 let AsmMatchConverter = "cvtVLDwbRegister"; 1418 } 1419} 1420 1421defm VLD2DUPd8wb : VLD2DUPWB<{0,0,0,0}, "8", VecListDPairAllLanes>; 1422defm VLD2DUPd16wb : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes>; 1423defm VLD2DUPd32wb : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes>; 1424 1425defm VLD2DUPd8x2wb : VLD2DUPWB<{0,0,1,0}, "8", VecListDPairSpacedAllLanes>; 1426defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>; 1427defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>; 1428 1429// VLD3DUP : Vector Load (single 3-element structure to all lanes) 1430class VLD3DUP<bits<4> op7_4, string Dt> 1431 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 1432 (ins addrmode6dup:$Rn), IIC_VLD3dup, 1433 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []> { 1434 let Rm = 0b1111; 1435 let Inst{4} = 0; 1436 let DecoderMethod = "DecodeVLD3DupInstruction"; 1437} 1438 1439def VLD3DUPd8 : VLD3DUP<{0,0,0,?}, "8">; 1440def VLD3DUPd16 : VLD3DUP<{0,1,0,?}, "16">; 1441def VLD3DUPd32 : VLD3DUP<{1,0,0,?}, "32">; 1442 1443def VLD3DUPd8Pseudo : VLDQQPseudo<IIC_VLD3dup>; 1444def VLD3DUPd16Pseudo : VLDQQPseudo<IIC_VLD3dup>; 1445def VLD3DUPd32Pseudo : VLDQQPseudo<IIC_VLD3dup>; 1446 1447// ...with double-spaced registers (not used for codegen): 1448def VLD3DUPq8 : VLD3DUP<{0,0,1,?}, "8">; 1449def VLD3DUPq16 : VLD3DUP<{0,1,1,?}, "16">; 1450def VLD3DUPq32 : VLD3DUP<{1,0,1,?}, "32">; 1451 1452// ...with address register writeback: 1453class VLD3DUPWB<bits<4> op7_4, string Dt> 1454 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 1455 (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD3dupu, 1456 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm", 1457 "$Rn.addr = $wb", []> { 1458 let Inst{4} = 0; 1459 let DecoderMethod = "DecodeVLD3DupInstruction"; 1460} 1461 1462def VLD3DUPd8_UPD : VLD3DUPWB<{0,0,0,0}, "8">; 1463def VLD3DUPd16_UPD : VLD3DUPWB<{0,1,0,?}, "16">; 1464def VLD3DUPd32_UPD : VLD3DUPWB<{1,0,0,?}, "32">; 1465 1466def VLD3DUPq8_UPD : VLD3DUPWB<{0,0,1,0}, "8">; 1467def VLD3DUPq16_UPD : VLD3DUPWB<{0,1,1,?}, "16">; 1468def VLD3DUPq32_UPD : VLD3DUPWB<{1,0,1,?}, "32">; 1469 1470def VLD3DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>; 1471def VLD3DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>; 1472def VLD3DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>; 1473 1474// VLD4DUP : Vector Load (single 4-element structure to all lanes) 1475class VLD4DUP<bits<4> op7_4, string Dt> 1476 : NLdSt<1, 0b10, 0b1111, op7_4, 1477 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), 1478 (ins addrmode6dup:$Rn), IIC_VLD4dup, 1479 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> { 1480 let Rm = 0b1111; 1481 let Inst{4} = Rn{4}; 1482 let DecoderMethod = "DecodeVLD4DupInstruction"; 1483} 1484 1485def VLD4DUPd8 : VLD4DUP<{0,0,0,?}, "8">; 1486def VLD4DUPd16 : VLD4DUP<{0,1,0,?}, "16">; 1487def VLD4DUPd32 : VLD4DUP<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; } 1488 1489def VLD4DUPd8Pseudo : VLDQQPseudo<IIC_VLD4dup>; 1490def VLD4DUPd16Pseudo : VLDQQPseudo<IIC_VLD4dup>; 1491def VLD4DUPd32Pseudo : VLDQQPseudo<IIC_VLD4dup>; 1492 1493// ...with double-spaced registers (not used for codegen): 1494def VLD4DUPq8 : VLD4DUP<{0,0,1,?}, "8">; 1495def VLD4DUPq16 : VLD4DUP<{0,1,1,?}, "16">; 1496def VLD4DUPq32 : VLD4DUP<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; } 1497 1498// ...with address register writeback: 1499class VLD4DUPWB<bits<4> op7_4, string Dt> 1500 : NLdSt<1, 0b10, 0b1111, op7_4, 1501 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 1502 (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD4dupu, 1503 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm", 1504 "$Rn.addr = $wb", []> { 1505 let Inst{4} = Rn{4}; 1506 let DecoderMethod = "DecodeVLD4DupInstruction"; 1507} 1508 1509def VLD4DUPd8_UPD : VLD4DUPWB<{0,0,0,0}, "8">; 1510def VLD4DUPd16_UPD : VLD4DUPWB<{0,1,0,?}, "16">; 1511def VLD4DUPd32_UPD : VLD4DUPWB<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; } 1512 1513def VLD4DUPq8_UPD : VLD4DUPWB<{0,0,1,0}, "8">; 1514def VLD4DUPq16_UPD : VLD4DUPWB<{0,1,1,?}, "16">; 1515def VLD4DUPq32_UPD : VLD4DUPWB<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; } 1516 1517def VLD4DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>; 1518def VLD4DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>; 1519def VLD4DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>; 1520 1521} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1522 1523let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 1524 1525// Classes for VST* pseudo-instructions with multi-register operands. 1526// These are expanded to real instructions after register allocation. 1527class VSTQPseudo<InstrItinClass itin> 1528 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src), itin, "">; 1529class VSTQWBPseudo<InstrItinClass itin> 1530 : PseudoNLdSt<(outs GPR:$wb), 1531 (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin, 1532 "$addr.addr = $wb">; 1533class VSTQWBfixedPseudo<InstrItinClass itin> 1534 : PseudoNLdSt<(outs GPR:$wb), 1535 (ins addrmode6:$addr, QPR:$src), itin, 1536 "$addr.addr = $wb">; 1537class VSTQWBregisterPseudo<InstrItinClass itin> 1538 : PseudoNLdSt<(outs GPR:$wb), 1539 (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin, 1540 "$addr.addr = $wb">; 1541class VSTQQPseudo<InstrItinClass itin> 1542 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">; 1543class VSTQQWBPseudo<InstrItinClass itin> 1544 : PseudoNLdSt<(outs GPR:$wb), 1545 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src), itin, 1546 "$addr.addr = $wb">; 1547class VSTQQWBfixedPseudo<InstrItinClass itin> 1548 : PseudoNLdSt<(outs GPR:$wb), 1549 (ins addrmode6:$addr, QQPR:$src), itin, 1550 "$addr.addr = $wb">; 1551class VSTQQWBregisterPseudo<InstrItinClass itin> 1552 : PseudoNLdSt<(outs GPR:$wb), 1553 (ins addrmode6:$addr, rGPR:$offset, QQPR:$src), itin, 1554 "$addr.addr = $wb">; 1555 1556class VSTQQQQPseudo<InstrItinClass itin> 1557 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src), itin, "">; 1558class VSTQQQQWBPseudo<InstrItinClass itin> 1559 : PseudoNLdSt<(outs GPR:$wb), 1560 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin, 1561 "$addr.addr = $wb">; 1562 1563// VST1 : Vector Store (multiple single elements) 1564class VST1D<bits<4> op7_4, string Dt> 1565 : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins addrmode6:$Rn, VecListOneD:$Vd), 1566 IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []> { 1567 let Rm = 0b1111; 1568 let Inst{4} = Rn{4}; 1569 let DecoderMethod = "DecodeVSTInstruction"; 1570} 1571class VST1Q<bits<4> op7_4, string Dt> 1572 : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins addrmode6:$Rn, VecListDPair:$Vd), 1573 IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []> { 1574 let Rm = 0b1111; 1575 let Inst{5-4} = Rn{5-4}; 1576 let DecoderMethod = "DecodeVSTInstruction"; 1577} 1578 1579def VST1d8 : VST1D<{0,0,0,?}, "8">; 1580def VST1d16 : VST1D<{0,1,0,?}, "16">; 1581def VST1d32 : VST1D<{1,0,0,?}, "32">; 1582def VST1d64 : VST1D<{1,1,0,?}, "64">; 1583 1584def VST1q8 : VST1Q<{0,0,?,?}, "8">; 1585def VST1q16 : VST1Q<{0,1,?,?}, "16">; 1586def VST1q32 : VST1Q<{1,0,?,?}, "32">; 1587def VST1q64 : VST1Q<{1,1,?,?}, "64">; 1588 1589// ...with address register writeback: 1590multiclass VST1DWB<bits<4> op7_4, string Dt> { 1591 def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb), 1592 (ins addrmode6:$Rn, VecListOneD:$Vd), IIC_VLD1u, 1593 "vst1", Dt, "$Vd, $Rn!", 1594 "$Rn.addr = $wb", []> { 1595 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1596 let Inst{4} = Rn{4}; 1597 let DecoderMethod = "DecodeVSTInstruction"; 1598 let AsmMatchConverter = "cvtVSTwbFixed"; 1599 } 1600 def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb), 1601 (ins addrmode6:$Rn, rGPR:$Rm, VecListOneD:$Vd), 1602 IIC_VLD1u, 1603 "vst1", Dt, "$Vd, $Rn, $Rm", 1604 "$Rn.addr = $wb", []> { 1605 let Inst{4} = Rn{4}; 1606 let DecoderMethod = "DecodeVSTInstruction"; 1607 let AsmMatchConverter = "cvtVSTwbRegister"; 1608 } 1609} 1610multiclass VST1QWB<bits<4> op7_4, string Dt> { 1611 def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), 1612 (ins addrmode6:$Rn, VecListDPair:$Vd), IIC_VLD1x2u, 1613 "vst1", Dt, "$Vd, $Rn!", 1614 "$Rn.addr = $wb", []> { 1615 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1616 let Inst{5-4} = Rn{5-4}; 1617 let DecoderMethod = "DecodeVSTInstruction"; 1618 let AsmMatchConverter = "cvtVSTwbFixed"; 1619 } 1620 def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), 1621 (ins addrmode6:$Rn, rGPR:$Rm, VecListDPair:$Vd), 1622 IIC_VLD1x2u, 1623 "vst1", Dt, "$Vd, $Rn, $Rm", 1624 "$Rn.addr = $wb", []> { 1625 let Inst{5-4} = Rn{5-4}; 1626 let DecoderMethod = "DecodeVSTInstruction"; 1627 let AsmMatchConverter = "cvtVSTwbRegister"; 1628 } 1629} 1630 1631defm VST1d8wb : VST1DWB<{0,0,0,?}, "8">; 1632defm VST1d16wb : VST1DWB<{0,1,0,?}, "16">; 1633defm VST1d32wb : VST1DWB<{1,0,0,?}, "32">; 1634defm VST1d64wb : VST1DWB<{1,1,0,?}, "64">; 1635 1636defm VST1q8wb : VST1QWB<{0,0,?,?}, "8">; 1637defm VST1q16wb : VST1QWB<{0,1,?,?}, "16">; 1638defm VST1q32wb : VST1QWB<{1,0,?,?}, "32">; 1639defm VST1q64wb : VST1QWB<{1,1,?,?}, "64">; 1640 1641// ...with 3 registers 1642class VST1D3<bits<4> op7_4, string Dt> 1643 : NLdSt<0, 0b00, 0b0110, op7_4, (outs), 1644 (ins addrmode6:$Rn, VecListThreeD:$Vd), 1645 IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []> { 1646 let Rm = 0b1111; 1647 let Inst{4} = Rn{4}; 1648 let DecoderMethod = "DecodeVSTInstruction"; 1649} 1650multiclass VST1D3WB<bits<4> op7_4, string Dt> { 1651 def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), 1652 (ins addrmode6:$Rn, VecListThreeD:$Vd), IIC_VLD1x3u, 1653 "vst1", Dt, "$Vd, $Rn!", 1654 "$Rn.addr = $wb", []> { 1655 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1656 let Inst{5-4} = Rn{5-4}; 1657 let DecoderMethod = "DecodeVSTInstruction"; 1658 let AsmMatchConverter = "cvtVSTwbFixed"; 1659 } 1660 def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), 1661 (ins addrmode6:$Rn, rGPR:$Rm, VecListThreeD:$Vd), 1662 IIC_VLD1x3u, 1663 "vst1", Dt, "$Vd, $Rn, $Rm", 1664 "$Rn.addr = $wb", []> { 1665 let Inst{5-4} = Rn{5-4}; 1666 let DecoderMethod = "DecodeVSTInstruction"; 1667 let AsmMatchConverter = "cvtVSTwbRegister"; 1668 } 1669} 1670 1671def VST1d8T : VST1D3<{0,0,0,?}, "8">; 1672def VST1d16T : VST1D3<{0,1,0,?}, "16">; 1673def VST1d32T : VST1D3<{1,0,0,?}, "32">; 1674def VST1d64T : VST1D3<{1,1,0,?}, "64">; 1675 1676defm VST1d8Twb : VST1D3WB<{0,0,0,?}, "8">; 1677defm VST1d16Twb : VST1D3WB<{0,1,0,?}, "16">; 1678defm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32">; 1679defm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64">; 1680 1681def VST1d64TPseudo : VSTQQPseudo<IIC_VST1x3>; 1682def VST1d64TPseudoWB_fixed : VSTQQWBPseudo<IIC_VST1x3u>; 1683def VST1d64TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>; 1684 1685// ...with 4 registers 1686class VST1D4<bits<4> op7_4, string Dt> 1687 : NLdSt<0, 0b00, 0b0010, op7_4, (outs), 1688 (ins addrmode6:$Rn, VecListFourD:$Vd), 1689 IIC_VST1x4, "vst1", Dt, "$Vd, $Rn", "", 1690 []> { 1691 let Rm = 0b1111; 1692 let Inst{5-4} = Rn{5-4}; 1693 let DecoderMethod = "DecodeVSTInstruction"; 1694} 1695multiclass VST1D4WB<bits<4> op7_4, string Dt> { 1696 def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), 1697 (ins addrmode6:$Rn, VecListFourD:$Vd), IIC_VLD1x4u, 1698 "vst1", Dt, "$Vd, $Rn!", 1699 "$Rn.addr = $wb", []> { 1700 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1701 let Inst{5-4} = Rn{5-4}; 1702 let DecoderMethod = "DecodeVSTInstruction"; 1703 let AsmMatchConverter = "cvtVSTwbFixed"; 1704 } 1705 def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), 1706 (ins addrmode6:$Rn, rGPR:$Rm, VecListFourD:$Vd), 1707 IIC_VLD1x4u, 1708 "vst1", Dt, "$Vd, $Rn, $Rm", 1709 "$Rn.addr = $wb", []> { 1710 let Inst{5-4} = Rn{5-4}; 1711 let DecoderMethod = "DecodeVSTInstruction"; 1712 let AsmMatchConverter = "cvtVSTwbRegister"; 1713 } 1714} 1715 1716def VST1d8Q : VST1D4<{0,0,?,?}, "8">; 1717def VST1d16Q : VST1D4<{0,1,?,?}, "16">; 1718def VST1d32Q : VST1D4<{1,0,?,?}, "32">; 1719def VST1d64Q : VST1D4<{1,1,?,?}, "64">; 1720 1721defm VST1d8Qwb : VST1D4WB<{0,0,?,?}, "8">; 1722defm VST1d16Qwb : VST1D4WB<{0,1,?,?}, "16">; 1723defm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32">; 1724defm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64">; 1725 1726def VST1d64QPseudo : VSTQQPseudo<IIC_VST1x4>; 1727def VST1d64QPseudoWB_fixed : VSTQQWBPseudo<IIC_VST1x4u>; 1728def VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>; 1729 1730// VST2 : Vector Store (multiple 2-element structures) 1731class VST2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, 1732 InstrItinClass itin> 1733 : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd), 1734 itin, "vst2", Dt, "$Vd, $Rn", "", []> { 1735 let Rm = 0b1111; 1736 let Inst{5-4} = Rn{5-4}; 1737 let DecoderMethod = "DecodeVSTInstruction"; 1738} 1739 1740def VST2d8 : VST2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VST2>; 1741def VST2d16 : VST2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VST2>; 1742def VST2d32 : VST2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VST2>; 1743 1744def VST2q8 : VST2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VST2x2>; 1745def VST2q16 : VST2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VST2x2>; 1746def VST2q32 : VST2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VST2x2>; 1747 1748def VST2q8Pseudo : VSTQQPseudo<IIC_VST2x2>; 1749def VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>; 1750def VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>; 1751 1752// ...with address register writeback: 1753multiclass VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt, 1754 RegisterOperand VdTy> { 1755 def _fixed : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1756 (ins addrmode6:$Rn, VdTy:$Vd), IIC_VLD1u, 1757 "vst2", Dt, "$Vd, $Rn!", 1758 "$Rn.addr = $wb", []> { 1759 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1760 let Inst{5-4} = Rn{5-4}; 1761 let DecoderMethod = "DecodeVSTInstruction"; 1762 let AsmMatchConverter = "cvtVSTwbFixed"; 1763 } 1764 def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1765 (ins addrmode6:$Rn, rGPR:$Rm, VdTy:$Vd), IIC_VLD1u, 1766 "vst2", Dt, "$Vd, $Rn, $Rm", 1767 "$Rn.addr = $wb", []> { 1768 let Inst{5-4} = Rn{5-4}; 1769 let DecoderMethod = "DecodeVSTInstruction"; 1770 let AsmMatchConverter = "cvtVSTwbRegister"; 1771 } 1772} 1773multiclass VST2QWB<bits<4> op7_4, string Dt> { 1774 def _fixed : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), 1775 (ins addrmode6:$Rn, VecListFourD:$Vd), IIC_VLD1u, 1776 "vst2", Dt, "$Vd, $Rn!", 1777 "$Rn.addr = $wb", []> { 1778 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1779 let Inst{5-4} = Rn{5-4}; 1780 let DecoderMethod = "DecodeVSTInstruction"; 1781 let AsmMatchConverter = "cvtVSTwbFixed"; 1782 } 1783 def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), 1784 (ins addrmode6:$Rn, rGPR:$Rm, VecListFourD:$Vd), 1785 IIC_VLD1u, 1786 "vst2", Dt, "$Vd, $Rn, $Rm", 1787 "$Rn.addr = $wb", []> { 1788 let Inst{5-4} = Rn{5-4}; 1789 let DecoderMethod = "DecodeVSTInstruction"; 1790 let AsmMatchConverter = "cvtVSTwbRegister"; 1791 } 1792} 1793 1794defm VST2d8wb : VST2DWB<0b1000, {0,0,?,?}, "8", VecListDPair>; 1795defm VST2d16wb : VST2DWB<0b1000, {0,1,?,?}, "16", VecListDPair>; 1796defm VST2d32wb : VST2DWB<0b1000, {1,0,?,?}, "32", VecListDPair>; 1797 1798defm VST2q8wb : VST2QWB<{0,0,?,?}, "8">; 1799defm VST2q16wb : VST2QWB<{0,1,?,?}, "16">; 1800defm VST2q32wb : VST2QWB<{1,0,?,?}, "32">; 1801 1802def VST2q8PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>; 1803def VST2q16PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>; 1804def VST2q32PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>; 1805def VST2q8PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>; 1806def VST2q16PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>; 1807def VST2q32PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>; 1808 1809// ...with double-spaced registers 1810def VST2b8 : VST2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VST2>; 1811def VST2b16 : VST2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VST2>; 1812def VST2b32 : VST2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VST2>; 1813defm VST2b8wb : VST2DWB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced>; 1814defm VST2b16wb : VST2DWB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced>; 1815defm VST2b32wb : VST2DWB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced>; 1816 1817// VST3 : Vector Store (multiple 3-element structures) 1818class VST3D<bits<4> op11_8, bits<4> op7_4, string Dt> 1819 : NLdSt<0, 0b00, op11_8, op7_4, (outs), 1820 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3, 1821 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> { 1822 let Rm = 0b1111; 1823 let Inst{4} = Rn{4}; 1824 let DecoderMethod = "DecodeVSTInstruction"; 1825} 1826 1827def VST3d8 : VST3D<0b0100, {0,0,0,?}, "8">; 1828def VST3d16 : VST3D<0b0100, {0,1,0,?}, "16">; 1829def VST3d32 : VST3D<0b0100, {1,0,0,?}, "32">; 1830 1831def VST3d8Pseudo : VSTQQPseudo<IIC_VST3>; 1832def VST3d16Pseudo : VSTQQPseudo<IIC_VST3>; 1833def VST3d32Pseudo : VSTQQPseudo<IIC_VST3>; 1834 1835// ...with address register writeback: 1836class VST3DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1837 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1838 (ins addrmode6:$Rn, am6offset:$Rm, 1839 DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3u, 1840 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm", 1841 "$Rn.addr = $wb", []> { 1842 let Inst{4} = Rn{4}; 1843 let DecoderMethod = "DecodeVSTInstruction"; 1844} 1845 1846def VST3d8_UPD : VST3DWB<0b0100, {0,0,0,?}, "8">; 1847def VST3d16_UPD : VST3DWB<0b0100, {0,1,0,?}, "16">; 1848def VST3d32_UPD : VST3DWB<0b0100, {1,0,0,?}, "32">; 1849 1850def VST3d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>; 1851def VST3d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>; 1852def VST3d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>; 1853 1854// ...with double-spaced registers: 1855def VST3q8 : VST3D<0b0101, {0,0,0,?}, "8">; 1856def VST3q16 : VST3D<0b0101, {0,1,0,?}, "16">; 1857def VST3q32 : VST3D<0b0101, {1,0,0,?}, "32">; 1858def VST3q8_UPD : VST3DWB<0b0101, {0,0,0,?}, "8">; 1859def VST3q16_UPD : VST3DWB<0b0101, {0,1,0,?}, "16">; 1860def VST3q32_UPD : VST3DWB<0b0101, {1,0,0,?}, "32">; 1861 1862def VST3q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1863def VST3q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1864def VST3q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1865 1866// ...alternate versions to be allocated odd register numbers: 1867def VST3q8oddPseudo : VSTQQQQPseudo<IIC_VST3>; 1868def VST3q16oddPseudo : VSTQQQQPseudo<IIC_VST3>; 1869def VST3q32oddPseudo : VSTQQQQPseudo<IIC_VST3>; 1870 1871def VST3q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1872def VST3q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1873def VST3q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>; 1874 1875// VST4 : Vector Store (multiple 4-element structures) 1876class VST4D<bits<4> op11_8, bits<4> op7_4, string Dt> 1877 : NLdSt<0, 0b00, op11_8, op7_4, (outs), 1878 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), 1879 IIC_VST4, "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn", 1880 "", []> { 1881 let Rm = 0b1111; 1882 let Inst{5-4} = Rn{5-4}; 1883 let DecoderMethod = "DecodeVSTInstruction"; 1884} 1885 1886def VST4d8 : VST4D<0b0000, {0,0,?,?}, "8">; 1887def VST4d16 : VST4D<0b0000, {0,1,?,?}, "16">; 1888def VST4d32 : VST4D<0b0000, {1,0,?,?}, "32">; 1889 1890def VST4d8Pseudo : VSTQQPseudo<IIC_VST4>; 1891def VST4d16Pseudo : VSTQQPseudo<IIC_VST4>; 1892def VST4d32Pseudo : VSTQQPseudo<IIC_VST4>; 1893 1894// ...with address register writeback: 1895class VST4DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1896 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1897 (ins addrmode6:$Rn, am6offset:$Rm, 1898 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST4u, 1899 "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", 1900 "$Rn.addr = $wb", []> { 1901 let Inst{5-4} = Rn{5-4}; 1902 let DecoderMethod = "DecodeVSTInstruction"; 1903} 1904 1905def VST4d8_UPD : VST4DWB<0b0000, {0,0,?,?}, "8">; 1906def VST4d16_UPD : VST4DWB<0b0000, {0,1,?,?}, "16">; 1907def VST4d32_UPD : VST4DWB<0b0000, {1,0,?,?}, "32">; 1908 1909def VST4d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>; 1910def VST4d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>; 1911def VST4d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>; 1912 1913// ...with double-spaced registers: 1914def VST4q8 : VST4D<0b0001, {0,0,?,?}, "8">; 1915def VST4q16 : VST4D<0b0001, {0,1,?,?}, "16">; 1916def VST4q32 : VST4D<0b0001, {1,0,?,?}, "32">; 1917def VST4q8_UPD : VST4DWB<0b0001, {0,0,?,?}, "8">; 1918def VST4q16_UPD : VST4DWB<0b0001, {0,1,?,?}, "16">; 1919def VST4q32_UPD : VST4DWB<0b0001, {1,0,?,?}, "32">; 1920 1921def VST4q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1922def VST4q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1923def VST4q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1924 1925// ...alternate versions to be allocated odd register numbers: 1926def VST4q8oddPseudo : VSTQQQQPseudo<IIC_VST4>; 1927def VST4q16oddPseudo : VSTQQQQPseudo<IIC_VST4>; 1928def VST4q32oddPseudo : VSTQQQQPseudo<IIC_VST4>; 1929 1930def VST4q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1931def VST4q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1932def VST4q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>; 1933 1934} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 1935 1936// Classes for VST*LN pseudo-instructions with multi-register operands. 1937// These are expanded to real instructions after register allocation. 1938class VSTQLNPseudo<InstrItinClass itin> 1939 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane), 1940 itin, "">; 1941class VSTQLNWBPseudo<InstrItinClass itin> 1942 : PseudoNLdSt<(outs GPR:$wb), 1943 (ins addrmode6:$addr, am6offset:$offset, QPR:$src, 1944 nohash_imm:$lane), itin, "$addr.addr = $wb">; 1945class VSTQQLNPseudo<InstrItinClass itin> 1946 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane), 1947 itin, "">; 1948class VSTQQLNWBPseudo<InstrItinClass itin> 1949 : PseudoNLdSt<(outs GPR:$wb), 1950 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src, 1951 nohash_imm:$lane), itin, "$addr.addr = $wb">; 1952class VSTQQQQLNPseudo<InstrItinClass itin> 1953 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane), 1954 itin, "">; 1955class VSTQQQQLNWBPseudo<InstrItinClass itin> 1956 : PseudoNLdSt<(outs GPR:$wb), 1957 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src, 1958 nohash_imm:$lane), itin, "$addr.addr = $wb">; 1959 1960// VST1LN : Vector Store (single element from one lane) 1961class VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 1962 PatFrag StoreOp, SDNode ExtractOp, Operand AddrMode> 1963 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 1964 (ins AddrMode:$Rn, DPR:$Vd, nohash_imm:$lane), 1965 IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "", 1966 [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), AddrMode:$Rn)]> { 1967 let Rm = 0b1111; 1968 let DecoderMethod = "DecodeVST1LN"; 1969} 1970class VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> 1971 : VSTQLNPseudo<IIC_VST1ln> { 1972 let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), 1973 addrmode6:$addr)]; 1974} 1975 1976def VST1LNd8 : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8, 1977 NEONvgetlaneu, addrmode6> { 1978 let Inst{7-5} = lane{2-0}; 1979} 1980def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16, 1981 NEONvgetlaneu, addrmode6> { 1982 let Inst{7-6} = lane{1-0}; 1983 let Inst{4} = Rn{4}; 1984} 1985 1986def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt, 1987 addrmode6oneL32> { 1988 let Inst{7} = lane{0}; 1989 let Inst{5-4} = Rn{5-4}; 1990} 1991 1992def VST1LNq8Pseudo : VST1QLNPseudo<v16i8, truncstorei8, NEONvgetlaneu>; 1993def VST1LNq16Pseudo : VST1QLNPseudo<v8i16, truncstorei16, NEONvgetlaneu>; 1994def VST1LNq32Pseudo : VST1QLNPseudo<v4i32, store, extractelt>; 1995 1996def : Pat<(store (extractelt (v2f32 DPR:$src), imm:$lane), addrmode6:$addr), 1997 (VST1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>; 1998def : Pat<(store (extractelt (v4f32 QPR:$src), imm:$lane), addrmode6:$addr), 1999 (VST1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 2000 2001// ...with address register writeback: 2002class VST1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 2003 PatFrag StoreOp, SDNode ExtractOp, Operand AdrMode> 2004 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2005 (ins AdrMode:$Rn, am6offset:$Rm, 2006 DPR:$Vd, nohash_imm:$lane), IIC_VST1lnu, "vst1", Dt, 2007 "\\{$Vd[$lane]\\}, $Rn$Rm", 2008 "$Rn.addr = $wb", 2009 [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), 2010 AdrMode:$Rn, am6offset:$Rm))]> { 2011 let DecoderMethod = "DecodeVST1LN"; 2012} 2013class VST1QLNWBPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> 2014 : VSTQLNWBPseudo<IIC_VST1lnu> { 2015 let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), 2016 addrmode6:$addr, am6offset:$offset))]; 2017} 2018 2019def VST1LNd8_UPD : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8, 2020 NEONvgetlaneu, addrmode6> { 2021 let Inst{7-5} = lane{2-0}; 2022} 2023def VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16, 2024 NEONvgetlaneu, addrmode6> { 2025 let Inst{7-6} = lane{1-0}; 2026 let Inst{4} = Rn{4}; 2027} 2028def VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store, 2029 extractelt, addrmode6oneL32> { 2030 let Inst{7} = lane{0}; 2031 let Inst{5-4} = Rn{5-4}; 2032} 2033 2034def VST1LNq8Pseudo_UPD : VST1QLNWBPseudo<v16i8, post_truncsti8, NEONvgetlaneu>; 2035def VST1LNq16Pseudo_UPD : VST1QLNWBPseudo<v8i16, post_truncsti16,NEONvgetlaneu>; 2036def VST1LNq32Pseudo_UPD : VST1QLNWBPseudo<v4i32, post_store, extractelt>; 2037 2038let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 2039 2040// VST2LN : Vector Store (single 2-element structure from one lane) 2041class VST2LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2042 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2043 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, nohash_imm:$lane), 2044 IIC_VST2ln, "vst2", Dt, "\\{$Vd[$lane], $src2[$lane]\\}, $Rn", 2045 "", []> { 2046 let Rm = 0b1111; 2047 let Inst{4} = Rn{4}; 2048 let DecoderMethod = "DecodeVST2LN"; 2049} 2050 2051def VST2LNd8 : VST2LN<0b0001, {?,?,?,?}, "8"> { 2052 let Inst{7-5} = lane{2-0}; 2053} 2054def VST2LNd16 : VST2LN<0b0101, {?,?,0,?}, "16"> { 2055 let Inst{7-6} = lane{1-0}; 2056} 2057def VST2LNd32 : VST2LN<0b1001, {?,0,0,?}, "32"> { 2058 let Inst{7} = lane{0}; 2059} 2060 2061def VST2LNd8Pseudo : VSTQLNPseudo<IIC_VST2ln>; 2062def VST2LNd16Pseudo : VSTQLNPseudo<IIC_VST2ln>; 2063def VST2LNd32Pseudo : VSTQLNPseudo<IIC_VST2ln>; 2064 2065// ...with double-spaced registers: 2066def VST2LNq16 : VST2LN<0b0101, {?,?,1,?}, "16"> { 2067 let Inst{7-6} = lane{1-0}; 2068 let Inst{4} = Rn{4}; 2069} 2070def VST2LNq32 : VST2LN<0b1001, {?,1,0,?}, "32"> { 2071 let Inst{7} = lane{0}; 2072 let Inst{4} = Rn{4}; 2073} 2074 2075def VST2LNq16Pseudo : VSTQQLNPseudo<IIC_VST2ln>; 2076def VST2LNq32Pseudo : VSTQQLNPseudo<IIC_VST2ln>; 2077 2078// ...with address register writeback: 2079class VST2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2080 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2081 (ins addrmode6:$Rn, am6offset:$Rm, 2082 DPR:$Vd, DPR:$src2, nohash_imm:$lane), IIC_VST2lnu, "vst2", Dt, 2083 "\\{$Vd[$lane], $src2[$lane]\\}, $Rn$Rm", 2084 "$Rn.addr = $wb", []> { 2085 let Inst{4} = Rn{4}; 2086 let DecoderMethod = "DecodeVST2LN"; 2087} 2088 2089def VST2LNd8_UPD : VST2LNWB<0b0001, {?,?,?,?}, "8"> { 2090 let Inst{7-5} = lane{2-0}; 2091} 2092def VST2LNd16_UPD : VST2LNWB<0b0101, {?,?,0,?}, "16"> { 2093 let Inst{7-6} = lane{1-0}; 2094} 2095def VST2LNd32_UPD : VST2LNWB<0b1001, {?,0,0,?}, "32"> { 2096 let Inst{7} = lane{0}; 2097} 2098 2099def VST2LNd8Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>; 2100def VST2LNd16Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>; 2101def VST2LNd32Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>; 2102 2103def VST2LNq16_UPD : VST2LNWB<0b0101, {?,?,1,?}, "16"> { 2104 let Inst{7-6} = lane{1-0}; 2105} 2106def VST2LNq32_UPD : VST2LNWB<0b1001, {?,1,0,?}, "32"> { 2107 let Inst{7} = lane{0}; 2108} 2109 2110def VST2LNq16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>; 2111def VST2LNq32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>; 2112 2113// VST3LN : Vector Store (single 3-element structure from one lane) 2114class VST3LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2115 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2116 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, 2117 nohash_imm:$lane), IIC_VST3ln, "vst3", Dt, 2118 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []> { 2119 let Rm = 0b1111; 2120 let DecoderMethod = "DecodeVST3LN"; 2121} 2122 2123def VST3LNd8 : VST3LN<0b0010, {?,?,?,0}, "8"> { 2124 let Inst{7-5} = lane{2-0}; 2125} 2126def VST3LNd16 : VST3LN<0b0110, {?,?,0,0}, "16"> { 2127 let Inst{7-6} = lane{1-0}; 2128} 2129def VST3LNd32 : VST3LN<0b1010, {?,0,0,0}, "32"> { 2130 let Inst{7} = lane{0}; 2131} 2132 2133def VST3LNd8Pseudo : VSTQQLNPseudo<IIC_VST3ln>; 2134def VST3LNd16Pseudo : VSTQQLNPseudo<IIC_VST3ln>; 2135def VST3LNd32Pseudo : VSTQQLNPseudo<IIC_VST3ln>; 2136 2137// ...with double-spaced registers: 2138def VST3LNq16 : VST3LN<0b0110, {?,?,1,0}, "16"> { 2139 let Inst{7-6} = lane{1-0}; 2140} 2141def VST3LNq32 : VST3LN<0b1010, {?,1,0,0}, "32"> { 2142 let Inst{7} = lane{0}; 2143} 2144 2145def VST3LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>; 2146def VST3LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>; 2147 2148// ...with address register writeback: 2149class VST3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2150 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2151 (ins addrmode6:$Rn, am6offset:$Rm, 2152 DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane), 2153 IIC_VST3lnu, "vst3", Dt, 2154 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm", 2155 "$Rn.addr = $wb", []> { 2156 let DecoderMethod = "DecodeVST3LN"; 2157} 2158 2159def VST3LNd8_UPD : VST3LNWB<0b0010, {?,?,?,0}, "8"> { 2160 let Inst{7-5} = lane{2-0}; 2161} 2162def VST3LNd16_UPD : VST3LNWB<0b0110, {?,?,0,0}, "16"> { 2163 let Inst{7-6} = lane{1-0}; 2164} 2165def VST3LNd32_UPD : VST3LNWB<0b1010, {?,0,0,0}, "32"> { 2166 let Inst{7} = lane{0}; 2167} 2168 2169def VST3LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>; 2170def VST3LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>; 2171def VST3LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>; 2172 2173def VST3LNq16_UPD : VST3LNWB<0b0110, {?,?,1,0}, "16"> { 2174 let Inst{7-6} = lane{1-0}; 2175} 2176def VST3LNq32_UPD : VST3LNWB<0b1010, {?,1,0,0}, "32"> { 2177 let Inst{7} = lane{0}; 2178} 2179 2180def VST3LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>; 2181def VST3LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>; 2182 2183// VST4LN : Vector Store (single 4-element structure from one lane) 2184class VST4LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2185 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2186 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, 2187 nohash_imm:$lane), IIC_VST4ln, "vst4", Dt, 2188 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn", 2189 "", []> { 2190 let Rm = 0b1111; 2191 let Inst{4} = Rn{4}; 2192 let DecoderMethod = "DecodeVST4LN"; 2193} 2194 2195def VST4LNd8 : VST4LN<0b0011, {?,?,?,?}, "8"> { 2196 let Inst{7-5} = lane{2-0}; 2197} 2198def VST4LNd16 : VST4LN<0b0111, {?,?,0,?}, "16"> { 2199 let Inst{7-6} = lane{1-0}; 2200} 2201def VST4LNd32 : VST4LN<0b1011, {?,0,?,?}, "32"> { 2202 let Inst{7} = lane{0}; 2203 let Inst{5} = Rn{5}; 2204} 2205 2206def VST4LNd8Pseudo : VSTQQLNPseudo<IIC_VST4ln>; 2207def VST4LNd16Pseudo : VSTQQLNPseudo<IIC_VST4ln>; 2208def VST4LNd32Pseudo : VSTQQLNPseudo<IIC_VST4ln>; 2209 2210// ...with double-spaced registers: 2211def VST4LNq16 : VST4LN<0b0111, {?,?,1,?}, "16"> { 2212 let Inst{7-6} = lane{1-0}; 2213} 2214def VST4LNq32 : VST4LN<0b1011, {?,1,?,?}, "32"> { 2215 let Inst{7} = lane{0}; 2216 let Inst{5} = Rn{5}; 2217} 2218 2219def VST4LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>; 2220def VST4LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>; 2221 2222// ...with address register writeback: 2223class VST4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2224 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2225 (ins addrmode6:$Rn, am6offset:$Rm, 2226 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), 2227 IIC_VST4lnu, "vst4", Dt, 2228 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm", 2229 "$Rn.addr = $wb", []> { 2230 let Inst{4} = Rn{4}; 2231 let DecoderMethod = "DecodeVST4LN"; 2232} 2233 2234def VST4LNd8_UPD : VST4LNWB<0b0011, {?,?,?,?}, "8"> { 2235 let Inst{7-5} = lane{2-0}; 2236} 2237def VST4LNd16_UPD : VST4LNWB<0b0111, {?,?,0,?}, "16"> { 2238 let Inst{7-6} = lane{1-0}; 2239} 2240def VST4LNd32_UPD : VST4LNWB<0b1011, {?,0,?,?}, "32"> { 2241 let Inst{7} = lane{0}; 2242 let Inst{5} = Rn{5}; 2243} 2244 2245def VST4LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>; 2246def VST4LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>; 2247def VST4LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>; 2248 2249def VST4LNq16_UPD : VST4LNWB<0b0111, {?,?,1,?}, "16"> { 2250 let Inst{7-6} = lane{1-0}; 2251} 2252def VST4LNq32_UPD : VST4LNWB<0b1011, {?,1,?,?}, "32"> { 2253 let Inst{7} = lane{0}; 2254 let Inst{5} = Rn{5}; 2255} 2256 2257def VST4LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>; 2258def VST4LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>; 2259 2260} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 2261 2262// Use vld1/vst1 for unaligned f64 load / store 2263def : Pat<(f64 (hword_alignedload addrmode6:$addr)), 2264 (VLD1d16 addrmode6:$addr)>, Requires<[IsLE]>; 2265def : Pat<(hword_alignedstore (f64 DPR:$value), addrmode6:$addr), 2266 (VST1d16 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>; 2267def : Pat<(f64 (byte_alignedload addrmode6:$addr)), 2268 (VLD1d8 addrmode6:$addr)>, Requires<[IsLE]>; 2269def : Pat<(byte_alignedstore (f64 DPR:$value), addrmode6:$addr), 2270 (VST1d8 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>; 2271def : Pat<(f64 (non_word_alignedload addrmode6:$addr)), 2272 (VLD1d64 addrmode6:$addr)>, Requires<[IsBE]>; 2273def : Pat<(non_word_alignedstore (f64 DPR:$value), addrmode6:$addr), 2274 (VST1d64 addrmode6:$addr, DPR:$value)>, Requires<[IsBE]>; 2275 2276//===----------------------------------------------------------------------===// 2277// NEON pattern fragments 2278//===----------------------------------------------------------------------===// 2279 2280// Extract D sub-registers of Q registers. 2281def DSubReg_i8_reg : SDNodeXForm<imm, [{ 2282 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2283 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, MVT::i32); 2284}]>; 2285def DSubReg_i16_reg : SDNodeXForm<imm, [{ 2286 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2287 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, MVT::i32); 2288}]>; 2289def DSubReg_i32_reg : SDNodeXForm<imm, [{ 2290 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2291 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, MVT::i32); 2292}]>; 2293def DSubReg_f64_reg : SDNodeXForm<imm, [{ 2294 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2295 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), MVT::i32); 2296}]>; 2297 2298// Extract S sub-registers of Q/D registers. 2299def SSubReg_f32_reg : SDNodeXForm<imm, [{ 2300 assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); 2301 return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), MVT::i32); 2302}]>; 2303 2304// Translate lane numbers from Q registers to D subregs. 2305def SubReg_i8_lane : SDNodeXForm<imm, [{ 2306 return CurDAG->getTargetConstant(N->getZExtValue() & 7, MVT::i32); 2307}]>; 2308def SubReg_i16_lane : SDNodeXForm<imm, [{ 2309 return CurDAG->getTargetConstant(N->getZExtValue() & 3, MVT::i32); 2310}]>; 2311def SubReg_i32_lane : SDNodeXForm<imm, [{ 2312 return CurDAG->getTargetConstant(N->getZExtValue() & 1, MVT::i32); 2313}]>; 2314 2315//===----------------------------------------------------------------------===// 2316// Instruction Classes 2317//===----------------------------------------------------------------------===// 2318 2319// Basic 2-register operations: double- and quad-register. 2320class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2321 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, 2322 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> 2323 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 2324 (ins DPR:$Vm), IIC_VUNAD, OpcodeStr, Dt,"$Vd, $Vm", "", 2325 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm))))]>; 2326class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2327 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, 2328 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> 2329 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 2330 (ins QPR:$Vm), IIC_VUNAQ, OpcodeStr, Dt,"$Vd, $Vm", "", 2331 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm))))]>; 2332 2333// Basic 2-register intrinsics, both double- and quad-register. 2334class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2335 bits<2> op17_16, bits<5> op11_7, bit op4, 2336 InstrItinClass itin, string OpcodeStr, string Dt, 2337 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2338 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 2339 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2340 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>; 2341class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2342 bits<2> op17_16, bits<5> op11_7, bit op4, 2343 InstrItinClass itin, string OpcodeStr, string Dt, 2344 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2345 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 2346 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2347 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 2348 2349// Narrow 2-register operations. 2350class N2VN<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2351 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2352 InstrItinClass itin, string OpcodeStr, string Dt, 2353 ValueType TyD, ValueType TyQ, SDNode OpNode> 2354 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd), 2355 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2356 [(set DPR:$Vd, (TyD (OpNode (TyQ QPR:$Vm))))]>; 2357 2358// Narrow 2-register intrinsics. 2359class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2360 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2361 InstrItinClass itin, string OpcodeStr, string Dt, 2362 ValueType TyD, ValueType TyQ, SDPatternOperator IntOp> 2363 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd), 2364 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2365 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vm))))]>; 2366 2367// Long 2-register operations (currently only used for VMOVL). 2368class N2VL<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2369 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2370 InstrItinClass itin, string OpcodeStr, string Dt, 2371 ValueType TyQ, ValueType TyD, SDNode OpNode> 2372 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd), 2373 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2374 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vm))))]>; 2375 2376// Long 2-register intrinsics. 2377class N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2378 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2379 InstrItinClass itin, string OpcodeStr, string Dt, 2380 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp> 2381 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd), 2382 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2383 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vm))))]>; 2384 2385// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register. 2386class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt> 2387 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$Vd, DPR:$Vm), 2388 (ins DPR:$src1, DPR:$src2), IIC_VPERMD, 2389 OpcodeStr, Dt, "$Vd, $Vm", 2390 "$src1 = $Vd, $src2 = $Vm", []>; 2391class N2VQShuffle<bits<2> op19_18, bits<5> op11_7, 2392 InstrItinClass itin, string OpcodeStr, string Dt> 2393 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$Vd, QPR:$Vm), 2394 (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm", 2395 "$src1 = $Vd, $src2 = $Vm", []>; 2396 2397// Basic 3-register operations: double- and quad-register. 2398class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2399 InstrItinClass itin, string OpcodeStr, string Dt, 2400 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2401 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2402 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2403 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2404 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { 2405 // All of these have a two-operand InstAlias. 2406 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2407 let isCommutable = Commutable; 2408} 2409// Same as N3VD but no data type. 2410class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2411 InstrItinClass itin, string OpcodeStr, 2412 ValueType ResTy, ValueType OpTy, 2413 SDNode OpNode, bit Commutable> 2414 : N3VX<op24, op23, op21_20, op11_8, 0, op4, 2415 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2416 OpcodeStr, "$Vd, $Vn, $Vm", "", 2417 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>{ 2418 // All of these have a two-operand InstAlias. 2419 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2420 let isCommutable = Commutable; 2421} 2422 2423class N3VDSL<bits<2> op21_20, bits<4> op11_8, 2424 InstrItinClass itin, string OpcodeStr, string Dt, 2425 ValueType Ty, SDNode ShOp> 2426 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2427 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2428 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2429 [(set (Ty DPR:$Vd), 2430 (Ty (ShOp (Ty DPR:$Vn), 2431 (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),imm:$lane)))))]> { 2432 // All of these have a two-operand InstAlias. 2433 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2434 let isCommutable = 0; 2435} 2436class N3VDSL16<bits<2> op21_20, bits<4> op11_8, 2437 string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp> 2438 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2439 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2440 NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane","", 2441 [(set (Ty DPR:$Vd), 2442 (Ty (ShOp (Ty DPR:$Vn), 2443 (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> { 2444 // All of these have a two-operand InstAlias. 2445 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2446 let isCommutable = 0; 2447} 2448 2449class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2450 InstrItinClass itin, string OpcodeStr, string Dt, 2451 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2452 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2453 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2454 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2455 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> { 2456 // All of these have a two-operand InstAlias. 2457 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2458 let isCommutable = Commutable; 2459} 2460class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2461 InstrItinClass itin, string OpcodeStr, 2462 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2463 : N3VX<op24, op23, op21_20, op11_8, 1, op4, 2464 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2465 OpcodeStr, "$Vd, $Vn, $Vm", "", 2466 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>{ 2467 // All of these have a two-operand InstAlias. 2468 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2469 let isCommutable = Commutable; 2470} 2471class N3VQSL<bits<2> op21_20, bits<4> op11_8, 2472 InstrItinClass itin, string OpcodeStr, string Dt, 2473 ValueType ResTy, ValueType OpTy, SDNode ShOp> 2474 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2475 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2476 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2477 [(set (ResTy QPR:$Vd), 2478 (ResTy (ShOp (ResTy QPR:$Vn), 2479 (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm), 2480 imm:$lane)))))]> { 2481 // All of these have a two-operand InstAlias. 2482 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2483 let isCommutable = 0; 2484} 2485class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt, 2486 ValueType ResTy, ValueType OpTy, SDNode ShOp> 2487 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2488 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2489 NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane", "", 2490 [(set (ResTy QPR:$Vd), 2491 (ResTy (ShOp (ResTy QPR:$Vn), 2492 (ResTy (NEONvduplane (OpTy DPR_8:$Vm), 2493 imm:$lane)))))]> { 2494 // All of these have a two-operand InstAlias. 2495 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2496 let isCommutable = 0; 2497} 2498 2499// Basic 3-register intrinsics, both double- and quad-register. 2500class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2501 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2502 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable> 2503 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2504 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, 2505 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2506 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { 2507 // All of these have a two-operand InstAlias. 2508 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2509 let isCommutable = Commutable; 2510} 2511class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2512 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp> 2513 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2514 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2515 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2516 [(set (Ty DPR:$Vd), 2517 (Ty (IntOp (Ty DPR:$Vn), 2518 (Ty (NEONvduplane (Ty DPR_VFP2:$Vm), 2519 imm:$lane)))))]> { 2520 let isCommutable = 0; 2521} 2522class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2523 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp> 2524 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2525 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2526 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2527 [(set (Ty DPR:$Vd), 2528 (Ty (IntOp (Ty DPR:$Vn), 2529 (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> { 2530 let isCommutable = 0; 2531} 2532class N3VDIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2533 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2534 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2535 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2536 (outs DPR:$Vd), (ins DPR:$Vm, DPR:$Vn), f, itin, 2537 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "", 2538 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (OpTy DPR:$Vn))))]> { 2539 let TwoOperandAliasConstraint = "$Vm = $Vd"; 2540 let isCommutable = 0; 2541} 2542 2543class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2544 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2545 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable> 2546 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2547 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, 2548 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2549 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> { 2550 // All of these have a two-operand InstAlias. 2551 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2552 let isCommutable = Commutable; 2553} 2554class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2555 string OpcodeStr, string Dt, 2556 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2557 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2558 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2559 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2560 [(set (ResTy QPR:$Vd), 2561 (ResTy (IntOp (ResTy QPR:$Vn), 2562 (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm), 2563 imm:$lane)))))]> { 2564 let isCommutable = 0; 2565} 2566class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2567 string OpcodeStr, string Dt, 2568 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2569 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2570 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2571 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2572 [(set (ResTy QPR:$Vd), 2573 (ResTy (IntOp (ResTy QPR:$Vn), 2574 (ResTy (NEONvduplane (OpTy DPR_8:$Vm), 2575 imm:$lane)))))]> { 2576 let isCommutable = 0; 2577} 2578class N3VQIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2579 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2580 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2581 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2582 (outs QPR:$Vd), (ins QPR:$Vm, QPR:$Vn), f, itin, 2583 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "", 2584 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (OpTy QPR:$Vn))))]> { 2585 let TwoOperandAliasConstraint = "$Vm = $Vd"; 2586 let isCommutable = 0; 2587} 2588 2589// Multiply-Add/Sub operations: double- and quad-register. 2590class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2591 InstrItinClass itin, string OpcodeStr, string Dt, 2592 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode> 2593 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2594 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2595 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2596 [(set DPR:$Vd, (Ty (OpNode DPR:$src1, 2597 (Ty (MulOp DPR:$Vn, DPR:$Vm)))))]>; 2598 2599class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2600 string OpcodeStr, string Dt, 2601 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp> 2602 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2603 (outs DPR:$Vd), 2604 (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2605 NVMulSLFrm, itin, 2606 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2607 [(set (Ty DPR:$Vd), 2608 (Ty (ShOp (Ty DPR:$src1), 2609 (Ty (MulOp DPR:$Vn, 2610 (Ty (NEONvduplane (Ty DPR_VFP2:$Vm), 2611 imm:$lane)))))))]>; 2612class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2613 string OpcodeStr, string Dt, 2614 ValueType Ty, SDNode MulOp, SDNode ShOp> 2615 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2616 (outs DPR:$Vd), 2617 (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2618 NVMulSLFrm, itin, 2619 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2620 [(set (Ty DPR:$Vd), 2621 (Ty (ShOp (Ty DPR:$src1), 2622 (Ty (MulOp DPR:$Vn, 2623 (Ty (NEONvduplane (Ty DPR_8:$Vm), 2624 imm:$lane)))))))]>; 2625 2626class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2627 InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, 2628 SDPatternOperator MulOp, SDPatternOperator OpNode> 2629 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2630 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2631 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2632 [(set QPR:$Vd, (Ty (OpNode QPR:$src1, 2633 (Ty (MulOp QPR:$Vn, QPR:$Vm)))))]>; 2634class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2635 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 2636 SDPatternOperator MulOp, SDPatternOperator ShOp> 2637 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2638 (outs QPR:$Vd), 2639 (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2640 NVMulSLFrm, itin, 2641 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2642 [(set (ResTy QPR:$Vd), 2643 (ResTy (ShOp (ResTy QPR:$src1), 2644 (ResTy (MulOp QPR:$Vn, 2645 (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm), 2646 imm:$lane)))))))]>; 2647class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2648 string OpcodeStr, string Dt, 2649 ValueType ResTy, ValueType OpTy, 2650 SDNode MulOp, SDNode ShOp> 2651 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2652 (outs QPR:$Vd), 2653 (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2654 NVMulSLFrm, itin, 2655 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2656 [(set (ResTy QPR:$Vd), 2657 (ResTy (ShOp (ResTy QPR:$src1), 2658 (ResTy (MulOp QPR:$Vn, 2659 (ResTy (NEONvduplane (OpTy DPR_8:$Vm), 2660 imm:$lane)))))))]>; 2661 2662// Neon Intrinsic-Op instructions (VABA): double- and quad-register. 2663class N3VDIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2664 InstrItinClass itin, string OpcodeStr, string Dt, 2665 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode> 2666 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2667 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2668 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2669 [(set DPR:$Vd, (Ty (OpNode DPR:$src1, 2670 (Ty (IntOp (Ty DPR:$Vn), (Ty DPR:$Vm))))))]>; 2671class N3VQIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2672 InstrItinClass itin, string OpcodeStr, string Dt, 2673 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode> 2674 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2675 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2676 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2677 [(set QPR:$Vd, (Ty (OpNode QPR:$src1, 2678 (Ty (IntOp (Ty QPR:$Vn), (Ty QPR:$Vm))))))]>; 2679 2680// Neon 3-argument intrinsics, both double- and quad-register. 2681// The destination register is also used as the first source operand register. 2682class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2683 InstrItinClass itin, string OpcodeStr, string Dt, 2684 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2685 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2686 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2687 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2688 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$src1), 2689 (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>; 2690class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2691 InstrItinClass itin, string OpcodeStr, string Dt, 2692 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2693 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2694 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2695 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2696 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src1), 2697 (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>; 2698 2699// Long Multiply-Add/Sub operations. 2700class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2701 InstrItinClass itin, string OpcodeStr, string Dt, 2702 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2703 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2704 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2705 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2706 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1), 2707 (TyQ (MulOp (TyD DPR:$Vn), 2708 (TyD DPR:$Vm)))))]>; 2709class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8, 2710 InstrItinClass itin, string OpcodeStr, string Dt, 2711 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2712 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), 2713 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2714 NVMulSLFrm, itin, 2715 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2716 [(set QPR:$Vd, 2717 (OpNode (TyQ QPR:$src1), 2718 (TyQ (MulOp (TyD DPR:$Vn), 2719 (TyD (NEONvduplane (TyD DPR_VFP2:$Vm), 2720 imm:$lane))))))]>; 2721class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 2722 InstrItinClass itin, string OpcodeStr, string Dt, 2723 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2724 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), 2725 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2726 NVMulSLFrm, itin, 2727 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2728 [(set QPR:$Vd, 2729 (OpNode (TyQ QPR:$src1), 2730 (TyQ (MulOp (TyD DPR:$Vn), 2731 (TyD (NEONvduplane (TyD DPR_8:$Vm), 2732 imm:$lane))))))]>; 2733 2734// Long Intrinsic-Op vector operations with explicit extend (VABAL). 2735class N3VLIntExtOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2736 InstrItinClass itin, string OpcodeStr, string Dt, 2737 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp, 2738 SDNode OpNode> 2739 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2740 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2741 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2742 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1), 2743 (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn), 2744 (TyD DPR:$Vm)))))))]>; 2745 2746// Neon Long 3-argument intrinsic. The destination register is 2747// a quad-register and is also used as the first source operand register. 2748class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2749 InstrItinClass itin, string OpcodeStr, string Dt, 2750 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp> 2751 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2752 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2753 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2754 [(set QPR:$Vd, 2755 (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$Vn), (TyD DPR:$Vm))))]>; 2756class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2757 string OpcodeStr, string Dt, 2758 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2759 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 2760 (outs QPR:$Vd), 2761 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2762 NVMulSLFrm, itin, 2763 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2764 [(set (ResTy QPR:$Vd), 2765 (ResTy (IntOp (ResTy QPR:$src1), 2766 (OpTy DPR:$Vn), 2767 (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm), 2768 imm:$lane)))))]>; 2769class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8, 2770 InstrItinClass itin, string OpcodeStr, string Dt, 2771 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2772 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 2773 (outs QPR:$Vd), 2774 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2775 NVMulSLFrm, itin, 2776 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2777 [(set (ResTy QPR:$Vd), 2778 (ResTy (IntOp (ResTy QPR:$src1), 2779 (OpTy DPR:$Vn), 2780 (OpTy (NEONvduplane (OpTy DPR_8:$Vm), 2781 imm:$lane)))))]>; 2782 2783// Narrowing 3-register intrinsics. 2784class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2785 string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ, 2786 SDPatternOperator IntOp, bit Commutable> 2787 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2788 (outs DPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINi4D, 2789 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2790 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vn), (TyQ QPR:$Vm))))]> { 2791 let isCommutable = Commutable; 2792} 2793 2794// Long 3-register operations. 2795class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2796 InstrItinClass itin, string OpcodeStr, string Dt, 2797 ValueType TyQ, ValueType TyD, SDNode OpNode, bit Commutable> 2798 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2799 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2800 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2801 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vn), (TyD DPR:$Vm))))]> { 2802 let isCommutable = Commutable; 2803} 2804class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8, 2805 InstrItinClass itin, string OpcodeStr, string Dt, 2806 ValueType TyQ, ValueType TyD, SDNode OpNode> 2807 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 2808 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2809 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2810 [(set QPR:$Vd, 2811 (TyQ (OpNode (TyD DPR:$Vn), 2812 (TyD (NEONvduplane (TyD DPR_VFP2:$Vm),imm:$lane)))))]>; 2813class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 2814 InstrItinClass itin, string OpcodeStr, string Dt, 2815 ValueType TyQ, ValueType TyD, SDNode OpNode> 2816 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 2817 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2818 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2819 [(set QPR:$Vd, 2820 (TyQ (OpNode (TyD DPR:$Vn), 2821 (TyD (NEONvduplane (TyD DPR_8:$Vm), imm:$lane)))))]>; 2822 2823// Long 3-register operations with explicitly extended operands. 2824class N3VLExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2825 InstrItinClass itin, string OpcodeStr, string Dt, 2826 ValueType TyQ, ValueType TyD, SDNode OpNode, SDNode ExtOp, 2827 bit Commutable> 2828 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2829 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2830 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2831 [(set QPR:$Vd, (OpNode (TyQ (ExtOp (TyD DPR:$Vn))), 2832 (TyQ (ExtOp (TyD DPR:$Vm)))))]> { 2833 let isCommutable = Commutable; 2834} 2835 2836// Long 3-register intrinsics with explicit extend (VABDL). 2837class N3VLIntExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2838 InstrItinClass itin, string OpcodeStr, string Dt, 2839 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp, 2840 bit Commutable> 2841 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2842 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2843 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2844 [(set QPR:$Vd, (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn), 2845 (TyD DPR:$Vm))))))]> { 2846 let isCommutable = Commutable; 2847} 2848 2849// Long 3-register intrinsics. 2850class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2851 InstrItinClass itin, string OpcodeStr, string Dt, 2852 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, bit Commutable> 2853 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2854 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2855 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2856 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vn), (TyD DPR:$Vm))))]> { 2857 let isCommutable = Commutable; 2858} 2859class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2860 string OpcodeStr, string Dt, 2861 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2862 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 2863 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2864 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2865 [(set (ResTy QPR:$Vd), 2866 (ResTy (IntOp (OpTy DPR:$Vn), 2867 (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm), 2868 imm:$lane)))))]>; 2869class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 2870 InstrItinClass itin, string OpcodeStr, string Dt, 2871 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2872 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 2873 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2874 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2875 [(set (ResTy QPR:$Vd), 2876 (ResTy (IntOp (OpTy DPR:$Vn), 2877 (OpTy (NEONvduplane (OpTy DPR_8:$Vm), 2878 imm:$lane)))))]>; 2879 2880// Wide 3-register operations. 2881class N3VW<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2882 string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, 2883 SDNode OpNode, SDNode ExtOp, bit Commutable> 2884 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2885 (outs QPR:$Vd), (ins QPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VSUBiD, 2886 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2887 [(set QPR:$Vd, (OpNode (TyQ QPR:$Vn), 2888 (TyQ (ExtOp (TyD DPR:$Vm)))))]> { 2889 // All of these have a two-operand InstAlias. 2890 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2891 let isCommutable = Commutable; 2892} 2893 2894// Pairwise long 2-register intrinsics, both double- and quad-register. 2895class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2896 bits<2> op17_16, bits<5> op11_7, bit op4, 2897 string OpcodeStr, string Dt, 2898 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2899 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 2900 (ins DPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 2901 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>; 2902class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2903 bits<2> op17_16, bits<5> op11_7, bit op4, 2904 string OpcodeStr, string Dt, 2905 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2906 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 2907 (ins QPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 2908 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 2909 2910// Pairwise long 2-register accumulate intrinsics, 2911// both double- and quad-register. 2912// The destination register is also used as the first source operand register. 2913class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2914 bits<2> op17_16, bits<5> op11_7, bit op4, 2915 string OpcodeStr, string Dt, 2916 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2917 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, 2918 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vm), IIC_VPALiD, 2919 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd", 2920 [(set DPR:$Vd, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$Vm))))]>; 2921class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2922 bits<2> op17_16, bits<5> op11_7, bit op4, 2923 string OpcodeStr, string Dt, 2924 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2925 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, 2926 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vm), IIC_VPALiQ, 2927 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd", 2928 [(set QPR:$Vd, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$Vm))))]>; 2929 2930// Shift by immediate, 2931// both double- and quad-register. 2932let TwoOperandAliasConstraint = "$Vm = $Vd" in { 2933class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 2934 Format f, InstrItinClass itin, Operand ImmTy, 2935 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode> 2936 : N2VImm<op24, op23, op11_8, op7, 0, op4, 2937 (outs DPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), f, itin, 2938 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 2939 [(set DPR:$Vd, (Ty (OpNode (Ty DPR:$Vm), (i32 imm:$SIMM))))]>; 2940class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 2941 Format f, InstrItinClass itin, Operand ImmTy, 2942 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode> 2943 : N2VImm<op24, op23, op11_8, op7, 1, op4, 2944 (outs QPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), f, itin, 2945 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 2946 [(set QPR:$Vd, (Ty (OpNode (Ty QPR:$Vm), (i32 imm:$SIMM))))]>; 2947} 2948 2949// Long shift by immediate. 2950class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2951 string OpcodeStr, string Dt, 2952 ValueType ResTy, ValueType OpTy, Operand ImmTy, SDNode OpNode> 2953 : N2VImm<op24, op23, op11_8, op7, op6, op4, 2954 (outs QPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), N2RegVShLFrm, 2955 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 2956 [(set QPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm), 2957 (i32 imm:$SIMM))))]>; 2958 2959// Narrow shift by immediate. 2960class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2961 InstrItinClass itin, string OpcodeStr, string Dt, 2962 ValueType ResTy, ValueType OpTy, Operand ImmTy, SDNode OpNode> 2963 : N2VImm<op24, op23, op11_8, op7, op6, op4, 2964 (outs DPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, itin, 2965 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 2966 [(set DPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm), 2967 (i32 imm:$SIMM))))]>; 2968 2969// Shift right by immediate and accumulate, 2970// both double- and quad-register. 2971let TwoOperandAliasConstraint = "$Vm = $Vd" in { 2972class N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 2973 Operand ImmTy, string OpcodeStr, string Dt, 2974 ValueType Ty, SDNode ShOp> 2975 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd), 2976 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD, 2977 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 2978 [(set DPR:$Vd, (Ty (add DPR:$src1, 2979 (Ty (ShOp DPR:$Vm, (i32 imm:$SIMM))))))]>; 2980class N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 2981 Operand ImmTy, string OpcodeStr, string Dt, 2982 ValueType Ty, SDNode ShOp> 2983 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd), 2984 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD, 2985 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 2986 [(set QPR:$Vd, (Ty (add QPR:$src1, 2987 (Ty (ShOp QPR:$Vm, (i32 imm:$SIMM))))))]>; 2988} 2989 2990// Shift by immediate and insert, 2991// both double- and quad-register. 2992let TwoOperandAliasConstraint = "$Vm = $Vd" in { 2993class N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 2994 Operand ImmTy, Format f, string OpcodeStr, string Dt, 2995 ValueType Ty,SDNode ShOp> 2996 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd), 2997 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiD, 2998 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 2999 [(set DPR:$Vd, (Ty (ShOp DPR:$src1, DPR:$Vm, (i32 imm:$SIMM))))]>; 3000class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3001 Operand ImmTy, Format f, string OpcodeStr, string Dt, 3002 ValueType Ty,SDNode ShOp> 3003 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd), 3004 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiQ, 3005 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 3006 [(set QPR:$Vd, (Ty (ShOp QPR:$src1, QPR:$Vm, (i32 imm:$SIMM))))]>; 3007} 3008 3009// Convert, with fractional bits immediate, 3010// both double- and quad-register. 3011class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3012 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 3013 SDPatternOperator IntOp> 3014 : N2VImm<op24, op23, op11_8, op7, 0, op4, 3015 (outs DPR:$Vd), (ins DPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm, 3016 IIC_VUNAD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3017 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (i32 imm:$SIMM))))]>; 3018class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3019 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 3020 SDPatternOperator IntOp> 3021 : N2VImm<op24, op23, op11_8, op7, 1, op4, 3022 (outs QPR:$Vd), (ins QPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm, 3023 IIC_VUNAQ, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3024 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (i32 imm:$SIMM))))]>; 3025 3026//===----------------------------------------------------------------------===// 3027// Multiclasses 3028//===----------------------------------------------------------------------===// 3029 3030// Abbreviations used in multiclass suffixes: 3031// Q = quarter int (8 bit) elements 3032// H = half int (16 bit) elements 3033// S = single int (32 bit) elements 3034// D = double int (64 bit) elements 3035 3036// Neon 2-register vector operations and intrinsics. 3037 3038// Neon 2-register comparisons. 3039// source operand element sizes of 8, 16 and 32 bits: 3040multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3041 bits<5> op11_7, bit op4, string opc, string Dt, 3042 string asm, SDNode OpNode> { 3043 // 64-bit vector types. 3044 def v8i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4, 3045 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3046 opc, !strconcat(Dt, "8"), asm, "", 3047 [(set DPR:$Vd, (v8i8 (OpNode (v8i8 DPR:$Vm))))]>; 3048 def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4, 3049 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3050 opc, !strconcat(Dt, "16"), asm, "", 3051 [(set DPR:$Vd, (v4i16 (OpNode (v4i16 DPR:$Vm))))]>; 3052 def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4, 3053 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3054 opc, !strconcat(Dt, "32"), asm, "", 3055 [(set DPR:$Vd, (v2i32 (OpNode (v2i32 DPR:$Vm))))]>; 3056 def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4, 3057 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3058 opc, "f32", asm, "", 3059 [(set DPR:$Vd, (v2i32 (OpNode (v2f32 DPR:$Vm))))]> { 3060 let Inst{10} = 1; // overwrite F = 1 3061 } 3062 3063 // 128-bit vector types. 3064 def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4, 3065 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3066 opc, !strconcat(Dt, "8"), asm, "", 3067 [(set QPR:$Vd, (v16i8 (OpNode (v16i8 QPR:$Vm))))]>; 3068 def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4, 3069 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3070 opc, !strconcat(Dt, "16"), asm, "", 3071 [(set QPR:$Vd, (v8i16 (OpNode (v8i16 QPR:$Vm))))]>; 3072 def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4, 3073 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3074 opc, !strconcat(Dt, "32"), asm, "", 3075 [(set QPR:$Vd, (v4i32 (OpNode (v4i32 QPR:$Vm))))]>; 3076 def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4, 3077 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3078 opc, "f32", asm, "", 3079 [(set QPR:$Vd, (v4i32 (OpNode (v4f32 QPR:$Vm))))]> { 3080 let Inst{10} = 1; // overwrite F = 1 3081 } 3082} 3083 3084 3085// Neon 2-register vector intrinsics, 3086// element sizes of 8, 16 and 32 bits: 3087multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3088 bits<5> op11_7, bit op4, 3089 InstrItinClass itinD, InstrItinClass itinQ, 3090 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3091 // 64-bit vector types. 3092 def v8i8 : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3093 itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>; 3094 def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3095 itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>; 3096 def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3097 itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>; 3098 3099 // 128-bit vector types. 3100 def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3101 itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>; 3102 def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3103 itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>; 3104 def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3105 itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>; 3106} 3107 3108 3109// Neon Narrowing 2-register vector operations, 3110// source operand element sizes of 16, 32 and 64 bits: 3111multiclass N2VN_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3112 bits<5> op11_7, bit op6, bit op4, 3113 InstrItinClass itin, string OpcodeStr, string Dt, 3114 SDNode OpNode> { 3115 def v8i8 : N2VN<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4, 3116 itin, OpcodeStr, !strconcat(Dt, "16"), 3117 v8i8, v8i16, OpNode>; 3118 def v4i16 : N2VN<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4, 3119 itin, OpcodeStr, !strconcat(Dt, "32"), 3120 v4i16, v4i32, OpNode>; 3121 def v2i32 : N2VN<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4, 3122 itin, OpcodeStr, !strconcat(Dt, "64"), 3123 v2i32, v2i64, OpNode>; 3124} 3125 3126// Neon Narrowing 2-register vector intrinsics, 3127// source operand element sizes of 16, 32 and 64 bits: 3128multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3129 bits<5> op11_7, bit op6, bit op4, 3130 InstrItinClass itin, string OpcodeStr, string Dt, 3131 SDPatternOperator IntOp> { 3132 def v8i8 : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4, 3133 itin, OpcodeStr, !strconcat(Dt, "16"), 3134 v8i8, v8i16, IntOp>; 3135 def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4, 3136 itin, OpcodeStr, !strconcat(Dt, "32"), 3137 v4i16, v4i32, IntOp>; 3138 def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4, 3139 itin, OpcodeStr, !strconcat(Dt, "64"), 3140 v2i32, v2i64, IntOp>; 3141} 3142 3143 3144// Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL). 3145// source operand element sizes of 16, 32 and 64 bits: 3146multiclass N2VL_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4, 3147 string OpcodeStr, string Dt, SDNode OpNode> { 3148 def v8i16 : N2VL<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3149 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode>; 3150 def v4i32 : N2VL<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3151 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode>; 3152 def v2i64 : N2VL<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3153 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode>; 3154} 3155 3156 3157// Neon 3-register vector operations. 3158 3159// First with only element sizes of 8, 16 and 32 bits: 3160multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3161 InstrItinClass itinD16, InstrItinClass itinD32, 3162 InstrItinClass itinQ16, InstrItinClass itinQ32, 3163 string OpcodeStr, string Dt, 3164 SDNode OpNode, bit Commutable = 0> { 3165 // 64-bit vector types. 3166 def v8i8 : N3VD<op24, op23, 0b00, op11_8, op4, itinD16, 3167 OpcodeStr, !strconcat(Dt, "8"), 3168 v8i8, v8i8, OpNode, Commutable>; 3169 def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16, 3170 OpcodeStr, !strconcat(Dt, "16"), 3171 v4i16, v4i16, OpNode, Commutable>; 3172 def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32, 3173 OpcodeStr, !strconcat(Dt, "32"), 3174 v2i32, v2i32, OpNode, Commutable>; 3175 3176 // 128-bit vector types. 3177 def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16, 3178 OpcodeStr, !strconcat(Dt, "8"), 3179 v16i8, v16i8, OpNode, Commutable>; 3180 def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16, 3181 OpcodeStr, !strconcat(Dt, "16"), 3182 v8i16, v8i16, OpNode, Commutable>; 3183 def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32, 3184 OpcodeStr, !strconcat(Dt, "32"), 3185 v4i32, v4i32, OpNode, Commutable>; 3186} 3187 3188multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, SDNode ShOp> { 3189 def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, "i16", v4i16, ShOp>; 3190 def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, "i32", v2i32, ShOp>; 3191 def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, "i16", v8i16, v4i16, ShOp>; 3192 def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, "i32", 3193 v4i32, v2i32, ShOp>; 3194} 3195 3196// ....then also with element size 64 bits: 3197multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3198 InstrItinClass itinD, InstrItinClass itinQ, 3199 string OpcodeStr, string Dt, 3200 SDNode OpNode, bit Commutable = 0> 3201 : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ, 3202 OpcodeStr, Dt, OpNode, Commutable> { 3203 def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD, 3204 OpcodeStr, !strconcat(Dt, "64"), 3205 v1i64, v1i64, OpNode, Commutable>; 3206 def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ, 3207 OpcodeStr, !strconcat(Dt, "64"), 3208 v2i64, v2i64, OpNode, Commutable>; 3209} 3210 3211 3212// Neon 3-register vector intrinsics. 3213 3214// First with only element sizes of 16 and 32 bits: 3215multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3216 InstrItinClass itinD16, InstrItinClass itinD32, 3217 InstrItinClass itinQ16, InstrItinClass itinQ32, 3218 string OpcodeStr, string Dt, 3219 SDPatternOperator IntOp, bit Commutable = 0> { 3220 // 64-bit vector types. 3221 def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, f, itinD16, 3222 OpcodeStr, !strconcat(Dt, "16"), 3223 v4i16, v4i16, IntOp, Commutable>; 3224 def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, f, itinD32, 3225 OpcodeStr, !strconcat(Dt, "32"), 3226 v2i32, v2i32, IntOp, Commutable>; 3227 3228 // 128-bit vector types. 3229 def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, f, itinQ16, 3230 OpcodeStr, !strconcat(Dt, "16"), 3231 v8i16, v8i16, IntOp, Commutable>; 3232 def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, f, itinQ32, 3233 OpcodeStr, !strconcat(Dt, "32"), 3234 v4i32, v4i32, IntOp, Commutable>; 3235} 3236multiclass N3VInt_HSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3237 InstrItinClass itinD16, InstrItinClass itinD32, 3238 InstrItinClass itinQ16, InstrItinClass itinQ32, 3239 string OpcodeStr, string Dt, 3240 SDPatternOperator IntOp> { 3241 // 64-bit vector types. 3242 def v4i16 : N3VDIntSh<op24, op23, 0b01, op11_8, op4, f, itinD16, 3243 OpcodeStr, !strconcat(Dt, "16"), 3244 v4i16, v4i16, IntOp>; 3245 def v2i32 : N3VDIntSh<op24, op23, 0b10, op11_8, op4, f, itinD32, 3246 OpcodeStr, !strconcat(Dt, "32"), 3247 v2i32, v2i32, IntOp>; 3248 3249 // 128-bit vector types. 3250 def v8i16 : N3VQIntSh<op24, op23, 0b01, op11_8, op4, f, itinQ16, 3251 OpcodeStr, !strconcat(Dt, "16"), 3252 v8i16, v8i16, IntOp>; 3253 def v4i32 : N3VQIntSh<op24, op23, 0b10, op11_8, op4, f, itinQ32, 3254 OpcodeStr, !strconcat(Dt, "32"), 3255 v4i32, v4i32, IntOp>; 3256} 3257 3258multiclass N3VIntSL_HS<bits<4> op11_8, 3259 InstrItinClass itinD16, InstrItinClass itinD32, 3260 InstrItinClass itinQ16, InstrItinClass itinQ32, 3261 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3262 def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16, 3263 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>; 3264 def v2i32 : N3VDIntSL<0b10, op11_8, itinD32, 3265 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>; 3266 def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16, 3267 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>; 3268 def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32, 3269 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>; 3270} 3271 3272// ....then also with element size of 8 bits: 3273multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3274 InstrItinClass itinD16, InstrItinClass itinD32, 3275 InstrItinClass itinQ16, InstrItinClass itinQ32, 3276 string OpcodeStr, string Dt, 3277 SDPatternOperator IntOp, bit Commutable = 0> 3278 : N3VInt_HS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3279 OpcodeStr, Dt, IntOp, Commutable> { 3280 def v8i8 : N3VDInt<op24, op23, 0b00, op11_8, op4, f, itinD16, 3281 OpcodeStr, !strconcat(Dt, "8"), 3282 v8i8, v8i8, IntOp, Commutable>; 3283 def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, f, itinQ16, 3284 OpcodeStr, !strconcat(Dt, "8"), 3285 v16i8, v16i8, IntOp, Commutable>; 3286} 3287multiclass N3VInt_QHSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3288 InstrItinClass itinD16, InstrItinClass itinD32, 3289 InstrItinClass itinQ16, InstrItinClass itinQ32, 3290 string OpcodeStr, string Dt, 3291 SDPatternOperator IntOp> 3292 : N3VInt_HSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3293 OpcodeStr, Dt, IntOp> { 3294 def v8i8 : N3VDIntSh<op24, op23, 0b00, op11_8, op4, f, itinD16, 3295 OpcodeStr, !strconcat(Dt, "8"), 3296 v8i8, v8i8, IntOp>; 3297 def v16i8 : N3VQIntSh<op24, op23, 0b00, op11_8, op4, f, itinQ16, 3298 OpcodeStr, !strconcat(Dt, "8"), 3299 v16i8, v16i8, IntOp>; 3300} 3301 3302 3303// ....then also with element size of 64 bits: 3304multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3305 InstrItinClass itinD16, InstrItinClass itinD32, 3306 InstrItinClass itinQ16, InstrItinClass itinQ32, 3307 string OpcodeStr, string Dt, 3308 SDPatternOperator IntOp, bit Commutable = 0> 3309 : N3VInt_QHS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3310 OpcodeStr, Dt, IntOp, Commutable> { 3311 def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, f, itinD32, 3312 OpcodeStr, !strconcat(Dt, "64"), 3313 v1i64, v1i64, IntOp, Commutable>; 3314 def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, f, itinQ32, 3315 OpcodeStr, !strconcat(Dt, "64"), 3316 v2i64, v2i64, IntOp, Commutable>; 3317} 3318multiclass N3VInt_QHSDSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3319 InstrItinClass itinD16, InstrItinClass itinD32, 3320 InstrItinClass itinQ16, InstrItinClass itinQ32, 3321 string OpcodeStr, string Dt, 3322 SDPatternOperator IntOp> 3323 : N3VInt_QHSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3324 OpcodeStr, Dt, IntOp> { 3325 def v1i64 : N3VDIntSh<op24, op23, 0b11, op11_8, op4, f, itinD32, 3326 OpcodeStr, !strconcat(Dt, "64"), 3327 v1i64, v1i64, IntOp>; 3328 def v2i64 : N3VQIntSh<op24, op23, 0b11, op11_8, op4, f, itinQ32, 3329 OpcodeStr, !strconcat(Dt, "64"), 3330 v2i64, v2i64, IntOp>; 3331} 3332 3333// Neon Narrowing 3-register vector intrinsics, 3334// source operand element sizes of 16, 32 and 64 bits: 3335multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3336 string OpcodeStr, string Dt, 3337 SDPatternOperator IntOp, bit Commutable = 0> { 3338 def v8i8 : N3VNInt<op24, op23, 0b00, op11_8, op4, 3339 OpcodeStr, !strconcat(Dt, "16"), 3340 v8i8, v8i16, IntOp, Commutable>; 3341 def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4, 3342 OpcodeStr, !strconcat(Dt, "32"), 3343 v4i16, v4i32, IntOp, Commutable>; 3344 def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4, 3345 OpcodeStr, !strconcat(Dt, "64"), 3346 v2i32, v2i64, IntOp, Commutable>; 3347} 3348 3349 3350// Neon Long 3-register vector operations. 3351 3352multiclass N3VL_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3353 InstrItinClass itin16, InstrItinClass itin32, 3354 string OpcodeStr, string Dt, 3355 SDNode OpNode, bit Commutable = 0> { 3356 def v8i16 : N3VL<op24, op23, 0b00, op11_8, op4, itin16, 3357 OpcodeStr, !strconcat(Dt, "8"), 3358 v8i16, v8i8, OpNode, Commutable>; 3359 def v4i32 : N3VL<op24, op23, 0b01, op11_8, op4, itin16, 3360 OpcodeStr, !strconcat(Dt, "16"), 3361 v4i32, v4i16, OpNode, Commutable>; 3362 def v2i64 : N3VL<op24, op23, 0b10, op11_8, op4, itin32, 3363 OpcodeStr, !strconcat(Dt, "32"), 3364 v2i64, v2i32, OpNode, Commutable>; 3365} 3366 3367multiclass N3VLSL_HS<bit op24, bits<4> op11_8, 3368 InstrItinClass itin, string OpcodeStr, string Dt, 3369 SDNode OpNode> { 3370 def v4i16 : N3VLSL16<op24, 0b01, op11_8, itin, OpcodeStr, 3371 !strconcat(Dt, "16"), v4i32, v4i16, OpNode>; 3372 def v2i32 : N3VLSL<op24, 0b10, op11_8, itin, OpcodeStr, 3373 !strconcat(Dt, "32"), v2i64, v2i32, OpNode>; 3374} 3375 3376multiclass N3VLExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3377 InstrItinClass itin16, InstrItinClass itin32, 3378 string OpcodeStr, string Dt, 3379 SDNode OpNode, SDNode ExtOp, bit Commutable = 0> { 3380 def v8i16 : N3VLExt<op24, op23, 0b00, op11_8, op4, itin16, 3381 OpcodeStr, !strconcat(Dt, "8"), 3382 v8i16, v8i8, OpNode, ExtOp, Commutable>; 3383 def v4i32 : N3VLExt<op24, op23, 0b01, op11_8, op4, itin16, 3384 OpcodeStr, !strconcat(Dt, "16"), 3385 v4i32, v4i16, OpNode, ExtOp, Commutable>; 3386 def v2i64 : N3VLExt<op24, op23, 0b10, op11_8, op4, itin32, 3387 OpcodeStr, !strconcat(Dt, "32"), 3388 v2i64, v2i32, OpNode, ExtOp, Commutable>; 3389} 3390 3391// Neon Long 3-register vector intrinsics. 3392 3393// First with only element sizes of 16 and 32 bits: 3394multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, 3395 InstrItinClass itin16, InstrItinClass itin32, 3396 string OpcodeStr, string Dt, 3397 SDPatternOperator IntOp, bit Commutable = 0> { 3398 def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin16, 3399 OpcodeStr, !strconcat(Dt, "16"), 3400 v4i32, v4i16, IntOp, Commutable>; 3401 def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin32, 3402 OpcodeStr, !strconcat(Dt, "32"), 3403 v2i64, v2i32, IntOp, Commutable>; 3404} 3405 3406multiclass N3VLIntSL_HS<bit op24, bits<4> op11_8, 3407 InstrItinClass itin, string OpcodeStr, string Dt, 3408 SDPatternOperator IntOp> { 3409 def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin, 3410 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>; 3411 def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin, 3412 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3413} 3414 3415// ....then also with element size of 8 bits: 3416multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3417 InstrItinClass itin16, InstrItinClass itin32, 3418 string OpcodeStr, string Dt, 3419 SDPatternOperator IntOp, bit Commutable = 0> 3420 : N3VLInt_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, 3421 IntOp, Commutable> { 3422 def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin16, 3423 OpcodeStr, !strconcat(Dt, "8"), 3424 v8i16, v8i8, IntOp, Commutable>; 3425} 3426 3427// ....with explicit extend (VABDL). 3428multiclass N3VLIntExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3429 InstrItinClass itin, string OpcodeStr, string Dt, 3430 SDPatternOperator IntOp, SDNode ExtOp, bit Commutable = 0> { 3431 def v8i16 : N3VLIntExt<op24, op23, 0b00, op11_8, op4, itin, 3432 OpcodeStr, !strconcat(Dt, "8"), 3433 v8i16, v8i8, IntOp, ExtOp, Commutable>; 3434 def v4i32 : N3VLIntExt<op24, op23, 0b01, op11_8, op4, itin, 3435 OpcodeStr, !strconcat(Dt, "16"), 3436 v4i32, v4i16, IntOp, ExtOp, Commutable>; 3437 def v2i64 : N3VLIntExt<op24, op23, 0b10, op11_8, op4, itin, 3438 OpcodeStr, !strconcat(Dt, "32"), 3439 v2i64, v2i32, IntOp, ExtOp, Commutable>; 3440} 3441 3442 3443// Neon Wide 3-register vector intrinsics, 3444// source operand element sizes of 8, 16 and 32 bits: 3445multiclass N3VW_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3446 string OpcodeStr, string Dt, 3447 SDNode OpNode, SDNode ExtOp, bit Commutable = 0> { 3448 def v8i16 : N3VW<op24, op23, 0b00, op11_8, op4, 3449 OpcodeStr, !strconcat(Dt, "8"), 3450 v8i16, v8i8, OpNode, ExtOp, Commutable>; 3451 def v4i32 : N3VW<op24, op23, 0b01, op11_8, op4, 3452 OpcodeStr, !strconcat(Dt, "16"), 3453 v4i32, v4i16, OpNode, ExtOp, Commutable>; 3454 def v2i64 : N3VW<op24, op23, 0b10, op11_8, op4, 3455 OpcodeStr, !strconcat(Dt, "32"), 3456 v2i64, v2i32, OpNode, ExtOp, Commutable>; 3457} 3458 3459 3460// Neon Multiply-Op vector operations, 3461// element sizes of 8, 16 and 32 bits: 3462multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3463 InstrItinClass itinD16, InstrItinClass itinD32, 3464 InstrItinClass itinQ16, InstrItinClass itinQ32, 3465 string OpcodeStr, string Dt, SDNode OpNode> { 3466 // 64-bit vector types. 3467 def v8i8 : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16, 3468 OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>; 3469 def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16, 3470 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>; 3471 def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32, 3472 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>; 3473 3474 // 128-bit vector types. 3475 def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16, 3476 OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>; 3477 def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16, 3478 OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>; 3479 def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32, 3480 OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>; 3481} 3482 3483multiclass N3VMulOpSL_HS<bits<4> op11_8, 3484 InstrItinClass itinD16, InstrItinClass itinD32, 3485 InstrItinClass itinQ16, InstrItinClass itinQ32, 3486 string OpcodeStr, string Dt, SDNode ShOp> { 3487 def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16, 3488 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>; 3489 def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32, 3490 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>; 3491 def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16, 3492 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, 3493 mul, ShOp>; 3494 def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32, 3495 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, 3496 mul, ShOp>; 3497} 3498 3499// Neon Intrinsic-Op vector operations, 3500// element sizes of 8, 16 and 32 bits: 3501multiclass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3502 InstrItinClass itinD, InstrItinClass itinQ, 3503 string OpcodeStr, string Dt, SDPatternOperator IntOp, 3504 SDNode OpNode> { 3505 // 64-bit vector types. 3506 def v8i8 : N3VDIntOp<op24, op23, 0b00, op11_8, op4, itinD, 3507 OpcodeStr, !strconcat(Dt, "8"), v8i8, IntOp, OpNode>; 3508 def v4i16 : N3VDIntOp<op24, op23, 0b01, op11_8, op4, itinD, 3509 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp, OpNode>; 3510 def v2i32 : N3VDIntOp<op24, op23, 0b10, op11_8, op4, itinD, 3511 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp, OpNode>; 3512 3513 // 128-bit vector types. 3514 def v16i8 : N3VQIntOp<op24, op23, 0b00, op11_8, op4, itinQ, 3515 OpcodeStr, !strconcat(Dt, "8"), v16i8, IntOp, OpNode>; 3516 def v8i16 : N3VQIntOp<op24, op23, 0b01, op11_8, op4, itinQ, 3517 OpcodeStr, !strconcat(Dt, "16"), v8i16, IntOp, OpNode>; 3518 def v4i32 : N3VQIntOp<op24, op23, 0b10, op11_8, op4, itinQ, 3519 OpcodeStr, !strconcat(Dt, "32"), v4i32, IntOp, OpNode>; 3520} 3521 3522// Neon 3-argument intrinsics, 3523// element sizes of 8, 16 and 32 bits: 3524multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3525 InstrItinClass itinD, InstrItinClass itinQ, 3526 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3527 // 64-bit vector types. 3528 def v8i8 : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD, 3529 OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>; 3530 def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD, 3531 OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>; 3532 def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD, 3533 OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>; 3534 3535 // 128-bit vector types. 3536 def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ, 3537 OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>; 3538 def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ, 3539 OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>; 3540 def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ, 3541 OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>; 3542} 3543 3544 3545// Neon Long Multiply-Op vector operations, 3546// element sizes of 8, 16 and 32 bits: 3547multiclass N3VLMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3548 InstrItinClass itin16, InstrItinClass itin32, 3549 string OpcodeStr, string Dt, SDNode MulOp, 3550 SDNode OpNode> { 3551 def v8i16 : N3VLMulOp<op24, op23, 0b00, op11_8, op4, itin16, OpcodeStr, 3552 !strconcat(Dt, "8"), v8i16, v8i8, MulOp, OpNode>; 3553 def v4i32 : N3VLMulOp<op24, op23, 0b01, op11_8, op4, itin16, OpcodeStr, 3554 !strconcat(Dt, "16"), v4i32, v4i16, MulOp, OpNode>; 3555 def v2i64 : N3VLMulOp<op24, op23, 0b10, op11_8, op4, itin32, OpcodeStr, 3556 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>; 3557} 3558 3559multiclass N3VLMulOpSL_HS<bit op24, bits<4> op11_8, string OpcodeStr, 3560 string Dt, SDNode MulOp, SDNode OpNode> { 3561 def v4i16 : N3VLMulOpSL16<op24, 0b01, op11_8, IIC_VMACi16D, OpcodeStr, 3562 !strconcat(Dt,"16"), v4i32, v4i16, MulOp, OpNode>; 3563 def v2i32 : N3VLMulOpSL<op24, 0b10, op11_8, IIC_VMACi32D, OpcodeStr, 3564 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>; 3565} 3566 3567 3568// Neon Long 3-argument intrinsics. 3569 3570// First with only element sizes of 16 and 32 bits: 3571multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4, 3572 InstrItinClass itin16, InstrItinClass itin32, 3573 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3574 def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, itin16, 3575 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>; 3576 def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, itin32, 3577 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3578} 3579 3580multiclass N3VLInt3SL_HS<bit op24, bits<4> op11_8, 3581 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3582 def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D, 3583 OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>; 3584 def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D, 3585 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3586} 3587 3588// ....then also with element size of 8 bits: 3589multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3590 InstrItinClass itin16, InstrItinClass itin32, 3591 string OpcodeStr, string Dt, SDPatternOperator IntOp> 3592 : N3VLInt3_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, IntOp> { 3593 def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, itin16, 3594 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>; 3595} 3596 3597// ....with explicit extend (VABAL). 3598multiclass N3VLIntExtOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3599 InstrItinClass itin, string OpcodeStr, string Dt, 3600 SDPatternOperator IntOp, SDNode ExtOp, SDNode OpNode> { 3601 def v8i16 : N3VLIntExtOp<op24, op23, 0b00, op11_8, op4, itin, 3602 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, 3603 IntOp, ExtOp, OpNode>; 3604 def v4i32 : N3VLIntExtOp<op24, op23, 0b01, op11_8, op4, itin, 3605 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, 3606 IntOp, ExtOp, OpNode>; 3607 def v2i64 : N3VLIntExtOp<op24, op23, 0b10, op11_8, op4, itin, 3608 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, 3609 IntOp, ExtOp, OpNode>; 3610} 3611 3612 3613// Neon Pairwise long 2-register intrinsics, 3614// element sizes of 8, 16 and 32 bits: 3615multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3616 bits<5> op11_7, bit op4, 3617 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3618 // 64-bit vector types. 3619 def v8i8 : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3620 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>; 3621 def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3622 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>; 3623 def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3624 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>; 3625 3626 // 128-bit vector types. 3627 def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3628 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>; 3629 def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3630 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>; 3631 def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3632 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>; 3633} 3634 3635 3636// Neon Pairwise long 2-register accumulate intrinsics, 3637// element sizes of 8, 16 and 32 bits: 3638multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3639 bits<5> op11_7, bit op4, 3640 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3641 // 64-bit vector types. 3642 def v8i8 : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3643 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>; 3644 def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3645 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>; 3646 def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3647 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>; 3648 3649 // 128-bit vector types. 3650 def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3651 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>; 3652 def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3653 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>; 3654 def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3655 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>; 3656} 3657 3658 3659// Neon 2-register vector shift by immediate, 3660// with f of either N2RegVShLFrm or N2RegVShRFrm 3661// element sizes of 8, 16, 32 and 64 bits: 3662multiclass N2VShL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3663 InstrItinClass itin, string OpcodeStr, string Dt, 3664 SDNode OpNode> { 3665 // 64-bit vector types. 3666 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3667 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> { 3668 let Inst{21-19} = 0b001; // imm6 = 001xxx 3669 } 3670 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3671 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> { 3672 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3673 } 3674 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3675 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> { 3676 let Inst{21} = 0b1; // imm6 = 1xxxxx 3677 } 3678 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm, 3679 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>; 3680 // imm6 = xxxxxx 3681 3682 // 128-bit vector types. 3683 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3684 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> { 3685 let Inst{21-19} = 0b001; // imm6 = 001xxx 3686 } 3687 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3688 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> { 3689 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3690 } 3691 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 3692 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> { 3693 let Inst{21} = 0b1; // imm6 = 1xxxxx 3694 } 3695 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm, 3696 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>; 3697 // imm6 = xxxxxx 3698} 3699multiclass N2VShR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3700 InstrItinClass itin, string OpcodeStr, string Dt, 3701 string baseOpc, SDNode OpNode> { 3702 // 64-bit vector types. 3703 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8, 3704 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> { 3705 let Inst{21-19} = 0b001; // imm6 = 001xxx 3706 } 3707 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16, 3708 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> { 3709 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3710 } 3711 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32, 3712 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> { 3713 let Inst{21} = 0b1; // imm6 = 1xxxxx 3714 } 3715 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64, 3716 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>; 3717 // imm6 = xxxxxx 3718 3719 // 128-bit vector types. 3720 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8, 3721 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> { 3722 let Inst{21-19} = 0b001; // imm6 = 001xxx 3723 } 3724 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16, 3725 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> { 3726 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3727 } 3728 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32, 3729 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> { 3730 let Inst{21} = 0b1; // imm6 = 1xxxxx 3731 } 3732 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64, 3733 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>; 3734 // imm6 = xxxxxx 3735} 3736 3737// Neon Shift-Accumulate vector operations, 3738// element sizes of 8, 16, 32 and 64 bits: 3739multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3740 string OpcodeStr, string Dt, SDNode ShOp> { 3741 // 64-bit vector types. 3742 def v8i8 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm8, 3743 OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> { 3744 let Inst{21-19} = 0b001; // imm6 = 001xxx 3745 } 3746 def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm16, 3747 OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> { 3748 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3749 } 3750 def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm32, 3751 OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> { 3752 let Inst{21} = 0b1; // imm6 = 1xxxxx 3753 } 3754 def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4, shr_imm64, 3755 OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>; 3756 // imm6 = xxxxxx 3757 3758 // 128-bit vector types. 3759 def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm8, 3760 OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> { 3761 let Inst{21-19} = 0b001; // imm6 = 001xxx 3762 } 3763 def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm16, 3764 OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> { 3765 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3766 } 3767 def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm32, 3768 OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> { 3769 let Inst{21} = 0b1; // imm6 = 1xxxxx 3770 } 3771 def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4, shr_imm64, 3772 OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>; 3773 // imm6 = xxxxxx 3774} 3775 3776// Neon Shift-Insert vector operations, 3777// with f of either N2RegVShLFrm or N2RegVShRFrm 3778// element sizes of 8, 16, 32 and 64 bits: 3779multiclass N2VShInsL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3780 string OpcodeStr> { 3781 // 64-bit vector types. 3782 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 3783 N2RegVShLFrm, OpcodeStr, "8", v8i8, NEONvsli> { 3784 let Inst{21-19} = 0b001; // imm6 = 001xxx 3785 } 3786 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 3787 N2RegVShLFrm, OpcodeStr, "16", v4i16, NEONvsli> { 3788 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3789 } 3790 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 3791 N2RegVShLFrm, OpcodeStr, "32", v2i32, NEONvsli> { 3792 let Inst{21} = 0b1; // imm6 = 1xxxxx 3793 } 3794 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, i32imm, 3795 N2RegVShLFrm, OpcodeStr, "64", v1i64, NEONvsli>; 3796 // imm6 = xxxxxx 3797 3798 // 128-bit vector types. 3799 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 3800 N2RegVShLFrm, OpcodeStr, "8", v16i8, NEONvsli> { 3801 let Inst{21-19} = 0b001; // imm6 = 001xxx 3802 } 3803 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 3804 N2RegVShLFrm, OpcodeStr, "16", v8i16, NEONvsli> { 3805 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3806 } 3807 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 3808 N2RegVShLFrm, OpcodeStr, "32", v4i32, NEONvsli> { 3809 let Inst{21} = 0b1; // imm6 = 1xxxxx 3810 } 3811 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, i32imm, 3812 N2RegVShLFrm, OpcodeStr, "64", v2i64, NEONvsli>; 3813 // imm6 = xxxxxx 3814} 3815multiclass N2VShInsR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3816 string OpcodeStr> { 3817 // 64-bit vector types. 3818 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm8, 3819 N2RegVShRFrm, OpcodeStr, "8", v8i8, NEONvsri> { 3820 let Inst{21-19} = 0b001; // imm6 = 001xxx 3821 } 3822 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm16, 3823 N2RegVShRFrm, OpcodeStr, "16", v4i16, NEONvsri> { 3824 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3825 } 3826 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm32, 3827 N2RegVShRFrm, OpcodeStr, "32", v2i32, NEONvsri> { 3828 let Inst{21} = 0b1; // imm6 = 1xxxxx 3829 } 3830 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, shr_imm64, 3831 N2RegVShRFrm, OpcodeStr, "64", v1i64, NEONvsri>; 3832 // imm6 = xxxxxx 3833 3834 // 128-bit vector types. 3835 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm8, 3836 N2RegVShRFrm, OpcodeStr, "8", v16i8, NEONvsri> { 3837 let Inst{21-19} = 0b001; // imm6 = 001xxx 3838 } 3839 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm16, 3840 N2RegVShRFrm, OpcodeStr, "16", v8i16, NEONvsri> { 3841 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3842 } 3843 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm32, 3844 N2RegVShRFrm, OpcodeStr, "32", v4i32, NEONvsri> { 3845 let Inst{21} = 0b1; // imm6 = 1xxxxx 3846 } 3847 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, shr_imm64, 3848 N2RegVShRFrm, OpcodeStr, "64", v2i64, NEONvsri>; 3849 // imm6 = xxxxxx 3850} 3851 3852// Neon Shift Long operations, 3853// element sizes of 8, 16, 32 bits: 3854multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, 3855 bit op4, string OpcodeStr, string Dt, SDNode OpNode> { 3856 def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 3857 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, imm1_7, OpNode> { 3858 let Inst{21-19} = 0b001; // imm6 = 001xxx 3859 } 3860 def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 3861 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, imm1_15, OpNode> { 3862 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3863 } 3864 def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 3865 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, imm1_31, OpNode> { 3866 let Inst{21} = 0b1; // imm6 = 1xxxxx 3867 } 3868} 3869 3870// Neon Shift Narrow operations, 3871// element sizes of 16, 32, 64 bits: 3872multiclass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, 3873 bit op4, InstrItinClass itin, string OpcodeStr, string Dt, 3874 SDNode OpNode> { 3875 def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 3876 OpcodeStr, !strconcat(Dt, "16"), 3877 v8i8, v8i16, shr_imm8, OpNode> { 3878 let Inst{21-19} = 0b001; // imm6 = 001xxx 3879 } 3880 def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 3881 OpcodeStr, !strconcat(Dt, "32"), 3882 v4i16, v4i32, shr_imm16, OpNode> { 3883 let Inst{21-20} = 0b01; // imm6 = 01xxxx 3884 } 3885 def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 3886 OpcodeStr, !strconcat(Dt, "64"), 3887 v2i32, v2i64, shr_imm32, OpNode> { 3888 let Inst{21} = 0b1; // imm6 = 1xxxxx 3889 } 3890} 3891 3892//===----------------------------------------------------------------------===// 3893// Instruction Definitions. 3894//===----------------------------------------------------------------------===// 3895 3896// Vector Add Operations. 3897 3898// VADD : Vector Add (integer and floating-point) 3899defm VADD : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i", 3900 add, 1>; 3901def VADDfd : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32", 3902 v2f32, v2f32, fadd, 1>; 3903def VADDfq : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32", 3904 v4f32, v4f32, fadd, 1>; 3905// VADDL : Vector Add Long (Q = D + D) 3906defm VADDLs : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD, 3907 "vaddl", "s", add, sext, 1>; 3908defm VADDLu : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD, 3909 "vaddl", "u", add, zext, 1>; 3910// VADDW : Vector Add Wide (Q = Q + D) 3911defm VADDWs : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>; 3912defm VADDWu : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zext, 0>; 3913// VHADD : Vector Halving Add 3914defm VHADDs : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm, 3915 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3916 "vhadd", "s", int_arm_neon_vhadds, 1>; 3917defm VHADDu : N3VInt_QHS<1, 0, 0b0000, 0, N3RegFrm, 3918 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3919 "vhadd", "u", int_arm_neon_vhaddu, 1>; 3920// VRHADD : Vector Rounding Halving Add 3921defm VRHADDs : N3VInt_QHS<0, 0, 0b0001, 0, N3RegFrm, 3922 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3923 "vrhadd", "s", int_arm_neon_vrhadds, 1>; 3924defm VRHADDu : N3VInt_QHS<1, 0, 0b0001, 0, N3RegFrm, 3925 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3926 "vrhadd", "u", int_arm_neon_vrhaddu, 1>; 3927// VQADD : Vector Saturating Add 3928defm VQADDs : N3VInt_QHSD<0, 0, 0b0000, 1, N3RegFrm, 3929 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3930 "vqadd", "s", int_arm_neon_vqadds, 1>; 3931defm VQADDu : N3VInt_QHSD<1, 0, 0b0000, 1, N3RegFrm, 3932 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 3933 "vqadd", "u", int_arm_neon_vqaddu, 1>; 3934// VADDHN : Vector Add and Narrow Returning High Half (D = Q + Q) 3935defm VADDHN : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i", 3936 int_arm_neon_vaddhn, 1>; 3937// VRADDHN : Vector Rounding Add and Narrow Returning High Half (D = Q + Q) 3938defm VRADDHN : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i", 3939 int_arm_neon_vraddhn, 1>; 3940 3941// Vector Multiply Operations. 3942 3943// VMUL : Vector Multiply (integer, polynomial and floating-point) 3944defm VMUL : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D, 3945 IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>; 3946def VMULpd : N3VDInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16D, "vmul", 3947 "p8", v8i8, v8i8, int_arm_neon_vmulp, 1>; 3948def VMULpq : N3VQInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16Q, "vmul", 3949 "p8", v16i8, v16i8, int_arm_neon_vmulp, 1>; 3950def VMULfd : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VFMULD, "vmul", "f32", 3951 v2f32, v2f32, fmul, 1>; 3952def VMULfq : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VFMULQ, "vmul", "f32", 3953 v4f32, v4f32, fmul, 1>; 3954defm VMULsl : N3VSL_HS<0b1000, "vmul", mul>; 3955def VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>; 3956def VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32, 3957 v2f32, fmul>; 3958 3959def : Pat<(v8i16 (mul (v8i16 QPR:$src1), 3960 (v8i16 (NEONvduplane (v8i16 QPR:$src2), imm:$lane)))), 3961 (v8i16 (VMULslv8i16 (v8i16 QPR:$src1), 3962 (v4i16 (EXTRACT_SUBREG QPR:$src2, 3963 (DSubReg_i16_reg imm:$lane))), 3964 (SubReg_i16_lane imm:$lane)))>; 3965def : Pat<(v4i32 (mul (v4i32 QPR:$src1), 3966 (v4i32 (NEONvduplane (v4i32 QPR:$src2), imm:$lane)))), 3967 (v4i32 (VMULslv4i32 (v4i32 QPR:$src1), 3968 (v2i32 (EXTRACT_SUBREG QPR:$src2, 3969 (DSubReg_i32_reg imm:$lane))), 3970 (SubReg_i32_lane imm:$lane)))>; 3971def : Pat<(v4f32 (fmul (v4f32 QPR:$src1), 3972 (v4f32 (NEONvduplane (v4f32 QPR:$src2), imm:$lane)))), 3973 (v4f32 (VMULslfq (v4f32 QPR:$src1), 3974 (v2f32 (EXTRACT_SUBREG QPR:$src2, 3975 (DSubReg_i32_reg imm:$lane))), 3976 (SubReg_i32_lane imm:$lane)))>; 3977 3978// VQDMULH : Vector Saturating Doubling Multiply Returning High Half 3979defm VQDMULH : N3VInt_HS<0, 0, 0b1011, 0, N3RegFrm, IIC_VMULi16D, IIC_VMULi32D, 3980 IIC_VMULi16Q, IIC_VMULi32Q, 3981 "vqdmulh", "s", int_arm_neon_vqdmulh, 1>; 3982defm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D, 3983 IIC_VMULi16Q, IIC_VMULi32Q, 3984 "vqdmulh", "s", int_arm_neon_vqdmulh>; 3985def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1), 3986 (v8i16 (NEONvduplane (v8i16 QPR:$src2), 3987 imm:$lane)))), 3988 (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1), 3989 (v4i16 (EXTRACT_SUBREG QPR:$src2, 3990 (DSubReg_i16_reg imm:$lane))), 3991 (SubReg_i16_lane imm:$lane)))>; 3992def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1), 3993 (v4i32 (NEONvduplane (v4i32 QPR:$src2), 3994 imm:$lane)))), 3995 (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1), 3996 (v2i32 (EXTRACT_SUBREG QPR:$src2, 3997 (DSubReg_i32_reg imm:$lane))), 3998 (SubReg_i32_lane imm:$lane)))>; 3999 4000// VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half 4001defm VQRDMULH : N3VInt_HS<1, 0, 0b1011, 0, N3RegFrm, 4002 IIC_VMULi16D,IIC_VMULi32D,IIC_VMULi16Q,IIC_VMULi32Q, 4003 "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>; 4004defm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D, 4005 IIC_VMULi16Q, IIC_VMULi32Q, 4006 "vqrdmulh", "s", int_arm_neon_vqrdmulh>; 4007def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1), 4008 (v8i16 (NEONvduplane (v8i16 QPR:$src2), 4009 imm:$lane)))), 4010 (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1), 4011 (v4i16 (EXTRACT_SUBREG QPR:$src2, 4012 (DSubReg_i16_reg imm:$lane))), 4013 (SubReg_i16_lane imm:$lane)))>; 4014def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1), 4015 (v4i32 (NEONvduplane (v4i32 QPR:$src2), 4016 imm:$lane)))), 4017 (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1), 4018 (v2i32 (EXTRACT_SUBREG QPR:$src2, 4019 (DSubReg_i32_reg imm:$lane))), 4020 (SubReg_i32_lane imm:$lane)))>; 4021 4022// VMULL : Vector Multiply Long (integer and polynomial) (Q = D * D) 4023defm VMULLs : N3VL_QHS<0,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D, 4024 "vmull", "s", NEONvmulls, 1>; 4025defm VMULLu : N3VL_QHS<1,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D, 4026 "vmull", "u", NEONvmullu, 1>; 4027def VMULLp : N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8", 4028 v8i16, v8i8, int_arm_neon_vmullp, 1>; 4029defm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", NEONvmulls>; 4030defm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", NEONvmullu>; 4031 4032// VQDMULL : Vector Saturating Doubling Multiply Long (Q = D * D) 4033defm VQDMULL : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, IIC_VMULi32D, 4034 "vqdmull", "s", int_arm_neon_vqdmull, 1>; 4035defm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D, 4036 "vqdmull", "s", int_arm_neon_vqdmull>; 4037 4038// Vector Multiply-Accumulate and Multiply-Subtract Operations. 4039 4040// VMLA : Vector Multiply Accumulate (integer and floating-point) 4041defm VMLA : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4042 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>; 4043def VMLAfd : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32", 4044 v2f32, fmul_su, fadd_mlx>, 4045 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>; 4046def VMLAfq : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32", 4047 v4f32, fmul_su, fadd_mlx>, 4048 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>; 4049defm VMLAsl : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D, 4050 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>; 4051def VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32", 4052 v2f32, fmul_su, fadd_mlx>, 4053 Requires<[HasNEON, UseFPVMLx]>; 4054def VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32", 4055 v4f32, v2f32, fmul_su, fadd_mlx>, 4056 Requires<[HasNEON, UseFPVMLx]>; 4057 4058def : Pat<(v8i16 (add (v8i16 QPR:$src1), 4059 (mul (v8i16 QPR:$src2), 4060 (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))), 4061 (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2), 4062 (v4i16 (EXTRACT_SUBREG QPR:$src3, 4063 (DSubReg_i16_reg imm:$lane))), 4064 (SubReg_i16_lane imm:$lane)))>; 4065 4066def : Pat<(v4i32 (add (v4i32 QPR:$src1), 4067 (mul (v4i32 QPR:$src2), 4068 (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))), 4069 (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2), 4070 (v2i32 (EXTRACT_SUBREG QPR:$src3, 4071 (DSubReg_i32_reg imm:$lane))), 4072 (SubReg_i32_lane imm:$lane)))>; 4073 4074def : Pat<(v4f32 (fadd_mlx (v4f32 QPR:$src1), 4075 (fmul_su (v4f32 QPR:$src2), 4076 (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))), 4077 (v4f32 (VMLAslfq (v4f32 QPR:$src1), 4078 (v4f32 QPR:$src2), 4079 (v2f32 (EXTRACT_SUBREG QPR:$src3, 4080 (DSubReg_i32_reg imm:$lane))), 4081 (SubReg_i32_lane imm:$lane)))>, 4082 Requires<[HasNEON, UseFPVMLx]>; 4083 4084// VMLAL : Vector Multiply Accumulate Long (Q += D * D) 4085defm VMLALs : N3VLMulOp_QHS<0,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D, 4086 "vmlal", "s", NEONvmulls, add>; 4087defm VMLALu : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D, 4088 "vmlal", "u", NEONvmullu, add>; 4089 4090defm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", NEONvmulls, add>; 4091defm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", NEONvmullu, add>; 4092 4093// VQDMLAL : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D) 4094defm VQDMLAL : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4095 "vqdmlal", "s", int_arm_neon_vqdmlal>; 4096defm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", int_arm_neon_vqdmlal>; 4097 4098// VMLS : Vector Multiply Subtract (integer and floating-point) 4099defm VMLS : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4100 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>; 4101def VMLSfd : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32", 4102 v2f32, fmul_su, fsub_mlx>, 4103 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>; 4104def VMLSfq : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32", 4105 v4f32, fmul_su, fsub_mlx>, 4106 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>; 4107defm VMLSsl : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D, 4108 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>; 4109def VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32", 4110 v2f32, fmul_su, fsub_mlx>, 4111 Requires<[HasNEON, UseFPVMLx]>; 4112def VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32", 4113 v4f32, v2f32, fmul_su, fsub_mlx>, 4114 Requires<[HasNEON, UseFPVMLx]>; 4115 4116def : Pat<(v8i16 (sub (v8i16 QPR:$src1), 4117 (mul (v8i16 QPR:$src2), 4118 (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))), 4119 (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2), 4120 (v4i16 (EXTRACT_SUBREG QPR:$src3, 4121 (DSubReg_i16_reg imm:$lane))), 4122 (SubReg_i16_lane imm:$lane)))>; 4123 4124def : Pat<(v4i32 (sub (v4i32 QPR:$src1), 4125 (mul (v4i32 QPR:$src2), 4126 (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))), 4127 (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2), 4128 (v2i32 (EXTRACT_SUBREG QPR:$src3, 4129 (DSubReg_i32_reg imm:$lane))), 4130 (SubReg_i32_lane imm:$lane)))>; 4131 4132def : Pat<(v4f32 (fsub_mlx (v4f32 QPR:$src1), 4133 (fmul_su (v4f32 QPR:$src2), 4134 (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))), 4135 (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2), 4136 (v2f32 (EXTRACT_SUBREG QPR:$src3, 4137 (DSubReg_i32_reg imm:$lane))), 4138 (SubReg_i32_lane imm:$lane)))>, 4139 Requires<[HasNEON, UseFPVMLx]>; 4140 4141// VMLSL : Vector Multiply Subtract Long (Q -= D * D) 4142defm VMLSLs : N3VLMulOp_QHS<0,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D, 4143 "vmlsl", "s", NEONvmulls, sub>; 4144defm VMLSLu : N3VLMulOp_QHS<1,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D, 4145 "vmlsl", "u", NEONvmullu, sub>; 4146 4147defm VMLSLsls : N3VLMulOpSL_HS<0, 0b0110, "vmlsl", "s", NEONvmulls, sub>; 4148defm VMLSLslu : N3VLMulOpSL_HS<1, 0b0110, "vmlsl", "u", NEONvmullu, sub>; 4149 4150// VQDMLSL : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D) 4151defm VQDMLSL : N3VLInt3_HS<0, 1, 0b1011, 0, IIC_VMACi16D, IIC_VMACi32D, 4152 "vqdmlsl", "s", int_arm_neon_vqdmlsl>; 4153defm VQDMLSLsl: N3VLInt3SL_HS<0, 0b111, "vqdmlsl", "s", int_arm_neon_vqdmlsl>; 4154 4155// Fused Vector Multiply-Accumulate and Fused Multiply-Subtract Operations. 4156def VFMAfd : N3VDMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACD, "vfma", "f32", 4157 v2f32, fmul_su, fadd_mlx>, 4158 Requires<[HasVFP4,UseFusedMAC]>; 4159 4160def VFMAfq : N3VQMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACQ, "vfma", "f32", 4161 v4f32, fmul_su, fadd_mlx>, 4162 Requires<[HasVFP4,UseFusedMAC]>; 4163 4164// Fused Vector Multiply Subtract (floating-point) 4165def VFMSfd : N3VDMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACD, "vfms", "f32", 4166 v2f32, fmul_su, fsub_mlx>, 4167 Requires<[HasVFP4,UseFusedMAC]>; 4168def VFMSfq : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32", 4169 v4f32, fmul_su, fsub_mlx>, 4170 Requires<[HasVFP4,UseFusedMAC]>; 4171 4172// Match @llvm.fma.* intrinsics 4173def : Pat<(v2f32 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)), 4174 (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>, 4175 Requires<[HasVFP4]>; 4176def : Pat<(v4f32 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)), 4177 (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>, 4178 Requires<[HasVFP4]>; 4179def : Pat<(v2f32 (fma (fneg DPR:$Vn), DPR:$Vm, DPR:$src1)), 4180 (VFMSfd DPR:$src1, DPR:$Vn, DPR:$Vm)>, 4181 Requires<[HasVFP4]>; 4182def : Pat<(v4f32 (fma (fneg QPR:$Vn), QPR:$Vm, QPR:$src1)), 4183 (VFMSfq QPR:$src1, QPR:$Vn, QPR:$Vm)>, 4184 Requires<[HasVFP4]>; 4185 4186// Vector Subtract Operations. 4187 4188// VSUB : Vector Subtract (integer and floating-point) 4189defm VSUB : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ, 4190 "vsub", "i", sub, 0>; 4191def VSUBfd : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32", 4192 v2f32, v2f32, fsub, 0>; 4193def VSUBfq : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32", 4194 v4f32, v4f32, fsub, 0>; 4195// VSUBL : Vector Subtract Long (Q = D - D) 4196defm VSUBLs : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD, 4197 "vsubl", "s", sub, sext, 0>; 4198defm VSUBLu : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD, 4199 "vsubl", "u", sub, zext, 0>; 4200// VSUBW : Vector Subtract Wide (Q = Q - D) 4201defm VSUBWs : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>; 4202defm VSUBWu : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zext, 0>; 4203// VHSUB : Vector Halving Subtract 4204defm VHSUBs : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm, 4205 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4206 "vhsub", "s", int_arm_neon_vhsubs, 0>; 4207defm VHSUBu : N3VInt_QHS<1, 0, 0b0010, 0, N3RegFrm, 4208 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4209 "vhsub", "u", int_arm_neon_vhsubu, 0>; 4210// VQSUB : Vector Saturing Subtract 4211defm VQSUBs : N3VInt_QHSD<0, 0, 0b0010, 1, N3RegFrm, 4212 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4213 "vqsub", "s", int_arm_neon_vqsubs, 0>; 4214defm VQSUBu : N3VInt_QHSD<1, 0, 0b0010, 1, N3RegFrm, 4215 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4216 "vqsub", "u", int_arm_neon_vqsubu, 0>; 4217// VSUBHN : Vector Subtract and Narrow Returning High Half (D = Q - Q) 4218defm VSUBHN : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i", 4219 int_arm_neon_vsubhn, 0>; 4220// VRSUBHN : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q) 4221defm VRSUBHN : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i", 4222 int_arm_neon_vrsubhn, 0>; 4223 4224// Vector Comparisons. 4225 4226// VCEQ : Vector Compare Equal 4227defm VCEQ : N3V_QHS<1, 0, 0b1000, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 4228 IIC_VSUBi4Q, "vceq", "i", NEONvceq, 1>; 4229def VCEQfd : N3VD<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32, 4230 NEONvceq, 1>; 4231def VCEQfq : N3VQ<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32, 4232 NEONvceq, 1>; 4233 4234defm VCEQz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i", 4235 "$Vd, $Vm, #0", NEONvceqz>; 4236 4237// VCGE : Vector Compare Greater Than or Equal 4238defm VCGEs : N3V_QHS<0, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 4239 IIC_VSUBi4Q, "vcge", "s", NEONvcge, 0>; 4240defm VCGEu : N3V_QHS<1, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 4241 IIC_VSUBi4Q, "vcge", "u", NEONvcgeu, 0>; 4242def VCGEfd : N3VD<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32", v2i32, v2f32, 4243 NEONvcge, 0>; 4244def VCGEfq : N3VQ<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32, 4245 NEONvcge, 0>; 4246 4247defm VCGEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s", 4248 "$Vd, $Vm, #0", NEONvcgez>; 4249defm VCLEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s", 4250 "$Vd, $Vm, #0", NEONvclez>; 4251 4252// VCGT : Vector Compare Greater Than 4253defm VCGTs : N3V_QHS<0, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 4254 IIC_VSUBi4Q, "vcgt", "s", NEONvcgt, 0>; 4255defm VCGTu : N3V_QHS<1, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 4256 IIC_VSUBi4Q, "vcgt", "u", NEONvcgtu, 0>; 4257def VCGTfd : N3VD<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32, 4258 NEONvcgt, 0>; 4259def VCGTfq : N3VQ<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32, 4260 NEONvcgt, 0>; 4261 4262defm VCGTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s", 4263 "$Vd, $Vm, #0", NEONvcgtz>; 4264defm VCLTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s", 4265 "$Vd, $Vm, #0", NEONvcltz>; 4266 4267// VACGE : Vector Absolute Compare Greater Than or Equal (aka VCAGE) 4268def VACGEd : N3VDInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge", 4269 "f32", v2i32, v2f32, int_arm_neon_vacged, 0>; 4270def VACGEq : N3VQInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge", 4271 "f32", v4i32, v4f32, int_arm_neon_vacgeq, 0>; 4272// VACGT : Vector Absolute Compare Greater Than (aka VCAGT) 4273def VACGTd : N3VDInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt", 4274 "f32", v2i32, v2f32, int_arm_neon_vacgtd, 0>; 4275def VACGTq : N3VQInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt", 4276 "f32", v4i32, v4f32, int_arm_neon_vacgtq, 0>; 4277// VTST : Vector Test Bits 4278defm VTST : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 4279 IIC_VBINi4Q, "vtst", "", NEONvtst, 1>; 4280 4281// Vector Bitwise Operations. 4282 4283def vnotd : PatFrag<(ops node:$in), 4284 (xor node:$in, (bitconvert (v8i8 NEONimmAllOnesV)))>; 4285def vnotq : PatFrag<(ops node:$in), 4286 (xor node:$in, (bitconvert (v16i8 NEONimmAllOnesV)))>; 4287 4288 4289// VAND : Vector Bitwise AND 4290def VANDd : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand", 4291 v2i32, v2i32, and, 1>; 4292def VANDq : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand", 4293 v4i32, v4i32, and, 1>; 4294 4295// VEOR : Vector Bitwise Exclusive OR 4296def VEORd : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor", 4297 v2i32, v2i32, xor, 1>; 4298def VEORq : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor", 4299 v4i32, v4i32, xor, 1>; 4300 4301// VORR : Vector Bitwise OR 4302def VORRd : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr", 4303 v2i32, v2i32, or, 1>; 4304def VORRq : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr", 4305 v4i32, v4i32, or, 1>; 4306 4307def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1, 4308 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), 4309 IIC_VMOVImm, 4310 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", 4311 [(set DPR:$Vd, 4312 (v4i16 (NEONvorrImm DPR:$src, timm:$SIMM)))]> { 4313 let Inst{9} = SIMM{9}; 4314} 4315 4316def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1, 4317 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src), 4318 IIC_VMOVImm, 4319 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd", 4320 [(set DPR:$Vd, 4321 (v2i32 (NEONvorrImm DPR:$src, timm:$SIMM)))]> { 4322 let Inst{10-9} = SIMM{10-9}; 4323} 4324 4325def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1, 4326 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), 4327 IIC_VMOVImm, 4328 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", 4329 [(set QPR:$Vd, 4330 (v8i16 (NEONvorrImm QPR:$src, timm:$SIMM)))]> { 4331 let Inst{9} = SIMM{9}; 4332} 4333 4334def VORRiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 0, 1, 4335 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src), 4336 IIC_VMOVImm, 4337 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd", 4338 [(set QPR:$Vd, 4339 (v4i32 (NEONvorrImm QPR:$src, timm:$SIMM)))]> { 4340 let Inst{10-9} = SIMM{10-9}; 4341} 4342 4343 4344// VBIC : Vector Bitwise Bit Clear (AND NOT) 4345let TwoOperandAliasConstraint = "$Vn = $Vd" in { 4346def VBICd : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd), 4347 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD, 4348 "vbic", "$Vd, $Vn, $Vm", "", 4349 [(set DPR:$Vd, (v2i32 (and DPR:$Vn, 4350 (vnotd DPR:$Vm))))]>; 4351def VBICq : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), 4352 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ, 4353 "vbic", "$Vd, $Vn, $Vm", "", 4354 [(set QPR:$Vd, (v4i32 (and QPR:$Vn, 4355 (vnotq QPR:$Vm))))]>; 4356} 4357 4358def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1, 4359 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), 4360 IIC_VMOVImm, 4361 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", 4362 [(set DPR:$Vd, 4363 (v4i16 (NEONvbicImm DPR:$src, timm:$SIMM)))]> { 4364 let Inst{9} = SIMM{9}; 4365} 4366 4367def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1, 4368 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src), 4369 IIC_VMOVImm, 4370 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd", 4371 [(set DPR:$Vd, 4372 (v2i32 (NEONvbicImm DPR:$src, timm:$SIMM)))]> { 4373 let Inst{10-9} = SIMM{10-9}; 4374} 4375 4376def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1, 4377 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), 4378 IIC_VMOVImm, 4379 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", 4380 [(set QPR:$Vd, 4381 (v8i16 (NEONvbicImm QPR:$src, timm:$SIMM)))]> { 4382 let Inst{9} = SIMM{9}; 4383} 4384 4385def VBICiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 1, 1, 4386 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src), 4387 IIC_VMOVImm, 4388 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd", 4389 [(set QPR:$Vd, 4390 (v4i32 (NEONvbicImm QPR:$src, timm:$SIMM)))]> { 4391 let Inst{10-9} = SIMM{10-9}; 4392} 4393 4394// VORN : Vector Bitwise OR NOT 4395def VORNd : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$Vd), 4396 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD, 4397 "vorn", "$Vd, $Vn, $Vm", "", 4398 [(set DPR:$Vd, (v2i32 (or DPR:$Vn, 4399 (vnotd DPR:$Vm))))]>; 4400def VORNq : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd), 4401 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ, 4402 "vorn", "$Vd, $Vn, $Vm", "", 4403 [(set QPR:$Vd, (v4i32 (or QPR:$Vn, 4404 (vnotq QPR:$Vm))))]>; 4405 4406// VMVN : Vector Bitwise NOT (Immediate) 4407 4408let isReMaterializable = 1 in { 4409 4410def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd), 4411 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 4412 "vmvn", "i16", "$Vd, $SIMM", "", 4413 [(set DPR:$Vd, (v4i16 (NEONvmvnImm timm:$SIMM)))]> { 4414 let Inst{9} = SIMM{9}; 4415} 4416 4417def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd), 4418 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 4419 "vmvn", "i16", "$Vd, $SIMM", "", 4420 [(set QPR:$Vd, (v8i16 (NEONvmvnImm timm:$SIMM)))]> { 4421 let Inst{9} = SIMM{9}; 4422} 4423 4424def VMVNv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 1, 1, (outs DPR:$Vd), 4425 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 4426 "vmvn", "i32", "$Vd, $SIMM", "", 4427 [(set DPR:$Vd, (v2i32 (NEONvmvnImm timm:$SIMM)))]> { 4428 let Inst{11-8} = SIMM{11-8}; 4429} 4430 4431def VMVNv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 1, 1, (outs QPR:$Vd), 4432 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 4433 "vmvn", "i32", "$Vd, $SIMM", "", 4434 [(set QPR:$Vd, (v4i32 (NEONvmvnImm timm:$SIMM)))]> { 4435 let Inst{11-8} = SIMM{11-8}; 4436} 4437} 4438 4439// VMVN : Vector Bitwise NOT 4440def VMVNd : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0, 4441 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VSUBiD, 4442 "vmvn", "$Vd, $Vm", "", 4443 [(set DPR:$Vd, (v2i32 (vnotd DPR:$Vm)))]>; 4444def VMVNq : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0, 4445 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VSUBiD, 4446 "vmvn", "$Vd, $Vm", "", 4447 [(set QPR:$Vd, (v4i32 (vnotq QPR:$Vm)))]>; 4448def : Pat<(v2i32 (vnotd DPR:$src)), (VMVNd DPR:$src)>; 4449def : Pat<(v4i32 (vnotq QPR:$src)), (VMVNq QPR:$src)>; 4450 4451// VBSL : Vector Bitwise Select 4452def VBSLd : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd), 4453 (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 4454 N3RegFrm, IIC_VCNTiD, 4455 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4456 [(set DPR:$Vd, 4457 (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, DPR:$Vm)))]>; 4458 4459def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd), 4460 (and DPR:$Vm, (vnotd DPR:$Vd)))), 4461 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>; 4462 4463def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), 4464 (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 4465 N3RegFrm, IIC_VCNTiQ, 4466 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4467 [(set QPR:$Vd, 4468 (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, QPR:$Vm)))]>; 4469 4470def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd), 4471 (and QPR:$Vm, (vnotq QPR:$Vd)))), 4472 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>; 4473 4474// VBIF : Vector Bitwise Insert if False 4475// like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst", 4476// FIXME: This instruction's encoding MAY NOT BE correct. 4477def VBIFd : N3VX<1, 0, 0b11, 0b0001, 0, 1, 4478 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 4479 N3RegFrm, IIC_VBINiD, 4480 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4481 []>; 4482def VBIFq : N3VX<1, 0, 0b11, 0b0001, 1, 1, 4483 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 4484 N3RegFrm, IIC_VBINiQ, 4485 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4486 []>; 4487 4488// VBIT : Vector Bitwise Insert if True 4489// like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst", 4490// FIXME: This instruction's encoding MAY NOT BE correct. 4491def VBITd : N3VX<1, 0, 0b10, 0b0001, 0, 1, 4492 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 4493 N3RegFrm, IIC_VBINiD, 4494 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4495 []>; 4496def VBITq : N3VX<1, 0, 0b10, 0b0001, 1, 1, 4497 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 4498 N3RegFrm, IIC_VBINiQ, 4499 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd", 4500 []>; 4501 4502// VBIT/VBIF are not yet implemented. The TwoAddress pass will not go looking 4503// for equivalent operations with different register constraints; it just 4504// inserts copies. 4505 4506// Vector Absolute Differences. 4507 4508// VABD : Vector Absolute Difference 4509defm VABDs : N3VInt_QHS<0, 0, 0b0111, 0, N3RegFrm, 4510 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4511 "vabd", "s", int_arm_neon_vabds, 1>; 4512defm VABDu : N3VInt_QHS<1, 0, 0b0111, 0, N3RegFrm, 4513 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4514 "vabd", "u", int_arm_neon_vabdu, 1>; 4515def VABDfd : N3VDInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBIND, 4516 "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 1>; 4517def VABDfq : N3VQInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBINQ, 4518 "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 1>; 4519 4520// VABDL : Vector Absolute Difference Long (Q = | D - D |) 4521defm VABDLs : N3VLIntExt_QHS<0,1,0b0111,0, IIC_VSUBi4Q, 4522 "vabdl", "s", int_arm_neon_vabds, zext, 1>; 4523defm VABDLu : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q, 4524 "vabdl", "u", int_arm_neon_vabdu, zext, 1>; 4525 4526// VABA : Vector Absolute Difference and Accumulate 4527defm VABAs : N3VIntOp_QHS<0,0,0b0111,1, IIC_VABAD, IIC_VABAQ, 4528 "vaba", "s", int_arm_neon_vabds, add>; 4529defm VABAu : N3VIntOp_QHS<1,0,0b0111,1, IIC_VABAD, IIC_VABAQ, 4530 "vaba", "u", int_arm_neon_vabdu, add>; 4531 4532// VABAL : Vector Absolute Difference and Accumulate Long (Q += | D - D |) 4533defm VABALs : N3VLIntExtOp_QHS<0,1,0b0101,0, IIC_VABAD, 4534 "vabal", "s", int_arm_neon_vabds, zext, add>; 4535defm VABALu : N3VLIntExtOp_QHS<1,1,0b0101,0, IIC_VABAD, 4536 "vabal", "u", int_arm_neon_vabdu, zext, add>; 4537 4538// Vector Maximum and Minimum. 4539 4540// VMAX : Vector Maximum 4541defm VMAXs : N3VInt_QHS<0, 0, 0b0110, 0, N3RegFrm, 4542 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4543 "vmax", "s", int_arm_neon_vmaxs, 1>; 4544defm VMAXu : N3VInt_QHS<1, 0, 0b0110, 0, N3RegFrm, 4545 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4546 "vmax", "u", int_arm_neon_vmaxu, 1>; 4547def VMAXfd : N3VDInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBIND, 4548 "vmax", "f32", 4549 v2f32, v2f32, int_arm_neon_vmaxs, 1>; 4550def VMAXfq : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ, 4551 "vmax", "f32", 4552 v4f32, v4f32, int_arm_neon_vmaxs, 1>; 4553 4554// VMIN : Vector Minimum 4555defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm, 4556 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4557 "vmin", "s", int_arm_neon_vmins, 1>; 4558defm VMINu : N3VInt_QHS<1, 0, 0b0110, 1, N3RegFrm, 4559 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 4560 "vmin", "u", int_arm_neon_vminu, 1>; 4561def VMINfd : N3VDInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBIND, 4562 "vmin", "f32", 4563 v2f32, v2f32, int_arm_neon_vmins, 1>; 4564def VMINfq : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ, 4565 "vmin", "f32", 4566 v4f32, v4f32, int_arm_neon_vmins, 1>; 4567 4568// Vector Pairwise Operations. 4569 4570// VPADD : Vector Pairwise Add 4571def VPADDi8 : N3VDInt<0, 0, 0b00, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 4572 "vpadd", "i8", 4573 v8i8, v8i8, int_arm_neon_vpadd, 0>; 4574def VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 4575 "vpadd", "i16", 4576 v4i16, v4i16, int_arm_neon_vpadd, 0>; 4577def VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 4578 "vpadd", "i32", 4579 v2i32, v2i32, int_arm_neon_vpadd, 0>; 4580def VPADDf : N3VDInt<1, 0, 0b00, 0b1101, 0, N3RegFrm, 4581 IIC_VPBIND, "vpadd", "f32", 4582 v2f32, v2f32, int_arm_neon_vpadd, 0>; 4583 4584// VPADDL : Vector Pairwise Add Long 4585defm VPADDLs : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s", 4586 int_arm_neon_vpaddls>; 4587defm VPADDLu : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u", 4588 int_arm_neon_vpaddlu>; 4589 4590// VPADAL : Vector Pairwise Add and Accumulate Long 4591defm VPADALs : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s", 4592 int_arm_neon_vpadals>; 4593defm VPADALu : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u", 4594 int_arm_neon_vpadalu>; 4595 4596// VPMAX : Vector Pairwise Maximum 4597def VPMAXs8 : N3VDInt<0, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4598 "s8", v8i8, v8i8, int_arm_neon_vpmaxs, 0>; 4599def VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4600 "s16", v4i16, v4i16, int_arm_neon_vpmaxs, 0>; 4601def VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4602 "s32", v2i32, v2i32, int_arm_neon_vpmaxs, 0>; 4603def VPMAXu8 : N3VDInt<1, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4604 "u8", v8i8, v8i8, int_arm_neon_vpmaxu, 0>; 4605def VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4606 "u16", v4i16, v4i16, int_arm_neon_vpmaxu, 0>; 4607def VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 4608 "u32", v2i32, v2i32, int_arm_neon_vpmaxu, 0>; 4609def VPMAXf : N3VDInt<1, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax", 4610 "f32", v2f32, v2f32, int_arm_neon_vpmaxs, 0>; 4611 4612// VPMIN : Vector Pairwise Minimum 4613def VPMINs8 : N3VDInt<0, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4614 "s8", v8i8, v8i8, int_arm_neon_vpmins, 0>; 4615def VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4616 "s16", v4i16, v4i16, int_arm_neon_vpmins, 0>; 4617def VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4618 "s32", v2i32, v2i32, int_arm_neon_vpmins, 0>; 4619def VPMINu8 : N3VDInt<1, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4620 "u8", v8i8, v8i8, int_arm_neon_vpminu, 0>; 4621def VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4622 "u16", v4i16, v4i16, int_arm_neon_vpminu, 0>; 4623def VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 4624 "u32", v2i32, v2i32, int_arm_neon_vpminu, 0>; 4625def VPMINf : N3VDInt<1, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin", 4626 "f32", v2f32, v2f32, int_arm_neon_vpmins, 0>; 4627 4628// Vector Reciprocal and Reciprocal Square Root Estimate and Step. 4629 4630// VRECPE : Vector Reciprocal Estimate 4631def VRECPEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 4632 IIC_VUNAD, "vrecpe", "u32", 4633 v2i32, v2i32, int_arm_neon_vrecpe>; 4634def VRECPEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 4635 IIC_VUNAQ, "vrecpe", "u32", 4636 v4i32, v4i32, int_arm_neon_vrecpe>; 4637def VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, 4638 IIC_VUNAD, "vrecpe", "f32", 4639 v2f32, v2f32, int_arm_neon_vrecpe>; 4640def VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, 4641 IIC_VUNAQ, "vrecpe", "f32", 4642 v4f32, v4f32, int_arm_neon_vrecpe>; 4643 4644// VRECPS : Vector Reciprocal Step 4645def VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, N3RegFrm, 4646 IIC_VRECSD, "vrecps", "f32", 4647 v2f32, v2f32, int_arm_neon_vrecps, 1>; 4648def VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, N3RegFrm, 4649 IIC_VRECSQ, "vrecps", "f32", 4650 v4f32, v4f32, int_arm_neon_vrecps, 1>; 4651 4652// VRSQRTE : Vector Reciprocal Square Root Estimate 4653def VRSQRTEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, 4654 IIC_VUNAD, "vrsqrte", "u32", 4655 v2i32, v2i32, int_arm_neon_vrsqrte>; 4656def VRSQRTEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, 4657 IIC_VUNAQ, "vrsqrte", "u32", 4658 v4i32, v4i32, int_arm_neon_vrsqrte>; 4659def VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, 4660 IIC_VUNAD, "vrsqrte", "f32", 4661 v2f32, v2f32, int_arm_neon_vrsqrte>; 4662def VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, 4663 IIC_VUNAQ, "vrsqrte", "f32", 4664 v4f32, v4f32, int_arm_neon_vrsqrte>; 4665 4666// VRSQRTS : Vector Reciprocal Square Root Step 4667def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, N3RegFrm, 4668 IIC_VRECSD, "vrsqrts", "f32", 4669 v2f32, v2f32, int_arm_neon_vrsqrts, 1>; 4670def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, N3RegFrm, 4671 IIC_VRECSQ, "vrsqrts", "f32", 4672 v4f32, v4f32, int_arm_neon_vrsqrts, 1>; 4673 4674// Vector Shifts. 4675 4676// VSHL : Vector Shift 4677defm VSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 0, N3RegVShFrm, 4678 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ, 4679 "vshl", "s", int_arm_neon_vshifts>; 4680defm VSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 0, N3RegVShFrm, 4681 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ, 4682 "vshl", "u", int_arm_neon_vshiftu>; 4683 4684// VSHL : Vector Shift Left (Immediate) 4685defm VSHLi : N2VShL_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>; 4686 4687// VSHR : Vector Shift Right (Immediate) 4688defm VSHRs : N2VShR_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", "VSHRs", 4689 NEONvshrs>; 4690defm VSHRu : N2VShR_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", "VSHRu", 4691 NEONvshru>; 4692 4693// VSHLL : Vector Shift Left Long 4694defm VSHLLs : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s", NEONvshlls>; 4695defm VSHLLu : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u", NEONvshllu>; 4696 4697// VSHLL : Vector Shift Left Long (with maximum shift count) 4698class N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, 4699 bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy, 4700 ValueType OpTy, Operand ImmTy, SDNode OpNode> 4701 : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt, 4702 ResTy, OpTy, ImmTy, OpNode> { 4703 let Inst{21-16} = op21_16; 4704 let DecoderMethod = "DecodeVSHLMaxInstruction"; 4705} 4706def VSHLLi8 : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8", 4707 v8i16, v8i8, imm8, NEONvshlli>; 4708def VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16", 4709 v4i32, v4i16, imm16, NEONvshlli>; 4710def VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32", 4711 v2i64, v2i32, imm32, NEONvshlli>; 4712 4713// VSHRN : Vector Shift Right and Narrow 4714defm VSHRN : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i", 4715 NEONvshrn>; 4716 4717// VRSHL : Vector Rounding Shift 4718defm VRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 0, N3RegVShFrm, 4719 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4720 "vrshl", "s", int_arm_neon_vrshifts>; 4721defm VRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 0, N3RegVShFrm, 4722 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4723 "vrshl", "u", int_arm_neon_vrshiftu>; 4724// VRSHR : Vector Rounding Shift Right 4725defm VRSHRs : N2VShR_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", "VRSHRs", 4726 NEONvrshrs>; 4727defm VRSHRu : N2VShR_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", "VRSHRu", 4728 NEONvrshru>; 4729 4730// VRSHRN : Vector Rounding Shift Right and Narrow 4731defm VRSHRN : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i", 4732 NEONvrshrn>; 4733 4734// VQSHL : Vector Saturating Shift 4735defm VQSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 1, N3RegVShFrm, 4736 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4737 "vqshl", "s", int_arm_neon_vqshifts>; 4738defm VQSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 1, N3RegVShFrm, 4739 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4740 "vqshl", "u", int_arm_neon_vqshiftu>; 4741// VQSHL : Vector Saturating Shift Left (Immediate) 4742defm VQSHLsi : N2VShL_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s",NEONvqshls>; 4743defm VQSHLui : N2VShL_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u",NEONvqshlu>; 4744 4745// VQSHLU : Vector Saturating Shift Left (Immediate, Unsigned) 4746defm VQSHLsu : N2VShL_QHSD<1,1,0b0110,1, IIC_VSHLi4D,"vqshlu","s",NEONvqshlsu>; 4747 4748// VQSHRN : Vector Saturating Shift Right and Narrow 4749defm VQSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s", 4750 NEONvqshrns>; 4751defm VQSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u", 4752 NEONvqshrnu>; 4753 4754// VQSHRUN : Vector Saturating Shift Right and Narrow (Unsigned) 4755defm VQSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s", 4756 NEONvqshrnsu>; 4757 4758// VQRSHL : Vector Saturating Rounding Shift 4759defm VQRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 1, N3RegVShFrm, 4760 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4761 "vqrshl", "s", int_arm_neon_vqrshifts>; 4762defm VQRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 1, N3RegVShFrm, 4763 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 4764 "vqrshl", "u", int_arm_neon_vqrshiftu>; 4765 4766// VQRSHRN : Vector Saturating Rounding Shift Right and Narrow 4767defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s", 4768 NEONvqrshrns>; 4769defm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u", 4770 NEONvqrshrnu>; 4771 4772// VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned) 4773defm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s", 4774 NEONvqrshrnsu>; 4775 4776// VSRA : Vector Shift Right and Accumulate 4777defm VSRAs : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", NEONvshrs>; 4778defm VSRAu : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", NEONvshru>; 4779// VRSRA : Vector Rounding Shift Right and Accumulate 4780defm VRSRAs : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrs>; 4781defm VRSRAu : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshru>; 4782 4783// VSLI : Vector Shift Left and Insert 4784defm VSLI : N2VShInsL_QHSD<1, 1, 0b0101, 1, "vsli">; 4785 4786// VSRI : Vector Shift Right and Insert 4787defm VSRI : N2VShInsR_QHSD<1, 1, 0b0100, 1, "vsri">; 4788 4789// Vector Absolute and Saturating Absolute. 4790 4791// VABS : Vector Absolute Value 4792defm VABS : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0, 4793 IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", 4794 int_arm_neon_vabs>; 4795def VABSfd : N2VDInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 4796 IIC_VUNAD, "vabs", "f32", 4797 v2f32, v2f32, int_arm_neon_vabs>; 4798def VABSfq : N2VQInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 4799 IIC_VUNAQ, "vabs", "f32", 4800 v4f32, v4f32, int_arm_neon_vabs>; 4801 4802// VQABS : Vector Saturating Absolute Value 4803defm VQABS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0, 4804 IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s", 4805 int_arm_neon_vqabs>; 4806 4807// Vector Negate. 4808 4809def vnegd : PatFrag<(ops node:$in), 4810 (sub (bitconvert (v2i32 NEONimmAllZerosV)), node:$in)>; 4811def vnegq : PatFrag<(ops node:$in), 4812 (sub (bitconvert (v4i32 NEONimmAllZerosV)), node:$in)>; 4813 4814class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty> 4815 : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm), 4816 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 4817 [(set DPR:$Vd, (Ty (vnegd DPR:$Vm)))]>; 4818class VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty> 4819 : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$Vd), (ins QPR:$Vm), 4820 IIC_VSHLiQ, OpcodeStr, Dt, "$Vd, $Vm", "", 4821 [(set QPR:$Vd, (Ty (vnegq QPR:$Vm)))]>; 4822 4823// VNEG : Vector Negate (integer) 4824def VNEGs8d : VNEGD<0b00, "vneg", "s8", v8i8>; 4825def VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>; 4826def VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>; 4827def VNEGs8q : VNEGQ<0b00, "vneg", "s8", v16i8>; 4828def VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>; 4829def VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>; 4830 4831// VNEG : Vector Negate (floating-point) 4832def VNEGfd : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0, 4833 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD, 4834 "vneg", "f32", "$Vd, $Vm", "", 4835 [(set DPR:$Vd, (v2f32 (fneg DPR:$Vm)))]>; 4836def VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0, 4837 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ, 4838 "vneg", "f32", "$Vd, $Vm", "", 4839 [(set QPR:$Vd, (v4f32 (fneg QPR:$Vm)))]>; 4840 4841def : Pat<(v8i8 (vnegd DPR:$src)), (VNEGs8d DPR:$src)>; 4842def : Pat<(v4i16 (vnegd DPR:$src)), (VNEGs16d DPR:$src)>; 4843def : Pat<(v2i32 (vnegd DPR:$src)), (VNEGs32d DPR:$src)>; 4844def : Pat<(v16i8 (vnegq QPR:$src)), (VNEGs8q QPR:$src)>; 4845def : Pat<(v8i16 (vnegq QPR:$src)), (VNEGs16q QPR:$src)>; 4846def : Pat<(v4i32 (vnegq QPR:$src)), (VNEGs32q QPR:$src)>; 4847 4848// VQNEG : Vector Saturating Negate 4849defm VQNEG : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0, 4850 IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s", 4851 int_arm_neon_vqneg>; 4852 4853// Vector Bit Counting Operations. 4854 4855// VCLS : Vector Count Leading Sign Bits 4856defm VCLS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0, 4857 IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s", 4858 int_arm_neon_vcls>; 4859// VCLZ : Vector Count Leading Zeros 4860defm VCLZ : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0, 4861 IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i", 4862 ctlz>; 4863// VCNT : Vector Count One Bits 4864def VCNTd : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, 4865 IIC_VCNTiD, "vcnt", "8", 4866 v8i8, v8i8, ctpop>; 4867def VCNTq : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, 4868 IIC_VCNTiQ, "vcnt", "8", 4869 v16i8, v16i8, ctpop>; 4870 4871// Vector Swap 4872def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0, 4873 (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2), 4874 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm", 4875 []>; 4876def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0, 4877 (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2), 4878 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm", 4879 []>; 4880 4881// Vector Move Operations. 4882 4883// VMOV : Vector Move (Register) 4884def : InstAlias<"vmov${p} $Vd, $Vm", 4885 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>; 4886def : InstAlias<"vmov${p} $Vd, $Vm", 4887 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>; 4888 4889// VMOV : Vector Move (Immediate) 4890 4891let isReMaterializable = 1 in { 4892def VMOVv8i8 : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$Vd), 4893 (ins nImmSplatI8:$SIMM), IIC_VMOVImm, 4894 "vmov", "i8", "$Vd, $SIMM", "", 4895 [(set DPR:$Vd, (v8i8 (NEONvmovImm timm:$SIMM)))]>; 4896def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd), 4897 (ins nImmSplatI8:$SIMM), IIC_VMOVImm, 4898 "vmov", "i8", "$Vd, $SIMM", "", 4899 [(set QPR:$Vd, (v16i8 (NEONvmovImm timm:$SIMM)))]>; 4900 4901def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd), 4902 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 4903 "vmov", "i16", "$Vd, $SIMM", "", 4904 [(set DPR:$Vd, (v4i16 (NEONvmovImm timm:$SIMM)))]> { 4905 let Inst{9} = SIMM{9}; 4906} 4907 4908def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd), 4909 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 4910 "vmov", "i16", "$Vd, $SIMM", "", 4911 [(set QPR:$Vd, (v8i16 (NEONvmovImm timm:$SIMM)))]> { 4912 let Inst{9} = SIMM{9}; 4913} 4914 4915def VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 0, 1, (outs DPR:$Vd), 4916 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 4917 "vmov", "i32", "$Vd, $SIMM", "", 4918 [(set DPR:$Vd, (v2i32 (NEONvmovImm timm:$SIMM)))]> { 4919 let Inst{11-8} = SIMM{11-8}; 4920} 4921 4922def VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 0, 1, (outs QPR:$Vd), 4923 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 4924 "vmov", "i32", "$Vd, $SIMM", "", 4925 [(set QPR:$Vd, (v4i32 (NEONvmovImm timm:$SIMM)))]> { 4926 let Inst{11-8} = SIMM{11-8}; 4927} 4928 4929def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$Vd), 4930 (ins nImmSplatI64:$SIMM), IIC_VMOVImm, 4931 "vmov", "i64", "$Vd, $SIMM", "", 4932 [(set DPR:$Vd, (v1i64 (NEONvmovImm timm:$SIMM)))]>; 4933def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$Vd), 4934 (ins nImmSplatI64:$SIMM), IIC_VMOVImm, 4935 "vmov", "i64", "$Vd, $SIMM", "", 4936 [(set QPR:$Vd, (v2i64 (NEONvmovImm timm:$SIMM)))]>; 4937 4938def VMOVv2f32 : N1ModImm<1, 0b000, 0b1111, 0, 0, 0, 1, (outs DPR:$Vd), 4939 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm, 4940 "vmov", "f32", "$Vd, $SIMM", "", 4941 [(set DPR:$Vd, (v2f32 (NEONvmovFPImm timm:$SIMM)))]>; 4942def VMOVv4f32 : N1ModImm<1, 0b000, 0b1111, 0, 1, 0, 1, (outs QPR:$Vd), 4943 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm, 4944 "vmov", "f32", "$Vd, $SIMM", "", 4945 [(set QPR:$Vd, (v4f32 (NEONvmovFPImm timm:$SIMM)))]>; 4946} // isReMaterializable 4947 4948// VMOV : Vector Get Lane (move scalar to ARM core register) 4949 4950def VGETLNs8 : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?}, 4951 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane), 4952 IIC_VMOVSI, "vmov", "s8", "$R, $V$lane", 4953 [(set GPR:$R, (NEONvgetlanes (v8i8 DPR:$V), 4954 imm:$lane))]> { 4955 let Inst{21} = lane{2}; 4956 let Inst{6-5} = lane{1-0}; 4957} 4958def VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1}, 4959 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane), 4960 IIC_VMOVSI, "vmov", "s16", "$R, $V$lane", 4961 [(set GPR:$R, (NEONvgetlanes (v4i16 DPR:$V), 4962 imm:$lane))]> { 4963 let Inst{21} = lane{1}; 4964 let Inst{6} = lane{0}; 4965} 4966def VGETLNu8 : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?}, 4967 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane), 4968 IIC_VMOVSI, "vmov", "u8", "$R, $V$lane", 4969 [(set GPR:$R, (NEONvgetlaneu (v8i8 DPR:$V), 4970 imm:$lane))]> { 4971 let Inst{21} = lane{2}; 4972 let Inst{6-5} = lane{1-0}; 4973} 4974def VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1}, 4975 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane), 4976 IIC_VMOVSI, "vmov", "u16", "$R, $V$lane", 4977 [(set GPR:$R, (NEONvgetlaneu (v4i16 DPR:$V), 4978 imm:$lane))]> { 4979 let Inst{21} = lane{1}; 4980 let Inst{6} = lane{0}; 4981} 4982def VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00, 4983 (outs GPR:$R), (ins DPR:$V, VectorIndex32:$lane), 4984 IIC_VMOVSI, "vmov", "32", "$R, $V$lane", 4985 [(set GPR:$R, (extractelt (v2i32 DPR:$V), 4986 imm:$lane))]> { 4987 let Inst{21} = lane{0}; 4988} 4989// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td 4990def : Pat<(NEONvgetlanes (v16i8 QPR:$src), imm:$lane), 4991 (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src, 4992 (DSubReg_i8_reg imm:$lane))), 4993 (SubReg_i8_lane imm:$lane))>; 4994def : Pat<(NEONvgetlanes (v8i16 QPR:$src), imm:$lane), 4995 (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src, 4996 (DSubReg_i16_reg imm:$lane))), 4997 (SubReg_i16_lane imm:$lane))>; 4998def : Pat<(NEONvgetlaneu (v16i8 QPR:$src), imm:$lane), 4999 (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src, 5000 (DSubReg_i8_reg imm:$lane))), 5001 (SubReg_i8_lane imm:$lane))>; 5002def : Pat<(NEONvgetlaneu (v8i16 QPR:$src), imm:$lane), 5003 (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src, 5004 (DSubReg_i16_reg imm:$lane))), 5005 (SubReg_i16_lane imm:$lane))>; 5006def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane), 5007 (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src, 5008 (DSubReg_i32_reg imm:$lane))), 5009 (SubReg_i32_lane imm:$lane))>; 5010def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2), 5011 (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)), 5012 (SSubReg_f32_reg imm:$src2))>; 5013def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2), 5014 (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)), 5015 (SSubReg_f32_reg imm:$src2))>; 5016//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2), 5017// (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; 5018def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2), 5019 (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; 5020 5021 5022// VMOV : Vector Set Lane (move ARM core register to scalar) 5023 5024let Constraints = "$src1 = $V" in { 5025def VSETLNi8 : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$V), 5026 (ins DPR:$src1, GPR:$R, VectorIndex8:$lane), 5027 IIC_VMOVISL, "vmov", "8", "$V$lane, $R", 5028 [(set DPR:$V, (vector_insert (v8i8 DPR:$src1), 5029 GPR:$R, imm:$lane))]> { 5030 let Inst{21} = lane{2}; 5031 let Inst{6-5} = lane{1-0}; 5032} 5033def VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$V), 5034 (ins DPR:$src1, GPR:$R, VectorIndex16:$lane), 5035 IIC_VMOVISL, "vmov", "16", "$V$lane, $R", 5036 [(set DPR:$V, (vector_insert (v4i16 DPR:$src1), 5037 GPR:$R, imm:$lane))]> { 5038 let Inst{21} = lane{1}; 5039 let Inst{6} = lane{0}; 5040} 5041def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V), 5042 (ins DPR:$src1, GPR:$R, VectorIndex32:$lane), 5043 IIC_VMOVISL, "vmov", "32", "$V$lane, $R", 5044 [(set DPR:$V, (insertelt (v2i32 DPR:$src1), 5045 GPR:$R, imm:$lane))]> { 5046 let Inst{21} = lane{0}; 5047} 5048 5049def VSETLNi8Q : PseudoNeonI<(outs QPR:$V), 5050 (ins QPR:$src1, GPR:$R, VectorIndex8:$lane), 5051 IIC_VMOVISL, "", 5052 [(set QPR:$V, (vector_insert (v16i8 QPR:$src1), 5053 GPR:$R, imm:$lane))]>; 5054def VSETLNi16Q : PseudoNeonI<(outs QPR:$V), 5055 (ins QPR:$src1, GPR:$R, VectorIndex16:$lane), 5056 IIC_VMOVISL, "", 5057 [(set QPR:$V, (vector_insert (v8i16 QPR:$src1), 5058 GPR:$R, imm:$lane))]>; 5059} 5060 5061def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), 5062 (v4i32 (INSERT_SUBREG QPR:$src1, 5063 GPR:$src2, 5064 (SSubReg_f32_reg imm:$lane)))>; 5065 5066def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)), 5067 (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)), 5068 SPR:$src2, (SSubReg_f32_reg imm:$src3))>; 5069def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)), 5070 (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)), 5071 SPR:$src2, (SSubReg_f32_reg imm:$src3))>; 5072 5073//def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), 5074// (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; 5075def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), 5076 (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; 5077 5078def : Pat<(v2f32 (scalar_to_vector SPR:$src)), 5079 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; 5080def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))), 5081 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 5082def : Pat<(v4f32 (scalar_to_vector SPR:$src)), 5083 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; 5084 5085def : Pat<(v8i8 (scalar_to_vector GPR:$src)), 5086 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 5087def : Pat<(v4i16 (scalar_to_vector GPR:$src)), 5088 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 5089def : Pat<(v2i32 (scalar_to_vector GPR:$src)), 5090 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 5091 5092def : Pat<(v16i8 (scalar_to_vector GPR:$src)), 5093 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), 5094 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 5095 dsub_0)>; 5096def : Pat<(v8i16 (scalar_to_vector GPR:$src)), 5097 (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), 5098 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 5099 dsub_0)>; 5100def : Pat<(v4i32 (scalar_to_vector GPR:$src)), 5101 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 5102 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 5103 dsub_0)>; 5104 5105// VDUP : Vector Duplicate (from ARM core register to all elements) 5106 5107class VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty> 5108 : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$V), (ins GPR:$R), 5109 IIC_VMOVIS, "vdup", Dt, "$V, $R", 5110 [(set DPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>; 5111class VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty> 5112 : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$V), (ins GPR:$R), 5113 IIC_VMOVIS, "vdup", Dt, "$V, $R", 5114 [(set QPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>; 5115 5116def VDUP8d : VDUPD<0b11101100, 0b00, "8", v8i8>; 5117def VDUP16d : VDUPD<0b11101000, 0b01, "16", v4i16>; 5118def VDUP32d : VDUPD<0b11101000, 0b00, "32", v2i32>; 5119def VDUP8q : VDUPQ<0b11101110, 0b00, "8", v16i8>; 5120def VDUP16q : VDUPQ<0b11101010, 0b01, "16", v8i16>; 5121def VDUP32q : VDUPQ<0b11101010, 0b00, "32", v4i32>; 5122 5123def : Pat<(v2f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32d GPR:$R)>; 5124def : Pat<(v4f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>; 5125 5126// VDUP : Vector Duplicate Lane (from scalar to all elements) 5127 5128class VDUPLND<bits<4> op19_16, string OpcodeStr, string Dt, 5129 ValueType Ty, Operand IdxTy> 5130 : NVDupLane<op19_16, 0, (outs DPR:$Vd), (ins DPR:$Vm, IdxTy:$lane), 5131 IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane", 5132 [(set DPR:$Vd, (Ty (NEONvduplane (Ty DPR:$Vm), imm:$lane)))]>; 5133 5134class VDUPLNQ<bits<4> op19_16, string OpcodeStr, string Dt, 5135 ValueType ResTy, ValueType OpTy, Operand IdxTy> 5136 : NVDupLane<op19_16, 1, (outs QPR:$Vd), (ins DPR:$Vm, IdxTy:$lane), 5137 IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane", 5138 [(set QPR:$Vd, (ResTy (NEONvduplane (OpTy DPR:$Vm), 5139 VectorIndex32:$lane)))]>; 5140 5141// Inst{19-16} is partially specified depending on the element size. 5142 5143def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> { 5144 bits<3> lane; 5145 let Inst{19-17} = lane{2-0}; 5146} 5147def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> { 5148 bits<2> lane; 5149 let Inst{19-18} = lane{1-0}; 5150} 5151def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> { 5152 bits<1> lane; 5153 let Inst{19} = lane{0}; 5154} 5155def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> { 5156 bits<3> lane; 5157 let Inst{19-17} = lane{2-0}; 5158} 5159def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> { 5160 bits<2> lane; 5161 let Inst{19-18} = lane{1-0}; 5162} 5163def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> { 5164 bits<1> lane; 5165 let Inst{19} = lane{0}; 5166} 5167 5168def : Pat<(v2f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)), 5169 (VDUPLN32d DPR:$Vm, imm:$lane)>; 5170 5171def : Pat<(v4f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)), 5172 (VDUPLN32q DPR:$Vm, imm:$lane)>; 5173 5174def : Pat<(v16i8 (NEONvduplane (v16i8 QPR:$src), imm:$lane)), 5175 (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src, 5176 (DSubReg_i8_reg imm:$lane))), 5177 (SubReg_i8_lane imm:$lane)))>; 5178def : Pat<(v8i16 (NEONvduplane (v8i16 QPR:$src), imm:$lane)), 5179 (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src, 5180 (DSubReg_i16_reg imm:$lane))), 5181 (SubReg_i16_lane imm:$lane)))>; 5182def : Pat<(v4i32 (NEONvduplane (v4i32 QPR:$src), imm:$lane)), 5183 (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src, 5184 (DSubReg_i32_reg imm:$lane))), 5185 (SubReg_i32_lane imm:$lane)))>; 5186def : Pat<(v4f32 (NEONvduplane (v4f32 QPR:$src), imm:$lane)), 5187 (v4f32 (VDUPLN32q (v2f32 (EXTRACT_SUBREG QPR:$src, 5188 (DSubReg_i32_reg imm:$lane))), 5189 (SubReg_i32_lane imm:$lane)))>; 5190 5191def VDUPfdf : PseudoNeonI<(outs DPR:$dst), (ins SPR:$src), IIC_VMOVD, "", 5192 [(set DPR:$dst, (v2f32 (NEONvdup (f32 SPR:$src))))]>; 5193def VDUPfqf : PseudoNeonI<(outs QPR:$dst), (ins SPR:$src), IIC_VMOVD, "", 5194 [(set QPR:$dst, (v4f32 (NEONvdup (f32 SPR:$src))))]>; 5195 5196// VMOVN : Vector Narrowing Move 5197defm VMOVN : N2VN_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVN, 5198 "vmovn", "i", trunc>; 5199// VQMOVN : Vector Saturating Narrowing Move 5200defm VQMOVNs : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD, 5201 "vqmovn", "s", int_arm_neon_vqmovns>; 5202defm VQMOVNu : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD, 5203 "vqmovn", "u", int_arm_neon_vqmovnu>; 5204defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD, 5205 "vqmovun", "s", int_arm_neon_vqmovnsu>; 5206// VMOVL : Vector Lengthening Move 5207defm VMOVLs : N2VL_QHS<0b01,0b10100,0,1, "vmovl", "s", sext>; 5208defm VMOVLu : N2VL_QHS<0b11,0b10100,0,1, "vmovl", "u", zext>; 5209def : Pat<(v8i16 (anyext (v8i8 DPR:$Vm))), (VMOVLuv8i16 DPR:$Vm)>; 5210def : Pat<(v4i32 (anyext (v4i16 DPR:$Vm))), (VMOVLuv4i32 DPR:$Vm)>; 5211def : Pat<(v2i64 (anyext (v2i32 DPR:$Vm))), (VMOVLuv2i64 DPR:$Vm)>; 5212 5213// Vector Conversions. 5214 5215// VCVT : Vector Convert Between Floating-Point and Integers 5216def VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32", 5217 v2i32, v2f32, fp_to_sint>; 5218def VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32", 5219 v2i32, v2f32, fp_to_uint>; 5220def VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32", 5221 v2f32, v2i32, sint_to_fp>; 5222def VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32", 5223 v2f32, v2i32, uint_to_fp>; 5224 5225def VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32", 5226 v4i32, v4f32, fp_to_sint>; 5227def VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32", 5228 v4i32, v4f32, fp_to_uint>; 5229def VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32", 5230 v4f32, v4i32, sint_to_fp>; 5231def VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32", 5232 v4f32, v4i32, uint_to_fp>; 5233 5234// VCVT : Vector Convert Between Floating-Point and Fixed-Point. 5235let DecoderMethod = "DecodeVCVTD" in { 5236def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32", 5237 v2i32, v2f32, int_arm_neon_vcvtfp2fxs>; 5238def VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32", 5239 v2i32, v2f32, int_arm_neon_vcvtfp2fxu>; 5240def VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32", 5241 v2f32, v2i32, int_arm_neon_vcvtfxs2fp>; 5242def VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32", 5243 v2f32, v2i32, int_arm_neon_vcvtfxu2fp>; 5244} 5245 5246let DecoderMethod = "DecodeVCVTQ" in { 5247def VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32", 5248 v4i32, v4f32, int_arm_neon_vcvtfp2fxs>; 5249def VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32", 5250 v4i32, v4f32, int_arm_neon_vcvtfp2fxu>; 5251def VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32", 5252 v4f32, v4i32, int_arm_neon_vcvtfxs2fp>; 5253def VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32", 5254 v4f32, v4i32, int_arm_neon_vcvtfxu2fp>; 5255} 5256 5257// VCVT : Vector Convert Between Half-Precision and Single-Precision. 5258def VCVTf2h : N2VNInt<0b11, 0b11, 0b01, 0b10, 0b01100, 0, 0, 5259 IIC_VUNAQ, "vcvt", "f16.f32", 5260 v4i16, v4f32, int_arm_neon_vcvtfp2hf>, 5261 Requires<[HasNEON, HasFP16]>; 5262def VCVTh2f : N2VLInt<0b11, 0b11, 0b01, 0b10, 0b01110, 0, 0, 5263 IIC_VUNAQ, "vcvt", "f32.f16", 5264 v4f32, v4i16, int_arm_neon_vcvthf2fp>, 5265 Requires<[HasNEON, HasFP16]>; 5266 5267// Vector Reverse. 5268 5269// VREV64 : Vector Reverse elements within 64-bit doublewords 5270 5271class VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5272 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$Vd), 5273 (ins DPR:$Vm), IIC_VMOVD, 5274 OpcodeStr, Dt, "$Vd, $Vm", "", 5275 [(set DPR:$Vd, (Ty (NEONvrev64 (Ty DPR:$Vm))))]>; 5276class VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5277 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$Vd), 5278 (ins QPR:$Vm), IIC_VMOVQ, 5279 OpcodeStr, Dt, "$Vd, $Vm", "", 5280 [(set QPR:$Vd, (Ty (NEONvrev64 (Ty QPR:$Vm))))]>; 5281 5282def VREV64d8 : VREV64D<0b00, "vrev64", "8", v8i8>; 5283def VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>; 5284def VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>; 5285def : Pat<(v2f32 (NEONvrev64 (v2f32 DPR:$Vm))), (VREV64d32 DPR:$Vm)>; 5286 5287def VREV64q8 : VREV64Q<0b00, "vrev64", "8", v16i8>; 5288def VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>; 5289def VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>; 5290def : Pat<(v4f32 (NEONvrev64 (v4f32 QPR:$Vm))), (VREV64q32 QPR:$Vm)>; 5291 5292// VREV32 : Vector Reverse elements within 32-bit words 5293 5294class VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5295 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$Vd), 5296 (ins DPR:$Vm), IIC_VMOVD, 5297 OpcodeStr, Dt, "$Vd, $Vm", "", 5298 [(set DPR:$Vd, (Ty (NEONvrev32 (Ty DPR:$Vm))))]>; 5299class VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5300 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$Vd), 5301 (ins QPR:$Vm), IIC_VMOVQ, 5302 OpcodeStr, Dt, "$Vd, $Vm", "", 5303 [(set QPR:$Vd, (Ty (NEONvrev32 (Ty QPR:$Vm))))]>; 5304 5305def VREV32d8 : VREV32D<0b00, "vrev32", "8", v8i8>; 5306def VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>; 5307 5308def VREV32q8 : VREV32Q<0b00, "vrev32", "8", v16i8>; 5309def VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>; 5310 5311// VREV16 : Vector Reverse elements within 16-bit halfwords 5312 5313class VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5314 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$Vd), 5315 (ins DPR:$Vm), IIC_VMOVD, 5316 OpcodeStr, Dt, "$Vd, $Vm", "", 5317 [(set DPR:$Vd, (Ty (NEONvrev16 (Ty DPR:$Vm))))]>; 5318class VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 5319 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$Vd), 5320 (ins QPR:$Vm), IIC_VMOVQ, 5321 OpcodeStr, Dt, "$Vd, $Vm", "", 5322 [(set QPR:$Vd, (Ty (NEONvrev16 (Ty QPR:$Vm))))]>; 5323 5324def VREV16d8 : VREV16D<0b00, "vrev16", "8", v8i8>; 5325def VREV16q8 : VREV16Q<0b00, "vrev16", "8", v16i8>; 5326 5327// Other Vector Shuffles. 5328 5329// Aligned extractions: really just dropping registers 5330 5331class AlignedVEXTq<ValueType DestTy, ValueType SrcTy, SDNodeXForm LaneCVT> 5332 : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))), 5333 (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>; 5334 5335def : AlignedVEXTq<v8i8, v16i8, DSubReg_i8_reg>; 5336 5337def : AlignedVEXTq<v4i16, v8i16, DSubReg_i16_reg>; 5338 5339def : AlignedVEXTq<v2i32, v4i32, DSubReg_i32_reg>; 5340 5341def : AlignedVEXTq<v1i64, v2i64, DSubReg_f64_reg>; 5342 5343def : AlignedVEXTq<v2f32, v4f32, DSubReg_i32_reg>; 5344 5345 5346// VEXT : Vector Extract 5347 5348 5349// All of these have a two-operand InstAlias. 5350let TwoOperandAliasConstraint = "$Vn = $Vd" in { 5351class VEXTd<string OpcodeStr, string Dt, ValueType Ty, Operand immTy> 5352 : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd), 5353 (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm, 5354 IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", 5355 [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn), 5356 (Ty DPR:$Vm), imm:$index)))]> { 5357 bits<4> index; 5358 let Inst{11-8} = index{3-0}; 5359} 5360 5361class VEXTq<string OpcodeStr, string Dt, ValueType Ty, Operand immTy> 5362 : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd), 5363 (ins QPR:$Vn, QPR:$Vm, imm0_15:$index), NVExtFrm, 5364 IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", 5365 [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn), 5366 (Ty QPR:$Vm), imm:$index)))]> { 5367 bits<4> index; 5368 let Inst{11-8} = index{3-0}; 5369} 5370} 5371 5372def VEXTd8 : VEXTd<"vext", "8", v8i8, imm0_7> { 5373 let Inst{11-8} = index{3-0}; 5374} 5375def VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> { 5376 let Inst{11-9} = index{2-0}; 5377 let Inst{8} = 0b0; 5378} 5379def VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> { 5380 let Inst{11-10} = index{1-0}; 5381 let Inst{9-8} = 0b00; 5382} 5383def : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn), 5384 (v2f32 DPR:$Vm), 5385 (i32 imm:$index))), 5386 (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>; 5387 5388def VEXTq8 : VEXTq<"vext", "8", v16i8, imm0_15> { 5389 let Inst{11-8} = index{3-0}; 5390} 5391def VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> { 5392 let Inst{11-9} = index{2-0}; 5393 let Inst{8} = 0b0; 5394} 5395def VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> { 5396 let Inst{11-10} = index{1-0}; 5397 let Inst{9-8} = 0b00; 5398} 5399def VEXTq64 : VEXTq<"vext", "64", v2i64, imm0_1> { 5400 let Inst{11} = index{0}; 5401 let Inst{10-8} = 0b000; 5402} 5403def : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn), 5404 (v4f32 QPR:$Vm), 5405 (i32 imm:$index))), 5406 (VEXTq32 QPR:$Vn, QPR:$Vm, imm:$index)>; 5407 5408// VTRN : Vector Transpose 5409 5410def VTRNd8 : N2VDShuffle<0b00, 0b00001, "vtrn", "8">; 5411def VTRNd16 : N2VDShuffle<0b01, 0b00001, "vtrn", "16">; 5412def VTRNd32 : N2VDShuffle<0b10, 0b00001, "vtrn", "32">; 5413 5414def VTRNq8 : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">; 5415def VTRNq16 : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">; 5416def VTRNq32 : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">; 5417 5418// VUZP : Vector Unzip (Deinterleave) 5419 5420def VUZPd8 : N2VDShuffle<0b00, 0b00010, "vuzp", "8">; 5421def VUZPd16 : N2VDShuffle<0b01, 0b00010, "vuzp", "16">; 5422// vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 5423def : NEONInstAlias<"vuzp${p}.32 $Dd, $Dm", 5424 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>; 5425 5426def VUZPq8 : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">; 5427def VUZPq16 : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">; 5428def VUZPq32 : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">; 5429 5430// VZIP : Vector Zip (Interleave) 5431 5432def VZIPd8 : N2VDShuffle<0b00, 0b00011, "vzip", "8">; 5433def VZIPd16 : N2VDShuffle<0b01, 0b00011, "vzip", "16">; 5434// vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 5435def : NEONInstAlias<"vzip${p}.32 $Dd, $Dm", 5436 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>; 5437 5438def VZIPq8 : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">; 5439def VZIPq16 : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">; 5440def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">; 5441 5442// Vector Table Lookup and Table Extension. 5443 5444// VTBL : Vector Table Lookup 5445let DecoderMethod = "DecodeTBLInstruction" in { 5446def VTBL1 5447 : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd), 5448 (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1, 5449 "vtbl", "8", "$Vd, $Vn, $Vm", "", 5450 [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 VecListOneD:$Vn, DPR:$Vm)))]>; 5451let hasExtraSrcRegAllocReq = 1 in { 5452def VTBL2 5453 : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd), 5454 (ins VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB2, 5455 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 5456def VTBL3 5457 : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$Vd), 5458 (ins VecListThreeD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB3, 5459 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 5460def VTBL4 5461 : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$Vd), 5462 (ins VecListFourD:$Vn, DPR:$Vm), 5463 NVTBLFrm, IIC_VTB4, 5464 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 5465} // hasExtraSrcRegAllocReq = 1 5466 5467def VTBL3Pseudo 5468 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB3, "", []>; 5469def VTBL4Pseudo 5470 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB4, "", []>; 5471 5472// VTBX : Vector Table Extension 5473def VTBX1 5474 : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$Vd), 5475 (ins DPR:$orig, VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX1, 5476 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", 5477 [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbx1 5478 DPR:$orig, VecListOneD:$Vn, DPR:$Vm)))]>; 5479let hasExtraSrcRegAllocReq = 1 in { 5480def VTBX2 5481 : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$Vd), 5482 (ins DPR:$orig, VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX2, 5483 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", []>; 5484def VTBX3 5485 : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$Vd), 5486 (ins DPR:$orig, VecListThreeD:$Vn, DPR:$Vm), 5487 NVTBLFrm, IIC_VTBX3, 5488 "vtbx", "8", "$Vd, $Vn, $Vm", 5489 "$orig = $Vd", []>; 5490def VTBX4 5491 : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$Vd), 5492 (ins DPR:$orig, VecListFourD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX4, 5493 "vtbx", "8", "$Vd, $Vn, $Vm", 5494 "$orig = $Vd", []>; 5495} // hasExtraSrcRegAllocReq = 1 5496 5497def VTBX3Pseudo 5498 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src), 5499 IIC_VTBX3, "$orig = $dst", []>; 5500def VTBX4Pseudo 5501 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src), 5502 IIC_VTBX4, "$orig = $dst", []>; 5503} // DecoderMethod = "DecodeTBLInstruction" 5504 5505//===----------------------------------------------------------------------===// 5506// NEON instructions for single-precision FP math 5507//===----------------------------------------------------------------------===// 5508 5509class N2VSPat<SDNode OpNode, NeonI Inst> 5510 : NEONFPPat<(f32 (OpNode SPR:$a)), 5511 (EXTRACT_SUBREG 5512 (v2f32 (COPY_TO_REGCLASS (Inst 5513 (INSERT_SUBREG 5514 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5515 SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>; 5516 5517class N3VSPat<SDNode OpNode, NeonI Inst> 5518 : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), 5519 (EXTRACT_SUBREG 5520 (v2f32 (COPY_TO_REGCLASS (Inst 5521 (INSERT_SUBREG 5522 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5523 SPR:$a, ssub_0), 5524 (INSERT_SUBREG 5525 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5526 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; 5527 5528class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst> 5529 : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))), 5530 (EXTRACT_SUBREG 5531 (v2f32 (COPY_TO_REGCLASS (Inst 5532 (INSERT_SUBREG 5533 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5534 SPR:$acc, ssub_0), 5535 (INSERT_SUBREG 5536 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5537 SPR:$a, ssub_0), 5538 (INSERT_SUBREG 5539 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 5540 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; 5541 5542def : N3VSPat<fadd, VADDfd>; 5543def : N3VSPat<fsub, VSUBfd>; 5544def : N3VSPat<fmul, VMULfd>; 5545def : N3VSMulOpPat<fmul, fadd, VMLAfd>, 5546 Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>; 5547def : N3VSMulOpPat<fmul, fsub, VMLSfd>, 5548 Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>; 5549def : N3VSMulOpPat<fmul, fadd, VFMAfd>, 5550 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>; 5551def : N3VSMulOpPat<fmul, fsub, VFMSfd>, 5552 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>; 5553def : N2VSPat<fabs, VABSfd>; 5554def : N2VSPat<fneg, VNEGfd>; 5555def : N3VSPat<NEONfmax, VMAXfd>; 5556def : N3VSPat<NEONfmin, VMINfd>; 5557def : N2VSPat<arm_ftosi, VCVTf2sd>; 5558def : N2VSPat<arm_ftoui, VCVTf2ud>; 5559def : N2VSPat<arm_sitof, VCVTs2fd>; 5560def : N2VSPat<arm_uitof, VCVTu2fd>; 5561 5562//===----------------------------------------------------------------------===// 5563// Non-Instruction Patterns 5564//===----------------------------------------------------------------------===// 5565 5566// bit_convert 5567def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>; 5568def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>; 5569def : Pat<(v1i64 (bitconvert (v8i8 DPR:$src))), (v1i64 DPR:$src)>; 5570def : Pat<(v1i64 (bitconvert (f64 DPR:$src))), (v1i64 DPR:$src)>; 5571def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>; 5572def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>; 5573def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>; 5574def : Pat<(v2i32 (bitconvert (v8i8 DPR:$src))), (v2i32 DPR:$src)>; 5575def : Pat<(v2i32 (bitconvert (f64 DPR:$src))), (v2i32 DPR:$src)>; 5576def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>; 5577def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>; 5578def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>; 5579def : Pat<(v4i16 (bitconvert (v8i8 DPR:$src))), (v4i16 DPR:$src)>; 5580def : Pat<(v4i16 (bitconvert (f64 DPR:$src))), (v4i16 DPR:$src)>; 5581def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>; 5582def : Pat<(v8i8 (bitconvert (v1i64 DPR:$src))), (v8i8 DPR:$src)>; 5583def : Pat<(v8i8 (bitconvert (v2i32 DPR:$src))), (v8i8 DPR:$src)>; 5584def : Pat<(v8i8 (bitconvert (v4i16 DPR:$src))), (v8i8 DPR:$src)>; 5585def : Pat<(v8i8 (bitconvert (f64 DPR:$src))), (v8i8 DPR:$src)>; 5586def : Pat<(v8i8 (bitconvert (v2f32 DPR:$src))), (v8i8 DPR:$src)>; 5587def : Pat<(f64 (bitconvert (v1i64 DPR:$src))), (f64 DPR:$src)>; 5588def : Pat<(f64 (bitconvert (v2i32 DPR:$src))), (f64 DPR:$src)>; 5589def : Pat<(f64 (bitconvert (v4i16 DPR:$src))), (f64 DPR:$src)>; 5590def : Pat<(f64 (bitconvert (v8i8 DPR:$src))), (f64 DPR:$src)>; 5591def : Pat<(f64 (bitconvert (v2f32 DPR:$src))), (f64 DPR:$src)>; 5592def : Pat<(v2f32 (bitconvert (f64 DPR:$src))), (v2f32 DPR:$src)>; 5593def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>; 5594def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>; 5595def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>; 5596def : Pat<(v2f32 (bitconvert (v8i8 DPR:$src))), (v2f32 DPR:$src)>; 5597 5598def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>; 5599def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>; 5600def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>; 5601def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>; 5602def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>; 5603def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>; 5604def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>; 5605def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>; 5606def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>; 5607def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>; 5608def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>; 5609def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>; 5610def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>; 5611def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>; 5612def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>; 5613def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>; 5614def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>; 5615def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>; 5616def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>; 5617def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>; 5618def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>; 5619def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>; 5620def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>; 5621def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>; 5622def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>; 5623def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>; 5624def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>; 5625def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>; 5626def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>; 5627def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>; 5628 5629// Vector lengthening move with load, matching extending loads. 5630 5631// extload, zextload and sextload for a standard lengthening load. Example: 5632// Lengthen_Single<"8", "i16", "8"> = 5633// Pat<(v8i16 (extloadvi8 addrmode6:$addr)) 5634// (VMOVLuv8i16 (VLD1d8 addrmode6:$addr, 5635// (f64 (IMPLICIT_DEF)), (i32 0)))>; 5636multiclass Lengthen_Single<string DestLanes, string DestTy, string SrcTy> { 5637 let AddedComplexity = 10 in { 5638 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5639 (!cast<PatFrag>("extloadvi" # SrcTy) addrmode6:$addr)), 5640 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy) 5641 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>; 5642 5643 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5644 (!cast<PatFrag>("zextloadvi" # SrcTy) addrmode6:$addr)), 5645 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy) 5646 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>; 5647 5648 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5649 (!cast<PatFrag>("sextloadvi" # SrcTy) addrmode6:$addr)), 5650 (!cast<Instruction>("VMOVLsv" # DestLanes # DestTy) 5651 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>; 5652 } 5653} 5654 5655// extload, zextload and sextload for a lengthening load which only uses 5656// half the lanes available. Example: 5657// Lengthen_HalfSingle<"4", "i16", "8", "i16", "i8"> = 5658// Pat<(v4i16 (extloadvi8 addrmode6oneL32:$addr)), 5659// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr, 5660// (f64 (IMPLICIT_DEF)), (i32 0))), 5661// dsub_0)>; 5662multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy, 5663 string InsnLanes, string InsnTy> { 5664 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5665 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 5666 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 5667 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5668 dsub_0)>; 5669 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5670 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 5671 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 5672 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5673 dsub_0)>; 5674 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5675 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 5676 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy) 5677 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5678 dsub_0)>; 5679} 5680 5681// extload, zextload and sextload for a lengthening load followed by another 5682// lengthening load, to quadruple the initial length. 5683// 5684// Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32"> = 5685// Pat<(v4i32 (extloadvi8 addrmode6oneL32:$addr)) 5686// (EXTRACT_SUBREG (VMOVLuv4i32 5687// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr, 5688// (f64 (IMPLICIT_DEF)), 5689// (i32 0))), 5690// dsub_0)), 5691// dsub_0)>; 5692multiclass Lengthen_Double<string DestLanes, string DestTy, string SrcTy, 5693 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 5694 string Insn2Ty> { 5695 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5696 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 5697 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 5698 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 5699 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5700 dsub_0))>; 5701 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5702 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 5703 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 5704 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 5705 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5706 dsub_0))>; 5707 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5708 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 5709 (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 5710 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 5711 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5712 dsub_0))>; 5713} 5714 5715// extload, zextload and sextload for a lengthening load followed by another 5716// lengthening load, to quadruple the initial length, but which ends up only 5717// requiring half the available lanes (a 64-bit outcome instead of a 128-bit). 5718// 5719// Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> = 5720// Pat<(v2i32 (extloadvi8 addrmode6:$addr)) 5721// (EXTRACT_SUBREG (VMOVLuv4i32 5722// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd16 addrmode6:$addr, 5723// (f64 (IMPLICIT_DEF)), (i32 0))), 5724// dsub_0)), 5725// dsub_0)>; 5726multiclass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy, 5727 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 5728 string Insn2Ty> { 5729 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5730 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)), 5731 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 5732 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 5733 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5734 dsub_0)), 5735 dsub_0)>; 5736 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5737 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)), 5738 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 5739 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 5740 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5741 dsub_0)), 5742 dsub_0)>; 5743 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 5744 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)), 5745 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 5746 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 5747 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 5748 dsub_0)), 5749 dsub_0)>; 5750} 5751 5752defm : Lengthen_Single<"8", "i16", "8">; // v8i8 -> v8i16 5753defm : Lengthen_Single<"4", "i32", "16">; // v4i16 -> v4i32 5754defm : Lengthen_Single<"2", "i64", "32">; // v2i32 -> v2i64 5755 5756defm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i16 5757defm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i32 5758 5759// Double lengthening - v4i8 -> v4i16 -> v4i32 5760defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">; 5761// v2i8 -> v2i16 -> v2i32 5762defm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">; 5763// v2i16 -> v2i32 -> v2i64 5764defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">; 5765 5766// Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i64 5767def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)), 5768 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 5769 (VLD1LNd16 addrmode6:$addr, 5770 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 5771def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)), 5772 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 5773 (VLD1LNd16 addrmode6:$addr, 5774 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 5775def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)), 5776 (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16 5777 (VLD1LNd16 addrmode6:$addr, 5778 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 5779 5780//===----------------------------------------------------------------------===// 5781// Assembler aliases 5782// 5783 5784def : VFP2InstAlias<"fmdhr${p} $Dd, $Rn", 5785 (VSETLNi32 DPR:$Dd, GPR:$Rn, 1, pred:$p)>; 5786def : VFP2InstAlias<"fmdlr${p} $Dd, $Rn", 5787 (VSETLNi32 DPR:$Dd, GPR:$Rn, 0, pred:$p)>; 5788 5789// VAND/VBIC/VEOR/VORR accept but do not require a type suffix. 5790defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm", 5791 (VANDd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 5792defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm", 5793 (VANDq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 5794defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm", 5795 (VBICd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 5796defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm", 5797 (VBICq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 5798defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm", 5799 (VEORd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 5800defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm", 5801 (VEORq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 5802defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm", 5803 (VORRd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 5804defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm", 5805 (VORRq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 5806// ... two-operand aliases 5807defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm", 5808 (VANDd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 5809defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm", 5810 (VANDq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 5811defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm", 5812 (VEORd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 5813defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm", 5814 (VEORq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 5815defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm", 5816 (VORRd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 5817defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm", 5818 (VORRq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 5819 5820// VLD1 single-lane pseudo-instructions. These need special handling for 5821// the lane index that an InstAlias can't handle, so we use these instead. 5822def VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr", 5823 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5824def VLD1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr", 5825 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5826def VLD1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr", 5827 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5828 5829def VLD1LNdWB_fixed_Asm_8 : 5830 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr!", 5831 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5832def VLD1LNdWB_fixed_Asm_16 : 5833 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr!", 5834 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5835def VLD1LNdWB_fixed_Asm_32 : 5836 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr!", 5837 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5838def VLD1LNdWB_register_Asm_8 : 5839 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr, $Rm", 5840 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, 5841 rGPR:$Rm, pred:$p)>; 5842def VLD1LNdWB_register_Asm_16 : 5843 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr, $Rm", 5844 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, 5845 rGPR:$Rm, pred:$p)>; 5846def VLD1LNdWB_register_Asm_32 : 5847 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr, $Rm", 5848 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, 5849 rGPR:$Rm, pred:$p)>; 5850 5851 5852// VST1 single-lane pseudo-instructions. These need special handling for 5853// the lane index that an InstAlias can't handle, so we use these instead. 5854def VST1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr", 5855 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5856def VST1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr", 5857 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5858def VST1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr", 5859 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5860 5861def VST1LNdWB_fixed_Asm_8 : 5862 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr!", 5863 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5864def VST1LNdWB_fixed_Asm_16 : 5865 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr!", 5866 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5867def VST1LNdWB_fixed_Asm_32 : 5868 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr!", 5869 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5870def VST1LNdWB_register_Asm_8 : 5871 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr, $Rm", 5872 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, 5873 rGPR:$Rm, pred:$p)>; 5874def VST1LNdWB_register_Asm_16 : 5875 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr, $Rm", 5876 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, 5877 rGPR:$Rm, pred:$p)>; 5878def VST1LNdWB_register_Asm_32 : 5879 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr, $Rm", 5880 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, 5881 rGPR:$Rm, pred:$p)>; 5882 5883// VLD2 single-lane pseudo-instructions. These need special handling for 5884// the lane index that an InstAlias can't handle, so we use these instead. 5885def VLD2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr", 5886 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5887def VLD2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr", 5888 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5889def VLD2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr", 5890 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5891def VLD2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr", 5892 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5893def VLD2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr", 5894 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5895 5896def VLD2LNdWB_fixed_Asm_8 : 5897 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr!", 5898 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5899def VLD2LNdWB_fixed_Asm_16 : 5900 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!", 5901 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5902def VLD2LNdWB_fixed_Asm_32 : 5903 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!", 5904 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5905def VLD2LNqWB_fixed_Asm_16 : 5906 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!", 5907 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5908def VLD2LNqWB_fixed_Asm_32 : 5909 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!", 5910 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5911def VLD2LNdWB_register_Asm_8 : 5912 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr, $Rm", 5913 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, 5914 rGPR:$Rm, pred:$p)>; 5915def VLD2LNdWB_register_Asm_16 : 5916 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm", 5917 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, 5918 rGPR:$Rm, pred:$p)>; 5919def VLD2LNdWB_register_Asm_32 : 5920 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm", 5921 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, 5922 rGPR:$Rm, pred:$p)>; 5923def VLD2LNqWB_register_Asm_16 : 5924 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm", 5925 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, 5926 rGPR:$Rm, pred:$p)>; 5927def VLD2LNqWB_register_Asm_32 : 5928 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm", 5929 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, 5930 rGPR:$Rm, pred:$p)>; 5931 5932 5933// VST2 single-lane pseudo-instructions. These need special handling for 5934// the lane index that an InstAlias can't handle, so we use these instead. 5935def VST2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr", 5936 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5937def VST2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr", 5938 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5939def VST2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr", 5940 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5941def VST2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr", 5942 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5943def VST2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr", 5944 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5945 5946def VST2LNdWB_fixed_Asm_8 : 5947 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr!", 5948 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 5949def VST2LNdWB_fixed_Asm_16 : 5950 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!", 5951 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5952def VST2LNdWB_fixed_Asm_32 : 5953 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!", 5954 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5955def VST2LNqWB_fixed_Asm_16 : 5956 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!", 5957 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5958def VST2LNqWB_fixed_Asm_32 : 5959 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!", 5960 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 5961def VST2LNdWB_register_Asm_8 : 5962 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr, $Rm", 5963 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, 5964 rGPR:$Rm, pred:$p)>; 5965def VST2LNdWB_register_Asm_16 : 5966 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm", 5967 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, 5968 rGPR:$Rm, pred:$p)>; 5969def VST2LNdWB_register_Asm_32 : 5970 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm", 5971 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, 5972 rGPR:$Rm, pred:$p)>; 5973def VST2LNqWB_register_Asm_16 : 5974 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm", 5975 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, 5976 rGPR:$Rm, pred:$p)>; 5977def VST2LNqWB_register_Asm_32 : 5978 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm", 5979 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, 5980 rGPR:$Rm, pred:$p)>; 5981 5982// VLD3 all-lanes pseudo-instructions. These need special handling for 5983// the lane index that an InstAlias can't handle, so we use these instead. 5984def VLD3DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 5985 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 5986def VLD3DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 5987 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 5988def VLD3DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 5989 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 5990def VLD3DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 5991 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 5992def VLD3DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 5993 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 5994def VLD3DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 5995 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 5996 5997def VLD3DUPdWB_fixed_Asm_8 : 5998 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 5999 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6000def VLD3DUPdWB_fixed_Asm_16 : 6001 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6002 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6003def VLD3DUPdWB_fixed_Asm_32 : 6004 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6005 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6006def VLD3DUPqWB_fixed_Asm_8 : 6007 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 6008 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6009def VLD3DUPqWB_fixed_Asm_16 : 6010 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6011 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6012def VLD3DUPqWB_fixed_Asm_32 : 6013 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6014 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6015def VLD3DUPdWB_register_Asm_8 : 6016 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 6017 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, 6018 rGPR:$Rm, pred:$p)>; 6019def VLD3DUPdWB_register_Asm_16 : 6020 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6021 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, 6022 rGPR:$Rm, pred:$p)>; 6023def VLD3DUPdWB_register_Asm_32 : 6024 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6025 (ins VecListThreeDAllLanes:$list, addrmode6:$addr, 6026 rGPR:$Rm, pred:$p)>; 6027def VLD3DUPqWB_register_Asm_8 : 6028 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 6029 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, 6030 rGPR:$Rm, pred:$p)>; 6031def VLD3DUPqWB_register_Asm_16 : 6032 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6033 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, 6034 rGPR:$Rm, pred:$p)>; 6035def VLD3DUPqWB_register_Asm_32 : 6036 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6037 (ins VecListThreeQAllLanes:$list, addrmode6:$addr, 6038 rGPR:$Rm, pred:$p)>; 6039 6040 6041// VLD3 single-lane pseudo-instructions. These need special handling for 6042// the lane index that an InstAlias can't handle, so we use these instead. 6043def VLD3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 6044 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6045def VLD3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 6046 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6047def VLD3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 6048 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6049def VLD3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 6050 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6051def VLD3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 6052 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6053 6054def VLD3LNdWB_fixed_Asm_8 : 6055 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 6056 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6057def VLD3LNdWB_fixed_Asm_16 : 6058 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6059 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6060def VLD3LNdWB_fixed_Asm_32 : 6061 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6062 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6063def VLD3LNqWB_fixed_Asm_16 : 6064 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6065 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6066def VLD3LNqWB_fixed_Asm_32 : 6067 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6068 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6069def VLD3LNdWB_register_Asm_8 : 6070 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 6071 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, 6072 rGPR:$Rm, pred:$p)>; 6073def VLD3LNdWB_register_Asm_16 : 6074 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6075 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, 6076 rGPR:$Rm, pred:$p)>; 6077def VLD3LNdWB_register_Asm_32 : 6078 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6079 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, 6080 rGPR:$Rm, pred:$p)>; 6081def VLD3LNqWB_register_Asm_16 : 6082 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6083 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, 6084 rGPR:$Rm, pred:$p)>; 6085def VLD3LNqWB_register_Asm_32 : 6086 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6087 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, 6088 rGPR:$Rm, pred:$p)>; 6089 6090// VLD3 multiple structure pseudo-instructions. These need special handling for 6091// the vector operands that the normal instructions don't yet model. 6092// FIXME: Remove these when the register classes and instructions are updated. 6093def VLD3dAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 6094 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6095def VLD3dAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 6096 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6097def VLD3dAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 6098 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6099def VLD3qAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 6100 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6101def VLD3qAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 6102 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6103def VLD3qAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 6104 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6105 6106def VLD3dWB_fixed_Asm_8 : 6107 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 6108 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6109def VLD3dWB_fixed_Asm_16 : 6110 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6111 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6112def VLD3dWB_fixed_Asm_32 : 6113 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6114 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6115def VLD3qWB_fixed_Asm_8 : 6116 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 6117 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6118def VLD3qWB_fixed_Asm_16 : 6119 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 6120 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6121def VLD3qWB_fixed_Asm_32 : 6122 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 6123 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6124def VLD3dWB_register_Asm_8 : 6125 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 6126 (ins VecListThreeD:$list, addrmode6:$addr, 6127 rGPR:$Rm, pred:$p)>; 6128def VLD3dWB_register_Asm_16 : 6129 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6130 (ins VecListThreeD:$list, addrmode6:$addr, 6131 rGPR:$Rm, pred:$p)>; 6132def VLD3dWB_register_Asm_32 : 6133 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6134 (ins VecListThreeD:$list, addrmode6:$addr, 6135 rGPR:$Rm, pred:$p)>; 6136def VLD3qWB_register_Asm_8 : 6137 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 6138 (ins VecListThreeQ:$list, addrmode6:$addr, 6139 rGPR:$Rm, pred:$p)>; 6140def VLD3qWB_register_Asm_16 : 6141 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 6142 (ins VecListThreeQ:$list, addrmode6:$addr, 6143 rGPR:$Rm, pred:$p)>; 6144def VLD3qWB_register_Asm_32 : 6145 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 6146 (ins VecListThreeQ:$list, addrmode6:$addr, 6147 rGPR:$Rm, pred:$p)>; 6148 6149// VST3 single-lane pseudo-instructions. These need special handling for 6150// the lane index that an InstAlias can't handle, so we use these instead. 6151def VST3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 6152 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6153def VST3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 6154 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6155def VST3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 6156 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6157def VST3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 6158 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6159def VST3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 6160 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6161 6162def VST3LNdWB_fixed_Asm_8 : 6163 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 6164 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6165def VST3LNdWB_fixed_Asm_16 : 6166 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 6167 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6168def VST3LNdWB_fixed_Asm_32 : 6169 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 6170 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6171def VST3LNqWB_fixed_Asm_16 : 6172 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 6173 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6174def VST3LNqWB_fixed_Asm_32 : 6175 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 6176 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6177def VST3LNdWB_register_Asm_8 : 6178 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 6179 (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, 6180 rGPR:$Rm, pred:$p)>; 6181def VST3LNdWB_register_Asm_16 : 6182 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 6183 (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, 6184 rGPR:$Rm, pred:$p)>; 6185def VST3LNdWB_register_Asm_32 : 6186 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 6187 (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, 6188 rGPR:$Rm, pred:$p)>; 6189def VST3LNqWB_register_Asm_16 : 6190 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 6191 (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, 6192 rGPR:$Rm, pred:$p)>; 6193def VST3LNqWB_register_Asm_32 : 6194 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 6195 (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, 6196 rGPR:$Rm, pred:$p)>; 6197 6198 6199// VST3 multiple structure pseudo-instructions. These need special handling for 6200// the vector operands that the normal instructions don't yet model. 6201// FIXME: Remove these when the register classes and instructions are updated. 6202def VST3dAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 6203 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6204def VST3dAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 6205 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6206def VST3dAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 6207 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6208def VST3qAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 6209 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6210def VST3qAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 6211 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6212def VST3qAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 6213 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6214 6215def VST3dWB_fixed_Asm_8 : 6216 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 6217 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6218def VST3dWB_fixed_Asm_16 : 6219 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 6220 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6221def VST3dWB_fixed_Asm_32 : 6222 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 6223 (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>; 6224def VST3qWB_fixed_Asm_8 : 6225 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 6226 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6227def VST3qWB_fixed_Asm_16 : 6228 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 6229 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6230def VST3qWB_fixed_Asm_32 : 6231 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 6232 (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>; 6233def VST3dWB_register_Asm_8 : 6234 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 6235 (ins VecListThreeD:$list, addrmode6:$addr, 6236 rGPR:$Rm, pred:$p)>; 6237def VST3dWB_register_Asm_16 : 6238 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 6239 (ins VecListThreeD:$list, addrmode6:$addr, 6240 rGPR:$Rm, pred:$p)>; 6241def VST3dWB_register_Asm_32 : 6242 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 6243 (ins VecListThreeD:$list, addrmode6:$addr, 6244 rGPR:$Rm, pred:$p)>; 6245def VST3qWB_register_Asm_8 : 6246 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 6247 (ins VecListThreeQ:$list, addrmode6:$addr, 6248 rGPR:$Rm, pred:$p)>; 6249def VST3qWB_register_Asm_16 : 6250 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 6251 (ins VecListThreeQ:$list, addrmode6:$addr, 6252 rGPR:$Rm, pred:$p)>; 6253def VST3qWB_register_Asm_32 : 6254 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 6255 (ins VecListThreeQ:$list, addrmode6:$addr, 6256 rGPR:$Rm, pred:$p)>; 6257 6258// VLD4 all-lanes pseudo-instructions. These need special handling for 6259// the lane index that an InstAlias can't handle, so we use these instead. 6260def VLD4DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 6261 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6262def VLD4DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6263 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6264def VLD4DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6265 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6266def VLD4DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 6267 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6268def VLD4DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6269 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6270def VLD4DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6271 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6272 6273def VLD4DUPdWB_fixed_Asm_8 : 6274 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 6275 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6276def VLD4DUPdWB_fixed_Asm_16 : 6277 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6278 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6279def VLD4DUPdWB_fixed_Asm_32 : 6280 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6281 (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>; 6282def VLD4DUPqWB_fixed_Asm_8 : 6283 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 6284 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6285def VLD4DUPqWB_fixed_Asm_16 : 6286 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6287 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6288def VLD4DUPqWB_fixed_Asm_32 : 6289 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6290 (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>; 6291def VLD4DUPdWB_register_Asm_8 : 6292 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 6293 (ins VecListFourDAllLanes:$list, addrmode6:$addr, 6294 rGPR:$Rm, pred:$p)>; 6295def VLD4DUPdWB_register_Asm_16 : 6296 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6297 (ins VecListFourDAllLanes:$list, addrmode6:$addr, 6298 rGPR:$Rm, pred:$p)>; 6299def VLD4DUPdWB_register_Asm_32 : 6300 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6301 (ins VecListFourDAllLanes:$list, addrmode6:$addr, 6302 rGPR:$Rm, pred:$p)>; 6303def VLD4DUPqWB_register_Asm_8 : 6304 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 6305 (ins VecListFourQAllLanes:$list, addrmode6:$addr, 6306 rGPR:$Rm, pred:$p)>; 6307def VLD4DUPqWB_register_Asm_16 : 6308 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6309 (ins VecListFourQAllLanes:$list, addrmode6:$addr, 6310 rGPR:$Rm, pred:$p)>; 6311def VLD4DUPqWB_register_Asm_32 : 6312 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6313 (ins VecListFourQAllLanes:$list, addrmode6:$addr, 6314 rGPR:$Rm, pred:$p)>; 6315 6316 6317// VLD4 single-lane pseudo-instructions. These need special handling for 6318// the lane index that an InstAlias can't handle, so we use these instead. 6319def VLD4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 6320 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6321def VLD4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6322 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6323def VLD4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6324 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6325def VLD4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6326 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6327def VLD4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6328 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6329 6330def VLD4LNdWB_fixed_Asm_8 : 6331 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 6332 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6333def VLD4LNdWB_fixed_Asm_16 : 6334 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6335 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6336def VLD4LNdWB_fixed_Asm_32 : 6337 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6338 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6339def VLD4LNqWB_fixed_Asm_16 : 6340 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6341 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6342def VLD4LNqWB_fixed_Asm_32 : 6343 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6344 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6345def VLD4LNdWB_register_Asm_8 : 6346 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 6347 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, 6348 rGPR:$Rm, pred:$p)>; 6349def VLD4LNdWB_register_Asm_16 : 6350 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6351 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, 6352 rGPR:$Rm, pred:$p)>; 6353def VLD4LNdWB_register_Asm_32 : 6354 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6355 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, 6356 rGPR:$Rm, pred:$p)>; 6357def VLD4LNqWB_register_Asm_16 : 6358 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6359 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, 6360 rGPR:$Rm, pred:$p)>; 6361def VLD4LNqWB_register_Asm_32 : 6362 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6363 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, 6364 rGPR:$Rm, pred:$p)>; 6365 6366 6367 6368// VLD4 multiple structure pseudo-instructions. These need special handling for 6369// the vector operands that the normal instructions don't yet model. 6370// FIXME: Remove these when the register classes and instructions are updated. 6371def VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 6372 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6373def VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6374 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6375def VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6376 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6377def VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 6378 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6379def VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 6380 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6381def VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 6382 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6383 6384def VLD4dWB_fixed_Asm_8 : 6385 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 6386 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6387def VLD4dWB_fixed_Asm_16 : 6388 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6389 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6390def VLD4dWB_fixed_Asm_32 : 6391 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6392 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6393def VLD4qWB_fixed_Asm_8 : 6394 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 6395 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6396def VLD4qWB_fixed_Asm_16 : 6397 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 6398 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6399def VLD4qWB_fixed_Asm_32 : 6400 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 6401 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6402def VLD4dWB_register_Asm_8 : 6403 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 6404 (ins VecListFourD:$list, addrmode6:$addr, 6405 rGPR:$Rm, pred:$p)>; 6406def VLD4dWB_register_Asm_16 : 6407 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6408 (ins VecListFourD:$list, addrmode6:$addr, 6409 rGPR:$Rm, pred:$p)>; 6410def VLD4dWB_register_Asm_32 : 6411 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6412 (ins VecListFourD:$list, addrmode6:$addr, 6413 rGPR:$Rm, pred:$p)>; 6414def VLD4qWB_register_Asm_8 : 6415 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 6416 (ins VecListFourQ:$list, addrmode6:$addr, 6417 rGPR:$Rm, pred:$p)>; 6418def VLD4qWB_register_Asm_16 : 6419 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 6420 (ins VecListFourQ:$list, addrmode6:$addr, 6421 rGPR:$Rm, pred:$p)>; 6422def VLD4qWB_register_Asm_32 : 6423 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 6424 (ins VecListFourQ:$list, addrmode6:$addr, 6425 rGPR:$Rm, pred:$p)>; 6426 6427// VST4 single-lane pseudo-instructions. These need special handling for 6428// the lane index that an InstAlias can't handle, so we use these instead. 6429def VST4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 6430 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6431def VST4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 6432 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6433def VST4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 6434 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6435def VST4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 6436 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6437def VST4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 6438 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6439 6440def VST4LNdWB_fixed_Asm_8 : 6441 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 6442 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>; 6443def VST4LNdWB_fixed_Asm_16 : 6444 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 6445 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6446def VST4LNdWB_fixed_Asm_32 : 6447 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 6448 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6449def VST4LNqWB_fixed_Asm_16 : 6450 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 6451 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6452def VST4LNqWB_fixed_Asm_32 : 6453 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 6454 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>; 6455def VST4LNdWB_register_Asm_8 : 6456 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 6457 (ins VecListFourDByteIndexed:$list, addrmode6:$addr, 6458 rGPR:$Rm, pred:$p)>; 6459def VST4LNdWB_register_Asm_16 : 6460 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 6461 (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, 6462 rGPR:$Rm, pred:$p)>; 6463def VST4LNdWB_register_Asm_32 : 6464 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 6465 (ins VecListFourDWordIndexed:$list, addrmode6:$addr, 6466 rGPR:$Rm, pred:$p)>; 6467def VST4LNqWB_register_Asm_16 : 6468 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 6469 (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, 6470 rGPR:$Rm, pred:$p)>; 6471def VST4LNqWB_register_Asm_32 : 6472 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 6473 (ins VecListFourQWordIndexed:$list, addrmode6:$addr, 6474 rGPR:$Rm, pred:$p)>; 6475 6476 6477// VST4 multiple structure pseudo-instructions. These need special handling for 6478// the vector operands that the normal instructions don't yet model. 6479// FIXME: Remove these when the register classes and instructions are updated. 6480def VST4dAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 6481 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6482def VST4dAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 6483 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6484def VST4dAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 6485 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6486def VST4qAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 6487 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6488def VST4qAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 6489 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6490def VST4qAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 6491 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6492 6493def VST4dWB_fixed_Asm_8 : 6494 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 6495 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6496def VST4dWB_fixed_Asm_16 : 6497 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 6498 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6499def VST4dWB_fixed_Asm_32 : 6500 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 6501 (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; 6502def VST4qWB_fixed_Asm_8 : 6503 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 6504 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6505def VST4qWB_fixed_Asm_16 : 6506 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 6507 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6508def VST4qWB_fixed_Asm_32 : 6509 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 6510 (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; 6511def VST4dWB_register_Asm_8 : 6512 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 6513 (ins VecListFourD:$list, addrmode6:$addr, 6514 rGPR:$Rm, pred:$p)>; 6515def VST4dWB_register_Asm_16 : 6516 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 6517 (ins VecListFourD:$list, addrmode6:$addr, 6518 rGPR:$Rm, pred:$p)>; 6519def VST4dWB_register_Asm_32 : 6520 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 6521 (ins VecListFourD:$list, addrmode6:$addr, 6522 rGPR:$Rm, pred:$p)>; 6523def VST4qWB_register_Asm_8 : 6524 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 6525 (ins VecListFourQ:$list, addrmode6:$addr, 6526 rGPR:$Rm, pred:$p)>; 6527def VST4qWB_register_Asm_16 : 6528 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 6529 (ins VecListFourQ:$list, addrmode6:$addr, 6530 rGPR:$Rm, pred:$p)>; 6531def VST4qWB_register_Asm_32 : 6532 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 6533 (ins VecListFourQ:$list, addrmode6:$addr, 6534 rGPR:$Rm, pred:$p)>; 6535 6536// VMOV takes an optional datatype suffix 6537defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm", 6538 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>; 6539defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm", 6540 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>; 6541 6542// VCLT (register) is an assembler alias for VCGT w/ the operands reversed. 6543// D-register versions. 6544def : NEONInstAlias<"vcle${p}.s8 $Dd, $Dn, $Dm", 6545 (VCGEsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6546def : NEONInstAlias<"vcle${p}.s16 $Dd, $Dn, $Dm", 6547 (VCGEsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6548def : NEONInstAlias<"vcle${p}.s32 $Dd, $Dn, $Dm", 6549 (VCGEsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6550def : NEONInstAlias<"vcle${p}.u8 $Dd, $Dn, $Dm", 6551 (VCGEuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6552def : NEONInstAlias<"vcle${p}.u16 $Dd, $Dn, $Dm", 6553 (VCGEuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6554def : NEONInstAlias<"vcle${p}.u32 $Dd, $Dn, $Dm", 6555 (VCGEuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6556def : NEONInstAlias<"vcle${p}.f32 $Dd, $Dn, $Dm", 6557 (VCGEfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6558// Q-register versions. 6559def : NEONInstAlias<"vcle${p}.s8 $Qd, $Qn, $Qm", 6560 (VCGEsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6561def : NEONInstAlias<"vcle${p}.s16 $Qd, $Qn, $Qm", 6562 (VCGEsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6563def : NEONInstAlias<"vcle${p}.s32 $Qd, $Qn, $Qm", 6564 (VCGEsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6565def : NEONInstAlias<"vcle${p}.u8 $Qd, $Qn, $Qm", 6566 (VCGEuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6567def : NEONInstAlias<"vcle${p}.u16 $Qd, $Qn, $Qm", 6568 (VCGEuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6569def : NEONInstAlias<"vcle${p}.u32 $Qd, $Qn, $Qm", 6570 (VCGEuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6571def : NEONInstAlias<"vcle${p}.f32 $Qd, $Qn, $Qm", 6572 (VCGEfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6573 6574// VCLT (register) is an assembler alias for VCGT w/ the operands reversed. 6575// D-register versions. 6576def : NEONInstAlias<"vclt${p}.s8 $Dd, $Dn, $Dm", 6577 (VCGTsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6578def : NEONInstAlias<"vclt${p}.s16 $Dd, $Dn, $Dm", 6579 (VCGTsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6580def : NEONInstAlias<"vclt${p}.s32 $Dd, $Dn, $Dm", 6581 (VCGTsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6582def : NEONInstAlias<"vclt${p}.u8 $Dd, $Dn, $Dm", 6583 (VCGTuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6584def : NEONInstAlias<"vclt${p}.u16 $Dd, $Dn, $Dm", 6585 (VCGTuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6586def : NEONInstAlias<"vclt${p}.u32 $Dd, $Dn, $Dm", 6587 (VCGTuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6588def : NEONInstAlias<"vclt${p}.f32 $Dd, $Dn, $Dm", 6589 (VCGTfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 6590// Q-register versions. 6591def : NEONInstAlias<"vclt${p}.s8 $Qd, $Qn, $Qm", 6592 (VCGTsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6593def : NEONInstAlias<"vclt${p}.s16 $Qd, $Qn, $Qm", 6594 (VCGTsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6595def : NEONInstAlias<"vclt${p}.s32 $Qd, $Qn, $Qm", 6596 (VCGTsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6597def : NEONInstAlias<"vclt${p}.u8 $Qd, $Qn, $Qm", 6598 (VCGTuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6599def : NEONInstAlias<"vclt${p}.u16 $Qd, $Qn, $Qm", 6600 (VCGTuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6601def : NEONInstAlias<"vclt${p}.u32 $Qd, $Qn, $Qm", 6602 (VCGTuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6603def : NEONInstAlias<"vclt${p}.f32 $Qd, $Qn, $Qm", 6604 (VCGTfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 6605 6606// VSWP allows, but does not require, a type suffix. 6607defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm", 6608 (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>; 6609defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm", 6610 (VSWPq QPR:$Vd, QPR:$Vm, pred:$p)>; 6611 6612// VBIF, VBIT, and VBSL allow, but do not require, a type suffix. 6613defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm", 6614 (VBIFd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 6615defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm", 6616 (VBITd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 6617defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm", 6618 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 6619defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm", 6620 (VBIFq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 6621defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm", 6622 (VBITq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 6623defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm", 6624 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 6625 6626// "vmov Rd, #-imm" can be handled via "vmvn". 6627def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm", 6628 (VMVNv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 6629def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm", 6630 (VMVNv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 6631def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm", 6632 (VMOVv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 6633def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm", 6634 (VMOVv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 6635 6636// 'gas' compatibility aliases for quad-word instructions. Strictly speaking, 6637// these should restrict to just the Q register variants, but the register 6638// classes are enough to match correctly regardless, so we keep it simple 6639// and just use MnemonicAlias. 6640def : NEONMnemonicAlias<"vbicq", "vbic">; 6641def : NEONMnemonicAlias<"vandq", "vand">; 6642def : NEONMnemonicAlias<"veorq", "veor">; 6643def : NEONMnemonicAlias<"vorrq", "vorr">; 6644 6645def : NEONMnemonicAlias<"vmovq", "vmov">; 6646def : NEONMnemonicAlias<"vmvnq", "vmvn">; 6647// Explicit versions for floating point so that the FPImm variants get 6648// handled early. The parser gets confused otherwise. 6649def : NEONMnemonicAlias<"vmovq.f32", "vmov.f32">; 6650def : NEONMnemonicAlias<"vmovq.f64", "vmov.f64">; 6651 6652def : NEONMnemonicAlias<"vaddq", "vadd">; 6653def : NEONMnemonicAlias<"vsubq", "vsub">; 6654 6655def : NEONMnemonicAlias<"vminq", "vmin">; 6656def : NEONMnemonicAlias<"vmaxq", "vmax">; 6657 6658def : NEONMnemonicAlias<"vmulq", "vmul">; 6659 6660def : NEONMnemonicAlias<"vabsq", "vabs">; 6661 6662def : NEONMnemonicAlias<"vshlq", "vshl">; 6663def : NEONMnemonicAlias<"vshrq", "vshr">; 6664 6665def : NEONMnemonicAlias<"vcvtq", "vcvt">; 6666 6667def : NEONMnemonicAlias<"vcleq", "vcle">; 6668def : NEONMnemonicAlias<"vceqq", "vceq">; 6669 6670def : NEONMnemonicAlias<"vzipq", "vzip">; 6671def : NEONMnemonicAlias<"vswpq", "vswp">; 6672 6673def : NEONMnemonicAlias<"vrecpeq.f32", "vrecpe.f32">; 6674def : NEONMnemonicAlias<"vrecpeq.u32", "vrecpe.u32">; 6675 6676 6677// Alias for loading floating point immediates that aren't representable 6678// using the vmov.f32 encoding but the bitpattern is representable using 6679// the .i32 encoding. 6680def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm", 6681 (VMOVv4i32 QPR:$Vd, nImmVMOVI32:$imm, pred:$p)>; 6682def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm", 6683 (VMOVv2i32 DPR:$Vd, nImmVMOVI32:$imm, pred:$p)>; 6684