9290 lines · plain
1//===-- ARMInstrNEON.td - NEON support for ARM -------------*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the ARM NEON instruction set.10//11//===----------------------------------------------------------------------===//12 13 14//===----------------------------------------------------------------------===//15// NEON-specific Operands.16//===----------------------------------------------------------------------===//17def nModImm : Operand<i32> {18 let PrintMethod = "printVMOVModImmOperand";19}20 21def nImmSplatI8AsmOperand : AsmOperandClass { let Name = "NEONi8splat"; }22def nImmSplatI8 : Operand<i32> {23 let PrintMethod = "printVMOVModImmOperand";24 let ParserMatchClass = nImmSplatI8AsmOperand;25}26def nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; }27def nImmSplatI16 : Operand<i32> {28 let PrintMethod = "printVMOVModImmOperand";29 let ParserMatchClass = nImmSplatI16AsmOperand;30}31def nImmSplatI32AsmOperand : AsmOperandClass { let Name = "NEONi32splat"; }32def nImmSplatI32 : Operand<i32> {33 let PrintMethod = "printVMOVModImmOperand";34 let ParserMatchClass = nImmSplatI32AsmOperand;35}36def nImmSplatNotI16AsmOperand : AsmOperandClass { let Name = "NEONi16splatNot"; }37def nImmSplatNotI16 : Operand<i32> {38 let ParserMatchClass = nImmSplatNotI16AsmOperand;39}40def nImmSplatNotI32AsmOperand : AsmOperandClass { let Name = "NEONi32splatNot"; }41def nImmSplatNotI32 : Operand<i32> {42 let ParserMatchClass = nImmSplatNotI32AsmOperand;43}44def nImmVMOVI32AsmOperand : AsmOperandClass { let Name = "NEONi32vmov"; }45def nImmVMOVI32 : Operand<i32> {46 let PrintMethod = "printVMOVModImmOperand";47 let ParserMatchClass = nImmVMOVI32AsmOperand;48}49 50class nImmVMOVIAsmOperandReplicate<ValueType From, ValueType To>51 : AsmOperandClass {52 let Name = "NEONi" # To.Size # "vmovi" # From.Size # "Replicate";53 let PredicateMethod = "isNEONmovReplicate<" # From.Size # ", " # To.Size # ">";54 let RenderMethod = "addNEONvmovi" # From.Size # "ReplicateOperands";55}56 57class nImmVINVIAsmOperandReplicate<ValueType From, ValueType To>58 : AsmOperandClass {59 let Name = "NEONi" # To.Size # "invi" # From.Size # "Replicate";60 let PredicateMethod = "isNEONinvReplicate<" # From.Size # ", " # To.Size # ">";61 let RenderMethod = "addNEONinvi" # From.Size # "ReplicateOperands";62}63 64class nImmVMOVIReplicate<ValueType From, ValueType To> : Operand<i32> {65 let PrintMethod = "printVMOVModImmOperand";66 let ParserMatchClass = nImmVMOVIAsmOperandReplicate<From, To>;67}68 69class nImmVINVIReplicate<ValueType From, ValueType To> : Operand<i32> {70 let PrintMethod = "printVMOVModImmOperand";71 let ParserMatchClass = nImmVINVIAsmOperandReplicate<From, To>;72}73 74def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; }75def nImmVMOVI32Neg : Operand<i32> {76 let PrintMethod = "printVMOVModImmOperand";77 let ParserMatchClass = nImmVMOVI32NegAsmOperand;78}79def nImmVMOVF32 : Operand<i32> {80 let PrintMethod = "printFPImmOperand";81 let ParserMatchClass = FPImmOperand;82}83def nImmSplatI64AsmOperand : AsmOperandClass { let Name = "NEONi64splat"; }84def nImmSplatI64 : Operand<i32> {85 let PrintMethod = "printVMOVModImmOperand";86 let ParserMatchClass = nImmSplatI64AsmOperand;87}88 89def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; }90def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; }91def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; }92def VectorIndex64Operand : AsmOperandClass { let Name = "VectorIndex64"; }93def VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{94 return ((uint64_t)Imm) < 8;95}]> {96 let ParserMatchClass = VectorIndex8Operand;97 let PrintMethod = "printVectorIndex";98}99def VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{100 return ((uint64_t)Imm) < 4;101}]> {102 let ParserMatchClass = VectorIndex16Operand;103 let PrintMethod = "printVectorIndex";104}105def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{106 return ((uint64_t)Imm) < 2;107}]> {108 let ParserMatchClass = VectorIndex32Operand;109 let PrintMethod = "printVectorIndex";110}111def VectorIndex64 : Operand<i32>, ImmLeaf<i32, [{112 return ((uint64_t)Imm) < 1;113}]> {114 let ParserMatchClass = VectorIndex64Operand;115 let PrintMethod = "printVectorIndex";116}117 118// Register list of one D register.119def VecListOneDAsmOperand : AsmOperandClass {120 let Name = "VecListOneD";121 let ParserMethod = "parseVectorList";122 let RenderMethod = "addVecListOperands";123}124def VecListOneD : RegisterOperand<DPR, "printVectorListOne"> {125 let ParserMatchClass = VecListOneDAsmOperand;126}127// Register list of two sequential D registers.128def VecListDPairAsmOperand : AsmOperandClass {129 let Name = "VecListDPair";130 let ParserMethod = "parseVectorList";131 let RenderMethod = "addVecListOperands";132}133def VecListDPair : RegisterOperand<DPair, "printVectorListTwo"> {134 let ParserMatchClass = VecListDPairAsmOperand;135}136// Register list of three sequential D registers.137def VecListThreeDAsmOperand : AsmOperandClass {138 let Name = "VecListThreeD";139 let ParserMethod = "parseVectorList";140 let RenderMethod = "addVecListOperands";141}142def VecListThreeD : RegisterOperand<DPR, "printVectorListThree"> {143 let ParserMatchClass = VecListThreeDAsmOperand;144}145// Register list of four sequential D registers.146def VecListFourDAsmOperand : AsmOperandClass {147 let Name = "VecListFourD";148 let ParserMethod = "parseVectorList";149 let RenderMethod = "addVecListOperands";150}151def VecListFourD : RegisterOperand<DPR, "printVectorListFour"> {152 let ParserMatchClass = VecListFourDAsmOperand;153}154// Register list of two D registers spaced by 2 (two sequential Q registers).155def VecListDPairSpacedAsmOperand : AsmOperandClass {156 let Name = "VecListDPairSpaced";157 let ParserMethod = "parseVectorList";158 let RenderMethod = "addVecListOperands";159}160def VecListDPairSpaced : RegisterOperand<DPair, "printVectorListTwoSpaced"> {161 let ParserMatchClass = VecListDPairSpacedAsmOperand;162}163// Register list of three D registers spaced by 2 (three Q registers).164def VecListThreeQAsmOperand : AsmOperandClass {165 let Name = "VecListThreeQ";166 let ParserMethod = "parseVectorList";167 let RenderMethod = "addVecListOperands";168}169def VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> {170 let ParserMatchClass = VecListThreeQAsmOperand;171}172// Register list of three D registers spaced by 2 (three Q registers).173def VecListFourQAsmOperand : AsmOperandClass {174 let Name = "VecListFourQ";175 let ParserMethod = "parseVectorList";176 let RenderMethod = "addVecListOperands";177}178def VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> {179 let ParserMatchClass = VecListFourQAsmOperand;180}181 182// Register list of one D register, with "all lanes" subscripting.183def VecListOneDAllLanesAsmOperand : AsmOperandClass {184 let Name = "VecListOneDAllLanes";185 let ParserMethod = "parseVectorList";186 let RenderMethod = "addVecListOperands";187}188def VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> {189 let ParserMatchClass = VecListOneDAllLanesAsmOperand;190}191// Register list of two D registers, with "all lanes" subscripting.192def VecListDPairAllLanesAsmOperand : AsmOperandClass {193 let Name = "VecListDPairAllLanes";194 let ParserMethod = "parseVectorList";195 let RenderMethod = "addVecListOperands";196}197def VecListDPairAllLanes : RegisterOperand<DPair,198 "printVectorListTwoAllLanes"> {199 let ParserMatchClass = VecListDPairAllLanesAsmOperand;200}201// Register list of two D registers spaced by 2 (two sequential Q registers).202def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass {203 let Name = "VecListDPairSpacedAllLanes";204 let ParserMethod = "parseVectorList";205 let RenderMethod = "addVecListOperands";206}207def VecListDPairSpacedAllLanes : RegisterOperand<DPairSpc,208 "printVectorListTwoSpacedAllLanes"> {209 let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand;210}211// Register list of three D registers, with "all lanes" subscripting.212def VecListThreeDAllLanesAsmOperand : AsmOperandClass {213 let Name = "VecListThreeDAllLanes";214 let ParserMethod = "parseVectorList";215 let RenderMethod = "addVecListOperands";216}217def VecListThreeDAllLanes : RegisterOperand<DPR,218 "printVectorListThreeAllLanes"> {219 let ParserMatchClass = VecListThreeDAllLanesAsmOperand;220}221// Register list of three D registers spaced by 2 (three sequential Q regs).222def VecListThreeQAllLanesAsmOperand : AsmOperandClass {223 let Name = "VecListThreeQAllLanes";224 let ParserMethod = "parseVectorList";225 let RenderMethod = "addVecListOperands";226}227def VecListThreeQAllLanes : RegisterOperand<DPR,228 "printVectorListThreeSpacedAllLanes"> {229 let ParserMatchClass = VecListThreeQAllLanesAsmOperand;230}231// Register list of four D registers, with "all lanes" subscripting.232def VecListFourDAllLanesAsmOperand : AsmOperandClass {233 let Name = "VecListFourDAllLanes";234 let ParserMethod = "parseVectorList";235 let RenderMethod = "addVecListOperands";236}237def VecListFourDAllLanes : RegisterOperand<DPR, "printVectorListFourAllLanes"> {238 let ParserMatchClass = VecListFourDAllLanesAsmOperand;239}240// Register list of four D registers spaced by 2 (four sequential Q regs).241def VecListFourQAllLanesAsmOperand : AsmOperandClass {242 let Name = "VecListFourQAllLanes";243 let ParserMethod = "parseVectorList";244 let RenderMethod = "addVecListOperands";245}246def VecListFourQAllLanes : RegisterOperand<DPR,247 "printVectorListFourSpacedAllLanes"> {248 let ParserMatchClass = VecListFourQAllLanesAsmOperand;249}250 251 252// Register list of one D register, with byte lane subscripting.253def VecListOneDByteIndexAsmOperand : AsmOperandClass {254 let Name = "VecListOneDByteIndexed";255 let ParserMethod = "parseVectorList";256 let RenderMethod = "addVecListIndexedOperands";257}258def VecListOneDByteIndexed : Operand<i32> {259 let ParserMatchClass = VecListOneDByteIndexAsmOperand;260 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);261}262// ...with half-word lane subscripting.263def VecListOneDHWordIndexAsmOperand : AsmOperandClass {264 let Name = "VecListOneDHWordIndexed";265 let ParserMethod = "parseVectorList";266 let RenderMethod = "addVecListIndexedOperands";267}268def VecListOneDHWordIndexed : Operand<i32> {269 let ParserMatchClass = VecListOneDHWordIndexAsmOperand;270 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);271}272// ...with word lane subscripting.273def VecListOneDWordIndexAsmOperand : AsmOperandClass {274 let Name = "VecListOneDWordIndexed";275 let ParserMethod = "parseVectorList";276 let RenderMethod = "addVecListIndexedOperands";277}278def VecListOneDWordIndexed : Operand<i32> {279 let ParserMatchClass = VecListOneDWordIndexAsmOperand;280 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);281}282 283// Register list of two D registers with byte lane subscripting.284def VecListTwoDByteIndexAsmOperand : AsmOperandClass {285 let Name = "VecListTwoDByteIndexed";286 let ParserMethod = "parseVectorList";287 let RenderMethod = "addVecListIndexedOperands";288}289def VecListTwoDByteIndexed : Operand<i32> {290 let ParserMatchClass = VecListTwoDByteIndexAsmOperand;291 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);292}293// ...with half-word lane subscripting.294def VecListTwoDHWordIndexAsmOperand : AsmOperandClass {295 let Name = "VecListTwoDHWordIndexed";296 let ParserMethod = "parseVectorList";297 let RenderMethod = "addVecListIndexedOperands";298}299def VecListTwoDHWordIndexed : Operand<i32> {300 let ParserMatchClass = VecListTwoDHWordIndexAsmOperand;301 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);302}303// ...with word lane subscripting.304def VecListTwoDWordIndexAsmOperand : AsmOperandClass {305 let Name = "VecListTwoDWordIndexed";306 let ParserMethod = "parseVectorList";307 let RenderMethod = "addVecListIndexedOperands";308}309def VecListTwoDWordIndexed : Operand<i32> {310 let ParserMatchClass = VecListTwoDWordIndexAsmOperand;311 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);312}313// Register list of two Q registers with half-word lane subscripting.314def VecListTwoQHWordIndexAsmOperand : AsmOperandClass {315 let Name = "VecListTwoQHWordIndexed";316 let ParserMethod = "parseVectorList";317 let RenderMethod = "addVecListIndexedOperands";318}319def VecListTwoQHWordIndexed : Operand<i32> {320 let ParserMatchClass = VecListTwoQHWordIndexAsmOperand;321 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);322}323// ...with word lane subscripting.324def VecListTwoQWordIndexAsmOperand : AsmOperandClass {325 let Name = "VecListTwoQWordIndexed";326 let ParserMethod = "parseVectorList";327 let RenderMethod = "addVecListIndexedOperands";328}329def VecListTwoQWordIndexed : Operand<i32> {330 let ParserMatchClass = VecListTwoQWordIndexAsmOperand;331 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);332}333 334 335// Register list of three D registers with byte lane subscripting.336def VecListThreeDByteIndexAsmOperand : AsmOperandClass {337 let Name = "VecListThreeDByteIndexed";338 let ParserMethod = "parseVectorList";339 let RenderMethod = "addVecListIndexedOperands";340}341def VecListThreeDByteIndexed : Operand<i32> {342 let ParserMatchClass = VecListThreeDByteIndexAsmOperand;343 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);344}345// ...with half-word lane subscripting.346def VecListThreeDHWordIndexAsmOperand : AsmOperandClass {347 let Name = "VecListThreeDHWordIndexed";348 let ParserMethod = "parseVectorList";349 let RenderMethod = "addVecListIndexedOperands";350}351def VecListThreeDHWordIndexed : Operand<i32> {352 let ParserMatchClass = VecListThreeDHWordIndexAsmOperand;353 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);354}355// ...with word lane subscripting.356def VecListThreeDWordIndexAsmOperand : AsmOperandClass {357 let Name = "VecListThreeDWordIndexed";358 let ParserMethod = "parseVectorList";359 let RenderMethod = "addVecListIndexedOperands";360}361def VecListThreeDWordIndexed : Operand<i32> {362 let ParserMatchClass = VecListThreeDWordIndexAsmOperand;363 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);364}365// Register list of three Q registers with half-word lane subscripting.366def VecListThreeQHWordIndexAsmOperand : AsmOperandClass {367 let Name = "VecListThreeQHWordIndexed";368 let ParserMethod = "parseVectorList";369 let RenderMethod = "addVecListIndexedOperands";370}371def VecListThreeQHWordIndexed : Operand<i32> {372 let ParserMatchClass = VecListThreeQHWordIndexAsmOperand;373 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);374}375// ...with word lane subscripting.376def VecListThreeQWordIndexAsmOperand : AsmOperandClass {377 let Name = "VecListThreeQWordIndexed";378 let ParserMethod = "parseVectorList";379 let RenderMethod = "addVecListIndexedOperands";380}381def VecListThreeQWordIndexed : Operand<i32> {382 let ParserMatchClass = VecListThreeQWordIndexAsmOperand;383 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);384}385 386// Register list of four D registers with byte lane subscripting.387def VecListFourDByteIndexAsmOperand : AsmOperandClass {388 let Name = "VecListFourDByteIndexed";389 let ParserMethod = "parseVectorList";390 let RenderMethod = "addVecListIndexedOperands";391}392def VecListFourDByteIndexed : Operand<i32> {393 let ParserMatchClass = VecListFourDByteIndexAsmOperand;394 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);395}396// ...with half-word lane subscripting.397def VecListFourDHWordIndexAsmOperand : AsmOperandClass {398 let Name = "VecListFourDHWordIndexed";399 let ParserMethod = "parseVectorList";400 let RenderMethod = "addVecListIndexedOperands";401}402def VecListFourDHWordIndexed : Operand<i32> {403 let ParserMatchClass = VecListFourDHWordIndexAsmOperand;404 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);405}406// ...with word lane subscripting.407def VecListFourDWordIndexAsmOperand : AsmOperandClass {408 let Name = "VecListFourDWordIndexed";409 let ParserMethod = "parseVectorList";410 let RenderMethod = "addVecListIndexedOperands";411}412def VecListFourDWordIndexed : Operand<i32> {413 let ParserMatchClass = VecListFourDWordIndexAsmOperand;414 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);415}416// Register list of four Q registers with half-word lane subscripting.417def VecListFourQHWordIndexAsmOperand : AsmOperandClass {418 let Name = "VecListFourQHWordIndexed";419 let ParserMethod = "parseVectorList";420 let RenderMethod = "addVecListIndexedOperands";421}422def VecListFourQHWordIndexed : Operand<i32> {423 let ParserMatchClass = VecListFourQHWordIndexAsmOperand;424 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);425}426// ...with word lane subscripting.427def VecListFourQWordIndexAsmOperand : AsmOperandClass {428 let Name = "VecListFourQWordIndexed";429 let ParserMethod = "parseVectorList";430 let RenderMethod = "addVecListIndexedOperands";431}432def VecListFourQWordIndexed : Operand<i32> {433 let ParserMatchClass = VecListFourQWordIndexAsmOperand;434 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);435}436 437def dword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{438 return cast<LoadSDNode>(N)->getAlign() >= 8;439}]>;440def dword_alignedstore : PatFrag<(ops node:$val, node:$ptr),441 (store node:$val, node:$ptr), [{442 return cast<StoreSDNode>(N)->getAlign() >= 8;443}]>;444def word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{445 return cast<LoadSDNode>(N)->getAlign() == 4;446}]>;447def word_alignedstore : PatFrag<(ops node:$val, node:$ptr),448 (store node:$val, node:$ptr), [{449 return cast<StoreSDNode>(N)->getAlign() == 4;450}]>;451def hword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{452 return cast<LoadSDNode>(N)->getAlign() == 2;453}]>;454def hword_alignedstore : PatFrag<(ops node:$val, node:$ptr),455 (store node:$val, node:$ptr), [{456 return cast<StoreSDNode>(N)->getAlign() == 2;457}]>;458def byte_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{459 return cast<LoadSDNode>(N)->getAlign() == 1;460}]>;461def byte_alignedstore : PatFrag<(ops node:$val, node:$ptr),462 (store node:$val, node:$ptr), [{463 return cast<StoreSDNode>(N)->getAlign() == 1;464}]>;465def non_word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{466 return cast<LoadSDNode>(N)->getAlign() < 4;467}]>;468def non_word_alignedstore : PatFrag<(ops node:$val, node:$ptr),469 (store node:$val, node:$ptr), [{470 return cast<StoreSDNode>(N)->getAlign() < 4;471}]>;472 473//===----------------------------------------------------------------------===//474// NEON-specific DAG Nodes.475//===----------------------------------------------------------------------===//476 477def SDTARMVTST : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>;478 479// Vector test bits.480def NEONvtst : SDNode<"ARMISD::VTST", SDTARMVTST>;481 482// Types for vector shift by immediates. The "SHX" version is for long and483// narrow operations where the source and destination vectors have different484// types. The "SHINS" version is for shift and insert operations.485def SDTARMVSHXIMM : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,486 SDTCisVT<2, i32>]>;487def SDTARMVSHINSIMM : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,488 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;489 490def NEONvshrnImm : SDNode<"ARMISD::VSHRNIMM", SDTARMVSHXIMM>;491 492// Vector rounding shift by immediate493def NEONvrshrsImm : SDNode<"ARMISD::VRSHRsIMM", SDTARMVSHIMM>;494def NEONvrshruImm : SDNode<"ARMISD::VRSHRuIMM", SDTARMVSHIMM>;495def NEONvrshrnImm : SDNode<"ARMISD::VRSHRNIMM", SDTARMVSHXIMM>;496 497// Vector saturating shift by immediate498def NEONvqshlsImm : SDNode<"ARMISD::VQSHLsIMM", SDTARMVSHIMM>;499def NEONvqshluImm : SDNode<"ARMISD::VQSHLuIMM", SDTARMVSHIMM>;500def NEONvqshlsuImm : SDNode<"ARMISD::VQSHLsuIMM", SDTARMVSHIMM>;501def NEONvqshrnsImm : SDNode<"ARMISD::VQSHRNsIMM", SDTARMVSHXIMM>;502def NEONvqshrnuImm : SDNode<"ARMISD::VQSHRNuIMM", SDTARMVSHXIMM>;503def NEONvqshrnsuImm : SDNode<"ARMISD::VQSHRNsuIMM", SDTARMVSHXIMM>;504 505// Vector saturating rounding shift by immediate506def NEONvqrshrnsImm : SDNode<"ARMISD::VQRSHRNsIMM", SDTARMVSHXIMM>;507def NEONvqrshrnuImm : SDNode<"ARMISD::VQRSHRNuIMM", SDTARMVSHXIMM>;508def NEONvqrshrnsuImm : SDNode<"ARMISD::VQRSHRNsuIMM", SDTARMVSHXIMM>;509 510// Vector shift and insert511def NEONvsliImm : SDNode<"ARMISD::VSLIIMM", SDTARMVSHINSIMM>;512def NEONvsriImm : SDNode<"ARMISD::VSRIIMM", SDTARMVSHINSIMM>;513 514// Pseudo vector bitwise select515def NEONvbsp : SDNode<"ARMISD::VBSP",516 SDTypeProfile<1, 3, [SDTCisVec<0>,517 SDTCisSameAs<0, 1>,518 SDTCisSameAs<0, 2>,519 SDTCisSameAs<0, 3>]>>;520 521def SDTARMVEXT : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>,522 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;523def NEONvext : SDNode<"ARMISD::VEXT", SDTARMVEXT>;524 525def SDTARMVSHUF2 : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,526 SDTCisSameAs<0, 2>,527 SDTCisSameAs<0, 3>]>;528 529// zip (interleave)530def NEONzip : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>;531 532// unzip (deinterleave)533def NEONuzp : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>;534 535// transpose536def NEONtrn : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>;537 538def SDTARMVTBL1 : SDTypeProfile<1, 2, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>,539 SDTCisVT<2, v8i8>]>;540def SDTARMVTBL2 : SDTypeProfile<1, 3, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>,541 SDTCisVT<2, v8i8>, SDTCisVT<3, v8i8>]>;542 543// 1-register shuffle with mask544def NEONvtbl1 : SDNode<"ARMISD::VTBL1", SDTARMVTBL1>;545 546// 2-register shuffle with mask547def NEONvtbl2 : SDNode<"ARMISD::VTBL2", SDTARMVTBL2>;548 549 550//===----------------------------------------------------------------------===//551// NEON load / store instructions552//===----------------------------------------------------------------------===//553 554// Use VLDM to load a Q register as a D register pair.555// This is a pseudo instruction that is expanded to VLDMD after reg alloc.556def VLDMQIA557 : PseudoVFPLdStM<(outs DPair:$dst), (ins GPR:$Rn),558 IIC_fpLoad_m, "",559 [(set DPair:$dst, (v2f64 (word_alignedload GPR:$Rn)))]>;560 561// Use VSTM to store a Q register as a D register pair.562// This is a pseudo instruction that is expanded to VSTMD after reg alloc.563def VSTMQIA564 : PseudoVFPLdStM<(outs), (ins DPair:$src, GPR:$Rn),565 IIC_fpStore_m, "",566 [(word_alignedstore (v2f64 DPair:$src), GPR:$Rn)]>;567 568// Classes for VLD* pseudo-instructions with multi-register operands.569// These are expanded to real instructions after register allocation.570class VLDQPseudo<InstrItinClass itin>571 : PseudoNLdSt<(outs QPR:$dst), (ins addrmode6:$addr), itin, "">;572class VLDQWBPseudo<InstrItinClass itin>573 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),574 (ins addrmode6:$addr, am6offset:$offset), itin,575 "$addr.addr = $wb">;576class VLDQWBfixedPseudo<InstrItinClass itin>577 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),578 (ins addrmode6:$addr), itin,579 "$addr.addr = $wb">;580class VLDQWBregisterPseudo<InstrItinClass itin>581 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),582 (ins addrmode6:$addr, rGPR:$offset), itin,583 "$addr.addr = $wb">;584 585class VLDQQPseudo<InstrItinClass itin>586 : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">;587class VLDQQWBPseudo<InstrItinClass itin>588 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),589 (ins addrmode6:$addr, am6offset:$offset), itin,590 "$addr.addr = $wb">;591class VLDQQWBfixedPseudo<InstrItinClass itin>592 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),593 (ins addrmode6:$addr), itin,594 "$addr.addr = $wb">;595class VLDQQWBregisterPseudo<InstrItinClass itin>596 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),597 (ins addrmode6:$addr, rGPR:$offset), itin,598 "$addr.addr = $wb">;599 600 601class VLDQQQQPseudo<InstrItinClass itin>602 : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin,603 "$src = $dst">;604class VLDQQQQWBPseudo<InstrItinClass itin>605 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),606 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,607 "$addr.addr = $wb, $src = $dst">;608 609let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {610 611// VLD1 : Vector Load (multiple single elements)612class VLD1D<bits<4> op7_4, string Dt, Operand AddrMode>613 : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd),614 (ins AddrMode:$Rn), IIC_VLD1,615 "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD1]> {616 let Rm = 0b1111;617 let Inst{4} = Rn{4};618 let DecoderMethod = "DecodeVLDST1Instruction";619}620class VLD1Q<bits<4> op7_4, string Dt, Operand AddrMode>621 : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd),622 (ins AddrMode:$Rn), IIC_VLD1x2,623 "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD2]> {624 let Rm = 0b1111;625 let Inst{5-4} = Rn{5-4};626 let DecoderMethod = "DecodeVLDST1Instruction";627}628 629def VLD1d8 : VLD1D<{0,0,0,?}, "8", addrmode6align64>;630def VLD1d16 : VLD1D<{0,1,0,?}, "16", addrmode6align64>;631def VLD1d32 : VLD1D<{1,0,0,?}, "32", addrmode6align64>;632def VLD1d64 : VLD1D<{1,1,0,?}, "64", addrmode6align64>;633 634def VLD1q8 : VLD1Q<{0,0,?,?}, "8", addrmode6align64or128>;635def VLD1q16 : VLD1Q<{0,1,?,?}, "16", addrmode6align64or128>;636def VLD1q32 : VLD1Q<{1,0,?,?}, "32", addrmode6align64or128>;637def VLD1q64 : VLD1Q<{1,1,?,?}, "64", addrmode6align64or128>;638 639// ...with address register writeback:640multiclass VLD1DWB<bits<4> op7_4, string Dt, Operand AddrMode> {641 def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),642 (ins AddrMode:$Rn), IIC_VLD1u,643 "vld1", Dt, "$Vd, $Rn!",644 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {645 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.646 let Inst{4} = Rn{4};647 let DecoderMethod = "DecodeVLDST1Instruction";648 }649 def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),650 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1u,651 "vld1", Dt, "$Vd, $Rn, $Rm",652 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {653 let Inst{4} = Rn{4};654 let DecoderMethod = "DecodeVLDST1Instruction";655 }656}657multiclass VLD1QWB<bits<4> op7_4, string Dt, Operand AddrMode> {658 def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),659 (ins AddrMode:$Rn), IIC_VLD1x2u,660 "vld1", Dt, "$Vd, $Rn!",661 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {662 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.663 let Inst{5-4} = Rn{5-4};664 let DecoderMethod = "DecodeVLDST1Instruction";665 }666 def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),667 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,668 "vld1", Dt, "$Vd, $Rn, $Rm",669 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {670 let Inst{5-4} = Rn{5-4};671 let DecoderMethod = "DecodeVLDST1Instruction";672 }673}674 675defm VLD1d8wb : VLD1DWB<{0,0,0,?}, "8", addrmode6align64>;676defm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16", addrmode6align64>;677defm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32", addrmode6align64>;678defm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64", addrmode6align64>;679defm VLD1q8wb : VLD1QWB<{0,0,?,?}, "8", addrmode6align64or128>;680defm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16", addrmode6align64or128>;681defm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32", addrmode6align64or128>;682defm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64", addrmode6align64or128>;683 684// ...with 3 registers685class VLD1D3<bits<4> op7_4, string Dt, Operand AddrMode>686 : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd),687 (ins AddrMode:$Rn), IIC_VLD1x3, "vld1", Dt,688 "$Vd, $Rn", "", []>, Sched<[WriteVLD3]> {689 let Rm = 0b1111;690 let Inst{4} = Rn{4};691 let DecoderMethod = "DecodeVLDST1Instruction";692}693multiclass VLD1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> {694 def _fixed : NLdSt<0,0b10,0b0110, op7_4, (outs VecListThreeD:$Vd, GPR:$wb),695 (ins AddrMode:$Rn), IIC_VLD1x2u,696 "vld1", Dt, "$Vd, $Rn!",697 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {698 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.699 let Inst{4} = Rn{4};700 let DecoderMethod = "DecodeVLDST1Instruction";701 }702 def _register : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd, GPR:$wb),703 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,704 "vld1", Dt, "$Vd, $Rn, $Rm",705 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {706 let Inst{4} = Rn{4};707 let DecoderMethod = "DecodeVLDST1Instruction";708 }709}710 711def VLD1d8T : VLD1D3<{0,0,0,?}, "8", addrmode6align64>;712def VLD1d16T : VLD1D3<{0,1,0,?}, "16", addrmode6align64>;713def VLD1d32T : VLD1D3<{1,0,0,?}, "32", addrmode6align64>;714def VLD1d64T : VLD1D3<{1,1,0,?}, "64", addrmode6align64>;715 716defm VLD1d8Twb : VLD1D3WB<{0,0,0,?}, "8", addrmode6align64>;717defm VLD1d16Twb : VLD1D3WB<{0,1,0,?}, "16", addrmode6align64>;718defm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32", addrmode6align64>;719defm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64", addrmode6align64>;720 721def VLD1d8TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;722def VLD1d8TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;723def VLD1d8TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;724def VLD1d16TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;725def VLD1d16TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;726def VLD1d16TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;727def VLD1d32TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;728def VLD1d32TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;729def VLD1d32TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;730def VLD1d64TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;731def VLD1d64TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;732def VLD1d64TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;733 734def VLD1q8HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;735def VLD1q8HighTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;736def VLD1q8LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;737def VLD1q16HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;738def VLD1q16HighTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;739def VLD1q16LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;740def VLD1q32HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;741def VLD1q32HighTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;742def VLD1q32LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;743def VLD1q64HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;744def VLD1q64HighTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;745def VLD1q64LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;746 747// ...with 4 registers748class VLD1D4<bits<4> op7_4, string Dt, Operand AddrMode>749 : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd),750 (ins AddrMode:$Rn), IIC_VLD1x4, "vld1", Dt,751 "$Vd, $Rn", "", []>, Sched<[WriteVLD4]> {752 let Rm = 0b1111;753 let Inst{5-4} = Rn{5-4};754 let DecoderMethod = "DecodeVLDST1Instruction";755}756multiclass VLD1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> {757 def _fixed : NLdSt<0,0b10,0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb),758 (ins AddrMode:$Rn), IIC_VLD1x2u,759 "vld1", Dt, "$Vd, $Rn!",760 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {761 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.762 let Inst{5-4} = Rn{5-4};763 let DecoderMethod = "DecodeVLDST1Instruction";764 }765 def _register : NLdSt<0,0b10,0b0010,op7_4, (outs VecListFourD:$Vd, GPR:$wb),766 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,767 "vld1", Dt, "$Vd, $Rn, $Rm",768 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {769 let Inst{5-4} = Rn{5-4};770 let DecoderMethod = "DecodeVLDST1Instruction";771 }772}773 774def VLD1d8Q : VLD1D4<{0,0,?,?}, "8", addrmode6align64or128or256>;775def VLD1d16Q : VLD1D4<{0,1,?,?}, "16", addrmode6align64or128or256>;776def VLD1d32Q : VLD1D4<{1,0,?,?}, "32", addrmode6align64or128or256>;777def VLD1d64Q : VLD1D4<{1,1,?,?}, "64", addrmode6align64or128or256>;778 779defm VLD1d8Qwb : VLD1D4WB<{0,0,?,?}, "8", addrmode6align64or128or256>;780defm VLD1d16Qwb : VLD1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>;781defm VLD1d32Qwb : VLD1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>;782defm VLD1d64Qwb : VLD1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>;783 784def VLD1d8QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;785def VLD1d8QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;786def VLD1d8QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;787def VLD1d16QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;788def VLD1d16QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;789def VLD1d16QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;790def VLD1d32QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;791def VLD1d32QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;792def VLD1d32QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;793def VLD1d64QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;794def VLD1d64QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;795def VLD1d64QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;796 797def VLD1q8LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;798def VLD1q8HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;799def VLD1q8HighQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;800def VLD1q16LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;801def VLD1q16HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;802def VLD1q16HighQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;803def VLD1q32LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;804def VLD1q32HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;805def VLD1q32HighQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;806def VLD1q64LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;807def VLD1q64HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;808def VLD1q64HighQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;809 810// VLD2 : Vector Load (multiple 2-element structures)811class VLD2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,812 InstrItinClass itin, Operand AddrMode>813 : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd),814 (ins AddrMode:$Rn), itin,815 "vld2", Dt, "$Vd, $Rn", "", []> {816 let Rm = 0b1111;817 let Inst{5-4} = Rn{5-4};818 let DecoderMethod = "DecodeVLDST2Instruction";819}820 821def VLD2d8 : VLD2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2,822 addrmode6align64or128>, Sched<[WriteVLD2]>;823def VLD2d16 : VLD2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2,824 addrmode6align64or128>, Sched<[WriteVLD2]>;825def VLD2d32 : VLD2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2,826 addrmode6align64or128>, Sched<[WriteVLD2]>;827 828def VLD2q8 : VLD2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2,829 addrmode6align64or128or256>, Sched<[WriteVLD4]>;830def VLD2q16 : VLD2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2,831 addrmode6align64or128or256>, Sched<[WriteVLD4]>;832def VLD2q32 : VLD2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2,833 addrmode6align64or128or256>, Sched<[WriteVLD4]>;834 835def VLD2q8Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;836def VLD2q16Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;837def VLD2q32Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;838 839// ...with address register writeback:840multiclass VLD2WB<bits<4> op11_8, bits<4> op7_4, string Dt,841 RegisterOperand VdTy, InstrItinClass itin, Operand AddrMode> {842 def _fixed : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),843 (ins AddrMode:$Rn), itin,844 "vld2", Dt, "$Vd, $Rn!",845 "$Rn.addr = $wb", []> {846 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.847 let Inst{5-4} = Rn{5-4};848 let DecoderMethod = "DecodeVLDST2Instruction";849 }850 def _register : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),851 (ins AddrMode:$Rn, rGPR:$Rm), itin,852 "vld2", Dt, "$Vd, $Rn, $Rm",853 "$Rn.addr = $wb", []> {854 let Inst{5-4} = Rn{5-4};855 let DecoderMethod = "DecodeVLDST2Instruction";856 }857}858 859defm VLD2d8wb : VLD2WB<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2u,860 addrmode6align64or128>, Sched<[WriteVLD2]>;861defm VLD2d16wb : VLD2WB<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2u,862 addrmode6align64or128>, Sched<[WriteVLD2]>;863defm VLD2d32wb : VLD2WB<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2u,864 addrmode6align64or128>, Sched<[WriteVLD2]>;865 866defm VLD2q8wb : VLD2WB<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2u,867 addrmode6align64or128or256>, Sched<[WriteVLD4]>;868defm VLD2q16wb : VLD2WB<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2u,869 addrmode6align64or128or256>, Sched<[WriteVLD4]>;870defm VLD2q32wb : VLD2WB<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2u,871 addrmode6align64or128or256>, Sched<[WriteVLD4]>;872 873def VLD2q8PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;874def VLD2q16PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;875def VLD2q32PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;876def VLD2q8PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;877def VLD2q16PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;878def VLD2q32PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;879 880// ...with double-spaced registers881def VLD2b8 : VLD2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2,882 addrmode6align64or128>, Sched<[WriteVLD2]>;883def VLD2b16 : VLD2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2,884 addrmode6align64or128>, Sched<[WriteVLD2]>;885def VLD2b32 : VLD2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2,886 addrmode6align64or128>, Sched<[WriteVLD2]>;887defm VLD2b8wb : VLD2WB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2u,888 addrmode6align64or128>, Sched<[WriteVLD2]>;889defm VLD2b16wb : VLD2WB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2u,890 addrmode6align64or128>, Sched<[WriteVLD2]>;891defm VLD2b32wb : VLD2WB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2u,892 addrmode6align64or128>, Sched<[WriteVLD2]>;893 894// VLD3 : Vector Load (multiple 3-element structures)895class VLD3D<bits<4> op11_8, bits<4> op7_4, string Dt>896 : NLdSt<0, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),897 (ins addrmode6:$Rn), IIC_VLD3,898 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []>, Sched<[WriteVLD3]> {899 let Rm = 0b1111;900 let Inst{4} = Rn{4};901 let DecoderMethod = "DecodeVLDST3Instruction";902}903 904def VLD3d8 : VLD3D<0b0100, {0,0,0,?}, "8">;905def VLD3d16 : VLD3D<0b0100, {0,1,0,?}, "16">;906def VLD3d32 : VLD3D<0b0100, {1,0,0,?}, "32">;907 908def VLD3d8Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;909def VLD3d16Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;910def VLD3d32Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;911 912// ...with address register writeback:913class VLD3DWB<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, GPR:$wb),916 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD3u,917 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm",918 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {919 let Inst{4} = Rn{4};920 let DecoderMethod = "DecodeVLDST3Instruction";921}922 923def VLD3d8_UPD : VLD3DWB<0b0100, {0,0,0,?}, "8">;924def VLD3d16_UPD : VLD3DWB<0b0100, {0,1,0,?}, "16">;925def VLD3d32_UPD : VLD3DWB<0b0100, {1,0,0,?}, "32">;926 927def VLD3d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;928def VLD3d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;929def VLD3d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;930 931// ...with double-spaced registers:932def VLD3q8 : VLD3D<0b0101, {0,0,0,?}, "8">;933def VLD3q16 : VLD3D<0b0101, {0,1,0,?}, "16">;934def VLD3q32 : VLD3D<0b0101, {1,0,0,?}, "32">;935def VLD3q8_UPD : VLD3DWB<0b0101, {0,0,0,?}, "8">;936def VLD3q16_UPD : VLD3DWB<0b0101, {0,1,0,?}, "16">;937def VLD3q32_UPD : VLD3DWB<0b0101, {1,0,0,?}, "32">;938 939def VLD3q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;940def VLD3q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;941def VLD3q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;942 943// ...alternate versions to be allocated odd register numbers:944def VLD3q8oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;945def VLD3q16oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;946def VLD3q32oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;947 948def VLD3q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;949def VLD3q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;950def VLD3q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;951 952// VLD4 : Vector Load (multiple 4-element structures)953class VLD4D<bits<4> op11_8, bits<4> op7_4, string Dt>954 : NLdSt<0, 0b10, op11_8, op7_4,955 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),956 (ins addrmode6:$Rn), IIC_VLD4,957 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []>,958 Sched<[WriteVLD4]> {959 let Rm = 0b1111;960 let Inst{5-4} = Rn{5-4};961 let DecoderMethod = "DecodeVLDST4Instruction";962}963 964def VLD4d8 : VLD4D<0b0000, {0,0,?,?}, "8">;965def VLD4d16 : VLD4D<0b0000, {0,1,?,?}, "16">;966def VLD4d32 : VLD4D<0b0000, {1,0,?,?}, "32">;967 968def VLD4d8Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;969def VLD4d16Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;970def VLD4d32Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;971 972// ...with address register writeback:973class VLD4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>974 : NLdSt<0, 0b10, op11_8, op7_4,975 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),976 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD4u,977 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm",978 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {979 let Inst{5-4} = Rn{5-4};980 let DecoderMethod = "DecodeVLDST4Instruction";981}982 983def VLD4d8_UPD : VLD4DWB<0b0000, {0,0,?,?}, "8">;984def VLD4d16_UPD : VLD4DWB<0b0000, {0,1,?,?}, "16">;985def VLD4d32_UPD : VLD4DWB<0b0000, {1,0,?,?}, "32">;986 987def VLD4d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;988def VLD4d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;989def VLD4d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;990 991// ...with double-spaced registers:992def VLD4q8 : VLD4D<0b0001, {0,0,?,?}, "8">;993def VLD4q16 : VLD4D<0b0001, {0,1,?,?}, "16">;994def VLD4q32 : VLD4D<0b0001, {1,0,?,?}, "32">;995def VLD4q8_UPD : VLD4DWB<0b0001, {0,0,?,?}, "8">;996def VLD4q16_UPD : VLD4DWB<0b0001, {0,1,?,?}, "16">;997def VLD4q32_UPD : VLD4DWB<0b0001, {1,0,?,?}, "32">;998 999def VLD4q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1000def VLD4q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1001def VLD4q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1002 1003// ...alternate versions to be allocated odd register numbers:1004def VLD4q8oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;1005def VLD4q16oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;1006def VLD4q32oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;1007 1008def VLD4q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1009def VLD4q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1010def VLD4q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;1011 1012} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 11013 1014// Classes for VLD*LN pseudo-instructions with multi-register operands.1015// These are expanded to real instructions after register allocation.1016class VLDQLNPseudo<InstrItinClass itin>1017 : PseudoNLdSt<(outs QPR:$dst),1018 (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),1019 itin, "$src = $dst">;1020class VLDQLNWBPseudo<InstrItinClass itin>1021 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),1022 (ins addrmode6:$addr, am6offset:$offset, QPR:$src,1023 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;1024class VLDQQLNPseudo<InstrItinClass itin>1025 : PseudoNLdSt<(outs QQPR:$dst),1026 (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),1027 itin, "$src = $dst">;1028class VLDQQLNWBPseudo<InstrItinClass itin>1029 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),1030 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,1031 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;1032class VLDQQQQLNPseudo<InstrItinClass itin>1033 : PseudoNLdSt<(outs QQQQPR:$dst),1034 (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),1035 itin, "$src = $dst">;1036class VLDQQQQLNWBPseudo<InstrItinClass itin>1037 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),1038 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,1039 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;1040 1041// VLD1LN : Vector Load (single element to one lane)1042class VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,1043 PatFrag LoadOp>1044 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),1045 (ins addrmode6:$Rn, DPR:$src, nohash_imm:$lane),1046 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",1047 "$src = $Vd",1048 [(set DPR:$Vd, (vector_insert (Ty DPR:$src),1049 (i32 (LoadOp addrmode6:$Rn)),1050 imm:$lane))]> {1051 let Rm = 0b1111;1052 let DecoderMethod = "DecodeVLD1LN";1053}1054class VLD1LN32<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,1055 PatFrag LoadOp>1056 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),1057 (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane),1058 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",1059 "$src = $Vd",1060 [(set DPR:$Vd, (vector_insert (Ty DPR:$src),1061 (i32 (LoadOp addrmode6oneL32:$Rn)),1062 imm:$lane))]>, Sched<[WriteVLD1]> {1063 let Rm = 0b1111;1064 let DecoderMethod = "DecodeVLD1LN";1065}1066class VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln>,1067 Sched<[WriteVLD1]> {1068 let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src),1069 (i32 (LoadOp addrmode6:$addr)),1070 imm:$lane))];1071}1072 1073def VLD1LNd8 : VLD1LN<0b0000, {?,?,?,0}, "8", v8i8, extloadi8> {1074 let Inst{7-5} = lane{2-0};1075}1076def VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> {1077 let Inst{7-6} = lane{1-0};1078 let Inst{5-4} = Rn{5-4};1079}1080def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> {1081 let Inst{7} = lane{0};1082 let Inst{5-4} = Rn{5-4};1083}1084 1085def VLD1LNq8Pseudo : VLD1QLNPseudo<v16i8, extloadi8>;1086def VLD1LNq16Pseudo : VLD1QLNPseudo<v8i16, extloadi16>;1087def VLD1LNq32Pseudo : VLD1QLNPseudo<v4i32, load>;1088 1089let Predicates = [HasNEON] in {1090def : Pat<(vector_insert (v4f16 DPR:$src),1091 (f16 (load addrmode6:$addr)), imm:$lane),1092 (VLD1LNd16 addrmode6:$addr, DPR:$src, imm:$lane)>;1093def : Pat<(vector_insert (v8f16 QPR:$src),1094 (f16 (load addrmode6:$addr)), imm:$lane),1095 (VLD1LNq16Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;1096def : Pat<(vector_insert (v4bf16 DPR:$src),1097 (bf16 (load addrmode6:$addr)), imm:$lane),1098 (VLD1LNd16 addrmode6:$addr, DPR:$src, imm:$lane)>;1099def : Pat<(vector_insert (v8bf16 QPR:$src),1100 (bf16 (load addrmode6:$addr)), imm:$lane),1101 (VLD1LNq16Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;1102def : Pat<(vector_insert (v2f32 DPR:$src),1103 (f32 (load addrmode6:$addr)), imm:$lane),1104 (VLD1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;1105def : Pat<(vector_insert (v4f32 QPR:$src),1106 (f32 (load addrmode6:$addr)), imm:$lane),1107 (VLD1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;1108 1109// A 64-bit subvector insert to the first 128-bit vector position1110// is a subregister copy that needs no instruction.1111def : Pat<(insert_subvector undef, (v1i64 DPR:$src), (i32 0)),1112 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1113def : Pat<(insert_subvector undef, (v2i32 DPR:$src), (i32 0)),1114 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1115def : Pat<(insert_subvector undef, (v2f32 DPR:$src), (i32 0)),1116 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1117def : Pat<(insert_subvector undef, (v4i16 DPR:$src), (i32 0)),1118 (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1119def : Pat<(insert_subvector undef, (v4f16 DPR:$src), (i32 0)),1120 (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1121def : Pat<(insert_subvector (v16i8 undef), (v8i8 DPR:$src), (i32 0)),1122 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;1123}1124 1125 1126let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {1127 1128// ...with address register writeback:1129class VLD1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>1130 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, GPR:$wb),1131 (ins addrmode6:$Rn, am6offset:$Rm,1132 DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt,1133 "\\{$Vd[$lane]\\}, $Rn$Rm",1134 "$src = $Vd, $Rn.addr = $wb", []>, Sched<[WriteVLD1]> {1135 let DecoderMethod = "DecodeVLD1LN";1136}1137 1138def VLD1LNd8_UPD : VLD1LNWB<0b0000, {?,?,?,0}, "8"> {1139 let Inst{7-5} = lane{2-0};1140}1141def VLD1LNd16_UPD : VLD1LNWB<0b0100, {?,?,0,?}, "16"> {1142 let Inst{7-6} = lane{1-0};1143 let Inst{4} = Rn{4};1144}1145def VLD1LNd32_UPD : VLD1LNWB<0b1000, {?,0,?,?}, "32"> {1146 let Inst{7} = lane{0};1147 let Inst{5} = Rn{4};1148 let Inst{4} = Rn{4};1149}1150 1151def VLD1LNq8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;1152def VLD1LNq16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;1153def VLD1LNq32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;1154 1155// VLD2LN : Vector Load (single 2-element structure to one lane)1156class VLD2LN<bits<4> op11_8, bits<4> op7_4, string Dt>1157 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2),1158 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, nohash_imm:$lane),1159 IIC_VLD2ln, "vld2", Dt, "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn",1160 "$src1 = $Vd, $src2 = $dst2", []>, Sched<[WriteVLD1]> {1161 let Rm = 0b1111;1162 let Inst{4} = Rn{4};1163 let DecoderMethod = "DecodeVLD2LN";1164}1165 1166def VLD2LNd8 : VLD2LN<0b0001, {?,?,?,?}, "8"> {1167 let Inst{7-5} = lane{2-0};1168}1169def VLD2LNd16 : VLD2LN<0b0101, {?,?,0,?}, "16"> {1170 let Inst{7-6} = lane{1-0};1171}1172def VLD2LNd32 : VLD2LN<0b1001, {?,0,0,?}, "32"> {1173 let Inst{7} = lane{0};1174}1175 1176def VLD2LNd8Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;1177def VLD2LNd16Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;1178def VLD2LNd32Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;1179 1180// ...with double-spaced registers:1181def VLD2LNq16 : VLD2LN<0b0101, {?,?,1,?}, "16"> {1182 let Inst{7-6} = lane{1-0};1183}1184def VLD2LNq32 : VLD2LN<0b1001, {?,1,0,?}, "32"> {1185 let Inst{7} = lane{0};1186}1187 1188def VLD2LNq16Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;1189def VLD2LNq32Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;1190 1191// ...with address register writeback:1192class VLD2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>1193 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb),1194 (ins addrmode6:$Rn, am6offset:$Rm,1195 DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2lnu, "vld2", Dt,1196 "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm",1197 "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> {1198 let Inst{4} = Rn{4};1199 let DecoderMethod = "DecodeVLD2LN";1200}1201 1202def VLD2LNd8_UPD : VLD2LNWB<0b0001, {?,?,?,?}, "8"> {1203 let Inst{7-5} = lane{2-0};1204}1205def VLD2LNd16_UPD : VLD2LNWB<0b0101, {?,?,0,?}, "16"> {1206 let Inst{7-6} = lane{1-0};1207}1208def VLD2LNd32_UPD : VLD2LNWB<0b1001, {?,0,0,?}, "32"> {1209 let Inst{7} = lane{0};1210}1211 1212def VLD2LNd8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;1213def VLD2LNd16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;1214def VLD2LNd32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;1215 1216def VLD2LNq16_UPD : VLD2LNWB<0b0101, {?,?,1,?}, "16"> {1217 let Inst{7-6} = lane{1-0};1218}1219def VLD2LNq32_UPD : VLD2LNWB<0b1001, {?,1,0,?}, "32"> {1220 let Inst{7} = lane{0};1221}1222 1223def VLD2LNq16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;1224def VLD2LNq32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;1225 1226// VLD3LN : Vector Load (single 3-element structure to one lane)1227class VLD3LN<bits<4> op11_8, bits<4> op7_4, string Dt>1228 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),1229 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3,1230 nohash_imm:$lane), IIC_VLD3ln, "vld3", Dt,1231 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn",1232 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []>, Sched<[WriteVLD2]> {1233 let Rm = 0b1111;1234 let DecoderMethod = "DecodeVLD3LN";1235}1236 1237def VLD3LNd8 : VLD3LN<0b0010, {?,?,?,0}, "8"> {1238 let Inst{7-5} = lane{2-0};1239}1240def VLD3LNd16 : VLD3LN<0b0110, {?,?,0,0}, "16"> {1241 let Inst{7-6} = lane{1-0};1242}1243def VLD3LNd32 : VLD3LN<0b1010, {?,0,0,0}, "32"> {1244 let Inst{7} = lane{0};1245}1246 1247def VLD3LNd8Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;1248def VLD3LNd16Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;1249def VLD3LNd32Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;1250 1251// ...with double-spaced registers:1252def VLD3LNq16 : VLD3LN<0b0110, {?,?,1,0}, "16"> {1253 let Inst{7-6} = lane{1-0};1254}1255def VLD3LNq32 : VLD3LN<0b1010, {?,1,0,0}, "32"> {1256 let Inst{7} = lane{0};1257}1258 1259def VLD3LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;1260def VLD3LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;1261 1262// ...with address register writeback:1263class VLD3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>1264 : NLdStLn<1, 0b10, op11_8, op7_4,1265 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),1266 (ins addrmode6:$Rn, am6offset:$Rm,1267 DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane),1268 IIC_VLD3lnu, "vld3", Dt,1269 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm",1270 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb",1271 []>, Sched<[WriteVLD2]> {1272 let DecoderMethod = "DecodeVLD3LN";1273}1274 1275def VLD3LNd8_UPD : VLD3LNWB<0b0010, {?,?,?,0}, "8"> {1276 let Inst{7-5} = lane{2-0};1277}1278def VLD3LNd16_UPD : VLD3LNWB<0b0110, {?,?,0,0}, "16"> {1279 let Inst{7-6} = lane{1-0};1280}1281def VLD3LNd32_UPD : VLD3LNWB<0b1010, {?,0,0,0}, "32"> {1282 let Inst{7} = lane{0};1283}1284 1285def VLD3LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;1286def VLD3LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;1287def VLD3LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;1288 1289def VLD3LNq16_UPD : VLD3LNWB<0b0110, {?,?,1,0}, "16"> {1290 let Inst{7-6} = lane{1-0};1291}1292def VLD3LNq32_UPD : VLD3LNWB<0b1010, {?,1,0,0}, "32"> {1293 let Inst{7} = lane{0};1294}1295 1296def VLD3LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;1297def VLD3LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;1298 1299// VLD4LN : Vector Load (single 4-element structure to one lane)1300class VLD4LN<bits<4> op11_8, bits<4> op7_4, string Dt>1301 : NLdStLn<1, 0b10, op11_8, op7_4,1302 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),1303 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,1304 nohash_imm:$lane), IIC_VLD4ln, "vld4", Dt,1305 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn",1306 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>,1307 Sched<[WriteVLD2]> {1308 let Rm = 0b1111;1309 let Inst{4} = Rn{4};1310 let DecoderMethod = "DecodeVLD4LN";1311}1312 1313def VLD4LNd8 : VLD4LN<0b0011, {?,?,?,?}, "8"> {1314 let Inst{7-5} = lane{2-0};1315}1316def VLD4LNd16 : VLD4LN<0b0111, {?,?,0,?}, "16"> {1317 let Inst{7-6} = lane{1-0};1318}1319def VLD4LNd32 : VLD4LN<0b1011, {?,0,?,?}, "32"> {1320 let Inst{7} = lane{0};1321 let Inst{5} = Rn{5};1322}1323 1324def VLD4LNd8Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;1325def VLD4LNd16Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;1326def VLD4LNd32Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;1327 1328// ...with double-spaced registers:1329def VLD4LNq16 : VLD4LN<0b0111, {?,?,1,?}, "16"> {1330 let Inst{7-6} = lane{1-0};1331}1332def VLD4LNq32 : VLD4LN<0b1011, {?,1,?,?}, "32"> {1333 let Inst{7} = lane{0};1334 let Inst{5} = Rn{5};1335}1336 1337def VLD4LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;1338def VLD4LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;1339 1340// ...with address register writeback:1341class VLD4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>1342 : NLdStLn<1, 0b10, op11_8, op7_4,1343 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),1344 (ins addrmode6:$Rn, am6offset:$Rm,1345 DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),1346 IIC_VLD4lnu, "vld4", Dt,1347"\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn$Rm",1348"$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb",1349 []> {1350 let Inst{4} = Rn{4};1351 let DecoderMethod = "DecodeVLD4LN" ;1352}1353 1354def VLD4LNd8_UPD : VLD4LNWB<0b0011, {?,?,?,?}, "8"> {1355 let Inst{7-5} = lane{2-0};1356}1357def VLD4LNd16_UPD : VLD4LNWB<0b0111, {?,?,0,?}, "16"> {1358 let Inst{7-6} = lane{1-0};1359}1360def VLD4LNd32_UPD : VLD4LNWB<0b1011, {?,0,?,?}, "32"> {1361 let Inst{7} = lane{0};1362 let Inst{5} = Rn{5};1363}1364 1365def VLD4LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;1366def VLD4LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;1367def VLD4LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;1368 1369def VLD4LNq16_UPD : VLD4LNWB<0b0111, {?,?,1,?}, "16"> {1370 let Inst{7-6} = lane{1-0};1371}1372def VLD4LNq32_UPD : VLD4LNWB<0b1011, {?,1,?,?}, "32"> {1373 let Inst{7} = lane{0};1374 let Inst{5} = Rn{5};1375}1376 1377def VLD4LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;1378def VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;1379 1380} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 11381 1382// VLD1DUP : Vector Load (single element to all lanes)1383class VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp,1384 Operand AddrMode>1385 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd),1386 (ins AddrMode:$Rn),1387 IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "",1388 [(set VecListOneDAllLanes:$Vd,1389 (Ty (ARMvdup (i32 (LoadOp AddrMode:$Rn)))))]>,1390 Sched<[WriteVLD2]> {1391 let Rm = 0b1111;1392 let Inst{4} = Rn{4};1393 let DecoderMethod = "DecodeVLD1DupInstruction";1394}1395def VLD1DUPd8 : VLD1DUP<{0,0,0,?}, "8", v8i8, extloadi8,1396 addrmode6dupalignNone>;1397def VLD1DUPd16 : VLD1DUP<{0,1,0,?}, "16", v4i16, extloadi16,1398 addrmode6dupalign16>;1399def VLD1DUPd32 : VLD1DUP<{1,0,0,?}, "32", v2i32, load,1400 addrmode6dupalign32>;1401 1402let Predicates = [HasNEON] in {1403def : Pat<(v2f32 (ARMvdup (f32 (load addrmode6dup:$addr)))),1404 (VLD1DUPd32 addrmode6:$addr)>;1405}1406 1407class VLD1QDUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp,1408 Operand AddrMode>1409 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListDPairAllLanes:$Vd),1410 (ins AddrMode:$Rn), IIC_VLD1dup,1411 "vld1", Dt, "$Vd, $Rn", "",1412 [(set VecListDPairAllLanes:$Vd,1413 (Ty (ARMvdup (i32 (LoadOp AddrMode:$Rn)))))]> {1414 let Rm = 0b1111;1415 let Inst{4} = Rn{4};1416 let DecoderMethod = "DecodeVLD1DupInstruction";1417}1418 1419def VLD1DUPq8 : VLD1QDUP<{0,0,1,0}, "8", v16i8, extloadi8,1420 addrmode6dupalignNone>;1421def VLD1DUPq16 : VLD1QDUP<{0,1,1,?}, "16", v8i16, extloadi16,1422 addrmode6dupalign16>;1423def VLD1DUPq32 : VLD1QDUP<{1,0,1,?}, "32", v4i32, load,1424 addrmode6dupalign32>;1425 1426let Predicates = [HasNEON] in {1427def : Pat<(v4f32 (ARMvdup (f32 (load addrmode6dup:$addr)))),1428 (VLD1DUPq32 addrmode6:$addr)>;1429}1430 1431let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {1432// ...with address register writeback:1433multiclass VLD1DUPWB<bits<4> op7_4, string Dt, Operand AddrMode> {1434 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,1435 (outs VecListOneDAllLanes:$Vd, GPR:$wb),1436 (ins AddrMode:$Rn), IIC_VLD1dupu,1437 "vld1", Dt, "$Vd, $Rn!",1438 "$Rn.addr = $wb", []> {1439 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1440 let Inst{4} = Rn{4};1441 let DecoderMethod = "DecodeVLD1DupInstruction";1442 }1443 def _register : NLdSt<1, 0b10, 0b1100, op7_4,1444 (outs VecListOneDAllLanes:$Vd, GPR:$wb),1445 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu,1446 "vld1", Dt, "$Vd, $Rn, $Rm",1447 "$Rn.addr = $wb", []> {1448 let Inst{4} = Rn{4};1449 let DecoderMethod = "DecodeVLD1DupInstruction";1450 }1451}1452multiclass VLD1QDUPWB<bits<4> op7_4, string Dt, Operand AddrMode> {1453 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,1454 (outs VecListDPairAllLanes:$Vd, GPR:$wb),1455 (ins AddrMode:$Rn), IIC_VLD1dupu,1456 "vld1", Dt, "$Vd, $Rn!",1457 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {1458 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1459 let Inst{4} = Rn{4};1460 let DecoderMethod = "DecodeVLD1DupInstruction";1461 }1462 def _register : NLdSt<1, 0b10, 0b1100, op7_4,1463 (outs VecListDPairAllLanes:$Vd, GPR:$wb),1464 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu,1465 "vld1", Dt, "$Vd, $Rn, $Rm",1466 "$Rn.addr = $wb", []> {1467 let Inst{4} = Rn{4};1468 let DecoderMethod = "DecodeVLD1DupInstruction";1469 }1470}1471 1472defm VLD1DUPd8wb : VLD1DUPWB<{0,0,0,0}, "8", addrmode6dupalignNone>;1473defm VLD1DUPd16wb : VLD1DUPWB<{0,1,0,?}, "16", addrmode6dupalign16>;1474defm VLD1DUPd32wb : VLD1DUPWB<{1,0,0,?}, "32", addrmode6dupalign32>;1475 1476defm VLD1DUPq8wb : VLD1QDUPWB<{0,0,1,0}, "8", addrmode6dupalignNone>;1477defm VLD1DUPq16wb : VLD1QDUPWB<{0,1,1,?}, "16", addrmode6dupalign16>;1478defm VLD1DUPq32wb : VLD1QDUPWB<{1,0,1,?}, "32", addrmode6dupalign32>;1479 1480// VLD2DUP : Vector Load (single 2-element structure to all lanes)1481class VLD2DUP<bits<4> op7_4, string Dt, RegisterOperand VdTy, Operand AddrMode>1482 : NLdSt<1, 0b10, 0b1101, op7_4, (outs VdTy:$Vd),1483 (ins AddrMode:$Rn), IIC_VLD2dup,1484 "vld2", Dt, "$Vd, $Rn", "", []> {1485 let Rm = 0b1111;1486 let Inst{4} = Rn{4};1487 let DecoderMethod = "DecodeVLD2DupInstruction";1488}1489 1490def VLD2DUPd8 : VLD2DUP<{0,0,0,?}, "8", VecListDPairAllLanes,1491 addrmode6dupalign16>;1492def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes,1493 addrmode6dupalign32>;1494def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes,1495 addrmode6dupalign64>;1496 1497// HACK this one, VLD2DUPd8x2 must be changed at the same time with VLD2b8 or1498// "vld2.8 {d0[], d2[]}, [r4:32]" will become "vld2.8 {d0, d2}, [r4:32]".1499// ...with double-spaced registers1500def VLD2DUPd8x2 : VLD2DUP<{0,0,1,?}, "8", VecListDPairSpacedAllLanes,1501 addrmode6dupalign16>;1502def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes,1503 addrmode6dupalign32>;1504def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes,1505 addrmode6dupalign64>;1506 1507// Duplicate of VLDQQPseudo but with a constraint variable1508// to ensure the odd and even lanes use the same register range 1509class VLDQQPseudoInputDST<InstrItinClass itin>1510 : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr, QQPR: $src), itin, 1511 "$src = $dst">;1512class VLDQQWBPseudoInputDST<InstrItinClass itin>1513 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),1514 (ins addrmode6:$addr, am6offset:$offset, QQPR: $src), itin,1515 "$addr.addr = $wb, $src = $dst">;1516class VLDQQWBfixedPseudoInputDST<InstrItinClass itin>1517 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),1518 (ins addrmode6:$addr, QQPR: $src), itin,1519 "$addr.addr = $wb, $src = $dst">;1520 1521def VLD2DUPq8EvenPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1522def VLD2DUPq8OddPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1523def VLD2DUPq16EvenPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1524def VLD2DUPq16OddPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1525def VLD2DUPq32EvenPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1526def VLD2DUPq32OddPseudo : VLDQQPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1527 1528// ...with address register writeback:1529multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy,1530 Operand AddrMode> {1531 def _fixed : NLdSt<1, 0b10, 0b1101, op7_4,1532 (outs VdTy:$Vd, GPR:$wb),1533 (ins AddrMode:$Rn), IIC_VLD2dupu,1534 "vld2", Dt, "$Vd, $Rn!",1535 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {1536 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1537 let Inst{4} = Rn{4};1538 let DecoderMethod = "DecodeVLD2DupInstruction";1539 }1540 def _register : NLdSt<1, 0b10, 0b1101, op7_4,1541 (outs VdTy:$Vd, GPR:$wb),1542 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD2dupu,1543 "vld2", Dt, "$Vd, $Rn, $Rm",1544 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {1545 let Inst{4} = Rn{4};1546 let DecoderMethod = "DecodeVLD2DupInstruction";1547 }1548}1549 1550defm VLD2DUPd8wb : VLD2DUPWB<{0,0,0,0}, "8", VecListDPairAllLanes,1551 addrmode6dupalign16>;1552defm VLD2DUPd16wb : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes,1553 addrmode6dupalign32>;1554defm VLD2DUPd32wb : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes,1555 addrmode6dupalign64>;1556 1557defm VLD2DUPd8x2wb : VLD2DUPWB<{0,0,1,0}, "8", VecListDPairSpacedAllLanes,1558 addrmode6dupalign16>;1559defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes,1560 addrmode6dupalign32>;1561defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes,1562 addrmode6dupalign64>;1563 1564def VLD2DUPq8OddPseudoWB_fixed : VLDQQWBfixedPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1565def VLD2DUPq16OddPseudoWB_fixed : VLDQQWBfixedPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1566def VLD2DUPq32OddPseudoWB_fixed : VLDQQWBfixedPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1567def VLD2DUPq8OddPseudoWB_register : VLDQQWBPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1568def VLD2DUPq16OddPseudoWB_register : VLDQQWBPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1569def VLD2DUPq32OddPseudoWB_register : VLDQQWBPseudoInputDST<IIC_VLD2dup>, Sched<[WriteVLD2]>;1570 1571// VLD3DUP : Vector Load (single 3-element structure to all lanes)1572class VLD3DUP<bits<4> op7_4, string Dt>1573 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),1574 (ins addrmode6dup:$Rn), IIC_VLD3dup,1575 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []>,1576 Sched<[WriteVLD2]> {1577 let Rm = 0b1111;1578 let Inst{4} = 0;1579 let DecoderMethod = "DecodeVLD3DupInstruction";1580}1581 1582def VLD3DUPd8 : VLD3DUP<{0,0,0,?}, "8">;1583def VLD3DUPd16 : VLD3DUP<{0,1,0,?}, "16">;1584def VLD3DUPd32 : VLD3DUP<{1,0,0,?}, "32">;1585 1586def VLD3DUPd8Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1587def VLD3DUPd16Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1588def VLD3DUPd32Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1589 1590// ...with double-spaced registers (not used for codegen):1591def VLD3DUPq8 : VLD3DUP<{0,0,1,?}, "8">;1592def VLD3DUPq16 : VLD3DUP<{0,1,1,?}, "16">;1593def VLD3DUPq32 : VLD3DUP<{1,0,1,?}, "32">;1594 1595def VLD3DUPq8EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1596def VLD3DUPq8OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1597def VLD3DUPq16EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1598def VLD3DUPq16OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1599def VLD3DUPq32EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1600def VLD3DUPq32OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;1601 1602// ...with address register writeback:1603class VLD3DUPWB<bits<4> op7_4, string Dt, Operand AddrMode>1604 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),1605 (ins AddrMode:$Rn, am6offset:$Rm), IIC_VLD3dupu,1606 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm",1607 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {1608 let Inst{4} = 0;1609 let DecoderMethod = "DecodeVLD3DupInstruction";1610}1611 1612def VLD3DUPd8_UPD : VLD3DUPWB<{0,0,0,0}, "8", addrmode6dupalign64>;1613def VLD3DUPd16_UPD : VLD3DUPWB<{0,1,0,?}, "16", addrmode6dupalign64>;1614def VLD3DUPd32_UPD : VLD3DUPWB<{1,0,0,?}, "32", addrmode6dupalign64>;1615 1616def VLD3DUPq8_UPD : VLD3DUPWB<{0,0,1,0}, "8", addrmode6dupalign64>;1617def VLD3DUPq16_UPD : VLD3DUPWB<{0,1,1,?}, "16", addrmode6dupalign64>;1618def VLD3DUPq32_UPD : VLD3DUPWB<{1,0,1,?}, "32", addrmode6dupalign64>;1619 1620def VLD3DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1621def VLD3DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1622def VLD3DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1623 1624def VLD3DUPq8OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1625def VLD3DUPq16OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1626def VLD3DUPq32OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;1627 1628// VLD4DUP : Vector Load (single 4-element structure to all lanes)1629class VLD4DUP<bits<4> op7_4, string Dt>1630 : NLdSt<1, 0b10, 0b1111, op7_4,1631 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),1632 (ins addrmode6dup:$Rn), IIC_VLD4dup,1633 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> {1634 let Rm = 0b1111;1635 let Inst{4} = Rn{4};1636 let DecoderMethod = "DecodeVLD4DupInstruction";1637}1638 1639def VLD4DUPd8 : VLD4DUP<{0,0,0,?}, "8">;1640def VLD4DUPd16 : VLD4DUP<{0,1,0,?}, "16">;1641def VLD4DUPd32 : VLD4DUP<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }1642 1643def VLD4DUPd8Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1644def VLD4DUPd16Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1645def VLD4DUPd32Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1646 1647// ...with double-spaced registers (not used for codegen):1648def VLD4DUPq8 : VLD4DUP<{0,0,1,?}, "8">;1649def VLD4DUPq16 : VLD4DUP<{0,1,1,?}, "16">;1650def VLD4DUPq32 : VLD4DUP<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }1651 1652def VLD4DUPq8EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1653def VLD4DUPq8OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1654def VLD4DUPq16EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1655def VLD4DUPq16OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1656def VLD4DUPq32EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1657def VLD4DUPq32OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;1658 1659// ...with address register writeback:1660class VLD4DUPWB<bits<4> op7_4, string Dt>1661 : NLdSt<1, 0b10, 0b1111, op7_4,1662 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),1663 (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD4dupu,1664 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm",1665 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {1666 let Inst{4} = Rn{4};1667 let DecoderMethod = "DecodeVLD4DupInstruction";1668}1669 1670def VLD4DUPd8_UPD : VLD4DUPWB<{0,0,0,0}, "8">;1671def VLD4DUPd16_UPD : VLD4DUPWB<{0,1,0,?}, "16">;1672def VLD4DUPd32_UPD : VLD4DUPWB<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }1673 1674def VLD4DUPq8_UPD : VLD4DUPWB<{0,0,1,0}, "8">;1675def VLD4DUPq16_UPD : VLD4DUPWB<{0,1,1,?}, "16">;1676def VLD4DUPq32_UPD : VLD4DUPWB<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }1677 1678def VLD4DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1679def VLD4DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1680def VLD4DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1681 1682def VLD4DUPq8OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1683def VLD4DUPq16OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1684def VLD4DUPq32OddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;1685 1686} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 11687 1688let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {1689 1690// Classes for VST* pseudo-instructions with multi-register operands.1691// These are expanded to real instructions after register allocation.1692class VSTQPseudo<InstrItinClass itin>1693 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src), itin, "">;1694class VSTQWBPseudo<InstrItinClass itin>1695 : PseudoNLdSt<(outs GPR:$wb),1696 (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin,1697 "$addr.addr = $wb">;1698class VSTQWBfixedPseudo<InstrItinClass itin>1699 : PseudoNLdSt<(outs GPR:$wb),1700 (ins addrmode6:$addr, QPR:$src), itin,1701 "$addr.addr = $wb">;1702class VSTQWBregisterPseudo<InstrItinClass itin>1703 : PseudoNLdSt<(outs GPR:$wb),1704 (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin,1705 "$addr.addr = $wb">;1706class VSTQQPseudo<InstrItinClass itin>1707 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">;1708class VSTQQWBPseudo<InstrItinClass itin>1709 : PseudoNLdSt<(outs GPR:$wb),1710 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src), itin,1711 "$addr.addr = $wb">;1712class VSTQQWBfixedPseudo<InstrItinClass itin>1713 : PseudoNLdSt<(outs GPR:$wb),1714 (ins addrmode6:$addr, QQPR:$src), itin,1715 "$addr.addr = $wb">;1716class VSTQQWBregisterPseudo<InstrItinClass itin>1717 : PseudoNLdSt<(outs GPR:$wb),1718 (ins addrmode6:$addr, rGPR:$offset, QQPR:$src), itin,1719 "$addr.addr = $wb">;1720 1721class VSTQQQQPseudo<InstrItinClass itin>1722 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src), itin, "">;1723class VSTQQQQWBPseudo<InstrItinClass itin>1724 : PseudoNLdSt<(outs GPR:$wb),1725 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,1726 "$addr.addr = $wb">;1727 1728// VST1 : Vector Store (multiple single elements)1729class VST1D<bits<4> op7_4, string Dt, Operand AddrMode>1730 : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins AddrMode:$Rn, VecListOneD:$Vd),1731 IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST1]> {1732 let Rm = 0b1111;1733 let Inst{4} = Rn{4};1734 let DecoderMethod = "DecodeVLDST1Instruction";1735}1736class VST1Q<bits<4> op7_4, string Dt, Operand AddrMode>1737 : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins AddrMode:$Rn, VecListDPair:$Vd),1738 IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST2]> {1739 let Rm = 0b1111;1740 let Inst{5-4} = Rn{5-4};1741 let DecoderMethod = "DecodeVLDST1Instruction";1742}1743 1744def VST1d8 : VST1D<{0,0,0,?}, "8", addrmode6align64>;1745def VST1d16 : VST1D<{0,1,0,?}, "16", addrmode6align64>;1746def VST1d32 : VST1D<{1,0,0,?}, "32", addrmode6align64>;1747def VST1d64 : VST1D<{1,1,0,?}, "64", addrmode6align64>;1748 1749def VST1q8 : VST1Q<{0,0,?,?}, "8", addrmode6align64or128>;1750def VST1q16 : VST1Q<{0,1,?,?}, "16", addrmode6align64or128>;1751def VST1q32 : VST1Q<{1,0,?,?}, "32", addrmode6align64or128>;1752def VST1q64 : VST1Q<{1,1,?,?}, "64", addrmode6align64or128>;1753 1754// ...with address register writeback:1755multiclass VST1DWB<bits<4> op7_4, string Dt, Operand AddrMode> {1756 def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb),1757 (ins AddrMode:$Rn, VecListOneD:$Vd), IIC_VLD1u,1758 "vst1", Dt, "$Vd, $Rn!",1759 "$Rn.addr = $wb", []>, Sched<[WriteVST1]> {1760 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1761 let Inst{4} = Rn{4};1762 let DecoderMethod = "DecodeVLDST1Instruction";1763 }1764 def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb),1765 (ins AddrMode:$Rn, rGPR:$Rm, VecListOneD:$Vd),1766 IIC_VLD1u,1767 "vst1", Dt, "$Vd, $Rn, $Rm",1768 "$Rn.addr = $wb", []>, Sched<[WriteVST1]> {1769 let Inst{4} = Rn{4};1770 let DecoderMethod = "DecodeVLDST1Instruction";1771 }1772}1773multiclass VST1QWB<bits<4> op7_4, string Dt, Operand AddrMode> {1774 def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),1775 (ins AddrMode:$Rn, VecListDPair:$Vd), IIC_VLD1x2u,1776 "vst1", Dt, "$Vd, $Rn!",1777 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {1778 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1779 let Inst{5-4} = Rn{5-4};1780 let DecoderMethod = "DecodeVLDST1Instruction";1781 }1782 def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),1783 (ins AddrMode:$Rn, rGPR:$Rm, VecListDPair:$Vd),1784 IIC_VLD1x2u,1785 "vst1", Dt, "$Vd, $Rn, $Rm",1786 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {1787 let Inst{5-4} = Rn{5-4};1788 let DecoderMethod = "DecodeVLDST1Instruction";1789 }1790}1791 1792defm VST1d8wb : VST1DWB<{0,0,0,?}, "8", addrmode6align64>;1793defm VST1d16wb : VST1DWB<{0,1,0,?}, "16", addrmode6align64>;1794defm VST1d32wb : VST1DWB<{1,0,0,?}, "32", addrmode6align64>;1795defm VST1d64wb : VST1DWB<{1,1,0,?}, "64", addrmode6align64>;1796 1797defm VST1q8wb : VST1QWB<{0,0,?,?}, "8", addrmode6align64or128>;1798defm VST1q16wb : VST1QWB<{0,1,?,?}, "16", addrmode6align64or128>;1799defm VST1q32wb : VST1QWB<{1,0,?,?}, "32", addrmode6align64or128>;1800defm VST1q64wb : VST1QWB<{1,1,?,?}, "64", addrmode6align64or128>;1801 1802// ...with 3 registers1803class VST1D3<bits<4> op7_4, string Dt, Operand AddrMode>1804 : NLdSt<0, 0b00, 0b0110, op7_4, (outs),1805 (ins AddrMode:$Rn, VecListThreeD:$Vd),1806 IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST3]> {1807 let Rm = 0b1111;1808 let Inst{4} = Rn{4};1809 let DecoderMethod = "DecodeVLDST1Instruction";1810}1811multiclass VST1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> {1812 def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),1813 (ins AddrMode:$Rn, VecListThreeD:$Vd), IIC_VLD1x3u,1814 "vst1", Dt, "$Vd, $Rn!",1815 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {1816 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1817 let Inst{5-4} = Rn{5-4};1818 let DecoderMethod = "DecodeVLDST1Instruction";1819 }1820 def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),1821 (ins AddrMode:$Rn, rGPR:$Rm, VecListThreeD:$Vd),1822 IIC_VLD1x3u,1823 "vst1", Dt, "$Vd, $Rn, $Rm",1824 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {1825 let Inst{5-4} = Rn{5-4};1826 let DecoderMethod = "DecodeVLDST1Instruction";1827 }1828}1829 1830def VST1d8T : VST1D3<{0,0,0,?}, "8", addrmode6align64>;1831def VST1d16T : VST1D3<{0,1,0,?}, "16", addrmode6align64>;1832def VST1d32T : VST1D3<{1,0,0,?}, "32", addrmode6align64>;1833def VST1d64T : VST1D3<{1,1,0,?}, "64", addrmode6align64>;1834 1835defm VST1d8Twb : VST1D3WB<{0,0,0,?}, "8", addrmode6align64>;1836defm VST1d16Twb : VST1D3WB<{0,1,0,?}, "16", addrmode6align64>;1837defm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32", addrmode6align64>;1838defm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64", addrmode6align64>;1839 1840def VST1d8TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1841def VST1d8TPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1842def VST1d8TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1843def VST1d16TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1844def VST1d16TPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1845def VST1d16TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1846def VST1d32TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1847def VST1d32TPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1848def VST1d32TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1849def VST1d64TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1850def VST1d64TPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1851def VST1d64TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;1852 1853def VST1q8HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1854def VST1q16HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1855def VST1q32HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1856def VST1q64HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1857 1858def VST1q8HighTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1859def VST1q16HighTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1860def VST1q32HighTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1861def VST1q64HighTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1862 1863def VST1q8LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1864def VST1q16LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1865def VST1q32LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1866def VST1q64LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;1867 1868// ...with 4 registers1869class VST1D4<bits<4> op7_4, string Dt, Operand AddrMode>1870 : NLdSt<0, 0b00, 0b0010, op7_4, (outs),1871 (ins AddrMode:$Rn, VecListFourD:$Vd),1872 IIC_VST1x4, "vst1", Dt, "$Vd, $Rn", "",1873 []>, Sched<[WriteVST4]> {1874 let Rm = 0b1111;1875 let Inst{5-4} = Rn{5-4};1876 let DecoderMethod = "DecodeVLDST1Instruction";1877}1878multiclass VST1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> {1879 def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),1880 (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1x4u,1881 "vst1", Dt, "$Vd, $Rn!",1882 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {1883 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1884 let Inst{5-4} = Rn{5-4};1885 let DecoderMethod = "DecodeVLDST1Instruction";1886 }1887 def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),1888 (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd),1889 IIC_VLD1x4u,1890 "vst1", Dt, "$Vd, $Rn, $Rm",1891 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {1892 let Inst{5-4} = Rn{5-4};1893 let DecoderMethod = "DecodeVLDST1Instruction";1894 }1895}1896 1897def VST1d8Q : VST1D4<{0,0,?,?}, "8", addrmode6align64or128or256>;1898def VST1d16Q : VST1D4<{0,1,?,?}, "16", addrmode6align64or128or256>;1899def VST1d32Q : VST1D4<{1,0,?,?}, "32", addrmode6align64or128or256>;1900def VST1d64Q : VST1D4<{1,1,?,?}, "64", addrmode6align64or128or256>;1901 1902defm VST1d8Qwb : VST1D4WB<{0,0,?,?}, "8", addrmode6align64or128or256>;1903defm VST1d16Qwb : VST1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>;1904defm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>;1905defm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>;1906 1907def VST1d8QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1908def VST1d8QPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1909def VST1d8QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1910def VST1d16QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1911def VST1d16QPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1912def VST1d16QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1913def VST1d32QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1914def VST1d32QPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1915def VST1d32QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1916def VST1d64QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1917def VST1d64QPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1918def VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;1919 1920def VST1q8HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1921def VST1q16HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1922def VST1q32HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1923def VST1q64HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1924 1925def VST1q8HighQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1926def VST1q16HighQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1927def VST1q32HighQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1928def VST1q64HighQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1929 1930def VST1q8LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1931def VST1q16LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1932def VST1q32LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1933def VST1q64LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;1934 1935// VST2 : Vector Store (multiple 2-element structures)1936class VST2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,1937 InstrItinClass itin, Operand AddrMode>1938 : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins AddrMode:$Rn, VdTy:$Vd),1939 itin, "vst2", Dt, "$Vd, $Rn", "", []> {1940 let Rm = 0b1111;1941 let Inst{5-4} = Rn{5-4};1942 let DecoderMethod = "DecodeVLDST2Instruction";1943}1944 1945def VST2d8 : VST2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VST2,1946 addrmode6align64or128>, Sched<[WriteVST2]>;1947def VST2d16 : VST2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VST2,1948 addrmode6align64or128>, Sched<[WriteVST2]>;1949def VST2d32 : VST2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VST2,1950 addrmode6align64or128>, Sched<[WriteVST2]>;1951 1952def VST2q8 : VST2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VST2x2,1953 addrmode6align64or128or256>, Sched<[WriteVST4]>;1954def VST2q16 : VST2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VST2x2,1955 addrmode6align64or128or256>, Sched<[WriteVST4]>;1956def VST2q32 : VST2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VST2x2,1957 addrmode6align64or128or256>, Sched<[WriteVST4]>;1958 1959def VST2q8Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;1960def VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;1961def VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;1962 1963// ...with address register writeback:1964multiclass VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt,1965 RegisterOperand VdTy, Operand AddrMode> {1966 def _fixed : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),1967 (ins AddrMode:$Rn, VdTy:$Vd), IIC_VLD1u,1968 "vst2", Dt, "$Vd, $Rn!",1969 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {1970 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1971 let Inst{5-4} = Rn{5-4};1972 let DecoderMethod = "DecodeVLDST2Instruction";1973 }1974 def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),1975 (ins AddrMode:$Rn, rGPR:$Rm, VdTy:$Vd), IIC_VLD1u,1976 "vst2", Dt, "$Vd, $Rn, $Rm",1977 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {1978 let Inst{5-4} = Rn{5-4};1979 let DecoderMethod = "DecodeVLDST2Instruction";1980 }1981}1982multiclass VST2QWB<bits<4> op7_4, string Dt, Operand AddrMode> {1983 def _fixed : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),1984 (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1u,1985 "vst2", Dt, "$Vd, $Rn!",1986 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {1987 let Rm = 0b1101; // NLdSt will assign to the right encoding bits.1988 let Inst{5-4} = Rn{5-4};1989 let DecoderMethod = "DecodeVLDST2Instruction";1990 }1991 def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),1992 (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd),1993 IIC_VLD1u,1994 "vst2", Dt, "$Vd, $Rn, $Rm",1995 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {1996 let Inst{5-4} = Rn{5-4};1997 let DecoderMethod = "DecodeVLDST2Instruction";1998 }1999}2000 2001defm VST2d8wb : VST2DWB<0b1000, {0,0,?,?}, "8", VecListDPair,2002 addrmode6align64or128>;2003defm VST2d16wb : VST2DWB<0b1000, {0,1,?,?}, "16", VecListDPair,2004 addrmode6align64or128>;2005defm VST2d32wb : VST2DWB<0b1000, {1,0,?,?}, "32", VecListDPair,2006 addrmode6align64or128>;2007 2008defm VST2q8wb : VST2QWB<{0,0,?,?}, "8", addrmode6align64or128or256>;2009defm VST2q16wb : VST2QWB<{0,1,?,?}, "16", addrmode6align64or128or256>;2010defm VST2q32wb : VST2QWB<{1,0,?,?}, "32", addrmode6align64or128or256>;2011 2012def VST2q8PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2013def VST2q16PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2014def VST2q32PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2015def VST2q8PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2016def VST2q16PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2017def VST2q32PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;2018 2019// ...with double-spaced registers2020def VST2b8 : VST2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VST2,2021 addrmode6align64or128>;2022def VST2b16 : VST2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VST2,2023 addrmode6align64or128>;2024def VST2b32 : VST2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VST2,2025 addrmode6align64or128>;2026defm VST2b8wb : VST2DWB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced,2027 addrmode6align64or128>;2028defm VST2b16wb : VST2DWB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced,2029 addrmode6align64or128>;2030defm VST2b32wb : VST2DWB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced,2031 addrmode6align64or128>;2032 2033// VST3 : Vector Store (multiple 3-element structures)2034class VST3D<bits<4> op11_8, bits<4> op7_4, string Dt>2035 : NLdSt<0, 0b00, op11_8, op7_4, (outs),2036 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3,2037 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []>, Sched<[WriteVST3]> {2038 let Rm = 0b1111;2039 let Inst{4} = Rn{4};2040 let DecoderMethod = "DecodeVLDST3Instruction";2041}2042 2043def VST3d8 : VST3D<0b0100, {0,0,0,?}, "8">;2044def VST3d16 : VST3D<0b0100, {0,1,0,?}, "16">;2045def VST3d32 : VST3D<0b0100, {1,0,0,?}, "32">;2046 2047def VST3d8Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2048def VST3d16Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2049def VST3d32Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2050 2051// ...with address register writeback:2052class VST3DWB<bits<4> op11_8, bits<4> op7_4, string Dt>2053 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),2054 (ins addrmode6:$Rn, am6offset:$Rm,2055 DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3u,2056 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm",2057 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {2058 let Inst{4} = Rn{4};2059 let DecoderMethod = "DecodeVLDST3Instruction";2060}2061 2062def VST3d8_UPD : VST3DWB<0b0100, {0,0,0,?}, "8">;2063def VST3d16_UPD : VST3DWB<0b0100, {0,1,0,?}, "16">;2064def VST3d32_UPD : VST3DWB<0b0100, {1,0,0,?}, "32">;2065 2066def VST3d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2067def VST3d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2068def VST3d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2069 2070// ...with double-spaced registers:2071def VST3q8 : VST3D<0b0101, {0,0,0,?}, "8">;2072def VST3q16 : VST3D<0b0101, {0,1,0,?}, "16">;2073def VST3q32 : VST3D<0b0101, {1,0,0,?}, "32">;2074def VST3q8_UPD : VST3DWB<0b0101, {0,0,0,?}, "8">;2075def VST3q16_UPD : VST3DWB<0b0101, {0,1,0,?}, "16">;2076def VST3q32_UPD : VST3DWB<0b0101, {1,0,0,?}, "32">;2077 2078def VST3q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2079def VST3q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2080def VST3q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2081 2082// ...alternate versions to be allocated odd register numbers:2083def VST3q8oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2084def VST3q16oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2085def VST3q32oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;2086 2087def VST3q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2088def VST3q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2089def VST3q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;2090 2091// VST4 : Vector Store (multiple 4-element structures)2092class VST4D<bits<4> op11_8, bits<4> op7_4, string Dt>2093 : NLdSt<0, 0b00, op11_8, op7_4, (outs),2094 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4),2095 IIC_VST4, "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn",2096 "", []>, Sched<[WriteVST4]> {2097 let Rm = 0b1111;2098 let Inst{5-4} = Rn{5-4};2099 let DecoderMethod = "DecodeVLDST4Instruction";2100}2101 2102def VST4d8 : VST4D<0b0000, {0,0,?,?}, "8">;2103def VST4d16 : VST4D<0b0000, {0,1,?,?}, "16">;2104def VST4d32 : VST4D<0b0000, {1,0,?,?}, "32">;2105 2106def VST4d8Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2107def VST4d16Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2108def VST4d32Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2109 2110// ...with address register writeback:2111class VST4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>2112 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),2113 (ins addrmode6:$Rn, am6offset:$Rm,2114 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST4u,2115 "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",2116 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {2117 let Inst{5-4} = Rn{5-4};2118 let DecoderMethod = "DecodeVLDST4Instruction";2119}2120 2121def VST4d8_UPD : VST4DWB<0b0000, {0,0,?,?}, "8">;2122def VST4d16_UPD : VST4DWB<0b0000, {0,1,?,?}, "16">;2123def VST4d32_UPD : VST4DWB<0b0000, {1,0,?,?}, "32">;2124 2125def VST4d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2126def VST4d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2127def VST4d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2128 2129// ...with double-spaced registers:2130def VST4q8 : VST4D<0b0001, {0,0,?,?}, "8">;2131def VST4q16 : VST4D<0b0001, {0,1,?,?}, "16">;2132def VST4q32 : VST4D<0b0001, {1,0,?,?}, "32">;2133def VST4q8_UPD : VST4DWB<0b0001, {0,0,?,?}, "8">;2134def VST4q16_UPD : VST4DWB<0b0001, {0,1,?,?}, "16">;2135def VST4q32_UPD : VST4DWB<0b0001, {1,0,?,?}, "32">;2136 2137def VST4q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2138def VST4q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2139def VST4q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2140 2141// ...alternate versions to be allocated odd register numbers:2142def VST4q8oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2143def VST4q16oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2144def VST4q32oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;2145 2146def VST4q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2147def VST4q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2148def VST4q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;2149 2150} // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 12151 2152// Classes for VST*LN pseudo-instructions with multi-register operands.2153// These are expanded to real instructions after register allocation.2154class VSTQLNPseudo<InstrItinClass itin>2155 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),2156 itin, "">;2157class VSTQLNWBPseudo<InstrItinClass itin>2158 : PseudoNLdSt<(outs GPR:$wb),2159 (ins addrmode6:$addr, am6offset:$offset, QPR:$src,2160 nohash_imm:$lane), itin, "$addr.addr = $wb">;2161class VSTQQLNPseudo<InstrItinClass itin>2162 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),2163 itin, "">;2164class VSTQQLNWBPseudo<InstrItinClass itin>2165 : PseudoNLdSt<(outs GPR:$wb),2166 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,2167 nohash_imm:$lane), itin, "$addr.addr = $wb">;2168class VSTQQQQLNPseudo<InstrItinClass itin>2169 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),2170 itin, "">;2171class VSTQQQQLNWBPseudo<InstrItinClass itin>2172 : PseudoNLdSt<(outs GPR:$wb),2173 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,2174 nohash_imm:$lane), itin, "$addr.addr = $wb">;2175 2176// VST1LN : Vector Store (single element from one lane)2177class VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,2178 PatFrag StoreOp, SDNode ExtractOp, Operand AddrMode>2179 : NLdStLn<1, 0b00, op11_8, op7_4, (outs),2180 (ins AddrMode:$Rn, DPR:$Vd, nohash_imm:$lane),2181 IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "",2182 [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), AddrMode:$Rn)]>,2183 Sched<[WriteVST1]> {2184 let Rm = 0b1111;2185 let DecoderMethod = "DecodeVST1LN";2186}2187class VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>2188 : VSTQLNPseudo<IIC_VST1ln>, Sched<[WriteVST1]> {2189 let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),2190 addrmode6:$addr)];2191}2192 2193def VST1LNd8 : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8,2194 ARMvgetlaneu, addrmode6> {2195 let Inst{7-5} = lane{2-0};2196}2197def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16,2198 ARMvgetlaneu, addrmode6> {2199 let Inst{7-6} = lane{1-0};2200 let Inst{4} = Rn{4};2201}2202 2203def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt,2204 addrmode6oneL32> {2205 let Inst{7} = lane{0};2206 let Inst{5-4} = Rn{5-4};2207}2208 2209def VST1LNq8Pseudo : VST1QLNPseudo<v16i8, truncstorei8, ARMvgetlaneu>;2210def VST1LNq16Pseudo : VST1QLNPseudo<v8i16, truncstorei16, ARMvgetlaneu>;2211def VST1LNq32Pseudo : VST1QLNPseudo<v4i32, store, extractelt>;2212 2213let Predicates = [HasNEON] in {2214def : Pat<(store (extractelt (v2f32 DPR:$src), imm:$lane), addrmode6:$addr),2215 (VST1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;2216def : Pat<(store (extractelt (v4f32 QPR:$src), imm:$lane), addrmode6:$addr),2217 (VST1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;2218 2219def : Pat<(store (extractelt (v4f16 DPR:$src), imm:$lane), addrmode6:$addr),2220 (VST1LNd16 addrmode6:$addr, DPR:$src, imm:$lane)>;2221def : Pat<(store (extractelt (v8f16 QPR:$src), imm:$lane), addrmode6:$addr),2222 (VST1LNq16Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;2223}2224 2225// ...with address register writeback:2226class VST1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,2227 PatFrag StoreOp, SDNode ExtractOp, Operand AdrMode>2228 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),2229 (ins AdrMode:$Rn, am6offset:$Rm,2230 DPR:$Vd, nohash_imm:$lane), IIC_VST1lnu, "vst1", Dt,2231 "\\{$Vd[$lane]\\}, $Rn$Rm",2232 "$Rn.addr = $wb",2233 [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane),2234 AdrMode:$Rn, am6offset:$Rm))]>,2235 Sched<[WriteVST1]> {2236 let DecoderMethod = "DecodeVST1LN";2237}2238class VST1QLNWBPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>2239 : VSTQLNWBPseudo<IIC_VST1lnu>, Sched<[WriteVST1]> {2240 let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),2241 addrmode6:$addr, am6offset:$offset))];2242}2243 2244def VST1LNd8_UPD : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8,2245 ARMvgetlaneu, addrmode6> {2246 let Inst{7-5} = lane{2-0};2247}2248def VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16,2249 ARMvgetlaneu, addrmode6> {2250 let Inst{7-6} = lane{1-0};2251 let Inst{4} = Rn{4};2252}2253def VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store,2254 extractelt, addrmode6oneL32> {2255 let Inst{7} = lane{0};2256 let Inst{5-4} = Rn{5-4};2257}2258 2259def VST1LNq8Pseudo_UPD : VST1QLNWBPseudo<v16i8, post_truncsti8, ARMvgetlaneu>;2260def VST1LNq16Pseudo_UPD : VST1QLNWBPseudo<v8i16, post_truncsti16,ARMvgetlaneu>;2261def VST1LNq32Pseudo_UPD : VST1QLNWBPseudo<v4i32, post_store, extractelt>;2262 2263let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {2264 2265// VST2LN : Vector Store (single 2-element structure from one lane)2266class VST2LN<bits<4> op11_8, bits<4> op7_4, string Dt>2267 : NLdStLn<1, 0b00, op11_8, op7_4, (outs),2268 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, nohash_imm:$lane),2269 IIC_VST2ln, "vst2", Dt, "\\{$Vd[$lane], $src2[$lane]\\}, $Rn",2270 "", []>, Sched<[WriteVST1]> {2271 let Rm = 0b1111;2272 let Inst{4} = Rn{4};2273 let DecoderMethod = "DecodeVST2LN";2274}2275 2276def VST2LNd8 : VST2LN<0b0001, {?,?,?,?}, "8"> {2277 let Inst{7-5} = lane{2-0};2278}2279def VST2LNd16 : VST2LN<0b0101, {?,?,0,?}, "16"> {2280 let Inst{7-6} = lane{1-0};2281}2282def VST2LNd32 : VST2LN<0b1001, {?,0,0,?}, "32"> {2283 let Inst{7} = lane{0};2284}2285 2286def VST2LNd8Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;2287def VST2LNd16Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;2288def VST2LNd32Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;2289 2290// ...with double-spaced registers:2291def VST2LNq16 : VST2LN<0b0101, {?,?,1,?}, "16"> {2292 let Inst{7-6} = lane{1-0};2293 let Inst{4} = Rn{4};2294}2295def VST2LNq32 : VST2LN<0b1001, {?,1,0,?}, "32"> {2296 let Inst{7} = lane{0};2297 let Inst{4} = Rn{4};2298}2299 2300def VST2LNq16Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;2301def VST2LNq32Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;2302 2303// ...with address register writeback:2304class VST2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>2305 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),2306 (ins addrmode6:$Rn, am6offset:$Rm,2307 DPR:$Vd, DPR:$src2, nohash_imm:$lane), IIC_VST2lnu, "vst2", Dt,2308 "\\{$Vd[$lane], $src2[$lane]\\}, $Rn$Rm",2309 "$Rn.addr = $wb", []> {2310 let Inst{4} = Rn{4};2311 let DecoderMethod = "DecodeVST2LN";2312}2313 2314def VST2LNd8_UPD : VST2LNWB<0b0001, {?,?,?,?}, "8"> {2315 let Inst{7-5} = lane{2-0};2316}2317def VST2LNd16_UPD : VST2LNWB<0b0101, {?,?,0,?}, "16"> {2318 let Inst{7-6} = lane{1-0};2319}2320def VST2LNd32_UPD : VST2LNWB<0b1001, {?,0,0,?}, "32"> {2321 let Inst{7} = lane{0};2322}2323 2324def VST2LNd8Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;2325def VST2LNd16Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;2326def VST2LNd32Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;2327 2328def VST2LNq16_UPD : VST2LNWB<0b0101, {?,?,1,?}, "16"> {2329 let Inst{7-6} = lane{1-0};2330}2331def VST2LNq32_UPD : VST2LNWB<0b1001, {?,1,0,?}, "32"> {2332 let Inst{7} = lane{0};2333}2334 2335def VST2LNq16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;2336def VST2LNq32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;2337 2338// VST3LN : Vector Store (single 3-element structure from one lane)2339class VST3LN<bits<4> op11_8, bits<4> op7_4, string Dt>2340 : NLdStLn<1, 0b00, op11_8, op7_4, (outs),2341 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3,2342 nohash_imm:$lane), IIC_VST3ln, "vst3", Dt,2343 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []>,2344 Sched<[WriteVST2]> {2345 let Rm = 0b1111;2346 let DecoderMethod = "DecodeVST3LN";2347}2348 2349def VST3LNd8 : VST3LN<0b0010, {?,?,?,0}, "8"> {2350 let Inst{7-5} = lane{2-0};2351}2352def VST3LNd16 : VST3LN<0b0110, {?,?,0,0}, "16"> {2353 let Inst{7-6} = lane{1-0};2354}2355def VST3LNd32 : VST3LN<0b1010, {?,0,0,0}, "32"> {2356 let Inst{7} = lane{0};2357}2358 2359def VST3LNd8Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;2360def VST3LNd16Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;2361def VST3LNd32Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;2362 2363// ...with double-spaced registers:2364def VST3LNq16 : VST3LN<0b0110, {?,?,1,0}, "16"> {2365 let Inst{7-6} = lane{1-0};2366}2367def VST3LNq32 : VST3LN<0b1010, {?,1,0,0}, "32"> {2368 let Inst{7} = lane{0};2369}2370 2371def VST3LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;2372def VST3LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;2373 2374// ...with address register writeback:2375class VST3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>2376 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),2377 (ins addrmode6:$Rn, am6offset:$Rm,2378 DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane),2379 IIC_VST3lnu, "vst3", Dt,2380 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm",2381 "$Rn.addr = $wb", []> {2382 let DecoderMethod = "DecodeVST3LN";2383}2384 2385def VST3LNd8_UPD : VST3LNWB<0b0010, {?,?,?,0}, "8"> {2386 let Inst{7-5} = lane{2-0};2387}2388def VST3LNd16_UPD : VST3LNWB<0b0110, {?,?,0,0}, "16"> {2389 let Inst{7-6} = lane{1-0};2390}2391def VST3LNd32_UPD : VST3LNWB<0b1010, {?,0,0,0}, "32"> {2392 let Inst{7} = lane{0};2393}2394 2395def VST3LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;2396def VST3LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;2397def VST3LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;2398 2399def VST3LNq16_UPD : VST3LNWB<0b0110, {?,?,1,0}, "16"> {2400 let Inst{7-6} = lane{1-0};2401}2402def VST3LNq32_UPD : VST3LNWB<0b1010, {?,1,0,0}, "32"> {2403 let Inst{7} = lane{0};2404}2405 2406def VST3LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;2407def VST3LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;2408 2409// VST4LN : Vector Store (single 4-element structure from one lane)2410class VST4LN<bits<4> op11_8, bits<4> op7_4, string Dt>2411 : NLdStLn<1, 0b00, op11_8, op7_4, (outs),2412 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4,2413 nohash_imm:$lane), IIC_VST4ln, "vst4", Dt,2414 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn",2415 "", []>, Sched<[WriteVST2]> {2416 let Rm = 0b1111;2417 let Inst{4} = Rn{4};2418 let DecoderMethod = "DecodeVST4LN";2419}2420 2421def VST4LNd8 : VST4LN<0b0011, {?,?,?,?}, "8"> {2422 let Inst{7-5} = lane{2-0};2423}2424def VST4LNd16 : VST4LN<0b0111, {?,?,0,?}, "16"> {2425 let Inst{7-6} = lane{1-0};2426}2427def VST4LNd32 : VST4LN<0b1011, {?,0,?,?}, "32"> {2428 let Inst{7} = lane{0};2429 let Inst{5} = Rn{5};2430}2431 2432def VST4LNd8Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;2433def VST4LNd16Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;2434def VST4LNd32Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;2435 2436// ...with double-spaced registers:2437def VST4LNq16 : VST4LN<0b0111, {?,?,1,?}, "16"> {2438 let Inst{7-6} = lane{1-0};2439}2440def VST4LNq32 : VST4LN<0b1011, {?,1,?,?}, "32"> {2441 let Inst{7} = lane{0};2442 let Inst{5} = Rn{5};2443}2444 2445def VST4LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;2446def VST4LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;2447 2448// ...with address register writeback:2449class VST4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>2450 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),2451 (ins addrmode6:$Rn, am6offset:$Rm,2452 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),2453 IIC_VST4lnu, "vst4", Dt,2454 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm",2455 "$Rn.addr = $wb", []> {2456 let Inst{4} = Rn{4};2457 let DecoderMethod = "DecodeVST4LN";2458}2459 2460def VST4LNd8_UPD : VST4LNWB<0b0011, {?,?,?,?}, "8"> {2461 let Inst{7-5} = lane{2-0};2462}2463def VST4LNd16_UPD : VST4LNWB<0b0111, {?,?,0,?}, "16"> {2464 let Inst{7-6} = lane{1-0};2465}2466def VST4LNd32_UPD : VST4LNWB<0b1011, {?,0,?,?}, "32"> {2467 let Inst{7} = lane{0};2468 let Inst{5} = Rn{5};2469}2470 2471def VST4LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;2472def VST4LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;2473def VST4LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;2474 2475def VST4LNq16_UPD : VST4LNWB<0b0111, {?,?,1,?}, "16"> {2476 let Inst{7-6} = lane{1-0};2477}2478def VST4LNq32_UPD : VST4LNWB<0b1011, {?,1,?,?}, "32"> {2479 let Inst{7} = lane{0};2480 let Inst{5} = Rn{5};2481}2482 2483def VST4LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;2484def VST4LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;2485 2486} // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 12487 2488// Use vld1/vst1 for unaligned f64 load / store2489let Predicates = [IsLE,HasNEON] in {2490def : Pat<(f64 (hword_alignedload addrmode6:$addr)),2491 (VLD1d16 addrmode6:$addr)>;2492def : Pat<(hword_alignedstore (f64 DPR:$value), addrmode6:$addr),2493 (VST1d16 addrmode6:$addr, DPR:$value)>;2494def : Pat<(f64 (byte_alignedload addrmode6:$addr)),2495 (VLD1d8 addrmode6:$addr)>;2496def : Pat<(byte_alignedstore (f64 DPR:$value), addrmode6:$addr),2497 (VST1d8 addrmode6:$addr, DPR:$value)>;2498}2499let Predicates = [IsBE,HasNEON] in {2500def : Pat<(f64 (non_word_alignedload addrmode6:$addr)),2501 (VLD1d64 addrmode6:$addr)>;2502def : Pat<(non_word_alignedstore (f64 DPR:$value), addrmode6:$addr),2503 (VST1d64 addrmode6:$addr, DPR:$value)>;2504}2505 2506// Use vld1/vst1 for Q and QQ. Also use them for unaligned v2f642507// load / store if it's legal.2508let Predicates = [HasNEON] in {2509def : Pat<(v2f64 (dword_alignedload addrmode6:$addr)),2510 (VLD1q64 addrmode6:$addr)>;2511def : Pat<(dword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),2512 (VST1q64 addrmode6:$addr, QPR:$value)>;2513}2514let Predicates = [IsLE,HasNEON] in {2515def : Pat<(v2f64 (word_alignedload addrmode6:$addr)),2516 (VLD1q32 addrmode6:$addr)>;2517def : Pat<(word_alignedstore (v2f64 QPR:$value), addrmode6:$addr),2518 (VST1q32 addrmode6:$addr, QPR:$value)>;2519def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)),2520 (VLD1q16 addrmode6:$addr)>;2521def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),2522 (VST1q16 addrmode6:$addr, QPR:$value)>;2523def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)),2524 (VLD1q8 addrmode6:$addr)>;2525def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr),2526 (VST1q8 addrmode6:$addr, QPR:$value)>;2527}2528 2529//===----------------------------------------------------------------------===//2530// Instruction Classes2531//===----------------------------------------------------------------------===//2532 2533// Basic 2-register operations: double- and quad-register.2534class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2535 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,2536 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>2537 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),2538 (ins DPR:$Vm), IIC_VUNAD, OpcodeStr, Dt,"$Vd, $Vm", "",2539 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm))))]>;2540class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2541 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,2542 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>2543 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),2544 (ins QPR:$Vm), IIC_VUNAQ, OpcodeStr, Dt,"$Vd, $Vm", "",2545 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm))))]>;2546 2547// Basic 2-register intrinsics, both double- and quad-register.2548class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2549 bits<2> op17_16, bits<5> op11_7, bit op4,2550 InstrItinClass itin, string OpcodeStr, string Dt,2551 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2552 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),2553 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2554 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;2555class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2556 bits<2> op17_16, bits<5> op11_7, bit op4,2557 InstrItinClass itin, string OpcodeStr, string Dt,2558 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2559 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),2560 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2561 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;2562 2563// Same as above, but not predicated.2564class N2VDIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7,2565 InstrItinClass itin, string OpcodeStr, string Dt,2566 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2567 : N2Vnp<op19_18, op17_16, op10_8, op7, 0, (outs DPR:$Vd), (ins DPR:$Vm),2568 itin, OpcodeStr, Dt,2569 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;2570 2571class N2VQIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7,2572 InstrItinClass itin, string OpcodeStr, string Dt,2573 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2574 : N2Vnp<op19_18, op17_16, op10_8, op7, 1, (outs QPR:$Vd), (ins QPR:$Vm),2575 itin, OpcodeStr, Dt,2576 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;2577 2578// Similar to NV2VQIntnp with some more encoding bits exposed (crypto).2579class N2VQIntXnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,2580 bit op7, InstrItinClass itin, string OpcodeStr, string Dt,2581 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2582 : N2Vnp<op19_18, op17_16, op10_8, op7, op6, (outs QPR:$Vd), (ins QPR:$Vm),2583 itin, OpcodeStr, Dt,2584 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;2585 2586// Same as N2VQIntXnp but with Vd as a src register.2587class N2VQIntX2np<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,2588 bit op7, InstrItinClass itin, string OpcodeStr, string Dt,2589 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2590 : N2Vnp<op19_18, op17_16, op10_8, op7, op6,2591 (outs QPR:$Vd), (ins QPR:$src, QPR:$Vm),2592 itin, OpcodeStr, Dt,2593 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vm))))]> {2594 let Constraints = "$src = $Vd";2595}2596 2597// Narrow 2-register operations.2598class N2VN<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2599 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,2600 InstrItinClass itin, string OpcodeStr, string Dt,2601 ValueType TyD, ValueType TyQ, SDNode OpNode>2602 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),2603 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2604 [(set DPR:$Vd, (TyD (OpNode (TyQ QPR:$Vm))))]>;2605 2606// Narrow 2-register intrinsics.2607class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2608 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,2609 InstrItinClass itin, string OpcodeStr, string Dt,2610 ValueType TyD, ValueType TyQ, SDPatternOperator IntOp>2611 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),2612 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2613 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vm))))]>;2614 2615// Long 2-register operations (currently only used for VMOVL).2616class N2VL<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2617 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,2618 InstrItinClass itin, string OpcodeStr, string Dt,2619 ValueType TyQ, ValueType TyD, SDNode OpNode>2620 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),2621 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2622 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vm))))]>;2623 2624// Long 2-register intrinsics.2625class N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,2626 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,2627 InstrItinClass itin, string OpcodeStr, string Dt,2628 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>2629 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),2630 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",2631 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vm))))]>;2632 2633// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register.2634class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>2635 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$Vd, DPR:$Vm),2636 (ins DPR:$src1, DPR:$src2), IIC_VPERMD,2637 OpcodeStr, Dt, "$Vd, $Vm",2638 "$src1 = $Vd, $src2 = $Vm", []>;2639class N2VQShuffle<bits<2> op19_18, bits<5> op11_7,2640 InstrItinClass itin, string OpcodeStr, string Dt>2641 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$Vd, QPR:$Vm),2642 (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm",2643 "$src1 = $Vd, $src2 = $Vm", []>;2644 2645// Basic 3-register operations: double- and quad-register.2646class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2647 InstrItinClass itin, string OpcodeStr, string Dt,2648 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>2649 : N3V<op24, op23, op21_20, op11_8, 0, op4,2650 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2651 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",2652 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {2653 // All of these have a two-operand InstAlias.2654 let TwoOperandAliasConstraint = "$Vn = $Vd";2655 let isCommutable = Commutable;2656}2657// Same as N3VD but no data type.2658class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2659 InstrItinClass itin, string OpcodeStr,2660 ValueType ResTy, ValueType OpTy,2661 SDNode OpNode, bit Commutable>2662 : N3VX<op24, op23, op21_20, op11_8, 0, op4,2663 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2664 OpcodeStr, "$Vd, $Vn, $Vm", "",2665 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>{2666 // All of these have a two-operand InstAlias.2667 let TwoOperandAliasConstraint = "$Vn = $Vd";2668 let isCommutable = Commutable;2669}2670 2671class N3VDSL<bits<2> op21_20, bits<4> op11_8,2672 InstrItinClass itin, string OpcodeStr, string Dt,2673 ValueType Ty, SDNode ShOp>2674 : N3VLane32<0, 1, op21_20, op11_8, 1, 0,2675 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2676 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2677 [(set (Ty DPR:$Vd),2678 (Ty (ShOp (Ty DPR:$Vn),2679 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm),imm:$lane)))))]> {2680 // All of these have a two-operand InstAlias.2681 let TwoOperandAliasConstraint = "$Vn = $Vd";2682 let isCommutable = 0;2683}2684class N3VDSL16<bits<2> op21_20, bits<4> op11_8,2685 string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>2686 : N3VLane16<0, 1, op21_20, op11_8, 1, 0,2687 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2688 NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane","",2689 [(set (Ty DPR:$Vd),2690 (Ty (ShOp (Ty DPR:$Vn),2691 (Ty (ARMvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {2692 // All of these have a two-operand InstAlias.2693 let TwoOperandAliasConstraint = "$Vn = $Vd";2694 let isCommutable = 0;2695}2696 2697class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2698 InstrItinClass itin, string OpcodeStr, string Dt,2699 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>2700 : N3V<op24, op23, op21_20, op11_8, 1, op4,2701 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,2702 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",2703 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {2704 // All of these have a two-operand InstAlias.2705 let TwoOperandAliasConstraint = "$Vn = $Vd";2706 let isCommutable = Commutable;2707}2708class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2709 InstrItinClass itin, string OpcodeStr,2710 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>2711 : N3VX<op24, op23, op21_20, op11_8, 1, op4,2712 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,2713 OpcodeStr, "$Vd, $Vn, $Vm", "",2714 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>{2715 // All of these have a two-operand InstAlias.2716 let TwoOperandAliasConstraint = "$Vn = $Vd";2717 let isCommutable = Commutable;2718}2719class N3VQSL<bits<2> op21_20, bits<4> op11_8,2720 InstrItinClass itin, string OpcodeStr, string Dt,2721 ValueType ResTy, ValueType OpTy, SDNode ShOp>2722 : N3VLane32<1, 1, op21_20, op11_8, 1, 0,2723 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2724 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2725 [(set (ResTy QPR:$Vd),2726 (ResTy (ShOp (ResTy QPR:$Vn),2727 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm),2728 imm:$lane)))))]> {2729 // All of these have a two-operand InstAlias.2730 let TwoOperandAliasConstraint = "$Vn = $Vd";2731 let isCommutable = 0;2732}2733class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,2734 ValueType ResTy, ValueType OpTy, SDNode ShOp>2735 : N3VLane16<1, 1, op21_20, op11_8, 1, 0,2736 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2737 NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane", "",2738 [(set (ResTy QPR:$Vd),2739 (ResTy (ShOp (ResTy QPR:$Vn),2740 (ResTy (ARMvduplane (OpTy DPR_8:$Vm),2741 imm:$lane)))))]> {2742 // All of these have a two-operand InstAlias.2743 let TwoOperandAliasConstraint = "$Vn = $Vd";2744 let isCommutable = 0;2745}2746 2747// Basic 3-register intrinsics, both double- and quad-register.2748class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2749 Format f, InstrItinClass itin, string OpcodeStr, string Dt,2750 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>2751 : N3V<op24, op23, op21_20, op11_8, 0, op4,2752 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin,2753 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",2754 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {2755 // All of these have a two-operand InstAlias.2756 let TwoOperandAliasConstraint = "$Vn = $Vd";2757 let isCommutable = Commutable;2758}2759 2760class N3VDIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,2761 bit op4, Format f, InstrItinClass itin, string OpcodeStr,2762 string Dt, ValueType ResTy, ValueType OpTy,2763 SDPatternOperator IntOp, bit Commutable>2764 : N3Vnp<op27_23, op21_20, op11_8, op6, op4,2765 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, OpcodeStr, Dt,2766 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {2767 let isCommutable = Commutable;2768}2769 2770 2771class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2772 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>2773 : N3VLane32<0, 1, op21_20, op11_8, 1, 0,2774 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2775 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2776 [(set (Ty DPR:$Vd),2777 (Ty (IntOp (Ty DPR:$Vn),2778 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm),2779 imm:$lane)))))]> {2780 let isCommutable = 0;2781}2782 2783class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2784 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>2785 : N3VLane16<0, 1, op21_20, op11_8, 1, 0,2786 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2787 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2788 [(set (Ty DPR:$Vd),2789 (Ty (IntOp (Ty DPR:$Vn),2790 (Ty (ARMvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {2791 let isCommutable = 0;2792}2793class N3VDIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2794 Format f, InstrItinClass itin, string OpcodeStr, string Dt,2795 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2796 : N3V<op24, op23, op21_20, op11_8, 0, op4,2797 (outs DPR:$Vd), (ins DPR:$Vm, DPR:$Vn), f, itin,2798 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",2799 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (OpTy DPR:$Vn))))]> {2800 let TwoOperandAliasConstraint = "$Vm = $Vd";2801 let isCommutable = 0;2802}2803 2804class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2805 Format f, InstrItinClass itin, string OpcodeStr, string Dt,2806 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>2807 : N3V<op24, op23, op21_20, op11_8, 1, op4,2808 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin,2809 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",2810 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {2811 // All of these have a two-operand InstAlias.2812 let TwoOperandAliasConstraint = "$Vn = $Vd";2813 let isCommutable = Commutable;2814}2815 2816class N3VQIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,2817 bit op4, Format f, InstrItinClass itin, string OpcodeStr,2818 string Dt, ValueType ResTy, ValueType OpTy,2819 SDPatternOperator IntOp, bit Commutable>2820 : N3Vnp<op27_23, op21_20, op11_8, op6, op4,2821 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt,2822 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {2823 let isCommutable = Commutable;2824}2825 2826// Same as N3VQIntnp but with Vd as a src register.2827class N3VQInt3np<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,2828 bit op4, Format f, InstrItinClass itin, string OpcodeStr,2829 string Dt, ValueType ResTy, ValueType OpTy,2830 SDPatternOperator IntOp>2831 : N3Vnp<op27_23, op21_20, op11_8, op6, op4,2832 (outs QPR:$Vd), (ins QPR:$src, QPR:$Vn, QPR:$Vm),2833 f, itin, OpcodeStr, Dt,2834 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vn),2835 (OpTy QPR:$Vm))))]> {2836 let Constraints = "$src = $Vd";2837 let isCommutable = 0;2838}2839 2840class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2841 string OpcodeStr, string Dt,2842 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2843 : N3VLane32<1, 1, op21_20, op11_8, 1, 0,2844 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2845 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2846 [(set (ResTy QPR:$Vd),2847 (ResTy (IntOp (ResTy QPR:$Vn),2848 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm),2849 imm:$lane)))))]> {2850 let isCommutable = 0;2851}2852class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2853 string OpcodeStr, string Dt,2854 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2855 : N3VLane16<1, 1, op21_20, op11_8, 1, 0,2856 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2857 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",2858 [(set (ResTy QPR:$Vd),2859 (ResTy (IntOp (ResTy QPR:$Vn),2860 (ResTy (ARMvduplane (OpTy DPR_8:$Vm),2861 imm:$lane)))))]> {2862 let isCommutable = 0;2863}2864class N3VQIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2865 Format f, InstrItinClass itin, string OpcodeStr, string Dt,2866 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2867 : N3V<op24, op23, op21_20, op11_8, 1, op4,2868 (outs QPR:$Vd), (ins QPR:$Vm, QPR:$Vn), f, itin,2869 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",2870 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (OpTy QPR:$Vn))))]> {2871 let TwoOperandAliasConstraint = "$Vm = $Vd";2872 let isCommutable = 0;2873}2874 2875// Multiply-Add/Sub operations: double- and quad-register.2876class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2877 InstrItinClass itin, string OpcodeStr, string Dt,2878 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode>2879 : N3V<op24, op23, op21_20, op11_8, 0, op4,2880 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2881 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2882 [(set DPR:$Vd, (Ty (OpNode DPR:$src1,2883 (Ty (MulOp DPR:$Vn, DPR:$Vm)))))]>;2884 2885class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2886 string OpcodeStr, string Dt,2887 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>2888 : N3VLane32<0, 1, op21_20, op11_8, 1, 0,2889 (outs DPR:$Vd),2890 (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2891 NVMulSLFrm, itin,2892 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",2893 [(set (Ty DPR:$Vd),2894 (Ty (ShOp (Ty DPR:$src1),2895 (Ty (MulOp DPR:$Vn,2896 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm),2897 imm:$lane)))))))]>;2898class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2899 string OpcodeStr, string Dt,2900 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>2901 : N3VLane16<0, 1, op21_20, op11_8, 1, 0,2902 (outs DPR:$Vd),2903 (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2904 NVMulSLFrm, itin,2905 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",2906 [(set (Ty DPR:$Vd),2907 (Ty (ShOp (Ty DPR:$src1),2908 (Ty (MulOp DPR:$Vn,2909 (Ty (ARMvduplane (Ty DPR_8:$Vm),2910 imm:$lane)))))))]>;2911 2912class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2913 InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,2914 SDPatternOperator MulOp, SDPatternOperator OpNode>2915 : N3V<op24, op23, op21_20, op11_8, 1, op4,2916 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,2917 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2918 [(set QPR:$Vd, (Ty (OpNode QPR:$src1,2919 (Ty (MulOp QPR:$Vn, QPR:$Vm)))))]>;2920class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2921 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,2922 SDPatternOperator MulOp, SDPatternOperator ShOp>2923 : N3VLane32<1, 1, op21_20, op11_8, 1, 0,2924 (outs QPR:$Vd),2925 (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),2926 NVMulSLFrm, itin,2927 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",2928 [(set (ResTy QPR:$Vd),2929 (ResTy (ShOp (ResTy QPR:$src1),2930 (ResTy (MulOp QPR:$Vn,2931 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm),2932 imm:$lane)))))))]>;2933class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,2934 string OpcodeStr, string Dt,2935 ValueType ResTy, ValueType OpTy,2936 SDPatternOperator MulOp, SDPatternOperator ShOp>2937 : N3VLane16<1, 1, op21_20, op11_8, 1, 0,2938 (outs QPR:$Vd),2939 (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),2940 NVMulSLFrm, itin,2941 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",2942 [(set (ResTy QPR:$Vd),2943 (ResTy (ShOp (ResTy QPR:$src1),2944 (ResTy (MulOp QPR:$Vn,2945 (ResTy (ARMvduplane (OpTy DPR_8:$Vm),2946 imm:$lane)))))))]>;2947 2948// Neon Intrinsic-Op instructions (VABA): double- and quad-register.2949class N3VDIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2950 InstrItinClass itin, string OpcodeStr, string Dt,2951 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>2952 : N3V<op24, op23, op21_20, op11_8, 0, op4,2953 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2954 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2955 [(set DPR:$Vd, (Ty (OpNode DPR:$src1,2956 (Ty (IntOp (Ty DPR:$Vn), (Ty DPR:$Vm))))))]>;2957class N3VQIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2958 InstrItinClass itin, string OpcodeStr, string Dt,2959 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>2960 : N3V<op24, op23, op21_20, op11_8, 1, op4,2961 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,2962 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2963 [(set QPR:$Vd, (Ty (OpNode QPR:$src1,2964 (Ty (IntOp (Ty QPR:$Vn), (Ty QPR:$Vm))))))]>;2965 2966// Neon 3-argument intrinsics, both double- and quad-register.2967// The destination register is also used as the first source operand register.2968class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2969 InstrItinClass itin, string OpcodeStr, string Dt,2970 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2971 : N3V<op24, op23, op21_20, op11_8, 0, op4,2972 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2973 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2974 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$src1),2975 (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;2976class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2977 InstrItinClass itin, string OpcodeStr, string Dt,2978 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>2979 : N3V<op24, op23, op21_20, op11_8, 1, op4,2980 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,2981 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2982 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src1),2983 (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;2984 2985// Long Multiply-Add/Sub operations.2986class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,2987 InstrItinClass itin, string OpcodeStr, string Dt,2988 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>2989 : N3V<op24, op23, op21_20, op11_8, 0, op4,2990 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,2991 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",2992 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),2993 (TyQ (MulOp (TyD DPR:$Vn),2994 (TyD DPR:$Vm)))))]>;2995class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,2996 InstrItinClass itin, string OpcodeStr, string Dt,2997 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>2998 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),2999 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),3000 NVMulSLFrm, itin,3001 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",3002 [(set QPR:$Vd,3003 (OpNode (TyQ QPR:$src1),3004 (TyQ (MulOp (TyD DPR:$Vn),3005 (TyD (ARMvduplane (TyD DPR_VFP2:$Vm),3006 imm:$lane))))))]>;3007class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8,3008 InstrItinClass itin, string OpcodeStr, string Dt,3009 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>3010 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),3011 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),3012 NVMulSLFrm, itin,3013 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",3014 [(set QPR:$Vd,3015 (OpNode (TyQ QPR:$src1),3016 (TyQ (MulOp (TyD DPR:$Vn),3017 (TyD (ARMvduplane (TyD DPR_8:$Vm),3018 imm:$lane))))))]>;3019 3020// Long Intrinsic-Op vector operations with explicit extend (VABAL).3021class N3VLIntExtOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3022 InstrItinClass itin, string OpcodeStr, string Dt,3023 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,3024 SDNode OpNode>3025 : N3V<op24, op23, op21_20, op11_8, 0, op4,3026 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3027 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",3028 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),3029 (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),3030 (TyD DPR:$Vm)))))))]>;3031 3032// Neon Long 3-argument intrinsic. The destination register is3033// a quad-register and is also used as the first source operand register.3034class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3035 InstrItinClass itin, string OpcodeStr, string Dt,3036 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>3037 : N3V<op24, op23, op21_20, op11_8, 0, op4,3038 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3039 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",3040 [(set QPR:$Vd,3041 (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$Vn), (TyD DPR:$Vm))))]>;3042class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,3043 string OpcodeStr, string Dt,3044 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3045 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,3046 (outs QPR:$Vd),3047 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),3048 NVMulSLFrm, itin,3049 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",3050 [(set (ResTy QPR:$Vd),3051 (ResTy (IntOp (ResTy QPR:$src1),3052 (OpTy DPR:$Vn),3053 (OpTy (ARMvduplane (OpTy DPR_VFP2:$Vm),3054 imm:$lane)))))]>;3055class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,3056 InstrItinClass itin, string OpcodeStr, string Dt,3057 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3058 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,3059 (outs QPR:$Vd),3060 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),3061 NVMulSLFrm, itin,3062 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",3063 [(set (ResTy QPR:$Vd),3064 (ResTy (IntOp (ResTy QPR:$src1),3065 (OpTy DPR:$Vn),3066 (OpTy (ARMvduplane (OpTy DPR_8:$Vm),3067 imm:$lane)))))]>;3068 3069// Narrowing 3-register intrinsics.3070class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3071 string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ,3072 SDPatternOperator IntOp, bit Commutable>3073 : N3V<op24, op23, op21_20, op11_8, 0, op4,3074 (outs DPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINi4D,3075 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3076 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vn), (TyQ QPR:$Vm))))]> {3077 let isCommutable = Commutable;3078}3079 3080// Long 3-register operations.3081class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3082 InstrItinClass itin, string OpcodeStr, string Dt,3083 ValueType TyQ, ValueType TyD, SDNode OpNode, bit Commutable>3084 : N3V<op24, op23, op21_20, op11_8, 0, op4,3085 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3086 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3087 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {3088 let isCommutable = Commutable;3089}3090 3091class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,3092 InstrItinClass itin, string OpcodeStr, string Dt,3093 ValueType TyQ, ValueType TyD, SDNode OpNode>3094 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,3095 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),3096 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",3097 [(set QPR:$Vd,3098 (TyQ (OpNode (TyD DPR:$Vn),3099 (TyD (ARMvduplane (TyD DPR_VFP2:$Vm),imm:$lane)))))]>;3100class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8,3101 InstrItinClass itin, string OpcodeStr, string Dt,3102 ValueType TyQ, ValueType TyD, SDNode OpNode>3103 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,3104 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),3105 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",3106 [(set QPR:$Vd,3107 (TyQ (OpNode (TyD DPR:$Vn),3108 (TyD (ARMvduplane (TyD DPR_8:$Vm), imm:$lane)))))]>;3109 3110// Long 3-register operations with explicitly extended operands.3111class N3VLExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3112 InstrItinClass itin, string OpcodeStr, string Dt,3113 ValueType TyQ, ValueType TyD, SDNode OpNode, SDPatternOperator ExtOp,3114 bit Commutable>3115 : N3V<op24, op23, op21_20, op11_8, 0, op4,3116 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3117 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3118 [(set QPR:$Vd, (OpNode (TyQ (ExtOp (TyD DPR:$Vn))),3119 (TyQ (ExtOp (TyD DPR:$Vm)))))]> {3120 let isCommutable = Commutable;3121}3122 3123// Long 3-register intrinsics with explicit extend (VABDL).3124class N3VLIntExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3125 InstrItinClass itin, string OpcodeStr, string Dt,3126 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,3127 bit Commutable>3128 : N3V<op24, op23, op21_20, op11_8, 0, op4,3129 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3130 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3131 [(set QPR:$Vd, (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),3132 (TyD DPR:$Vm))))))]> {3133 let isCommutable = Commutable;3134}3135 3136// Long 3-register intrinsics.3137class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3138 InstrItinClass itin, string OpcodeStr, string Dt,3139 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, bit Commutable>3140 : N3V<op24, op23, op21_20, op11_8, 0, op4,3141 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3142 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3143 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {3144 let isCommutable = Commutable;3145}3146 3147// Same as above, but not predicated.3148class N3VLIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,3149 bit op4, InstrItinClass itin, string OpcodeStr,3150 string Dt, ValueType ResTy, ValueType OpTy,3151 SDPatternOperator IntOp, bit Commutable>3152 : N3Vnp<op27_23, op21_20, op11_8, op6, op4,3153 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt,3154 [(set QPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {3155 let isCommutable = Commutable;3156}3157 3158 3159class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,3160 string OpcodeStr, string Dt,3161 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3162 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,3163 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),3164 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",3165 [(set (ResTy QPR:$Vd),3166 (ResTy (IntOp (OpTy DPR:$Vn),3167 (OpTy (ARMvduplane (OpTy DPR_VFP2:$Vm),3168 imm:$lane)))))]>;3169class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,3170 InstrItinClass itin, string OpcodeStr, string Dt,3171 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3172 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,3173 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),3174 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",3175 [(set (ResTy QPR:$Vd),3176 (ResTy (IntOp (OpTy DPR:$Vn),3177 (OpTy (ARMvduplane (OpTy DPR_8:$Vm),3178 imm:$lane)))))]>;3179 3180// Wide 3-register operations.3181class N3VW<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3182 string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD,3183 SDNode OpNode, SDPatternOperator ExtOp, bit Commutable>3184 : N3V<op24, op23, op21_20, op11_8, 0, op4,3185 (outs QPR:$Vd), (ins QPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VSUBiD,3186 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3187 [(set QPR:$Vd, (OpNode (TyQ QPR:$Vn),3188 (TyQ (ExtOp (TyD DPR:$Vm)))))]> {3189 // All of these have a two-operand InstAlias.3190 let TwoOperandAliasConstraint = "$Vn = $Vd";3191 let isCommutable = Commutable;3192}3193 3194// Pairwise long 2-register intrinsics, both double- and quad-register.3195class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,3196 bits<2> op17_16, bits<5> op11_7, bit op4,3197 string OpcodeStr, string Dt,3198 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3199 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),3200 (ins DPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",3201 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;3202class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,3203 bits<2> op17_16, bits<5> op11_7, bit op4,3204 string OpcodeStr, string Dt,3205 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3206 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),3207 (ins QPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",3208 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;3209 3210// Pairwise long 2-register accumulate intrinsics,3211// both double- and quad-register.3212// The destination register is also used as the first source operand register.3213class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,3214 bits<2> op17_16, bits<5> op11_7, bit op4,3215 string OpcodeStr, string Dt,3216 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3217 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,3218 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vm), IIC_VPALiD,3219 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",3220 [(set DPR:$Vd, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$Vm))))]>;3221class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,3222 bits<2> op17_16, bits<5> op11_7, bit op4,3223 string OpcodeStr, string Dt,3224 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>3225 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4,3226 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vm), IIC_VPALiQ,3227 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",3228 [(set QPR:$Vd, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$Vm))))]>;3229 3230// Shift by immediate,3231// both double- and quad-register.3232let TwoOperandAliasConstraint = "$Vm = $Vd" in {3233class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3234 Format f, InstrItinClass itin, Operand ImmTy,3235 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>3236 : N2VImm<op24, op23, op11_8, op7, 0, op4,3237 (outs DPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), f, itin,3238 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3239 [(set DPR:$Vd, (Ty (OpNode (Ty DPR:$Vm), (i32 imm:$SIMM))))]>;3240class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3241 Format f, InstrItinClass itin, Operand ImmTy,3242 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>3243 : N2VImm<op24, op23, op11_8, op7, 1, op4,3244 (outs QPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), f, itin,3245 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3246 [(set QPR:$Vd, (Ty (OpNode (Ty QPR:$Vm), (i32 imm:$SIMM))))]>;3247}3248 3249// Long shift by immediate.3250class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,3251 string OpcodeStr, string Dt,3252 ValueType ResTy, ValueType OpTy, Operand ImmTy,3253 SDPatternOperator OpNode>3254 : N2VImm<op24, op23, op11_8, op7, op6, op4,3255 (outs QPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), N2RegVShLFrm,3256 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3257 [(set QPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm), ImmTy:$SIMM)))]>;3258 3259// Narrow shift by immediate.3260class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,3261 InstrItinClass itin, string OpcodeStr, string Dt,3262 ValueType ResTy, ValueType OpTy, Operand ImmTy,3263 SDPatternOperator OpNode>3264 : N2VImm<op24, op23, op11_8, op7, op6, op4,3265 (outs DPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, itin,3266 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3267 [(set DPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm),3268 (i32 ImmTy:$SIMM))))]>;3269 3270// Shift right by immediate and accumulate,3271// both double- and quad-register.3272let TwoOperandAliasConstraint = "$Vm = $Vd" in {3273class N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3274 Operand ImmTy, string OpcodeStr, string Dt,3275 ValueType Ty, SDNode ShOp>3276 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),3277 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,3278 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",3279 [(set DPR:$Vd, (Ty (add DPR:$src1,3280 (Ty (ShOp DPR:$Vm, (i32 imm:$SIMM))))))]>;3281class N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3282 Operand ImmTy, string OpcodeStr, string Dt,3283 ValueType Ty, SDNode ShOp>3284 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),3285 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,3286 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",3287 [(set QPR:$Vd, (Ty (add QPR:$src1,3288 (Ty (ShOp QPR:$Vm, (i32 imm:$SIMM))))))]>;3289}3290 3291// Shift by immediate and insert,3292// both double- and quad-register.3293let TwoOperandAliasConstraint = "$Vm = $Vd" in {3294class N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3295 Operand ImmTy, Format f, string OpcodeStr, string Dt,3296 ValueType Ty,SDNode ShOp>3297 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),3298 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiD,3299 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",3300 [(set DPR:$Vd, (Ty (ShOp DPR:$src1, DPR:$Vm, (i32 imm:$SIMM))))]>;3301class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3302 Operand ImmTy, Format f, string OpcodeStr, string Dt,3303 ValueType Ty,SDNode ShOp>3304 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),3305 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiQ,3306 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",3307 [(set QPR:$Vd, (Ty (ShOp QPR:$src1, QPR:$Vm, (i32 imm:$SIMM))))]>;3308}3309 3310// Convert, with fractional bits immediate,3311// both double- and quad-register.3312class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3313 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,3314 SDPatternOperator IntOp>3315 : N2VImm<op24, op23, op11_8, op7, 0, op4,3316 (outs DPR:$Vd), (ins DPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,3317 IIC_VUNAD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3318 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (i32 imm:$SIMM))))]>;3319class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,3320 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,3321 SDPatternOperator IntOp>3322 : N2VImm<op24, op23, op11_8, op7, 1, op4,3323 (outs QPR:$Vd), (ins QPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,3324 IIC_VUNAQ, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",3325 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (i32 imm:$SIMM))))]>;3326 3327//===----------------------------------------------------------------------===//3328// Multiclasses3329//===----------------------------------------------------------------------===//3330 3331// Abbreviations used in multiclass suffixes:3332// Q = quarter int (8 bit) elements3333// H = half int (16 bit) elements3334// S = single int (32 bit) elements3335// D = double int (64 bit) elements3336 3337// Neon 2-register vector operations and intrinsics.3338 3339// Neon 2-register comparisons.3340// source operand element sizes of 8, 16 and 32 bits:3341multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,3342 bits<5> op11_7, bit op4, string opc, string Dt,3343 string asm, PatFrag fc> {3344 // 64-bit vector types.3345 def v8i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4,3346 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,3347 opc, !strconcat(Dt, "8"), asm, "",3348 [(set DPR:$Vd, (v8i8 (ARMvcmpz (v8i8 DPR:$Vm), fc)))]>;3349 def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,3350 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,3351 opc, !strconcat(Dt, "16"), asm, "",3352 [(set DPR:$Vd, (v4i16 (ARMvcmpz (v4i16 DPR:$Vm), fc)))]>;3353 def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,3354 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,3355 opc, !strconcat(Dt, "32"), asm, "",3356 [(set DPR:$Vd, (v2i32 (ARMvcmpz (v2i32 DPR:$Vm), fc)))]>;3357 def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,3358 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,3359 opc, "f32", asm, "",3360 [(set DPR:$Vd, (v2i32 (ARMvcmpz (v2f32 DPR:$Vm), fc)))]> {3361 let Inst{10} = 1; // overwrite F = 13362 }3363 def v4f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,3364 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,3365 opc, "f16", asm, "",3366 [(set DPR:$Vd, (v4i16 (ARMvcmpz (v4f16 DPR:$Vm), fc)))]>,3367 Requires<[HasNEON,HasFullFP16]> {3368 let Inst{10} = 1; // overwrite F = 13369 }3370 3371 // 128-bit vector types.3372 def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4,3373 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,3374 opc, !strconcat(Dt, "8"), asm, "",3375 [(set QPR:$Vd, (v16i8 (ARMvcmpz (v16i8 QPR:$Vm), fc)))]>;3376 def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,3377 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,3378 opc, !strconcat(Dt, "16"), asm, "",3379 [(set QPR:$Vd, (v8i16 (ARMvcmpz (v8i16 QPR:$Vm), fc)))]>;3380 def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,3381 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,3382 opc, !strconcat(Dt, "32"), asm, "",3383 [(set QPR:$Vd, (v4i32 (ARMvcmpz (v4i32 QPR:$Vm), fc)))]>;3384 def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,3385 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,3386 opc, "f32", asm, "",3387 [(set QPR:$Vd, (v4i32 (ARMvcmpz (v4f32 QPR:$Vm), fc)))]> {3388 let Inst{10} = 1; // overwrite F = 13389 }3390 def v8f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,3391 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,3392 opc, "f16", asm, "",3393 [(set QPR:$Vd, (v8i16 (ARMvcmpz (v8f16 QPR:$Vm), fc)))]>,3394 Requires<[HasNEON,HasFullFP16]> {3395 let Inst{10} = 1; // overwrite F = 13396 }3397}3398 3399// Neon 3-register comparisons.3400class N3VQ_cmp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3401 InstrItinClass itin, string OpcodeStr, string Dt,3402 ValueType ResTy, ValueType OpTy, PatFrag fc, bit Commutable>3403 : N3V<op24, op23, op21_20, op11_8, 1, op4,3404 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,3405 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3406 [(set QPR:$Vd, (ResTy (ARMvcmp (OpTy QPR:$Vn), (OpTy QPR:$Vm), fc)))]> {3407 // All of these have a two-operand InstAlias.3408 let TwoOperandAliasConstraint = "$Vn = $Vd";3409 let isCommutable = Commutable;3410}3411 3412class N3VD_cmp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,3413 InstrItinClass itin, string OpcodeStr, string Dt,3414 ValueType ResTy, ValueType OpTy, PatFrag fc, bit Commutable>3415 : N3V<op24, op23, op21_20, op11_8, 0, op4,3416 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,3417 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",3418 [(set DPR:$Vd, (ResTy (ARMvcmp (OpTy DPR:$Vn), (OpTy DPR:$Vm), fc)))]> {3419 // All of these have a two-operand InstAlias.3420 let TwoOperandAliasConstraint = "$Vn = $Vd";3421 let isCommutable = Commutable;3422}3423 3424multiclass N3V_QHS_cmp<bit op24, bit op23, bits<4> op11_8, bit op4,3425 InstrItinClass itinD16, InstrItinClass itinD32,3426 InstrItinClass itinQ16, InstrItinClass itinQ32,3427 string OpcodeStr, string Dt,3428 PatFrag fc, bit Commutable = 0> {3429 // 64-bit vector types.3430 def v8i8 : N3VD_cmp<op24, op23, 0b00, op11_8, op4, itinD16,3431 OpcodeStr, !strconcat(Dt, "8"),3432 v8i8, v8i8, fc, Commutable>;3433 def v4i16 : N3VD_cmp<op24, op23, 0b01, op11_8, op4, itinD16,3434 OpcodeStr, !strconcat(Dt, "16"),3435 v4i16, v4i16, fc, Commutable>;3436 def v2i32 : N3VD_cmp<op24, op23, 0b10, op11_8, op4, itinD32,3437 OpcodeStr, !strconcat(Dt, "32"),3438 v2i32, v2i32, fc, Commutable>;3439 3440 // 128-bit vector types.3441 def v16i8 : N3VQ_cmp<op24, op23, 0b00, op11_8, op4, itinQ16,3442 OpcodeStr, !strconcat(Dt, "8"),3443 v16i8, v16i8, fc, Commutable>;3444 def v8i16 : N3VQ_cmp<op24, op23, 0b01, op11_8, op4, itinQ16,3445 OpcodeStr, !strconcat(Dt, "16"),3446 v8i16, v8i16, fc, Commutable>;3447 def v4i32 : N3VQ_cmp<op24, op23, 0b10, op11_8, op4, itinQ32,3448 OpcodeStr, !strconcat(Dt, "32"),3449 v4i32, v4i32, fc, Commutable>;3450}3451 3452 3453// Neon 2-register vector intrinsics,3454// element sizes of 8, 16 and 32 bits:3455multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,3456 bits<5> op11_7, bit op4,3457 InstrItinClass itinD, InstrItinClass itinQ,3458 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3459 // 64-bit vector types.3460 def v8i8 : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,3461 itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;3462 def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,3463 itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>;3464 def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,3465 itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>;3466 3467 // 128-bit vector types.3468 def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,3469 itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>;3470 def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,3471 itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>;3472 def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,3473 itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>;3474}3475 3476 3477// Neon Narrowing 2-register vector operations,3478// source operand element sizes of 16, 32 and 64 bits:3479multiclass N2VN_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,3480 bits<5> op11_7, bit op6, bit op4,3481 InstrItinClass itin, string OpcodeStr, string Dt,3482 SDNode OpNode> {3483 def v8i8 : N2VN<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,3484 itin, OpcodeStr, !strconcat(Dt, "16"),3485 v8i8, v8i16, OpNode>;3486 def v4i16 : N2VN<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,3487 itin, OpcodeStr, !strconcat(Dt, "32"),3488 v4i16, v4i32, OpNode>;3489 def v2i32 : N2VN<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,3490 itin, OpcodeStr, !strconcat(Dt, "64"),3491 v2i32, v2i64, OpNode>;3492}3493 3494// Neon Narrowing 2-register vector intrinsics,3495// source operand element sizes of 16, 32 and 64 bits:3496multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,3497 bits<5> op11_7, bit op6, bit op4,3498 InstrItinClass itin, string OpcodeStr, string Dt,3499 SDPatternOperator IntOp> {3500 def v8i8 : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,3501 itin, OpcodeStr, !strconcat(Dt, "16"),3502 v8i8, v8i16, IntOp>;3503 def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,3504 itin, OpcodeStr, !strconcat(Dt, "32"),3505 v4i16, v4i32, IntOp>;3506 def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,3507 itin, OpcodeStr, !strconcat(Dt, "64"),3508 v2i32, v2i64, IntOp>;3509}3510 3511 3512// Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL).3513// source operand element sizes of 16, 32 and 64 bits:3514multiclass N2VL_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4,3515 string OpcodeStr, string Dt, SDNode OpNode> {3516 def v8i16 : N2VL<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD,3517 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode>;3518 def v4i32 : N2VL<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,3519 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;3520 def v2i64 : N2VL<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,3521 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;3522}3523 3524 3525// Neon 3-register vector operations.3526 3527// First with only element sizes of 8, 16 and 32 bits:3528multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3529 InstrItinClass itinD16, InstrItinClass itinD32,3530 InstrItinClass itinQ16, InstrItinClass itinQ32,3531 string OpcodeStr, string Dt,3532 SDNode OpNode, bit Commutable = 0> {3533 // 64-bit vector types.3534 def v8i8 : N3VD<op24, op23, 0b00, op11_8, op4, itinD16,3535 OpcodeStr, !strconcat(Dt, "8"),3536 v8i8, v8i8, OpNode, Commutable>;3537 def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16,3538 OpcodeStr, !strconcat(Dt, "16"),3539 v4i16, v4i16, OpNode, Commutable>;3540 def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32,3541 OpcodeStr, !strconcat(Dt, "32"),3542 v2i32, v2i32, OpNode, Commutable>;3543 3544 // 128-bit vector types.3545 def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16,3546 OpcodeStr, !strconcat(Dt, "8"),3547 v16i8, v16i8, OpNode, Commutable>;3548 def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16,3549 OpcodeStr, !strconcat(Dt, "16"),3550 v8i16, v8i16, OpNode, Commutable>;3551 def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32,3552 OpcodeStr, !strconcat(Dt, "32"),3553 v4i32, v4i32, OpNode, Commutable>;3554}3555 3556multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, SDNode ShOp> {3557 def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, "i16", v4i16, ShOp>;3558 def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, "i32", v2i32, ShOp>;3559 def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, "i16", v8i16, v4i16, ShOp>;3560 def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, "i32",3561 v4i32, v2i32, ShOp>;3562}3563 3564// ....then also with element size 64 bits:3565multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,3566 InstrItinClass itinD, InstrItinClass itinQ,3567 string OpcodeStr, string Dt,3568 SDNode OpNode, bit Commutable = 0>3569 : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ,3570 OpcodeStr, Dt, OpNode, Commutable> {3571 def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD,3572 OpcodeStr, !strconcat(Dt, "64"),3573 v1i64, v1i64, OpNode, Commutable>;3574 def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ,3575 OpcodeStr, !strconcat(Dt, "64"),3576 v2i64, v2i64, OpNode, Commutable>;3577}3578 3579 3580// Neon 3-register vector intrinsics.3581 3582// First with only element sizes of 16 and 32 bits:3583multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3584 InstrItinClass itinD16, InstrItinClass itinD32,3585 InstrItinClass itinQ16, InstrItinClass itinQ32,3586 string OpcodeStr, string Dt,3587 SDPatternOperator IntOp, bit Commutable = 0> {3588 // 64-bit vector types.3589 def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, f, itinD16,3590 OpcodeStr, !strconcat(Dt, "16"),3591 v4i16, v4i16, IntOp, Commutable>;3592 def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, f, itinD32,3593 OpcodeStr, !strconcat(Dt, "32"),3594 v2i32, v2i32, IntOp, Commutable>;3595 3596 // 128-bit vector types.3597 def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, f, itinQ16,3598 OpcodeStr, !strconcat(Dt, "16"),3599 v8i16, v8i16, IntOp, Commutable>;3600 def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, f, itinQ32,3601 OpcodeStr, !strconcat(Dt, "32"),3602 v4i32, v4i32, IntOp, Commutable>;3603}3604multiclass N3VInt_HSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3605 InstrItinClass itinD16, InstrItinClass itinD32,3606 InstrItinClass itinQ16, InstrItinClass itinQ32,3607 string OpcodeStr, string Dt,3608 SDPatternOperator IntOp> {3609 // 64-bit vector types.3610 def v4i16 : N3VDIntSh<op24, op23, 0b01, op11_8, op4, f, itinD16,3611 OpcodeStr, !strconcat(Dt, "16"),3612 v4i16, v4i16, IntOp>;3613 def v2i32 : N3VDIntSh<op24, op23, 0b10, op11_8, op4, f, itinD32,3614 OpcodeStr, !strconcat(Dt, "32"),3615 v2i32, v2i32, IntOp>;3616 3617 // 128-bit vector types.3618 def v8i16 : N3VQIntSh<op24, op23, 0b01, op11_8, op4, f, itinQ16,3619 OpcodeStr, !strconcat(Dt, "16"),3620 v8i16, v8i16, IntOp>;3621 def v4i32 : N3VQIntSh<op24, op23, 0b10, op11_8, op4, f, itinQ32,3622 OpcodeStr, !strconcat(Dt, "32"),3623 v4i32, v4i32, IntOp>;3624}3625 3626multiclass N3VIntSL_HS<bits<4> op11_8,3627 InstrItinClass itinD16, InstrItinClass itinD32,3628 InstrItinClass itinQ16, InstrItinClass itinQ32,3629 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3630 def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16,3631 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>;3632 def v2i32 : N3VDIntSL<0b10, op11_8, itinD32,3633 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>;3634 def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16,3635 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;3636 def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32,3637 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>;3638}3639 3640// ....then also with element size of 8 bits:3641multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3642 InstrItinClass itinD16, InstrItinClass itinD32,3643 InstrItinClass itinQ16, InstrItinClass itinQ32,3644 string OpcodeStr, string Dt,3645 SDPatternOperator IntOp, bit Commutable = 0>3646 : N3VInt_HS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,3647 OpcodeStr, Dt, IntOp, Commutable> {3648 def v8i8 : N3VDInt<op24, op23, 0b00, op11_8, op4, f, itinD16,3649 OpcodeStr, !strconcat(Dt, "8"),3650 v8i8, v8i8, IntOp, Commutable>;3651 def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, f, itinQ16,3652 OpcodeStr, !strconcat(Dt, "8"),3653 v16i8, v16i8, IntOp, Commutable>;3654}3655multiclass N3VInt_QHSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3656 InstrItinClass itinD16, InstrItinClass itinD32,3657 InstrItinClass itinQ16, InstrItinClass itinQ32,3658 string OpcodeStr, string Dt,3659 SDPatternOperator IntOp>3660 : N3VInt_HSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,3661 OpcodeStr, Dt, IntOp> {3662 def v8i8 : N3VDIntSh<op24, op23, 0b00, op11_8, op4, f, itinD16,3663 OpcodeStr, !strconcat(Dt, "8"),3664 v8i8, v8i8, IntOp>;3665 def v16i8 : N3VQIntSh<op24, op23, 0b00, op11_8, op4, f, itinQ16,3666 OpcodeStr, !strconcat(Dt, "8"),3667 v16i8, v16i8, IntOp>;3668}3669 3670 3671// ....then also with element size of 64 bits:3672multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3673 InstrItinClass itinD16, InstrItinClass itinD32,3674 InstrItinClass itinQ16, InstrItinClass itinQ32,3675 string OpcodeStr, string Dt,3676 SDPatternOperator IntOp, bit Commutable = 0>3677 : N3VInt_QHS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,3678 OpcodeStr, Dt, IntOp, Commutable> {3679 def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, f, itinD32,3680 OpcodeStr, !strconcat(Dt, "64"),3681 v1i64, v1i64, IntOp, Commutable>;3682 def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, f, itinQ32,3683 OpcodeStr, !strconcat(Dt, "64"),3684 v2i64, v2i64, IntOp, Commutable>;3685}3686multiclass N3VInt_QHSDSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,3687 InstrItinClass itinD16, InstrItinClass itinD32,3688 InstrItinClass itinQ16, InstrItinClass itinQ32,3689 string OpcodeStr, string Dt,3690 SDPatternOperator IntOp>3691 : N3VInt_QHSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,3692 OpcodeStr, Dt, IntOp> {3693 def v1i64 : N3VDIntSh<op24, op23, 0b11, op11_8, op4, f, itinD32,3694 OpcodeStr, !strconcat(Dt, "64"),3695 v1i64, v1i64, IntOp>;3696 def v2i64 : N3VQIntSh<op24, op23, 0b11, op11_8, op4, f, itinQ32,3697 OpcodeStr, !strconcat(Dt, "64"),3698 v2i64, v2i64, IntOp>;3699}3700 3701// Neon Narrowing 3-register vector intrinsics,3702// source operand element sizes of 16, 32 and 64 bits:3703multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4,3704 string OpcodeStr, string Dt,3705 SDPatternOperator IntOp, bit Commutable = 0> {3706 def v8i8 : N3VNInt<op24, op23, 0b00, op11_8, op4,3707 OpcodeStr, !strconcat(Dt, "16"),3708 v8i8, v8i16, IntOp, Commutable>;3709 def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4,3710 OpcodeStr, !strconcat(Dt, "32"),3711 v4i16, v4i32, IntOp, Commutable>;3712 def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4,3713 OpcodeStr, !strconcat(Dt, "64"),3714 v2i32, v2i64, IntOp, Commutable>;3715}3716 3717 3718// Neon Long 3-register vector operations.3719 3720multiclass N3VL_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3721 InstrItinClass itin16, InstrItinClass itin32,3722 string OpcodeStr, string Dt,3723 SDNode OpNode, bit Commutable = 0> {3724 def v8i16 : N3VL<op24, op23, 0b00, op11_8, op4, itin16,3725 OpcodeStr, !strconcat(Dt, "8"),3726 v8i16, v8i8, OpNode, Commutable>;3727 def v4i32 : N3VL<op24, op23, 0b01, op11_8, op4, itin16,3728 OpcodeStr, !strconcat(Dt, "16"),3729 v4i32, v4i16, OpNode, Commutable>;3730 def v2i64 : N3VL<op24, op23, 0b10, op11_8, op4, itin32,3731 OpcodeStr, !strconcat(Dt, "32"),3732 v2i64, v2i32, OpNode, Commutable>;3733}3734 3735multiclass N3VLSL_HS<bit op24, bits<4> op11_8,3736 InstrItinClass itin, string OpcodeStr, string Dt,3737 SDNode OpNode> {3738 def v4i16 : N3VLSL16<op24, 0b01, op11_8, itin, OpcodeStr,3739 !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;3740 def v2i32 : N3VLSL<op24, 0b10, op11_8, itin, OpcodeStr,3741 !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;3742}3743 3744multiclass N3VLExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3745 InstrItinClass itin16, InstrItinClass itin32,3746 string OpcodeStr, string Dt,3747 SDNode OpNode, SDPatternOperator ExtOp, bit Commutable = 0> {3748 def v8i16 : N3VLExt<op24, op23, 0b00, op11_8, op4, itin16,3749 OpcodeStr, !strconcat(Dt, "8"),3750 v8i16, v8i8, OpNode, ExtOp, Commutable>;3751 def v4i32 : N3VLExt<op24, op23, 0b01, op11_8, op4, itin16,3752 OpcodeStr, !strconcat(Dt, "16"),3753 v4i32, v4i16, OpNode, ExtOp, Commutable>;3754 def v2i64 : N3VLExt<op24, op23, 0b10, op11_8, op4, itin32,3755 OpcodeStr, !strconcat(Dt, "32"),3756 v2i64, v2i32, OpNode, ExtOp, Commutable>;3757}3758 3759// Neon Long 3-register vector intrinsics.3760 3761// First with only element sizes of 16 and 32 bits:3762multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4,3763 InstrItinClass itin16, InstrItinClass itin32,3764 string OpcodeStr, string Dt,3765 SDPatternOperator IntOp, bit Commutable = 0> {3766 def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin16,3767 OpcodeStr, !strconcat(Dt, "16"),3768 v4i32, v4i16, IntOp, Commutable>;3769 def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin32,3770 OpcodeStr, !strconcat(Dt, "32"),3771 v2i64, v2i32, IntOp, Commutable>;3772}3773 3774multiclass N3VLIntSL_HS<bit op24, bits<4> op11_8,3775 InstrItinClass itin, string OpcodeStr, string Dt,3776 SDPatternOperator IntOp> {3777 def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin,3778 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;3779 def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin,3780 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;3781}3782 3783// ....then also with element size of 8 bits:3784multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3785 InstrItinClass itin16, InstrItinClass itin32,3786 string OpcodeStr, string Dt,3787 SDPatternOperator IntOp, bit Commutable = 0>3788 : N3VLInt_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt,3789 IntOp, Commutable> {3790 def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin16,3791 OpcodeStr, !strconcat(Dt, "8"),3792 v8i16, v8i8, IntOp, Commutable>;3793}3794 3795// ....with explicit extend (VABDL).3796multiclass N3VLIntExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3797 InstrItinClass itin, string OpcodeStr, string Dt,3798 SDPatternOperator IntOp, SDNode ExtOp, bit Commutable = 0> {3799 def v8i16 : N3VLIntExt<op24, op23, 0b00, op11_8, op4, itin,3800 OpcodeStr, !strconcat(Dt, "8"),3801 v8i16, v8i8, IntOp, ExtOp, Commutable>;3802 def v4i32 : N3VLIntExt<op24, op23, 0b01, op11_8, op4, itin,3803 OpcodeStr, !strconcat(Dt, "16"),3804 v4i32, v4i16, IntOp, ExtOp, Commutable>;3805 def v2i64 : N3VLIntExt<op24, op23, 0b10, op11_8, op4, itin,3806 OpcodeStr, !strconcat(Dt, "32"),3807 v2i64, v2i32, IntOp, ExtOp, Commutable>;3808}3809 3810 3811// Neon Wide 3-register vector intrinsics,3812// source operand element sizes of 8, 16 and 32 bits:3813multiclass N3VW_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3814 string OpcodeStr, string Dt,3815 SDNode OpNode, SDPatternOperator ExtOp, bit Commutable = 0> {3816 def v8i16 : N3VW<op24, op23, 0b00, op11_8, op4,3817 OpcodeStr, !strconcat(Dt, "8"),3818 v8i16, v8i8, OpNode, ExtOp, Commutable>;3819 def v4i32 : N3VW<op24, op23, 0b01, op11_8, op4,3820 OpcodeStr, !strconcat(Dt, "16"),3821 v4i32, v4i16, OpNode, ExtOp, Commutable>;3822 def v2i64 : N3VW<op24, op23, 0b10, op11_8, op4,3823 OpcodeStr, !strconcat(Dt, "32"),3824 v2i64, v2i32, OpNode, ExtOp, Commutable>;3825}3826 3827 3828// Neon Multiply-Op vector operations,3829// element sizes of 8, 16 and 32 bits:3830multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3831 InstrItinClass itinD16, InstrItinClass itinD32,3832 InstrItinClass itinQ16, InstrItinClass itinQ32,3833 string OpcodeStr, string Dt, SDNode OpNode> {3834 // 64-bit vector types.3835 def v8i8 : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16,3836 OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>;3837 def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16,3838 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>;3839 def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32,3840 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>;3841 3842 // 128-bit vector types.3843 def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16,3844 OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>;3845 def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16,3846 OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>;3847 def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32,3848 OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>;3849}3850 3851multiclass N3VMulOpSL_HS<bits<4> op11_8,3852 InstrItinClass itinD16, InstrItinClass itinD32,3853 InstrItinClass itinQ16, InstrItinClass itinQ32,3854 string OpcodeStr, string Dt, SDPatternOperator ShOp> {3855 def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16,3856 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>;3857 def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,3858 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>;3859 def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16,3860 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16,3861 mul, ShOp>;3862 def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32,3863 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32,3864 mul, ShOp>;3865}3866 3867// Neon Intrinsic-Op vector operations,3868// element sizes of 8, 16 and 32 bits:3869multiclass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3870 InstrItinClass itinD, InstrItinClass itinQ,3871 string OpcodeStr, string Dt, SDPatternOperator IntOp,3872 SDNode OpNode> {3873 // 64-bit vector types.3874 def v8i8 : N3VDIntOp<op24, op23, 0b00, op11_8, op4, itinD,3875 OpcodeStr, !strconcat(Dt, "8"), v8i8, IntOp, OpNode>;3876 def v4i16 : N3VDIntOp<op24, op23, 0b01, op11_8, op4, itinD,3877 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp, OpNode>;3878 def v2i32 : N3VDIntOp<op24, op23, 0b10, op11_8, op4, itinD,3879 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp, OpNode>;3880 3881 // 128-bit vector types.3882 def v16i8 : N3VQIntOp<op24, op23, 0b00, op11_8, op4, itinQ,3883 OpcodeStr, !strconcat(Dt, "8"), v16i8, IntOp, OpNode>;3884 def v8i16 : N3VQIntOp<op24, op23, 0b01, op11_8, op4, itinQ,3885 OpcodeStr, !strconcat(Dt, "16"), v8i16, IntOp, OpNode>;3886 def v4i32 : N3VQIntOp<op24, op23, 0b10, op11_8, op4, itinQ,3887 OpcodeStr, !strconcat(Dt, "32"), v4i32, IntOp, OpNode>;3888}3889 3890// Neon 3-argument intrinsics,3891// element sizes of 16 and 32 bits:3892multiclass N3VInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,3893 InstrItinClass itinD16, InstrItinClass itinD32,3894 InstrItinClass itinQ16, InstrItinClass itinQ32,3895 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3896 // 64-bit vector types.3897 def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD16,3898 OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;3899 def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD32,3900 OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;3901 3902 // 128-bit vector types.3903 def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ16,3904 OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;3905 def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ32,3906 OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;3907}3908 3909// element sizes of 8, 16 and 32 bits:3910multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3911 InstrItinClass itinD16, InstrItinClass itinD32,3912 InstrItinClass itinQ16, InstrItinClass itinQ32,3913 string OpcodeStr, string Dt, SDPatternOperator IntOp>3914 :N3VInt3_HS <op24, op23, op11_8, op4, itinD16, itinD32,3915 itinQ16, itinQ32, OpcodeStr, Dt, IntOp>{3916 // 64-bit vector types.3917 def v8i8 : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD16,3918 OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;3919 // 128-bit vector types.3920 def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ16,3921 OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;3922}3923 3924// Neon Long Multiply-Op vector operations,3925// element sizes of 8, 16 and 32 bits:3926multiclass N3VLMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3927 InstrItinClass itin16, InstrItinClass itin32,3928 string OpcodeStr, string Dt, SDNode MulOp,3929 SDNode OpNode> {3930 def v8i16 : N3VLMulOp<op24, op23, 0b00, op11_8, op4, itin16, OpcodeStr,3931 !strconcat(Dt, "8"), v8i16, v8i8, MulOp, OpNode>;3932 def v4i32 : N3VLMulOp<op24, op23, 0b01, op11_8, op4, itin16, OpcodeStr,3933 !strconcat(Dt, "16"), v4i32, v4i16, MulOp, OpNode>;3934 def v2i64 : N3VLMulOp<op24, op23, 0b10, op11_8, op4, itin32, OpcodeStr,3935 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;3936}3937 3938multiclass N3VLMulOpSL_HS<bit op24, bits<4> op11_8, string OpcodeStr,3939 string Dt, SDNode MulOp, SDNode OpNode> {3940 def v4i16 : N3VLMulOpSL16<op24, 0b01, op11_8, IIC_VMACi16D, OpcodeStr,3941 !strconcat(Dt,"16"), v4i32, v4i16, MulOp, OpNode>;3942 def v2i32 : N3VLMulOpSL<op24, 0b10, op11_8, IIC_VMACi32D, OpcodeStr,3943 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;3944}3945 3946 3947// Neon Long 3-argument intrinsics.3948 3949// First with only element sizes of 16 and 32 bits:3950multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,3951 InstrItinClass itin16, InstrItinClass itin32,3952 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3953 def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, itin16,3954 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;3955 def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, itin32,3956 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;3957}3958 3959multiclass N3VLInt3SL_HS<bit op24, bits<4> op11_8,3960 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3961 def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D,3962 OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>;3963 def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D,3964 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;3965}3966 3967// ....then also with element size of 8 bits:3968multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3969 InstrItinClass itin16, InstrItinClass itin32,3970 string OpcodeStr, string Dt, SDPatternOperator IntOp>3971 : N3VLInt3_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, IntOp> {3972 def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, itin16,3973 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>;3974}3975 3976// ....with explicit extend (VABAL).3977multiclass N3VLIntExtOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,3978 InstrItinClass itin, string OpcodeStr, string Dt,3979 SDPatternOperator IntOp, SDNode ExtOp, SDNode OpNode> {3980 def v8i16 : N3VLIntExtOp<op24, op23, 0b00, op11_8, op4, itin,3981 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8,3982 IntOp, ExtOp, OpNode>;3983 def v4i32 : N3VLIntExtOp<op24, op23, 0b01, op11_8, op4, itin,3984 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16,3985 IntOp, ExtOp, OpNode>;3986 def v2i64 : N3VLIntExtOp<op24, op23, 0b10, op11_8, op4, itin,3987 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32,3988 IntOp, ExtOp, OpNode>;3989}3990 3991 3992// Neon Pairwise long 2-register intrinsics,3993// element sizes of 8, 16 and 32 bits:3994multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,3995 bits<5> op11_7, bit op4,3996 string OpcodeStr, string Dt, SDPatternOperator IntOp> {3997 // 64-bit vector types.3998 def v8i8 : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,3999 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;4000 def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,4001 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;4002 def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,4003 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;4004 4005 // 128-bit vector types.4006 def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,4007 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;4008 def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,4009 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;4010 def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,4011 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;4012}4013 4014 4015// Neon Pairwise long 2-register accumulate intrinsics,4016// element sizes of 8, 16 and 32 bits:4017multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,4018 bits<5> op11_7, bit op4,4019 string OpcodeStr, string Dt, SDPatternOperator IntOp> {4020 // 64-bit vector types.4021 def v8i8 : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,4022 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;4023 def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,4024 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;4025 def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,4026 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;4027 4028 // 128-bit vector types.4029 def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,4030 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;4031 def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,4032 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;4033 def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,4034 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;4035}4036 4037 4038// Neon 2-register vector shift by immediate,4039// with f of either N2RegVShLFrm or N2RegVShRFrm4040// element sizes of 8, 16, 32 and 64 bits:4041multiclass N2VShL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,4042 InstrItinClass itin, string OpcodeStr, string Dt,4043 SDNode OpNode> {4044 // 64-bit vector types.4045 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4046 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {4047 let Inst{21-19} = 0b001; // imm6 = 001xxx4048 }4049 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4050 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {4051 let Inst{21-20} = 0b01; // imm6 = 01xxxx4052 }4053 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4054 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {4055 let Inst{21} = 0b1; // imm6 = 1xxxxx4056 }4057 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,4058 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;4059 // imm6 = xxxxxx4060 4061 // 128-bit vector types.4062 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4063 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {4064 let Inst{21-19} = 0b001; // imm6 = 001xxx4065 }4066 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4067 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {4068 let Inst{21-20} = 0b01; // imm6 = 01xxxx4069 }4070 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,4071 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {4072 let Inst{21} = 0b1; // imm6 = 1xxxxx4073 }4074 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,4075 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;4076 // imm6 = xxxxxx4077}4078multiclass N2VShR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,4079 InstrItinClass itin, string OpcodeStr, string Dt,4080 SDNode OpNode> {4081 // 64-bit vector types.4082 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,4083 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {4084 let Inst{21-19} = 0b001; // imm6 = 001xxx4085 }4086 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,4087 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {4088 let Inst{21-20} = 0b01; // imm6 = 01xxxx4089 }4090 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,4091 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {4092 let Inst{21} = 0b1; // imm6 = 1xxxxx4093 }4094 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,4095 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;4096 // imm6 = xxxxxx4097 4098 // 128-bit vector types.4099 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,4100 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {4101 let Inst{21-19} = 0b001; // imm6 = 001xxx4102 }4103 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,4104 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {4105 let Inst{21-20} = 0b01; // imm6 = 01xxxx4106 }4107 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,4108 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {4109 let Inst{21} = 0b1; // imm6 = 1xxxxx4110 }4111 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,4112 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;4113 // imm6 = xxxxxx4114}4115 4116// Neon Shift-Accumulate vector operations,4117// element sizes of 8, 16, 32 and 64 bits:4118multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,4119 string OpcodeStr, string Dt, SDNode ShOp> {4120 // 64-bit vector types.4121 def v8i8 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm8,4122 OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> {4123 let Inst{21-19} = 0b001; // imm6 = 001xxx4124 }4125 def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm16,4126 OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> {4127 let Inst{21-20} = 0b01; // imm6 = 01xxxx4128 }4129 def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm32,4130 OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> {4131 let Inst{21} = 0b1; // imm6 = 1xxxxx4132 }4133 def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4, shr_imm64,4134 OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>;4135 // imm6 = xxxxxx4136 4137 // 128-bit vector types.4138 def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm8,4139 OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> {4140 let Inst{21-19} = 0b001; // imm6 = 001xxx4141 }4142 def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm16,4143 OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> {4144 let Inst{21-20} = 0b01; // imm6 = 01xxxx4145 }4146 def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm32,4147 OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> {4148 let Inst{21} = 0b1; // imm6 = 1xxxxx4149 }4150 def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4, shr_imm64,4151 OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>;4152 // imm6 = xxxxxx4153}4154 4155// Neon Shift-Insert vector operations,4156// with f of either N2RegVShLFrm or N2RegVShRFrm4157// element sizes of 8, 16, 32 and 64 bits:4158multiclass N2VShInsL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,4159 string OpcodeStr> {4160 // 64-bit vector types.4161 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,4162 N2RegVShLFrm, OpcodeStr, "8", v8i8, NEONvsliImm> {4163 let Inst{21-19} = 0b001; // imm6 = 001xxx4164 }4165 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,4166 N2RegVShLFrm, OpcodeStr, "16", v4i16, NEONvsliImm> {4167 let Inst{21-20} = 0b01; // imm6 = 01xxxx4168 }4169 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,4170 N2RegVShLFrm, OpcodeStr, "32", v2i32, NEONvsliImm> {4171 let Inst{21} = 0b1; // imm6 = 1xxxxx4172 }4173 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, i32imm,4174 N2RegVShLFrm, OpcodeStr, "64", v1i64, NEONvsliImm>;4175 // imm6 = xxxxxx4176 4177 // 128-bit vector types.4178 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,4179 N2RegVShLFrm, OpcodeStr, "8", v16i8, NEONvsliImm> {4180 let Inst{21-19} = 0b001; // imm6 = 001xxx4181 }4182 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,4183 N2RegVShLFrm, OpcodeStr, "16", v8i16, NEONvsliImm> {4184 let Inst{21-20} = 0b01; // imm6 = 01xxxx4185 }4186 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,4187 N2RegVShLFrm, OpcodeStr, "32", v4i32, NEONvsliImm> {4188 let Inst{21} = 0b1; // imm6 = 1xxxxx4189 }4190 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, i32imm,4191 N2RegVShLFrm, OpcodeStr, "64", v2i64, NEONvsliImm>;4192 // imm6 = xxxxxx4193}4194multiclass N2VShInsR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,4195 string OpcodeStr> {4196 // 64-bit vector types.4197 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm8,4198 N2RegVShRFrm, OpcodeStr, "8", v8i8, NEONvsriImm> {4199 let Inst{21-19} = 0b001; // imm6 = 001xxx4200 }4201 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm16,4202 N2RegVShRFrm, OpcodeStr, "16", v4i16, NEONvsriImm> {4203 let Inst{21-20} = 0b01; // imm6 = 01xxxx4204 }4205 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm32,4206 N2RegVShRFrm, OpcodeStr, "32", v2i32, NEONvsriImm> {4207 let Inst{21} = 0b1; // imm6 = 1xxxxx4208 }4209 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, shr_imm64,4210 N2RegVShRFrm, OpcodeStr, "64", v1i64, NEONvsriImm>;4211 // imm6 = xxxxxx4212 4213 // 128-bit vector types.4214 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm8,4215 N2RegVShRFrm, OpcodeStr, "8", v16i8, NEONvsriImm> {4216 let Inst{21-19} = 0b001; // imm6 = 001xxx4217 }4218 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm16,4219 N2RegVShRFrm, OpcodeStr, "16", v8i16, NEONvsriImm> {4220 let Inst{21-20} = 0b01; // imm6 = 01xxxx4221 }4222 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm32,4223 N2RegVShRFrm, OpcodeStr, "32", v4i32, NEONvsriImm> {4224 let Inst{21} = 0b1; // imm6 = 1xxxxx4225 }4226 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, shr_imm64,4227 N2RegVShRFrm, OpcodeStr, "64", v2i64, NEONvsriImm>;4228 // imm6 = xxxxxx4229}4230 4231// Neon Shift Long operations,4232// element sizes of 8, 16, 32 bits:4233multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,4234 bit op4, string OpcodeStr, string Dt,4235 SDPatternOperator OpNode> {4236 def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4,4237 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, imm1_7, OpNode> {4238 let Inst{21-19} = 0b001; // imm6 = 001xxx4239 }4240 def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4,4241 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, imm1_15, OpNode> {4242 let Inst{21-20} = 0b01; // imm6 = 01xxxx4243 }4244 def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4,4245 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, imm1_31, OpNode> {4246 let Inst{21} = 0b1; // imm6 = 1xxxxx4247 }4248}4249 4250// Neon Shift Narrow operations,4251// element sizes of 16, 32, 64 bits:4252multiclass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,4253 bit op4, InstrItinClass itin, string OpcodeStr, string Dt,4254 SDPatternOperator OpNode> {4255 def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,4256 OpcodeStr, !strconcat(Dt, "16"),4257 v8i8, v8i16, shr_imm8, OpNode> {4258 let Inst{21-19} = 0b001; // imm6 = 001xxx4259 }4260 def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,4261 OpcodeStr, !strconcat(Dt, "32"),4262 v4i16, v4i32, shr_imm16, OpNode> {4263 let Inst{21-20} = 0b01; // imm6 = 01xxxx4264 }4265 def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,4266 OpcodeStr, !strconcat(Dt, "64"),4267 v2i32, v2i64, shr_imm32, OpNode> {4268 let Inst{21} = 0b1; // imm6 = 1xxxxx4269 }4270}4271 4272//===----------------------------------------------------------------------===//4273// Instruction Definitions.4274//===----------------------------------------------------------------------===//4275 4276// Vector Add Operations.4277 4278// VADD : Vector Add (integer and floating-point)4279defm VADD : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i",4280 add, 1>;4281def VADDfd : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32",4282 v2f32, v2f32, fadd, 1>;4283def VADDfq : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32",4284 v4f32, v4f32, fadd, 1>;4285def VADDhd : N3VD<0, 0, 0b01, 0b1101, 0, IIC_VBIND, "vadd", "f16",4286 v4f16, v4f16, fadd, 1>,4287 Requires<[HasNEON,HasFullFP16]>;4288def VADDhq : N3VQ<0, 0, 0b01, 0b1101, 0, IIC_VBINQ, "vadd", "f16",4289 v8f16, v8f16, fadd, 1>,4290 Requires<[HasNEON,HasFullFP16]>;4291// VADDL : Vector Add Long (Q = D + D)4292defm VADDLs : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,4293 "vaddl", "s", add, sext, 1>;4294defm VADDLu : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,4295 "vaddl", "u", add, zanyext, 1>;4296// VADDW : Vector Add Wide (Q = Q + D)4297defm VADDWs : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>;4298defm VADDWu : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zanyext, 0>;4299// VHADD : Vector Halving Add4300defm VHADDs : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm,4301 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4302 "vhadd", "s", int_arm_neon_vhadds, 1>;4303defm VHADDu : N3VInt_QHS<1, 0, 0b0000, 0, N3RegFrm,4304 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4305 "vhadd", "u", int_arm_neon_vhaddu, 1>;4306// VRHADD : Vector Rounding Halving Add4307defm VRHADDs : N3VInt_QHS<0, 0, 0b0001, 0, N3RegFrm,4308 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4309 "vrhadd", "s", int_arm_neon_vrhadds, 1>;4310defm VRHADDu : N3VInt_QHS<1, 0, 0b0001, 0, N3RegFrm,4311 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4312 "vrhadd", "u", int_arm_neon_vrhaddu, 1>;4313// VQADD : Vector Saturating Add4314defm VQADDs : N3VInt_QHSD<0, 0, 0b0000, 1, N3RegFrm,4315 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4316 "vqadd", "s", saddsat, 1>;4317defm VQADDu : N3VInt_QHSD<1, 0, 0b0000, 1, N3RegFrm,4318 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,4319 "vqadd", "u", uaddsat, 1>;4320// VADDHN : Vector Add and Narrow Returning High Half (D = Q + Q)4321defm VADDHN : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i", null_frag, 1>;4322// VRADDHN : Vector Rounding Add and Narrow Returning High Half (D = Q + Q)4323defm VRADDHN : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i",4324 int_arm_neon_vraddhn, 1>;4325 4326let Predicates = [HasNEON] in {4327def : Pat<(v8i8 (trunc (ARMvshruImm (add (v8i16 QPR:$Vn), QPR:$Vm), 8))),4328 (VADDHNv8i8 QPR:$Vn, QPR:$Vm)>;4329def : Pat<(v4i16 (trunc (ARMvshruImm (add (v4i32 QPR:$Vn), QPR:$Vm), 16))),4330 (VADDHNv4i16 QPR:$Vn, QPR:$Vm)>;4331def : Pat<(v2i32 (trunc (ARMvshruImm (add (v2i64 QPR:$Vn), QPR:$Vm), 32))),4332 (VADDHNv2i32 QPR:$Vn, QPR:$Vm)>;4333}4334 4335// Vector Multiply Operations.4336 4337// VMUL : Vector Multiply (integer, polynomial and floating-point)4338defm VMUL : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D,4339 IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>;4340def VMULpd : N3VDInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16D, "vmul",4341 "p8", v8i8, v8i8, int_arm_neon_vmulp, 1>;4342def VMULpq : N3VQInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16Q, "vmul",4343 "p8", v16i8, v16i8, int_arm_neon_vmulp, 1>;4344def VMULfd : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VFMULD, "vmul", "f32",4345 v2f32, v2f32, fmul, 1>;4346def VMULfq : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VFMULQ, "vmul", "f32",4347 v4f32, v4f32, fmul, 1>;4348def VMULhd : N3VD<1, 0, 0b01, 0b1101, 1, IIC_VFMULD, "vmul", "f16",4349 v4f16, v4f16, fmul, 1>,4350 Requires<[HasNEON,HasFullFP16]>;4351def VMULhq : N3VQ<1, 0, 0b01, 0b1101, 1, IIC_VFMULQ, "vmul", "f16",4352 v8f16, v8f16, fmul, 1>,4353 Requires<[HasNEON,HasFullFP16]>;4354defm VMULsl : N3VSL_HS<0b1000, "vmul", mul>;4355def VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;4356def VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32,4357 v2f32, fmul>;4358def VMULslhd : N3VDSL16<0b01, 0b1001, "vmul", "f16", v4f16, fmul>,4359 Requires<[HasNEON,HasFullFP16]>;4360def VMULslhq : N3VQSL16<0b01, 0b1001, "vmul", "f16", v8f16,4361 v4f16, fmul>,4362 Requires<[HasNEON,HasFullFP16]>;4363 4364let Predicates = [HasNEON] in {4365def : Pat<(v8i16 (mul (v8i16 QPR:$src1),4366 (v8i16 (ARMvduplane (v8i16 QPR:$src2), imm:$lane)))),4367 (v8i16 (VMULslv8i16 (v8i16 QPR:$src1),4368 (v4i16 (EXTRACT_SUBREG QPR:$src2,4369 (DSubReg_i16_reg imm:$lane))),4370 (SubReg_i16_lane imm:$lane)))>;4371def : Pat<(v4i32 (mul (v4i32 QPR:$src1),4372 (v4i32 (ARMvduplane (v4i32 QPR:$src2), imm:$lane)))),4373 (v4i32 (VMULslv4i32 (v4i32 QPR:$src1),4374 (v2i32 (EXTRACT_SUBREG QPR:$src2,4375 (DSubReg_i32_reg imm:$lane))),4376 (SubReg_i32_lane imm:$lane)))>;4377def : Pat<(v4f32 (fmul (v4f32 QPR:$src1),4378 (v4f32 (ARMvduplane (v4f32 QPR:$src2), imm:$lane)))),4379 (v4f32 (VMULslfq (v4f32 QPR:$src1),4380 (v2f32 (EXTRACT_SUBREG QPR:$src2,4381 (DSubReg_i32_reg imm:$lane))),4382 (SubReg_i32_lane imm:$lane)))>;4383def : Pat<(v8f16 (fmul (v8f16 QPR:$src1),4384 (v8f16 (ARMvduplane (v8f16 QPR:$src2), imm:$lane)))),4385 (v8f16 (VMULslhq(v8f16 QPR:$src1),4386 (v4f16 (EXTRACT_SUBREG QPR:$src2,4387 (DSubReg_i16_reg imm:$lane))),4388 (SubReg_i16_lane imm:$lane)))>;4389 4390def : Pat<(v2f32 (fmul DPR:$Rn, (ARMvdup (f32 SPR:$Rm)))),4391 (VMULslfd DPR:$Rn,4392 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),4393 (i32 0))>;4394def : Pat<(v4f16 (fmul DPR:$Rn, (ARMvdup (f16 HPR:$Rm)))),4395 (VMULslhd DPR:$Rn,4396 (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), (f16 HPR:$Rm), ssub_0),4397 (i32 0))>;4398def : Pat<(v4f32 (fmul QPR:$Rn, (ARMvdup (f32 SPR:$Rm)))),4399 (VMULslfq QPR:$Rn,4400 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),4401 (i32 0))>;4402def : Pat<(v8f16 (fmul QPR:$Rn, (ARMvdup (f16 HPR:$Rm)))),4403 (VMULslhq QPR:$Rn,4404 (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), (f16 HPR:$Rm), ssub_0),4405 (i32 0))>;4406}4407 4408// VQDMULH : Vector Saturating Doubling Multiply Returning High Half4409defm VQDMULH : N3VInt_HS<0, 0, 0b1011, 0, N3RegFrm, IIC_VMULi16D, IIC_VMULi32D,4410 IIC_VMULi16Q, IIC_VMULi32Q,4411 "vqdmulh", "s", int_arm_neon_vqdmulh, 1>;4412defm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D,4413 IIC_VMULi16Q, IIC_VMULi32Q,4414 "vqdmulh", "s", int_arm_neon_vqdmulh>;4415 4416let Predicates = [HasNEON] in {4417def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1),4418 (v8i16 (ARMvduplane (v8i16 QPR:$src2),4419 imm:$lane)))),4420 (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1),4421 (v4i16 (EXTRACT_SUBREG QPR:$src2,4422 (DSubReg_i16_reg imm:$lane))),4423 (SubReg_i16_lane imm:$lane)))>;4424def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1),4425 (v4i32 (ARMvduplane (v4i32 QPR:$src2),4426 imm:$lane)))),4427 (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1),4428 (v2i32 (EXTRACT_SUBREG QPR:$src2,4429 (DSubReg_i32_reg imm:$lane))),4430 (SubReg_i32_lane imm:$lane)))>;4431}4432 4433// VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half4434defm VQRDMULH : N3VInt_HS<1, 0, 0b1011, 0, N3RegFrm,4435 IIC_VMULi16D,IIC_VMULi32D,IIC_VMULi16Q,IIC_VMULi32Q,4436 "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>;4437defm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D,4438 IIC_VMULi16Q, IIC_VMULi32Q,4439 "vqrdmulh", "s", int_arm_neon_vqrdmulh>;4440 4441let Predicates = [HasNEON] in {4442def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1),4443 (v8i16 (ARMvduplane (v8i16 QPR:$src2),4444 imm:$lane)))),4445 (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1),4446 (v4i16 (EXTRACT_SUBREG QPR:$src2,4447 (DSubReg_i16_reg imm:$lane))),4448 (SubReg_i16_lane imm:$lane)))>;4449def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1),4450 (v4i32 (ARMvduplane (v4i32 QPR:$src2),4451 imm:$lane)))),4452 (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1),4453 (v2i32 (EXTRACT_SUBREG QPR:$src2,4454 (DSubReg_i32_reg imm:$lane))),4455 (SubReg_i32_lane imm:$lane)))>;4456}4457 4458// VMULL : Vector Multiply Long (integer and polynomial) (Q = D * D)4459let PostEncoderMethod = "NEONThumb2DataIPostEncoder",4460 DecoderNamespace = "NEONData" in {4461 defm VMULLs : N3VL_QHS<0,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,4462 "vmull", "s", ARMvmulls, 1>;4463 defm VMULLu : N3VL_QHS<1,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,4464 "vmull", "u", ARMvmullu, 1>;4465 def VMULLp8 : N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8",4466 v8i16, v8i8, int_arm_neon_vmullp, 1>;4467 def VMULLp64 : N3VLIntnp<0b00101, 0b10, 0b1110, 0, 0, NoItinerary,4468 "vmull", "p64", v2i64, v1i64, int_arm_neon_vmullp, 1>,4469 Requires<[HasV8, HasAES]>;4470}4471defm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", ARMvmulls>;4472defm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", ARMvmullu>;4473 4474// VQDMULL : Vector Saturating Doubling Multiply Long (Q = D * D)4475defm VQDMULL : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, IIC_VMULi32D,4476 "vqdmull", "s", int_arm_neon_vqdmull, 1>;4477defm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D,4478 "vqdmull", "s", int_arm_neon_vqdmull>;4479 4480// Vector Multiply-Accumulate and Multiply-Subtract Operations.4481 4482// VMLA : Vector Multiply Accumulate (integer and floating-point)4483defm VMLA : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,4484 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;4485def VMLAfd : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32",4486 v2f32, fmul_su, fadd_mlx>,4487 Requires<[HasNEON, UseFPVMLx]>;4488def VMLAfq : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32",4489 v4f32, fmul_su, fadd_mlx>,4490 Requires<[HasNEON, UseFPVMLx]>;4491def VMLAhd : N3VDMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACD, "vmla", "f16",4492 v4f16, fmul_su, fadd_mlx>,4493 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4494def VMLAhq : N3VQMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACQ, "vmla", "f16",4495 v8f16, fmul_su, fadd_mlx>,4496 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4497defm VMLAsl : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D,4498 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;4499def VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32",4500 v2f32, fmul_su, fadd_mlx>,4501 Requires<[HasNEON, UseFPVMLx]>;4502def VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32",4503 v4f32, v2f32, fmul_su, fadd_mlx>,4504 Requires<[HasNEON, UseFPVMLx]>;4505def VMLAslhd : N3VDMulOpSL16<0b01, 0b0001, IIC_VMACD, "vmla", "f16",4506 v4f16, fmul, fadd>,4507 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4508def VMLAslhq : N3VQMulOpSL16<0b01, 0b0001, IIC_VMACQ, "vmla", "f16",4509 v8f16, v4f16, fmul, fadd>,4510 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4511 4512let Predicates = [HasNEON] in {4513def : Pat<(v8i16 (add (v8i16 QPR:$src1),4514 (mul (v8i16 QPR:$src2),4515 (v8i16 (ARMvduplane (v8i16 QPR:$src3), imm:$lane))))),4516 (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),4517 (v4i16 (EXTRACT_SUBREG QPR:$src3,4518 (DSubReg_i16_reg imm:$lane))),4519 (SubReg_i16_lane imm:$lane)))>;4520 4521def : Pat<(v4i32 (add (v4i32 QPR:$src1),4522 (mul (v4i32 QPR:$src2),4523 (v4i32 (ARMvduplane (v4i32 QPR:$src3), imm:$lane))))),4524 (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),4525 (v2i32 (EXTRACT_SUBREG QPR:$src3,4526 (DSubReg_i32_reg imm:$lane))),4527 (SubReg_i32_lane imm:$lane)))>;4528}4529 4530def : Pat<(v4f32 (fadd_mlx (v4f32 QPR:$src1),4531 (fmul_su (v4f32 QPR:$src2),4532 (v4f32 (ARMvduplane (v4f32 QPR:$src3), imm:$lane))))),4533 (v4f32 (VMLAslfq (v4f32 QPR:$src1),4534 (v4f32 QPR:$src2),4535 (v2f32 (EXTRACT_SUBREG QPR:$src3,4536 (DSubReg_i32_reg imm:$lane))),4537 (SubReg_i32_lane imm:$lane)))>,4538 Requires<[HasNEON, UseFPVMLx]>;4539 4540// VMLAL : Vector Multiply Accumulate Long (Q += D * D)4541defm VMLALs : N3VLMulOp_QHS<0,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,4542 "vmlal", "s", ARMvmulls, add>;4543defm VMLALu : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,4544 "vmlal", "u", ARMvmullu, add>;4545 4546defm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", ARMvmulls, add>;4547defm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", ARMvmullu, add>;4548 4549let Predicates = [HasNEON, HasV8_1a] in {4550 // v8.1a Neon Rounding Double Multiply-Op vector operations,4551 // VQRDMLAH : Vector Saturating Rounding Doubling Multiply Accumulate Long4552 // (Q += D * D)4553 defm VQRDMLAH : N3VInt3_HS<1, 0, 0b1011, 1, IIC_VMACi16D, IIC_VMACi32D,4554 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",4555 null_frag>;4556 def : Pat<(v4i16 (int_arm_neon_vqrdmlah (v4i16 DPR:$src1), (v4i16 DPR:$Vn),4557 (v4i16 DPR:$Vm))),4558 (v4i16 (VQRDMLAHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;4559 def : Pat<(v2i32 (int_arm_neon_vqrdmlah (v2i32 DPR:$src1), (v2i32 DPR:$Vn),4560 (v2i32 DPR:$Vm))),4561 (v2i32 (VQRDMLAHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;4562 def : Pat<(v8i16 (int_arm_neon_vqrdmlah (v8i16 QPR:$src1), (v8i16 QPR:$Vn),4563 (v8i16 QPR:$Vm))),4564 (v8i16 (VQRDMLAHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;4565 def : Pat<(v4i32 (int_arm_neon_vqrdmlah (v4i32 QPR:$src1), (v4i32 QPR:$Vn),4566 (v4i32 QPR:$Vm))),4567 (v4i32 (VQRDMLAHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;4568 4569 defm VQRDMLAHsl : N3VMulOpSL_HS<0b1110, IIC_VMACi16D, IIC_VMACi32D,4570 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",4571 null_frag>;4572 def : Pat<(v4i16 (int_arm_neon_vqrdmlah (v4i16 DPR:$src1),4573 (v4i16 DPR:$Vn),4574 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm),4575 imm:$lane)))),4576 (v4i16 (VQRDMLAHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm,4577 imm:$lane))>;4578 def : Pat<(v2i32 (int_arm_neon_vqrdmlah (v2i32 DPR:$src1),4579 (v2i32 DPR:$Vn),4580 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm),4581 imm:$lane)))),4582 (v2i32 (VQRDMLAHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,4583 imm:$lane))>;4584 def : Pat<(v8i16 (int_arm_neon_vqrdmlah (v8i16 QPR:$src1),4585 (v8i16 QPR:$src2),4586 (v8i16 (ARMvduplane (v8i16 QPR:$src3),4587 imm:$lane)))),4588 (v8i16 (VQRDMLAHslv8i16 (v8i16 QPR:$src1),4589 (v8i16 QPR:$src2),4590 (v4i16 (EXTRACT_SUBREG4591 QPR:$src3,4592 (DSubReg_i16_reg imm:$lane))),4593 (SubReg_i16_lane imm:$lane)))>;4594 def : Pat<(v4i32 (int_arm_neon_vqrdmlah (v4i32 QPR:$src1),4595 (v4i32 QPR:$src2),4596 (v4i32 (ARMvduplane (v4i32 QPR:$src3),4597 imm:$lane)))),4598 (v4i32 (VQRDMLAHslv4i32 (v4i32 QPR:$src1),4599 (v4i32 QPR:$src2),4600 (v2i32 (EXTRACT_SUBREG4601 QPR:$src3,4602 (DSubReg_i32_reg imm:$lane))),4603 (SubReg_i32_lane imm:$lane)))>;4604 4605 // VQRDMLSH : Vector Saturating Rounding Doubling Multiply Subtract Long4606 // (Q -= D * D)4607 defm VQRDMLSH : N3VInt3_HS<1, 0, 0b1100, 1, IIC_VMACi16D, IIC_VMACi32D,4608 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",4609 null_frag>;4610 def : Pat<(v4i16 (int_arm_neon_vqrdmlsh (v4i16 DPR:$src1), (v4i16 DPR:$Vn),4611 (v4i16 DPR:$Vm))),4612 (v4i16 (VQRDMLSHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;4613 def : Pat<(v2i32 (int_arm_neon_vqrdmlsh (v2i32 DPR:$src1), (v2i32 DPR:$Vn),4614 (v2i32 DPR:$Vm))),4615 (v2i32 (VQRDMLSHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;4616 def : Pat<(v8i16 (int_arm_neon_vqrdmlsh (v8i16 QPR:$src1), (v8i16 QPR:$Vn),4617 (v8i16 QPR:$Vm))),4618 (v8i16 (VQRDMLSHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;4619 def : Pat<(v4i32 (int_arm_neon_vqrdmlsh (v4i32 QPR:$src1), (v4i32 QPR:$Vn),4620 (v4i32 QPR:$Vm))),4621 (v4i32 (VQRDMLSHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;4622 4623 defm VQRDMLSHsl : N3VMulOpSL_HS<0b1111, IIC_VMACi16D, IIC_VMACi32D,4624 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",4625 null_frag>;4626 def : Pat<(v4i16 (int_arm_neon_vqrdmlsh (v4i16 DPR:$src1),4627 (v4i16 DPR:$Vn),4628 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm),4629 imm:$lane)))),4630 (v4i16 (VQRDMLSHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane))>;4631 def : Pat<(v2i32 (int_arm_neon_vqrdmlsh (v2i32 DPR:$src1),4632 (v2i32 DPR:$Vn),4633 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm),4634 imm:$lane)))),4635 (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,4636 imm:$lane))>;4637 def : Pat<(v8i16 (int_arm_neon_vqrdmlsh (v8i16 QPR:$src1),4638 (v8i16 QPR:$src2),4639 (v8i16 (ARMvduplane (v8i16 QPR:$src3),4640 imm:$lane)))),4641 (v8i16 (VQRDMLSHslv8i16 (v8i16 QPR:$src1),4642 (v8i16 QPR:$src2),4643 (v4i16 (EXTRACT_SUBREG4644 QPR:$src3,4645 (DSubReg_i16_reg imm:$lane))),4646 (SubReg_i16_lane imm:$lane)))>;4647 def : Pat<(v4i32 (int_arm_neon_vqrdmlsh (v4i32 QPR:$src1),4648 (v4i32 QPR:$src2),4649 (v4i32 (ARMvduplane (v4i32 QPR:$src3),4650 imm:$lane)))),4651 (v4i32 (VQRDMLSHslv4i32 (v4i32 QPR:$src1),4652 (v4i32 QPR:$src2),4653 (v2i32 (EXTRACT_SUBREG4654 QPR:$src3,4655 (DSubReg_i32_reg imm:$lane))),4656 (SubReg_i32_lane imm:$lane)))>;4657}4658// VQDMLAL : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D)4659defm VQDMLAL : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,4660 "vqdmlal", "s", null_frag>;4661defm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", null_frag>;4662 4663let Predicates = [HasNEON] in {4664def : Pat<(v4i32 (saddsat (v4i32 QPR:$src1),4665 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),4666 (v4i16 DPR:$Vm))))),4667 (VQDMLALv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;4668def : Pat<(v2i64 (saddsat (v2i64 QPR:$src1),4669 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),4670 (v2i32 DPR:$Vm))))),4671 (VQDMLALv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;4672def : Pat<(v4i32 (saddsat (v4i32 QPR:$src1),4673 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),4674 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm),4675 imm:$lane)))))),4676 (VQDMLALslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;4677def : Pat<(v2i64 (saddsat (v2i64 QPR:$src1),4678 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),4679 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm),4680 imm:$lane)))))),4681 (VQDMLALslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;4682}4683 4684// VMLS : Vector Multiply Subtract (integer and floating-point)4685defm VMLS : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,4686 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;4687def VMLSfd : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32",4688 v2f32, fmul_su, fsub_mlx>,4689 Requires<[HasNEON, UseFPVMLx]>;4690def VMLSfq : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32",4691 v4f32, fmul_su, fsub_mlx>,4692 Requires<[HasNEON, UseFPVMLx]>;4693def VMLShd : N3VDMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACD, "vmls", "f16",4694 v4f16, fmul, fsub>,4695 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4696def VMLShq : N3VQMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACQ, "vmls", "f16",4697 v8f16, fmul, fsub>,4698 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4699defm VMLSsl : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D,4700 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;4701def VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32",4702 v2f32, fmul_su, fsub_mlx>,4703 Requires<[HasNEON, UseFPVMLx]>;4704def VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32",4705 v4f32, v2f32, fmul_su, fsub_mlx>,4706 Requires<[HasNEON, UseFPVMLx]>;4707def VMLSslhd : N3VDMulOpSL16<0b01, 0b0101, IIC_VMACD, "vmls", "f16",4708 v4f16, fmul, fsub>,4709 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4710def VMLSslhq : N3VQMulOpSL16<0b01, 0b0101, IIC_VMACQ, "vmls", "f16",4711 v8f16, v4f16, fmul, fsub>,4712 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;4713 4714let Predicates = [HasNEON] in {4715def : Pat<(v8i16 (sub (v8i16 QPR:$src1),4716 (mul (v8i16 QPR:$src2),4717 (v8i16 (ARMvduplane (v8i16 QPR:$src3), imm:$lane))))),4718 (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),4719 (v4i16 (EXTRACT_SUBREG QPR:$src3,4720 (DSubReg_i16_reg imm:$lane))),4721 (SubReg_i16_lane imm:$lane)))>;4722 4723def : Pat<(v4i32 (sub (v4i32 QPR:$src1),4724 (mul (v4i32 QPR:$src2),4725 (v4i32 (ARMvduplane (v4i32 QPR:$src3), imm:$lane))))),4726 (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),4727 (v2i32 (EXTRACT_SUBREG QPR:$src3,4728 (DSubReg_i32_reg imm:$lane))),4729 (SubReg_i32_lane imm:$lane)))>;4730}4731 4732def : Pat<(v4f32 (fsub_mlx (v4f32 QPR:$src1),4733 (fmul_su (v4f32 QPR:$src2),4734 (v4f32 (ARMvduplane (v4f32 QPR:$src3), imm:$lane))))),4735 (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2),4736 (v2f32 (EXTRACT_SUBREG QPR:$src3,4737 (DSubReg_i32_reg imm:$lane))),4738 (SubReg_i32_lane imm:$lane)))>,4739 Requires<[HasNEON, UseFPVMLx]>;4740 4741// VMLSL : Vector Multiply Subtract Long (Q -= D * D)4742defm VMLSLs : N3VLMulOp_QHS<0,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,4743 "vmlsl", "s", ARMvmulls, sub>;4744defm VMLSLu : N3VLMulOp_QHS<1,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,4745 "vmlsl", "u", ARMvmullu, sub>;4746 4747defm VMLSLsls : N3VLMulOpSL_HS<0, 0b0110, "vmlsl", "s", ARMvmulls, sub>;4748defm VMLSLslu : N3VLMulOpSL_HS<1, 0b0110, "vmlsl", "u", ARMvmullu, sub>;4749 4750// VQDMLSL : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D)4751defm VQDMLSL : N3VLInt3_HS<0, 1, 0b1011, 0, IIC_VMACi16D, IIC_VMACi32D,4752 "vqdmlsl", "s", null_frag>;4753defm VQDMLSLsl: N3VLInt3SL_HS<0, 0b0111, "vqdmlsl", "s", null_frag>;4754 4755let Predicates = [HasNEON] in {4756def : Pat<(v4i32 (ssubsat (v4i32 QPR:$src1),4757 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),4758 (v4i16 DPR:$Vm))))),4759 (VQDMLSLv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;4760def : Pat<(v2i64 (ssubsat (v2i64 QPR:$src1),4761 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),4762 (v2i32 DPR:$Vm))))),4763 (VQDMLSLv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;4764def : Pat<(v4i32 (ssubsat (v4i32 QPR:$src1),4765 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),4766 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm),4767 imm:$lane)))))),4768 (VQDMLSLslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;4769def : Pat<(v2i64 (ssubsat (v2i64 QPR:$src1),4770 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),4771 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm),4772 imm:$lane)))))),4773 (VQDMLSLslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;4774}4775 4776// Fused Vector Multiply-Accumulate and Fused Multiply-Subtract Operations.4777def VFMAfd : N3VDMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACD, "vfma", "f32",4778 v2f32, fmul_su, fadd_mlx>,4779 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;4780 4781def VFMAfq : N3VQMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACQ, "vfma", "f32",4782 v4f32, fmul_su, fadd_mlx>,4783 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;4784def VFMAhd : N3VDMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACD, "vfma", "f16",4785 v4f16, fmul, fadd>,4786 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;4787 4788def VFMAhq : N3VQMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACQ, "vfma", "f16",4789 v8f16, fmul, fadd>,4790 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;4791 4792// Fused Vector Multiply Subtract (floating-point)4793def VFMSfd : N3VDMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACD, "vfms", "f32",4794 v2f32, fmul_su, fsub_mlx>,4795 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;4796def VFMSfq : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32",4797 v4f32, fmul_su, fsub_mlx>,4798 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;4799def VFMShd : N3VDMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACD, "vfms", "f16",4800 v4f16, fmul, fsub>,4801 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;4802def VFMShq : N3VQMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACQ, "vfms", "f16",4803 v8f16, fmul, fsub>,4804 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;4805 4806// Match @llvm.fma.* intrinsics4807def : Pat<(v4f16 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)),4808 (VFMAhd DPR:$src1, DPR:$Vn, DPR:$Vm)>,4809 Requires<[HasNEON,HasFullFP16]>;4810def : Pat<(v8f16 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)),4811 (VFMAhq QPR:$src1, QPR:$Vn, QPR:$Vm)>,4812 Requires<[HasNEON,HasFullFP16]>;4813def : Pat<(v2f32 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)),4814 (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,4815 Requires<[HasNEON,HasVFP4]>;4816def : Pat<(v4f32 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)),4817 (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,4818 Requires<[HasNEON,HasVFP4]>;4819def : Pat<(v2f32 (fma (fneg DPR:$Vn), DPR:$Vm, DPR:$src1)),4820 (VFMSfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,4821 Requires<[HasNEON,HasVFP4]>;4822def : Pat<(v4f32 (fma (fneg QPR:$Vn), QPR:$Vm, QPR:$src1)),4823 (VFMSfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,4824 Requires<[HasNEON,HasVFP4]>;4825 4826// ARMv8.2a dot product instructions.4827// We put them in the VFPV8 decoder namespace because the ARM and Thumb4828// encodings are the same and thus no further bit twiddling is necessary4829// in the disassembler.4830class VDOT<bit op6, bit op4, bit op23, RegisterClass RegTy, string Asm,4831 string AsmTy, ValueType AccumTy, ValueType InputTy,4832 SDPatternOperator OpNode> :4833 N3Vnp<{0b1100, op23}, 0b10, 0b1101, op6, op4, (outs RegTy:$dst),4834 (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm), N3RegFrm, IIC_VDOTPROD,4835 Asm, AsmTy,4836 [(set (AccumTy RegTy:$dst),4837 (OpNode (AccumTy RegTy:$Vd),4838 (InputTy RegTy:$Vn),4839 (InputTy RegTy:$Vm)))]> {4840 let Predicates = [HasDotProd];4841 let DecoderNamespace = "VFPV8";4842 let Constraints = "$dst = $Vd";4843}4844 4845def VUDOTD : VDOT<0, 1, 0, DPR, "vudot", "u8", v2i32, v8i8, int_arm_neon_udot>;4846def VSDOTD : VDOT<0, 0, 0, DPR, "vsdot", "s8", v2i32, v8i8, int_arm_neon_sdot>;4847def VUDOTQ : VDOT<1, 1, 0, QPR, "vudot", "u8", v4i32, v16i8, int_arm_neon_udot>;4848def VSDOTQ : VDOT<1, 0, 0, QPR, "vsdot", "s8", v4i32, v16i8, int_arm_neon_sdot>;4849 4850// Indexed dot product instructions:4851multiclass DOTI<string opc, string dt, bit Q, bit U, RegisterClass Ty,4852 ValueType AccumType, ValueType InputType, SDPatternOperator OpNode,4853 dag RHS> {4854 def "" : N3Vnp<0b11100, 0b10, 0b1101, Q, U, (outs Ty:$dst),4855 (ins Ty:$Vd, Ty:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),4856 N3RegFrm, IIC_VDOTPROD, opc, dt, []> {4857 bit lane;4858 let Inst{5} = lane;4859 let AsmString = !strconcat(opc, ".", dt, "\t$Vd, $Vn, $Vm$lane");4860 let Constraints = "$dst = $Vd";4861 let Predicates = [HasDotProd];4862 let DecoderNamespace = "VFPV8";4863 }4864 4865 def : Pat<4866 (AccumType (OpNode (AccumType Ty:$Vd),4867 (InputType Ty:$Vn),4868 (InputType (bitconvert (AccumType4869 (ARMvduplane (AccumType Ty:$Vm),4870 VectorIndex32:$lane)))))),4871 (!cast<Instruction>(NAME) Ty:$Vd, Ty:$Vn, RHS, VectorIndex32:$lane)>;4872}4873 4874defm VUDOTDI : DOTI<"vudot", "u8", 0b0, 0b1, DPR, v2i32, v8i8,4875 int_arm_neon_udot, (v2i32 DPR_VFP2:$Vm)>;4876defm VSDOTDI : DOTI<"vsdot", "s8", 0b0, 0b0, DPR, v2i32, v8i8,4877 int_arm_neon_sdot, (v2i32 DPR_VFP2:$Vm)>;4878defm VUDOTQI : DOTI<"vudot", "u8", 0b1, 0b1, QPR, v4i32, v16i8,4879 int_arm_neon_udot, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;4880defm VSDOTQI : DOTI<"vsdot", "s8", 0b1, 0b0, QPR, v4i32, v16i8,4881 int_arm_neon_sdot, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;4882 4883// v8.6A matrix multiplication extension4884let Predicates = [HasMatMulInt8] in {4885 class N3VMatMul<bit B, bit U, string Asm, string AsmTy,4886 SDPatternOperator OpNode>4887 : N3Vnp<{0b1100, B}, 0b10, 0b1100, 1, U, (outs QPR:$dst),4888 (ins QPR:$Vd, QPR:$Vn, QPR:$Vm), N3RegFrm, NoItinerary,4889 Asm, AsmTy,4890 [(set (v4i32 QPR:$dst), (OpNode (v4i32 QPR:$Vd),4891 (v16i8 QPR:$Vn),4892 (v16i8 QPR:$Vm)))]> {4893 let DecoderNamespace = "VFPV8";4894 let Constraints = "$dst = $Vd";4895 }4896 4897 multiclass N3VMixedDotLane<bit Q, bit U, string Asm, string AsmTy, RegisterClass RegTy,4898 ValueType AccumTy, ValueType InputTy, SDPatternOperator OpNode,4899 dag RHS> {4900 4901 def "" : N3Vnp<0b11101, 0b00, 0b1101, Q, U, (outs RegTy:$dst),4902 (ins RegTy:$Vd, RegTy:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), N3RegFrm,4903 NoItinerary, Asm, AsmTy, []> {4904 bit lane;4905 let Inst{5} = lane;4906 let AsmString = !strconcat(Asm, ".", AsmTy, "\t$Vd, $Vn, $Vm$lane");4907 let DecoderNamespace = "VFPV8";4908 let Constraints = "$dst = $Vd";4909 }4910 4911 def : Pat<4912 (AccumTy (OpNode (AccumTy RegTy:$Vd),4913 (InputTy RegTy:$Vn),4914 (InputTy (bitconvert (AccumTy4915 (ARMvduplane (AccumTy RegTy:$Vm),4916 VectorIndex32:$lane)))))),4917 (!cast<Instruction>(NAME) RegTy:$Vd, RegTy:$Vn, RHS, VectorIndex32:$lane)>;4918 4919 }4920 4921 multiclass SUDOTLane<bit Q, RegisterClass RegTy, ValueType AccumTy, ValueType InputTy, dag RHS>4922 : N3VMixedDotLane<Q, 1, "vsudot", "u8", RegTy, AccumTy, InputTy, null_frag, (ins)> {4923 def : Pat<4924 (AccumTy (int_arm_neon_usdot (AccumTy RegTy:$Vd),4925 (InputTy (bitconvert (AccumTy4926 (ARMvduplane (AccumTy RegTy:$Vm),4927 VectorIndex32:$lane)))),4928 (InputTy RegTy:$Vn))),4929 (!cast<Instruction>(NAME) RegTy:$Vd, RegTy:$Vn, RHS, VectorIndex32:$lane)>;4930 }4931 4932 def VSMMLA : N3VMatMul<0, 0, "vsmmla", "s8", int_arm_neon_smmla>;4933 def VUMMLA : N3VMatMul<0, 1, "vummla", "u8", int_arm_neon_ummla>;4934 def VUSMMLA : N3VMatMul<1, 0, "vusmmla", "s8", int_arm_neon_usmmla>;4935 def VUSDOTD : VDOT<0, 0, 1, DPR, "vusdot", "s8", v2i32, v8i8, int_arm_neon_usdot>;4936 def VUSDOTQ : VDOT<1, 0, 1, QPR, "vusdot", "s8", v4i32, v16i8, int_arm_neon_usdot>;4937 4938 defm VUSDOTDI : N3VMixedDotLane<0, 0, "vusdot", "s8", DPR, v2i32, v8i8,4939 int_arm_neon_usdot, (v2i32 DPR_VFP2:$Vm)>;4940 defm VUSDOTQI : N3VMixedDotLane<1, 0, "vusdot", "s8", QPR, v4i32, v16i8,4941 int_arm_neon_usdot, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;4942 defm VSUDOTDI : SUDOTLane<0, DPR, v2i32, v8i8, (v2i32 DPR_VFP2:$Vm)>;4943 defm VSUDOTQI : SUDOTLane<1, QPR, v4i32, v16i8, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;4944}4945 4946// ARMv8.3 complex operations4947class BaseN3VCP8ComplexTied<bit op21, bit op4, bit s, bit q,4948 InstrItinClass itin, dag oops, dag iops,4949 string opc, string dt, list<dag> pattern>4950 : N3VCP8<{?,?}, {op21,s}, q, op4, oops,4951 iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "$src1 = $Vd", pattern>{4952 bits<2> rot;4953 let Inst{24-23} = rot;4954}4955 4956class BaseN3VCP8ComplexOdd<bit op23, bit op21, bit op4, bit s, bit q,4957 InstrItinClass itin, dag oops, dag iops, string opc,4958 string dt, list<dag> pattern>4959 : N3VCP8<{?,op23}, {op21,s}, q, op4, oops,4960 iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "", pattern> {4961 bits<1> rot;4962 let Inst{24} = rot;4963}4964 4965class BaseN3VCP8ComplexTiedLane32<bit op4, bit s, bit q, InstrItinClass itin,4966 dag oops, dag iops, string opc, string dt,4967 list<dag> pattern>4968 : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt,4969 "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> {4970 bits<2> rot;4971 bit lane;4972 4973 let Inst{21-20} = rot;4974 let Inst{5} = lane;4975}4976 4977class BaseN3VCP8ComplexTiedLane64<bit op4, bit s, bit q, InstrItinClass itin,4978 dag oops, dag iops, string opc, string dt,4979 list<dag> pattern>4980 : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt,4981 "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> {4982 bits<2> rot;4983 bit lane;4984 4985 let Inst{21-20} = rot;4986 let Inst{5} = Vm{4};4987 // This is needed because the lane operand does not have any bits in the4988 // encoding (it only has one possible value), so we need to manually set it4989 // to it's default value.4990 let DecoderMethod = "DecodeNEONComplexLane64Instruction";4991}4992 4993multiclass N3VCP8ComplexTied<bit op21, bit op4,4994 string OpcodeStr> {4995 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {4996 def v4f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 0, IIC_VMACD, (outs DPR:$Vd),4997 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot),4998 OpcodeStr, "f16", []>;4999 def v8f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 1, IIC_VMACQ, (outs QPR:$Vd),5000 (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot),5001 OpcodeStr, "f16", []>;5002 }5003 let Predicates = [HasNEON,HasV8_3a] in {5004 def v2f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 0, IIC_VMACD, (outs DPR:$Vd),5005 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot),5006 OpcodeStr, "f32", []>;5007 def v4f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 1, IIC_VMACQ, (outs QPR:$Vd),5008 (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot),5009 OpcodeStr, "f32", []>;5010 }5011}5012 5013multiclass N3VCP8ComplexOdd<bit op23, bit op21, bit op4,5014 string OpcodeStr> {5015 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {5016 def v4f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 0, IIC_VMACD,5017 (outs DPR:$Vd),5018 (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot),5019 OpcodeStr, "f16", []>;5020 def v8f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 1, IIC_VMACQ,5021 (outs QPR:$Vd),5022 (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot),5023 OpcodeStr, "f16", []>;5024 }5025 let Predicates = [HasNEON,HasV8_3a] in {5026 def v2f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 0, IIC_VMACD,5027 (outs DPR:$Vd),5028 (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot),5029 OpcodeStr, "f32", []>;5030 def v4f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 1, IIC_VMACQ,5031 (outs QPR:$Vd),5032 (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot),5033 OpcodeStr, "f32", []>;5034 }5035}5036 5037// These instructions index by pairs of lanes, so the VectorIndexes are twice5038// as wide as the data types.5039multiclass N3VCP8ComplexTiedLane<bit op4, string OpcodeStr> {5040 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {5041 def v4f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 0, IIC_VMACD,5042 (outs DPR:$Vd),5043 (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,5044 VectorIndex32:$lane, complexrotateop:$rot),5045 OpcodeStr, "f16", []>;5046 def v8f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 1, IIC_VMACQ,5047 (outs QPR:$Vd),5048 (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm,5049 VectorIndex32:$lane, complexrotateop:$rot),5050 OpcodeStr, "f16", []>;5051 }5052 let Predicates = [HasNEON,HasV8_3a] in {5053 def v2f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 0, IIC_VMACD,5054 (outs DPR:$Vd),5055 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, VectorIndex64:$lane,5056 complexrotateop:$rot),5057 OpcodeStr, "f32", []>;5058 def v4f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 1, IIC_VMACQ,5059 (outs QPR:$Vd),5060 (ins QPR:$src1, QPR:$Vn, DPR:$Vm, VectorIndex64:$lane,5061 complexrotateop:$rot),5062 OpcodeStr, "f32", []>;5063 }5064}5065 5066defm VCMLA : N3VCP8ComplexTied<1, 0, "vcmla">;5067defm VCADD : N3VCP8ComplexOdd<1, 0, 0, "vcadd">;5068defm VCMLA : N3VCP8ComplexTiedLane<0, "vcmla">;5069 5070let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {5071 def : Pat<(v4f16 (int_arm_neon_vcadd_rot90 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm))),5072 (VCADDv4f16 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm), (i32 0))>;5073 def : Pat<(v4f16 (int_arm_neon_vcadd_rot270 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm))),5074 (VCADDv4f16 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm), (i32 1))>;5075 def : Pat<(v8f16 (int_arm_neon_vcadd_rot90 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm))),5076 (VCADDv8f16 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm), (i32 0))>;5077 def : Pat<(v8f16 (int_arm_neon_vcadd_rot270 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm))),5078 (VCADDv8f16 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm), (i32 1))>;5079}5080let Predicates = [HasNEON,HasV8_3a] in {5081 def : Pat<(v2f32 (int_arm_neon_vcadd_rot90 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm))),5082 (VCADDv2f32 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm), (i32 0))>;5083 def : Pat<(v2f32 (int_arm_neon_vcadd_rot270 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm))),5084 (VCADDv2f32 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm), (i32 1))>;5085 def : Pat<(v4f32 (int_arm_neon_vcadd_rot90 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm))),5086 (VCADDv4f32 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm), (i32 0))>;5087 def : Pat<(v4f32 (int_arm_neon_vcadd_rot270 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm))),5088 (VCADDv4f32 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm), (i32 1))>;5089}5090 5091// Vector Subtract Operations.5092 5093// VSUB : Vector Subtract (integer and floating-point)5094defm VSUB : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ,5095 "vsub", "i", sub, 0>;5096def VSUBfd : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32",5097 v2f32, v2f32, fsub, 0>;5098def VSUBfq : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32",5099 v4f32, v4f32, fsub, 0>;5100def VSUBhd : N3VD<0, 0, 0b11, 0b1101, 0, IIC_VBIND, "vsub", "f16",5101 v4f16, v4f16, fsub, 0>,5102 Requires<[HasNEON,HasFullFP16]>;5103def VSUBhq : N3VQ<0, 0, 0b11, 0b1101, 0, IIC_VBINQ, "vsub", "f16",5104 v8f16, v8f16, fsub, 0>,5105 Requires<[HasNEON,HasFullFP16]>;5106// VSUBL : Vector Subtract Long (Q = D - D)5107defm VSUBLs : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,5108 "vsubl", "s", sub, sext, 0>;5109defm VSUBLu : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,5110 "vsubl", "u", sub, zanyext, 0>;5111// VSUBW : Vector Subtract Wide (Q = Q - D)5112defm VSUBWs : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>;5113defm VSUBWu : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zanyext, 0>;5114// VHSUB : Vector Halving Subtract5115defm VHSUBs : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm,5116 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5117 "vhsub", "s", int_arm_neon_vhsubs, 0>;5118defm VHSUBu : N3VInt_QHS<1, 0, 0b0010, 0, N3RegFrm,5119 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5120 "vhsub", "u", int_arm_neon_vhsubu, 0>;5121// VQSUB : Vector Saturing Subtract5122defm VQSUBs : N3VInt_QHSD<0, 0, 0b0010, 1, N3RegFrm,5123 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5124 "vqsub", "s", ssubsat, 0>;5125defm VQSUBu : N3VInt_QHSD<1, 0, 0b0010, 1, N3RegFrm,5126 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5127 "vqsub", "u", usubsat, 0>;5128// VSUBHN : Vector Subtract and Narrow Returning High Half (D = Q - Q)5129defm VSUBHN : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i", null_frag, 0>;5130// VRSUBHN : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q)5131defm VRSUBHN : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i",5132 int_arm_neon_vrsubhn, 0>;5133 5134let Predicates = [HasNEON] in {5135def : Pat<(v8i8 (trunc (ARMvshruImm (sub (v8i16 QPR:$Vn), QPR:$Vm), 8))),5136 (VSUBHNv8i8 QPR:$Vn, QPR:$Vm)>;5137def : Pat<(v4i16 (trunc (ARMvshruImm (sub (v4i32 QPR:$Vn), QPR:$Vm), 16))),5138 (VSUBHNv4i16 QPR:$Vn, QPR:$Vm)>;5139def : Pat<(v2i32 (trunc (ARMvshruImm (sub (v2i64 QPR:$Vn), QPR:$Vm), 32))),5140 (VSUBHNv2i32 QPR:$Vn, QPR:$Vm)>;5141}5142 5143// Vector Comparisons.5144 5145// VCEQ : Vector Compare Equal5146defm VCEQ : N3V_QHS_cmp<1, 0, 0b1000, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,5147 IIC_VSUBi4Q, "vceq", "i", ARMCCeq, 1>;5148def VCEQfd : N3VD_cmp<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32,5149 ARMCCeq, 1>;5150def VCEQfq : N3VQ_cmp<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32,5151 ARMCCeq, 1>;5152def VCEQhd : N3VD_cmp<0,0,0b01,0b1110,0, IIC_VBIND, "vceq", "f16", v4i16, v4f16,5153 ARMCCeq, 1>,5154 Requires<[HasNEON, HasFullFP16]>;5155def VCEQhq : N3VQ_cmp<0,0,0b01,0b1110,0, IIC_VBINQ, "vceq", "f16", v8i16, v8f16,5156 ARMCCeq, 1>,5157 Requires<[HasNEON, HasFullFP16]>;5158 5159let TwoOperandAliasConstraint = "$Vm = $Vd" in5160defm VCEQz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i",5161 "$Vd, $Vm, #0", ARMCCeq>;5162 5163// VCGE : Vector Compare Greater Than or Equal5164defm VCGEs : N3V_QHS_cmp<0, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,5165 IIC_VSUBi4Q, "vcge", "s", ARMCCge, 0>;5166defm VCGEu : N3V_QHS_cmp<1, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,5167 IIC_VSUBi4Q, "vcge", "u", ARMCChs, 0>;5168def VCGEfd : N3VD_cmp<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32", v2i32, v2f32,5169 ARMCCge, 0>;5170def VCGEfq : N3VQ_cmp<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32,5171 ARMCCge, 0>;5172def VCGEhd : N3VD_cmp<1,0,0b01,0b1110,0, IIC_VBIND, "vcge", "f16", v4i16, v4f16,5173 ARMCCge, 0>,5174 Requires<[HasNEON, HasFullFP16]>;5175def VCGEhq : N3VQ_cmp<1,0,0b01,0b1110,0, IIC_VBINQ, "vcge", "f16", v8i16, v8f16,5176 ARMCCge, 0>,5177 Requires<[HasNEON, HasFullFP16]>;5178 5179let TwoOperandAliasConstraint = "$Vm = $Vd" in {5180defm VCGEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s",5181 "$Vd, $Vm, #0", ARMCCge>;5182defm VCLEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s",5183 "$Vd, $Vm, #0", ARMCCle>;5184}5185 5186// VCGT : Vector Compare Greater Than5187defm VCGTs : N3V_QHS_cmp<0, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,5188 IIC_VSUBi4Q, "vcgt", "s", ARMCCgt, 0>;5189defm VCGTu : N3V_QHS_cmp<1, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,5190 IIC_VSUBi4Q, "vcgt", "u", ARMCChi, 0>;5191def VCGTfd : N3VD_cmp<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32,5192 ARMCCgt, 0>;5193def VCGTfq : N3VQ_cmp<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32,5194 ARMCCgt, 0>;5195def VCGThd : N3VD_cmp<1,0,0b11,0b1110,0, IIC_VBIND, "vcgt", "f16", v4i16, v4f16,5196 ARMCCgt, 0>,5197 Requires<[HasNEON, HasFullFP16]>;5198def VCGThq : N3VQ_cmp<1,0,0b11,0b1110,0, IIC_VBINQ, "vcgt", "f16", v8i16, v8f16,5199 ARMCCgt, 0>,5200 Requires<[HasNEON, HasFullFP16]>;5201 5202let TwoOperandAliasConstraint = "$Vm = $Vd" in {5203defm VCGTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s",5204 "$Vd, $Vm, #0", ARMCCgt>;5205defm VCLTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s",5206 "$Vd, $Vm, #0", ARMCClt>;5207}5208 5209// VACGE : Vector Absolute Compare Greater Than or Equal (aka VCAGE)5210def VACGEfd : N3VDInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge",5211 "f32", v2i32, v2f32, int_arm_neon_vacge, 0>;5212def VACGEfq : N3VQInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge",5213 "f32", v4i32, v4f32, int_arm_neon_vacge, 0>;5214def VACGEhd : N3VDInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge",5215 "f16", v4i16, v4f16, int_arm_neon_vacge, 0>,5216 Requires<[HasNEON, HasFullFP16]>;5217def VACGEhq : N3VQInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge",5218 "f16", v8i16, v8f16, int_arm_neon_vacge, 0>,5219 Requires<[HasNEON, HasFullFP16]>;5220// VACGT : Vector Absolute Compare Greater Than (aka VCAGT)5221def VACGTfd : N3VDInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt",5222 "f32", v2i32, v2f32, int_arm_neon_vacgt, 0>;5223def VACGTfq : N3VQInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt",5224 "f32", v4i32, v4f32, int_arm_neon_vacgt, 0>;5225def VACGThd : N3VDInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt",5226 "f16", v4i16, v4f16, int_arm_neon_vacgt, 0>,5227 Requires<[HasNEON, HasFullFP16]>;5228def VACGThq : N3VQInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt",5229 "f16", v8i16, v8f16, int_arm_neon_vacgt, 0>,5230 Requires<[HasNEON, HasFullFP16]>;5231// VTST : Vector Test Bits5232defm VTST : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,5233 IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;5234 5235def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",5236 (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;5237def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",5238 (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;5239def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",5240 (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;5241def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",5242 (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;5243let Predicates = [HasNEON, HasFullFP16] in {5244def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm",5245 (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;5246def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm",5247 (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;5248def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm",5249 (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;5250def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm",5251 (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;5252}5253 5254// +fp16fml Floating Point Multiplication Variants5255let Predicates = [HasNEON, HasFP16FML], DecoderNamespace= "VFPV8" in {5256 5257class N3VCP8F16Q1<string asm, RegisterClass Td, RegisterClass Tn,5258 RegisterClass Tm, bits<2> op1, bits<2> op2, bit op3>5259 : N3VCP8<op1, op2, 1, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary,5260 asm, "f16", "$Vd, $Vn, $Vm", "", []>;5261 5262class N3VCP8F16Q0<string asm, RegisterClass Td, RegisterClass Tn,5263 RegisterClass Tm, bits<2> op1, bits<2> op2, bit op3>5264 : N3VCP8Q0<op1, op2, 0, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary,5265 asm, "f16", "$Vd, $Vn, $Vm", "", []>;5266 5267// Vd, Vs, Vs[0-15], Idx[0-1]5268class VFMD<string opc, string type, bits<2> S>5269 : N3VLaneCP8<0, S, 0, 1, (outs DPR:$Vd),5270 (ins SPR:$Vn, SPR_8:$Vm, VectorIndex32:$idx),5271 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {5272 bit idx;5273 let Inst{3} = idx;5274 let Inst{19-16} = Vn{4-1};5275 let Inst{7} = Vn{0};5276 let Inst{5} = Vm{0};5277 let Inst{2-0} = Vm{3-1};5278}5279 5280// Vq, Vd, Vd[0-7], Idx[0-3]5281class VFMQ<string opc, string type, bits<2> S>5282 : N3VLaneCP8<0, S, 1, 1, (outs QPR:$Vd),5283 (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx),5284 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {5285 bits<2> idx;5286 let Inst{5} = idx{1};5287 let Inst{3} = idx{0};5288}5289 5290// op1 op2 op35291def VFMALD : N3VCP8F16Q0<"vfmal", DPR, SPR, SPR, 0b00, 0b10, 1>;5292def VFMSLD : N3VCP8F16Q0<"vfmsl", DPR, SPR, SPR, 0b01, 0b10, 1>;5293def VFMALQ : N3VCP8F16Q1<"vfmal", QPR, DPR, DPR, 0b00, 0b10, 1>;5294def VFMSLQ : N3VCP8F16Q1<"vfmsl", QPR, DPR, DPR, 0b01, 0b10, 1>;5295def VFMALDI : VFMD<"vfmal", "f16", 0b00>;5296def VFMSLDI : VFMD<"vfmsl", "f16", 0b01>;5297def VFMALQI : VFMQ<"vfmal", "f16", 0b00>;5298def VFMSLQI : VFMQ<"vfmsl", "f16", 0b01>;5299} // HasNEON, HasFP16FML5300 5301 5302def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",5303 (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;5304def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",5305 (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;5306def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",5307 (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;5308def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",5309 (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;5310let Predicates = [HasNEON, HasFullFP16] in {5311def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm",5312 (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;5313def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm",5314 (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;5315def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm",5316 (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;5317def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm",5318 (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;5319}5320 5321// Vector Bitwise Operations.5322 5323def vnotd : PatFrag<(ops node:$in),5324 (xor node:$in, ARMimmAllOnesD)>;5325def vnotq : PatFrag<(ops node:$in),5326 (xor node:$in, ARMimmAllOnesV)>;5327 5328 5329// VAND : Vector Bitwise AND5330def VANDd : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand",5331 v2i32, v2i32, and, 1>;5332def VANDq : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand",5333 v4i32, v4i32, and, 1>;5334 5335// VEOR : Vector Bitwise Exclusive OR5336def VEORd : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor",5337 v2i32, v2i32, xor, 1>;5338def VEORq : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor",5339 v4i32, v4i32, xor, 1>;5340 5341// VORR : Vector Bitwise OR5342def VORRd : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr",5343 v2i32, v2i32, or, 1>;5344def VORRq : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr",5345 v4i32, v4i32, or, 1>;5346 5347multiclass BitwisePatterns<string Name, SDPatternOperator OpNodeD,5348 SDPatternOperator OpNodeQ> {5349 def : Pat<(v8i8 (OpNodeD DPR:$LHS, DPR:$RHS)),5350 (!cast<Instruction>(Name#"d") DPR:$LHS, DPR:$RHS)>;5351 def : Pat<(v4i16 (OpNodeD DPR:$LHS, DPR:$RHS)),5352 (!cast<Instruction>(Name#"d") DPR:$LHS, DPR:$RHS)>;5353 def : Pat<(v1i64 (OpNodeD DPR:$LHS, DPR:$RHS)),5354 (!cast<Instruction>(Name#"d") DPR:$LHS, DPR:$RHS)>;5355 5356 def : Pat<(v16i8 (OpNodeQ QPR:$LHS, QPR:$RHS)),5357 (!cast<Instruction>(Name#"q") QPR:$LHS, QPR:$RHS)>;5358 def : Pat<(v8i16 (OpNodeQ QPR:$LHS, QPR:$RHS)),5359 (!cast<Instruction>(Name#"q") QPR:$LHS, QPR:$RHS)>;5360 def : Pat<(v2i64 (OpNodeQ QPR:$LHS, QPR:$RHS)),5361 (!cast<Instruction>(Name#"q") QPR:$LHS, QPR:$RHS)>;5362}5363 5364let Predicates = [HasNEON] in {5365 defm : BitwisePatterns<"VAND", and, and>;5366 defm : BitwisePatterns<"VORR", or, or>;5367 defm : BitwisePatterns<"VEOR", xor, xor>;5368}5369 5370def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1,5371 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),5372 IIC_VMOVImm,5373 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",5374 [(set DPR:$Vd,5375 (v4i16 (ARMvorrImm DPR:$src, timm:$SIMM)))]> {5376 let Inst{9} = SIMM{9};5377}5378 5379def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1,5380 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),5381 IIC_VMOVImm,5382 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",5383 [(set DPR:$Vd,5384 (v2i32 (ARMvorrImm DPR:$src, timm:$SIMM)))]> {5385 let Inst{10-9} = SIMM{10-9};5386}5387 5388def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1,5389 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),5390 IIC_VMOVImm,5391 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",5392 [(set QPR:$Vd,5393 (v8i16 (ARMvorrImm QPR:$src, timm:$SIMM)))]> {5394 let Inst{9} = SIMM{9};5395}5396 5397def VORRiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 0, 1,5398 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),5399 IIC_VMOVImm,5400 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",5401 [(set QPR:$Vd,5402 (v4i32 (ARMvorrImm QPR:$src, timm:$SIMM)))]> {5403 let Inst{10-9} = SIMM{10-9};5404}5405 5406 5407// VBIC : Vector Bitwise Bit Clear (AND NOT)5408let TwoOperandAliasConstraint = "$Vn = $Vd" in {5409def VBICd : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),5410 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,5411 "vbic", "$Vd, $Vn, $Vm", "",5412 [(set DPR:$Vd, (v2i32 (and DPR:$Vn,5413 (vnotd DPR:$Vm))))]>;5414def VBICq : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),5415 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,5416 "vbic", "$Vd, $Vn, $Vm", "",5417 [(set QPR:$Vd, (v4i32 (and QPR:$Vn,5418 (vnotq QPR:$Vm))))]>;5419}5420 5421let Predicates = [HasNEON] in {5422 defm : BitwisePatterns<"VBIC", BinOpFrag<(and node:$LHS, (vnotd node:$RHS))>,5423 BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>>;5424}5425 5426def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1,5427 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),5428 IIC_VMOVImm,5429 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",5430 [(set DPR:$Vd,5431 (v4i16 (ARMvbicImm DPR:$src, timm:$SIMM)))]> {5432 let Inst{9} = SIMM{9};5433}5434 5435def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1,5436 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),5437 IIC_VMOVImm,5438 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",5439 [(set DPR:$Vd,5440 (v2i32 (ARMvbicImm DPR:$src, timm:$SIMM)))]> {5441 let Inst{10-9} = SIMM{10-9};5442}5443 5444def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1,5445 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),5446 IIC_VMOVImm,5447 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",5448 [(set QPR:$Vd,5449 (v8i16 (ARMvbicImm QPR:$src, timm:$SIMM)))]> {5450 let Inst{9} = SIMM{9};5451}5452 5453def VBICiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 1, 1,5454 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),5455 IIC_VMOVImm,5456 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",5457 [(set QPR:$Vd,5458 (v4i32 (ARMvbicImm QPR:$src, timm:$SIMM)))]> {5459 let Inst{10-9} = SIMM{10-9};5460}5461 5462// VORN : Vector Bitwise OR NOT5463def VORNd : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$Vd),5464 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,5465 "vorn", "$Vd, $Vn, $Vm", "",5466 [(set DPR:$Vd, (v2i32 (or DPR:$Vn,5467 (vnotd DPR:$Vm))))]>;5468def VORNq : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd),5469 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,5470 "vorn", "$Vd, $Vn, $Vm", "",5471 [(set QPR:$Vd, (v4i32 (or QPR:$Vn,5472 (vnotq QPR:$Vm))))]>;5473 5474let Predicates = [HasNEON] in {5475 defm : BitwisePatterns<"VORN", BinOpFrag<(or node:$LHS, (vnotd node:$RHS))>,5476 BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>>;5477}5478 5479// VMVN : Vector Bitwise NOT (Immediate)5480 5481let isReMaterializable = 1 in {5482 5483def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd),5484 (ins nImmSplatI16:$SIMM), IIC_VMOVImm,5485 "vmvn", "i16", "$Vd, $SIMM", "",5486 [(set DPR:$Vd, (v4i16 (ARMvmvnImm timm:$SIMM)))]> {5487 let Inst{9} = SIMM{9};5488}5489 5490def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd),5491 (ins nImmSplatI16:$SIMM), IIC_VMOVImm,5492 "vmvn", "i16", "$Vd, $SIMM", "",5493 [(set QPR:$Vd, (v8i16 (ARMvmvnImm timm:$SIMM)))]> {5494 let Inst{9} = SIMM{9};5495}5496 5497def VMVNv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 1, 1, (outs DPR:$Vd),5498 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,5499 "vmvn", "i32", "$Vd, $SIMM", "",5500 [(set DPR:$Vd, (v2i32 (ARMvmvnImm timm:$SIMM)))]> {5501 let Inst{11-8} = SIMM{11-8};5502}5503 5504def VMVNv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 1, 1, (outs QPR:$Vd),5505 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,5506 "vmvn", "i32", "$Vd, $SIMM", "",5507 [(set QPR:$Vd, (v4i32 (ARMvmvnImm timm:$SIMM)))]> {5508 let Inst{11-8} = SIMM{11-8};5509}5510}5511 5512// VMVN : Vector Bitwise NOT5513def VMVNd : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0,5514 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VSUBiD,5515 "vmvn", "$Vd, $Vm", "",5516 [(set DPR:$Vd, (v2i32 (vnotd DPR:$Vm)))]>;5517def VMVNq : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0,5518 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VSUBiD,5519 "vmvn", "$Vd, $Vm", "",5520 [(set QPR:$Vd, (v4i32 (vnotq QPR:$Vm)))]>;5521let Predicates = [HasNEON] in {5522def : Pat<(v1i64 (vnotd DPR:$src)),5523 (VMVNd DPR:$src)>;5524def : Pat<(v4i16 (vnotd DPR:$src)),5525 (VMVNd DPR:$src)>;5526def : Pat<(v8i8 (vnotd DPR:$src)),5527 (VMVNd DPR:$src)>;5528def : Pat<(v2i64 (vnotq QPR:$src)),5529 (VMVNq QPR:$src)>;5530def : Pat<(v8i16 (vnotq QPR:$src)),5531 (VMVNq QPR:$src)>;5532def : Pat<(v16i8 (vnotq QPR:$src)),5533 (VMVNq QPR:$src)>;5534}5535 5536// The TwoAddress pass will not go looking for equivalent operations5537// with different register constraints; it just inserts copies.5538// That is why pseudo VBSP implemented. Is is expanded later into5539// VBIT/VBIF/VBSL taking into account register constraints to avoid copies.5540def VBSPd : PseudoNeonI<(outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),5541 IIC_VBINiD, "", []>;5542let Predicates = [HasNEON] in {5543def : Pat<(v8i8 (NEONvbsp (v8i8 DPR:$src1),5544 (v8i8 DPR:$Vn), (v8i8 DPR:$Vm))),5545 (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;5546def : Pat<(v4i16 (NEONvbsp (v4i16 DPR:$src1),5547 (v4i16 DPR:$Vn), (v4i16 DPR:$Vm))),5548 (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;5549def : Pat<(v2i32 (NEONvbsp (v2i32 DPR:$src1),5550 (v2i32 DPR:$Vn), (v2i32 DPR:$Vm))),5551 (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;5552def : Pat<(v2f32 (NEONvbsp (v2f32 DPR:$src1),5553 (v2f32 DPR:$Vn), (v2f32 DPR:$Vm))),5554 (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;5555def : Pat<(v1i64 (NEONvbsp (v1i64 DPR:$src1),5556 (v1i64 DPR:$Vn), (v1i64 DPR:$Vm))),5557 (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;5558 5559def : Pat<(v8i8 (or (and DPR:$Vn, DPR:$Vd),5560 (and DPR:$Vm, (vnotd DPR:$Vd)))),5561 (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;5562def : Pat<(v4i16 (or (and DPR:$Vn, DPR:$Vd),5563 (and DPR:$Vm, (vnotd DPR:$Vd)))),5564 (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;5565def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),5566 (and DPR:$Vm, (vnotd DPR:$Vd)))),5567 (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;5568def : Pat<(v1i64 (or (and DPR:$Vn, DPR:$Vd),5569 (and DPR:$Vm, (vnotd DPR:$Vd)))),5570 (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;5571}5572 5573def VBSPq : PseudoNeonI<(outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),5574 IIC_VBINiQ, "", []>;5575let Predicates = [HasNEON] in {5576def : Pat<(v16i8 (NEONvbsp (v16i8 QPR:$src1),5577 (v16i8 QPR:$Vn), (v16i8 QPR:$Vm))),5578 (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;5579def : Pat<(v8i16 (NEONvbsp (v8i16 QPR:$src1),5580 (v8i16 QPR:$Vn), (v8i16 QPR:$Vm))),5581 (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;5582def : Pat<(v4i32 (NEONvbsp (v4i32 QPR:$src1),5583 (v4i32 QPR:$Vn), (v4i32 QPR:$Vm))),5584 (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;5585def : Pat<(v4f32 (NEONvbsp (v4f32 QPR:$src1),5586 (v4f32 QPR:$Vn), (v4f32 QPR:$Vm))),5587 (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;5588def : Pat<(v2i64 (NEONvbsp (v2i64 QPR:$src1),5589 (v2i64 QPR:$Vn), (v2i64 QPR:$Vm))),5590 (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;5591 5592def : Pat<(v16i8 (or (and QPR:$Vn, QPR:$Vd),5593 (and QPR:$Vm, (vnotq QPR:$Vd)))),5594 (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;5595def : Pat<(v8i16 (or (and QPR:$Vn, QPR:$Vd),5596 (and QPR:$Vm, (vnotq QPR:$Vd)))),5597 (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;5598def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),5599 (and QPR:$Vm, (vnotq QPR:$Vd)))),5600 (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;5601def : Pat<(v2i64 (or (and QPR:$Vn, QPR:$Vd),5602 (and QPR:$Vm, (vnotq QPR:$Vd)))),5603 (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;5604}5605 5606// VBSL : Vector Bitwise Select5607def VBSLd : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),5608 (ins DPR:$src1, DPR:$Vn, DPR:$Vm),5609 N3RegFrm, IIC_VBINiD,5610 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",5611 []>;5612 5613def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),5614 (ins QPR:$src1, QPR:$Vn, QPR:$Vm),5615 N3RegFrm, IIC_VBINiQ,5616 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",5617 []>;5618 5619// VBIF : Vector Bitwise Insert if False5620// like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",5621def VBIFd : N3VX<1, 0, 0b11, 0b0001, 0, 1,5622 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),5623 N3RegFrm, IIC_VBINiD,5624 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",5625 []>;5626def VBIFq : N3VX<1, 0, 0b11, 0b0001, 1, 1,5627 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),5628 N3RegFrm, IIC_VBINiQ,5629 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",5630 []>;5631 5632// VBIT : Vector Bitwise Insert if True5633// like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst",5634def VBITd : N3VX<1, 0, 0b10, 0b0001, 0, 1,5635 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),5636 N3RegFrm, IIC_VBINiD,5637 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",5638 []>;5639def VBITq : N3VX<1, 0, 0b10, 0b0001, 1, 1,5640 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),5641 N3RegFrm, IIC_VBINiQ,5642 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",5643 []>;5644 5645// Vector Absolute Differences.5646 5647// VABD : Vector Absolute Difference5648defm VABDs : N3VInt_QHS<0, 0, 0b0111, 0, N3RegFrm,5649 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5650 "vabd", "s", abds, 1>;5651defm VABDu : N3VInt_QHS<1, 0, 0b0111, 0, N3RegFrm,5652 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5653 "vabd", "u", abdu, 1>;5654def VABDfd : N3VDInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBIND,5655 "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 1>;5656def VABDfq : N3VQInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBINQ,5657 "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 1>;5658def VABDhd : N3VDInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBIND,5659 "vabd", "f16", v4f16, v4f16, int_arm_neon_vabds, 1>,5660 Requires<[HasNEON, HasFullFP16]>;5661def VABDhq : N3VQInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBINQ,5662 "vabd", "f16", v8f16, v8f16, int_arm_neon_vabds, 1>,5663 Requires<[HasNEON, HasFullFP16]>;5664 5665// VABDL : Vector Absolute Difference Long (Q = | D - D |)5666defm VABDLs : N3VLIntExt_QHS<0,1,0b0111,0, IIC_VSUBi4Q,5667 "vabdl", "s", abds, zext, 1>;5668defm VABDLu : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q,5669 "vabdl", "u", abdu, zext, 1>;5670 5671let Predicates = [HasNEON] in {5672def : Pat<(v8i16 (zext (abdu (v8i8 DPR:$opA), (v8i8 DPR:$opB)))),5673 (VABDLuv8i16 DPR:$opA, DPR:$opB)>;5674def : Pat<(v4i32 (zext (abdu (v4i16 DPR:$opA), (v4i16 DPR:$opB)))),5675 (VABDLuv4i32 DPR:$opA, DPR:$opB)>;5676def : Pat<(v2i64 (zext (abdu (v2i32 DPR:$opA), (v2i32 DPR:$opB)))),5677 (VABDLuv2i64 DPR:$opA, DPR:$opB)>;5678}5679 5680// VABA : Vector Absolute Difference and Accumulate5681defm VABAs : N3VIntOp_QHS<0,0,0b0111,1, IIC_VABAD, IIC_VABAQ,5682 "vaba", "s", abds, add>;5683defm VABAu : N3VIntOp_QHS<1,0,0b0111,1, IIC_VABAD, IIC_VABAQ,5684 "vaba", "u", abdu, add>;5685 5686// VABAL : Vector Absolute Difference and Accumulate Long (Q += | D - D |)5687defm VABALs : N3VLIntExtOp_QHS<0,1,0b0101,0, IIC_VABAD,5688 "vabal", "s", abds, zext, add>;5689defm VABALu : N3VLIntExtOp_QHS<1,1,0b0101,0, IIC_VABAD,5690 "vabal", "u", abdu, zext, add>;5691 5692// Vector Maximum and Minimum.5693 5694// VMAX : Vector Maximum5695defm VMAXs : N3VInt_QHS<0, 0, 0b0110, 0, N3RegFrm,5696 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5697 "vmax", "s", smax, 1>;5698defm VMAXu : N3VInt_QHS<1, 0, 0b0110, 0, N3RegFrm,5699 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5700 "vmax", "u", umax, 1>;5701def VMAXfd : N3VDInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBIND,5702 "vmax", "f32",5703 v2f32, v2f32, fmaximum, 1>;5704def VMAXfq : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ,5705 "vmax", "f32",5706 v4f32, v4f32, fmaximum, 1>;5707def VMAXhd : N3VDInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBIND,5708 "vmax", "f16",5709 v4f16, v4f16, fmaximum, 1>,5710 Requires<[HasNEON, HasFullFP16]>;5711def VMAXhq : N3VQInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBINQ,5712 "vmax", "f16",5713 v8f16, v8f16, fmaximum, 1>,5714 Requires<[HasNEON, HasFullFP16]>;5715 5716// VMAXNM5717let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {5718 def NEON_VMAXNMNDf : N3VDIntnp<0b00110, 0b00, 0b1111, 0, 1,5719 N3RegFrm, NoItinerary, "vmaxnm", "f32",5720 v2f32, v2f32, fmaxnum, 1>,5721 Requires<[HasFPARMv8, HasNEON]>;5722 def NEON_VMAXNMNQf : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1,5723 N3RegFrm, NoItinerary, "vmaxnm", "f32",5724 v4f32, v4f32, fmaxnum, 1>,5725 Requires<[HasFPARMv8, HasNEON]>;5726 def NEON_VMAXNMNDh : N3VDIntnp<0b00110, 0b01, 0b1111, 0, 1,5727 N3RegFrm, NoItinerary, "vmaxnm", "f16",5728 v4f16, v4f16, fmaxnum, 1>,5729 Requires<[HasFPARMv8, HasNEON, HasFullFP16]>;5730 def NEON_VMAXNMNQh : N3VQIntnp<0b00110, 0b01, 0b1111, 1, 1,5731 N3RegFrm, NoItinerary, "vmaxnm", "f16",5732 v8f16, v8f16, fmaxnum, 1>,5733 Requires<[HasFPARMv8, HasNEON, HasFullFP16]>;5734}5735 5736// VMIN : Vector Minimum5737defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm,5738 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5739 "vmin", "s", smin, 1>;5740defm VMINu : N3VInt_QHS<1, 0, 0b0110, 1, N3RegFrm,5741 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,5742 "vmin", "u", umin, 1>;5743def VMINfd : N3VDInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBIND,5744 "vmin", "f32",5745 v2f32, v2f32, fminimum, 1>;5746def VMINfq : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ,5747 "vmin", "f32",5748 v4f32, v4f32, fminimum, 1>;5749def VMINhd : N3VDInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBIND,5750 "vmin", "f16",5751 v4f16, v4f16, fminimum, 1>,5752 Requires<[HasNEON, HasFullFP16]>;5753def VMINhq : N3VQInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBINQ,5754 "vmin", "f16",5755 v8f16, v8f16, fminimum, 1>,5756 Requires<[HasNEON, HasFullFP16]>;5757 5758// VMINNM5759let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {5760 def NEON_VMINNMNDf : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1,5761 N3RegFrm, NoItinerary, "vminnm", "f32",5762 v2f32, v2f32, fminnum, 1>,5763 Requires<[HasFPARMv8, HasNEON]>;5764 def NEON_VMINNMNQf : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1,5765 N3RegFrm, NoItinerary, "vminnm", "f32",5766 v4f32, v4f32, fminnum, 1>,5767 Requires<[HasFPARMv8, HasNEON]>;5768 def NEON_VMINNMNDh : N3VDIntnp<0b00110, 0b11, 0b1111, 0, 1,5769 N3RegFrm, NoItinerary, "vminnm", "f16",5770 v4f16, v4f16, fminnum, 1>,5771 Requires<[HasFPARMv8, HasNEON, HasFullFP16]>;5772 def NEON_VMINNMNQh : N3VQIntnp<0b00110, 0b11, 0b1111, 1, 1,5773 N3RegFrm, NoItinerary, "vminnm", "f16",5774 v8f16, v8f16, fminnum, 1>,5775 Requires<[HasFPARMv8, HasNEON, HasFullFP16]>;5776}5777 5778// Vector Pairwise Operations.5779 5780// VPADD : Vector Pairwise Add5781def VPADDi8 : N3VDInt<0, 0, 0b00, 0b1011, 1, N3RegFrm, IIC_VSHLiD,5782 "vpadd", "i8",5783 v8i8, v8i8, int_arm_neon_vpadd, 0>;5784def VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, N3RegFrm, IIC_VSHLiD,5785 "vpadd", "i16",5786 v4i16, v4i16, int_arm_neon_vpadd, 0>;5787def VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, N3RegFrm, IIC_VSHLiD,5788 "vpadd", "i32",5789 v2i32, v2i32, int_arm_neon_vpadd, 0>;5790def VPADDf : N3VDInt<1, 0, 0b00, 0b1101, 0, N3RegFrm,5791 IIC_VPBIND, "vpadd", "f32",5792 v2f32, v2f32, int_arm_neon_vpadd, 0>;5793def VPADDh : N3VDInt<1, 0, 0b01, 0b1101, 0, N3RegFrm,5794 IIC_VPBIND, "vpadd", "f16",5795 v4f16, v4f16, int_arm_neon_vpadd, 0>,5796 Requires<[HasNEON, HasFullFP16]>;5797 5798// VPADDL : Vector Pairwise Add Long5799defm VPADDLs : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s",5800 int_arm_neon_vpaddls>;5801defm VPADDLu : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u",5802 int_arm_neon_vpaddlu>;5803 5804// VPADAL : Vector Pairwise Add and Accumulate Long5805defm VPADALs : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s",5806 int_arm_neon_vpadals>;5807defm VPADALu : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u",5808 int_arm_neon_vpadalu>;5809 5810// VPMAX : Vector Pairwise Maximum5811def VPMAXs8 : N3VDInt<0, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5812 "s8", v8i8, v8i8, int_arm_neon_vpmaxs, 0>;5813def VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5814 "s16", v4i16, v4i16, int_arm_neon_vpmaxs, 0>;5815def VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5816 "s32", v2i32, v2i32, int_arm_neon_vpmaxs, 0>;5817def VPMAXu8 : N3VDInt<1, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5818 "u8", v8i8, v8i8, int_arm_neon_vpmaxu, 0>;5819def VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5820 "u16", v4i16, v4i16, int_arm_neon_vpmaxu, 0>;5821def VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",5822 "u32", v2i32, v2i32, int_arm_neon_vpmaxu, 0>;5823def VPMAXf : N3VDInt<1, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax",5824 "f32", v2f32, v2f32, int_arm_neon_vpmaxs, 0>;5825def VPMAXh : N3VDInt<1, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax",5826 "f16", v4f16, v4f16, int_arm_neon_vpmaxs, 0>,5827 Requires<[HasNEON, HasFullFP16]>;5828 5829// VPMIN : Vector Pairwise Minimum5830def VPMINs8 : N3VDInt<0, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5831 "s8", v8i8, v8i8, int_arm_neon_vpmins, 0>;5832def VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5833 "s16", v4i16, v4i16, int_arm_neon_vpmins, 0>;5834def VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5835 "s32", v2i32, v2i32, int_arm_neon_vpmins, 0>;5836def VPMINu8 : N3VDInt<1, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5837 "u8", v8i8, v8i8, int_arm_neon_vpminu, 0>;5838def VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5839 "u16", v4i16, v4i16, int_arm_neon_vpminu, 0>;5840def VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",5841 "u32", v2i32, v2i32, int_arm_neon_vpminu, 0>;5842def VPMINf : N3VDInt<1, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin",5843 "f32", v2f32, v2f32, int_arm_neon_vpmins, 0>;5844def VPMINh : N3VDInt<1, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin",5845 "f16", v4f16, v4f16, int_arm_neon_vpmins, 0>,5846 Requires<[HasNEON, HasFullFP16]>;5847 5848// Vector Reciprocal and Reciprocal Square Root Estimate and Step.5849 5850// VRECPE : Vector Reciprocal Estimate5851def VRECPEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,5852 IIC_VUNAD, "vrecpe", "u32",5853 v2i32, v2i32, int_arm_neon_vrecpe>;5854def VRECPEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,5855 IIC_VUNAQ, "vrecpe", "u32",5856 v4i32, v4i32, int_arm_neon_vrecpe>;5857def VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,5858 IIC_VUNAD, "vrecpe", "f32",5859 v2f32, v2f32, int_arm_neon_vrecpe>;5860def VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,5861 IIC_VUNAQ, "vrecpe", "f32",5862 v4f32, v4f32, int_arm_neon_vrecpe>;5863def VRECPEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0,5864 IIC_VUNAD, "vrecpe", "f16",5865 v4f16, v4f16, int_arm_neon_vrecpe>,5866 Requires<[HasNEON, HasFullFP16]>;5867def VRECPEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0,5868 IIC_VUNAQ, "vrecpe", "f16",5869 v8f16, v8f16, int_arm_neon_vrecpe>,5870 Requires<[HasNEON, HasFullFP16]>;5871 5872// VRECPS : Vector Reciprocal Step5873def VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,5874 IIC_VRECSD, "vrecps", "f32",5875 v2f32, v2f32, int_arm_neon_vrecps, 1>;5876def VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,5877 IIC_VRECSQ, "vrecps", "f32",5878 v4f32, v4f32, int_arm_neon_vrecps, 1>;5879def VRECPShd : N3VDInt<0, 0, 0b01, 0b1111, 1, N3RegFrm,5880 IIC_VRECSD, "vrecps", "f16",5881 v4f16, v4f16, int_arm_neon_vrecps, 1>,5882 Requires<[HasNEON, HasFullFP16]>;5883def VRECPShq : N3VQInt<0, 0, 0b01, 0b1111, 1, N3RegFrm,5884 IIC_VRECSQ, "vrecps", "f16",5885 v8f16, v8f16, int_arm_neon_vrecps, 1>,5886 Requires<[HasNEON, HasFullFP16]>;5887 5888// VRSQRTE : Vector Reciprocal Square Root Estimate5889def VRSQRTEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,5890 IIC_VUNAD, "vrsqrte", "u32",5891 v2i32, v2i32, int_arm_neon_vrsqrte>;5892def VRSQRTEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,5893 IIC_VUNAQ, "vrsqrte", "u32",5894 v4i32, v4i32, int_arm_neon_vrsqrte>;5895def VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,5896 IIC_VUNAD, "vrsqrte", "f32",5897 v2f32, v2f32, int_arm_neon_vrsqrte>;5898def VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,5899 IIC_VUNAQ, "vrsqrte", "f32",5900 v4f32, v4f32, int_arm_neon_vrsqrte>;5901def VRSQRTEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0,5902 IIC_VUNAD, "vrsqrte", "f16",5903 v4f16, v4f16, int_arm_neon_vrsqrte>,5904 Requires<[HasNEON, HasFullFP16]>;5905def VRSQRTEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0,5906 IIC_VUNAQ, "vrsqrte", "f16",5907 v8f16, v8f16, int_arm_neon_vrsqrte>,5908 Requires<[HasNEON, HasFullFP16]>;5909 5910// VRSQRTS : Vector Reciprocal Square Root Step5911def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,5912 IIC_VRECSD, "vrsqrts", "f32",5913 v2f32, v2f32, int_arm_neon_vrsqrts, 1>;5914def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,5915 IIC_VRECSQ, "vrsqrts", "f32",5916 v4f32, v4f32, int_arm_neon_vrsqrts, 1>;5917def VRSQRTShd : N3VDInt<0, 0, 0b11, 0b1111, 1, N3RegFrm,5918 IIC_VRECSD, "vrsqrts", "f16",5919 v4f16, v4f16, int_arm_neon_vrsqrts, 1>,5920 Requires<[HasNEON, HasFullFP16]>;5921def VRSQRTShq : N3VQInt<0, 0, 0b11, 0b1111, 1, N3RegFrm,5922 IIC_VRECSQ, "vrsqrts", "f16",5923 v8f16, v8f16, int_arm_neon_vrsqrts, 1>,5924 Requires<[HasNEON, HasFullFP16]>;5925 5926// Vector Shifts.5927 5928// VSHL : Vector Shift5929defm VSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 0, N3RegVShFrm,5930 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,5931 "vshl", "s", int_arm_neon_vshifts>;5932defm VSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 0, N3RegVShFrm,5933 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,5934 "vshl", "u", int_arm_neon_vshiftu>;5935 5936let Predicates = [HasNEON] in {5937def : Pat<(v8i8 (ARMvshls (v8i8 DPR:$Dn), (v8i8 DPR:$Dm))),5938 (VSHLsv8i8 DPR:$Dn, DPR:$Dm)>;5939def : Pat<(v4i16 (ARMvshls (v4i16 DPR:$Dn), (v4i16 DPR:$Dm))),5940 (VSHLsv4i16 DPR:$Dn, DPR:$Dm)>;5941def : Pat<(v2i32 (ARMvshls (v2i32 DPR:$Dn), (v2i32 DPR:$Dm))),5942 (VSHLsv2i32 DPR:$Dn, DPR:$Dm)>;5943def : Pat<(v1i64 (ARMvshls (v1i64 DPR:$Dn), (v1i64 DPR:$Dm))),5944 (VSHLsv1i64 DPR:$Dn, DPR:$Dm)>;5945def : Pat<(v16i8 (ARMvshls (v16i8 QPR:$Dn), (v16i8 QPR:$Dm))),5946 (VSHLsv16i8 QPR:$Dn, QPR:$Dm)>;5947def : Pat<(v8i16 (ARMvshls (v8i16 QPR:$Dn), (v8i16 QPR:$Dm))),5948 (VSHLsv8i16 QPR:$Dn, QPR:$Dm)>;5949def : Pat<(v4i32 (ARMvshls (v4i32 QPR:$Dn), (v4i32 QPR:$Dm))),5950 (VSHLsv4i32 QPR:$Dn, QPR:$Dm)>;5951def : Pat<(v2i64 (ARMvshls (v2i64 QPR:$Dn), (v2i64 QPR:$Dm))),5952 (VSHLsv2i64 QPR:$Dn, QPR:$Dm)>;5953 5954def : Pat<(v8i8 (ARMvshlu (v8i8 DPR:$Dn), (v8i8 DPR:$Dm))),5955 (VSHLuv8i8 DPR:$Dn, DPR:$Dm)>;5956def : Pat<(v4i16 (ARMvshlu (v4i16 DPR:$Dn), (v4i16 DPR:$Dm))),5957 (VSHLuv4i16 DPR:$Dn, DPR:$Dm)>;5958def : Pat<(v2i32 (ARMvshlu (v2i32 DPR:$Dn), (v2i32 DPR:$Dm))),5959 (VSHLuv2i32 DPR:$Dn, DPR:$Dm)>;5960def : Pat<(v1i64 (ARMvshlu (v1i64 DPR:$Dn), (v1i64 DPR:$Dm))),5961 (VSHLuv1i64 DPR:$Dn, DPR:$Dm)>;5962def : Pat<(v16i8 (ARMvshlu (v16i8 QPR:$Dn), (v16i8 QPR:$Dm))),5963 (VSHLuv16i8 QPR:$Dn, QPR:$Dm)>;5964def : Pat<(v8i16 (ARMvshlu (v8i16 QPR:$Dn), (v8i16 QPR:$Dm))),5965 (VSHLuv8i16 QPR:$Dn, QPR:$Dm)>;5966def : Pat<(v4i32 (ARMvshlu (v4i32 QPR:$Dn), (v4i32 QPR:$Dm))),5967 (VSHLuv4i32 QPR:$Dn, QPR:$Dm)>;5968def : Pat<(v2i64 (ARMvshlu (v2i64 QPR:$Dn), (v2i64 QPR:$Dm))),5969 (VSHLuv2i64 QPR:$Dn, QPR:$Dm)>;5970 5971}5972 5973// VSHL : Vector Shift Left (Immediate)5974defm VSHLi : N2VShL_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", ARMvshlImm>;5975 5976// VSHR : Vector Shift Right (Immediate)5977defm VSHRs : N2VShR_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s",5978 ARMvshrsImm>;5979defm VSHRu : N2VShR_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u",5980 ARMvshruImm>;5981 5982// VSHLL : Vector Shift Left Long5983defm VSHLLs : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s",5984 PatFrag<(ops node:$LHS, node:$RHS), (ARMvshlImm (sext node:$LHS), node:$RHS)>>;5985defm VSHLLu : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u",5986 PatFrag<(ops node:$LHS, node:$RHS), (ARMvshlImm (zext node:$LHS), node:$RHS)>>;5987 5988// VSHLL : Vector Shift Left Long (with maximum shift count)5989class N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,5990 bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy,5991 ValueType OpTy, Operand ImmTy>5992 : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,5993 ResTy, OpTy, ImmTy, null_frag> {5994 let Inst{21-16} = op21_16;5995 let DecoderMethod = "DecodeVSHLMaxInstruction";5996}5997def VSHLLi8 : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",5998 v8i16, v8i8, imm8>;5999def VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16",6000 v4i32, v4i16, imm16>;6001def VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32",6002 v2i64, v2i32, imm32>;6003 6004let Predicates = [HasNEON] in {6005def : Pat<(v8i16 (ARMvshlImm (zext (v8i8 DPR:$Rn)), (i32 8))),6006 (VSHLLi8 DPR:$Rn, 8)>;6007def : Pat<(v4i32 (ARMvshlImm (zext (v4i16 DPR:$Rn)), (i32 16))),6008 (VSHLLi16 DPR:$Rn, 16)>;6009def : Pat<(v2i64 (ARMvshlImm (zext (v2i32 DPR:$Rn)), (i32 32))),6010 (VSHLLi32 DPR:$Rn, 32)>;6011def : Pat<(v8i16 (ARMvshlImm (sext (v8i8 DPR:$Rn)), (i32 8))),6012 (VSHLLi8 DPR:$Rn, 8)>;6013def : Pat<(v4i32 (ARMvshlImm (sext (v4i16 DPR:$Rn)), (i32 16))),6014 (VSHLLi16 DPR:$Rn, 16)>;6015def : Pat<(v2i64 (ARMvshlImm (sext (v2i32 DPR:$Rn)), (i32 32))),6016 (VSHLLi32 DPR:$Rn, 32)>;6017def : Pat<(v8i16 (ARMvshlImm (anyext (v8i8 DPR:$Rn)), (i32 8))),6018 (VSHLLi8 DPR:$Rn, 8)>;6019def : Pat<(v4i32 (ARMvshlImm (anyext (v4i16 DPR:$Rn)), (i32 16))),6020 (VSHLLi16 DPR:$Rn, 16)>;6021def : Pat<(v2i64 (ARMvshlImm (anyext (v2i32 DPR:$Rn)), (i32 32))),6022 (VSHLLi32 DPR:$Rn, 32)>;6023}6024 6025// VSHRN : Vector Shift Right and Narrow6026defm VSHRN : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i",6027 PatFrag<(ops node:$Rn, node:$amt),6028 (trunc (ARMvshrsImm node:$Rn, node:$amt))>>;6029 6030let Predicates = [HasNEON] in {6031def : Pat<(v8i8 (trunc (ARMvshruImm (v8i16 QPR:$Vn), shr_imm8:$amt))),6032 (VSHRNv8i8 QPR:$Vn, shr_imm8:$amt)>;6033def : Pat<(v4i16 (trunc (ARMvshruImm (v4i32 QPR:$Vn), shr_imm16:$amt))),6034 (VSHRNv4i16 QPR:$Vn, shr_imm16:$amt)>;6035def : Pat<(v2i32 (trunc (ARMvshruImm (v2i64 QPR:$Vn), shr_imm32:$amt))),6036 (VSHRNv2i32 QPR:$Vn, shr_imm32:$amt)>;6037}6038 6039// VRSHL : Vector Rounding Shift6040defm VRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 0, N3RegVShFrm,6041 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6042 "vrshl", "s", int_arm_neon_vrshifts>;6043defm VRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 0, N3RegVShFrm,6044 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6045 "vrshl", "u", int_arm_neon_vrshiftu>;6046// VRSHR : Vector Rounding Shift Right6047defm VRSHRs : N2VShR_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s",6048 NEONvrshrsImm>;6049defm VRSHRu : N2VShR_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u",6050 NEONvrshruImm>;6051 6052// VRSHRN : Vector Rounding Shift Right and Narrow6053defm VRSHRN : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",6054 NEONvrshrnImm>;6055 6056// VQSHL : Vector Saturating Shift6057defm VQSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 1, N3RegVShFrm,6058 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6059 "vqshl", "s", int_arm_neon_vqshifts>;6060defm VQSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 1, N3RegVShFrm,6061 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6062 "vqshl", "u", int_arm_neon_vqshiftu>;6063// VQSHL : Vector Saturating Shift Left (Immediate)6064defm VQSHLsi : N2VShL_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s",NEONvqshlsImm>;6065defm VQSHLui : N2VShL_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u",NEONvqshluImm>;6066 6067// VQSHLU : Vector Saturating Shift Left (Immediate, Unsigned)6068defm VQSHLsu : N2VShL_QHSD<1,1,0b0110,1, IIC_VSHLi4D,"vqshlu","s",NEONvqshlsuImm>;6069 6070// VQSHRN : Vector Saturating Shift Right and Narrow6071defm VQSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",6072 NEONvqshrnsImm>;6073defm VQSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u",6074 NEONvqshrnuImm>;6075 6076// VQSHRUN : Vector Saturating Shift Right and Narrow (Unsigned)6077defm VQSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s",6078 NEONvqshrnsuImm>;6079 6080// VQRSHL : Vector Saturating Rounding Shift6081defm VQRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 1, N3RegVShFrm,6082 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6083 "vqrshl", "s", int_arm_neon_vqrshifts>;6084defm VQRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 1, N3RegVShFrm,6085 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,6086 "vqrshl", "u", int_arm_neon_vqrshiftu>;6087 6088// VQRSHRN : Vector Saturating Rounding Shift Right and Narrow6089defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s",6090 NEONvqrshrnsImm>;6091defm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u",6092 NEONvqrshrnuImm>;6093 6094// VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned)6095defm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s",6096 NEONvqrshrnsuImm>;6097 6098// VSRA : Vector Shift Right and Accumulate6099defm VSRAs : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", ARMvshrsImm>;6100defm VSRAu : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", ARMvshruImm>;6101// VRSRA : Vector Rounding Shift Right and Accumulate6102defm VRSRAs : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrsImm>;6103defm VRSRAu : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshruImm>;6104 6105// VSLI : Vector Shift Left and Insert6106defm VSLI : N2VShInsL_QHSD<1, 1, 0b0101, 1, "vsli">;6107 6108// VSRI : Vector Shift Right and Insert6109defm VSRI : N2VShInsR_QHSD<1, 1, 0b0100, 1, "vsri">;6110 6111// Vector Absolute and Saturating Absolute.6112 6113// VABS : Vector Absolute Value6114defm VABS : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0,6115 IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", abs>;6116def VABSfd : N2VD<0b11, 0b11, 0b10, 0b01, 0b01110, 0,6117 "vabs", "f32",6118 v2f32, v2f32, fabs>;6119def VABSfq : N2VQ<0b11, 0b11, 0b10, 0b01, 0b01110, 0,6120 "vabs", "f32",6121 v4f32, v4f32, fabs>;6122def VABShd : N2VD<0b11, 0b11, 0b01, 0b01, 0b01110, 0,6123 "vabs", "f16",6124 v4f16, v4f16, fabs>,6125 Requires<[HasNEON, HasFullFP16]>;6126def VABShq : N2VQ<0b11, 0b11, 0b01, 0b01, 0b01110, 0,6127 "vabs", "f16",6128 v8f16, v8f16, fabs>,6129 Requires<[HasNEON, HasFullFP16]>;6130 6131// VQABS : Vector Saturating Absolute Value6132defm VQABS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0,6133 IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s",6134 int_arm_neon_vqabs>;6135 6136// Vector Negate.6137 6138def vnegd : PatFrag<(ops node:$in),6139 (sub ARMimmAllZerosD, node:$in)>;6140def vnegq : PatFrag<(ops node:$in),6141 (sub ARMimmAllZerosV, node:$in)>;6142 6143class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>6144 : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm),6145 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",6146 [(set DPR:$Vd, (Ty (vnegd DPR:$Vm)))]>;6147class VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>6148 : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$Vd), (ins QPR:$Vm),6149 IIC_VSHLiQ, OpcodeStr, Dt, "$Vd, $Vm", "",6150 [(set QPR:$Vd, (Ty (vnegq QPR:$Vm)))]>;6151 6152// VNEG : Vector Negate (integer)6153def VNEGs8d : VNEGD<0b00, "vneg", "s8", v8i8>;6154def VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>;6155def VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>;6156def VNEGs8q : VNEGQ<0b00, "vneg", "s8", v16i8>;6157def VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>;6158def VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>;6159 6160// VNEG : Vector Negate (floating-point)6161def VNEGfd : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,6162 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD,6163 "vneg", "f32", "$Vd, $Vm", "",6164 [(set DPR:$Vd, (v2f32 (fneg DPR:$Vm)))]>;6165def VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0,6166 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ,6167 "vneg", "f32", "$Vd, $Vm", "",6168 [(set QPR:$Vd, (v4f32 (fneg QPR:$Vm)))]>;6169def VNEGhd : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 0, 0,6170 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD,6171 "vneg", "f16", "$Vd, $Vm", "",6172 [(set DPR:$Vd, (v4f16 (fneg DPR:$Vm)))]>,6173 Requires<[HasNEON, HasFullFP16]>;6174def VNEGhq : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 1, 0,6175 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ,6176 "vneg", "f16", "$Vd, $Vm", "",6177 [(set QPR:$Vd, (v8f16 (fneg QPR:$Vm)))]>,6178 Requires<[HasNEON, HasFullFP16]>;6179 6180let Predicates = [HasNEON] in {6181def : Pat<(v8i8 (vnegd DPR:$src)), (VNEGs8d DPR:$src)>;6182def : Pat<(v4i16 (vnegd DPR:$src)), (VNEGs16d DPR:$src)>;6183def : Pat<(v2i32 (vnegd DPR:$src)), (VNEGs32d DPR:$src)>;6184def : Pat<(v16i8 (vnegq QPR:$src)), (VNEGs8q QPR:$src)>;6185def : Pat<(v8i16 (vnegq QPR:$src)), (VNEGs16q QPR:$src)>;6186def : Pat<(v4i32 (vnegq QPR:$src)), (VNEGs32q QPR:$src)>;6187}6188 6189// VQNEG : Vector Saturating Negate6190defm VQNEG : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0,6191 IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s",6192 int_arm_neon_vqneg>;6193 6194// Vector Bit Counting Operations.6195 6196// VCLS : Vector Count Leading Sign Bits6197defm VCLS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0,6198 IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s",6199 int_arm_neon_vcls>;6200// VCLZ : Vector Count Leading Zeros6201defm VCLZ : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0,6202 IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i",6203 ctlz>;6204// VCNT : Vector Count One Bits6205def VCNTd : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,6206 IIC_VCNTiD, "vcnt", "8",6207 v8i8, v8i8, ctpop>;6208def VCNTq : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,6209 IIC_VCNTiQ, "vcnt", "8",6210 v16i8, v16i8, ctpop>;6211 6212// Vector Swap6213def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,6214 (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2),6215 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",6216 []>;6217def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,6218 (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2),6219 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",6220 []>;6221 6222// Vector Move Operations.6223 6224// VMOV : Vector Move (Register)6225def : NEONInstAlias<"vmov${p} $Vd, $Vm",6226 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;6227def : NEONInstAlias<"vmov${p} $Vd, $Vm",6228 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;6229 6230// VMOV : Vector Move (Immediate)6231 6232// Although VMOVs are not strictly speaking cheap, they are as expensive6233// as their copies counterpart (VORR), so we should prefer rematerialization6234// over splitting when it applies.6235let isReMaterializable = 1, isAsCheapAsAMove=1 in {6236def VMOVv8i8 : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$Vd),6237 (ins nImmSplatI8:$SIMM), IIC_VMOVImm,6238 "vmov", "i8", "$Vd, $SIMM", "",6239 [(set DPR:$Vd, (v8i8 (ARMvmovImm timm:$SIMM)))]>;6240def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd),6241 (ins nImmSplatI8:$SIMM), IIC_VMOVImm,6242 "vmov", "i8", "$Vd, $SIMM", "",6243 [(set QPR:$Vd, (v16i8 (ARMvmovImm timm:$SIMM)))]>;6244 6245def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd),6246 (ins nImmSplatI16:$SIMM), IIC_VMOVImm,6247 "vmov", "i16", "$Vd, $SIMM", "",6248 [(set DPR:$Vd, (v4i16 (ARMvmovImm timm:$SIMM)))]> {6249 let Inst{9} = SIMM{9};6250}6251 6252def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd),6253 (ins nImmSplatI16:$SIMM), IIC_VMOVImm,6254 "vmov", "i16", "$Vd, $SIMM", "",6255 [(set QPR:$Vd, (v8i16 (ARMvmovImm timm:$SIMM)))]> {6256 let Inst{9} = SIMM{9};6257}6258 6259def VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 0, 1, (outs DPR:$Vd),6260 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,6261 "vmov", "i32", "$Vd, $SIMM", "",6262 [(set DPR:$Vd, (v2i32 (ARMvmovImm timm:$SIMM)))]> {6263 let Inst{11-8} = SIMM{11-8};6264}6265 6266def VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 0, 1, (outs QPR:$Vd),6267 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,6268 "vmov", "i32", "$Vd, $SIMM", "",6269 [(set QPR:$Vd, (v4i32 (ARMvmovImm timm:$SIMM)))]> {6270 let Inst{11-8} = SIMM{11-8};6271}6272 6273def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$Vd),6274 (ins nImmSplatI64:$SIMM), IIC_VMOVImm,6275 "vmov", "i64", "$Vd, $SIMM", "",6276 [(set DPR:$Vd, (v1i64 (ARMvmovImm timm:$SIMM)))]>;6277def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$Vd),6278 (ins nImmSplatI64:$SIMM), IIC_VMOVImm,6279 "vmov", "i64", "$Vd, $SIMM", "",6280 [(set QPR:$Vd, (v2i64 (ARMvmovImm timm:$SIMM)))]>;6281 6282def VMOVv2f32 : N1ModImm<1, 0b000, 0b1111, 0, 0, 0, 1, (outs DPR:$Vd),6283 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,6284 "vmov", "f32", "$Vd, $SIMM", "",6285 [(set DPR:$Vd, (v2f32 (ARMvmovFPImm timm:$SIMM)))]>;6286def VMOVv4f32 : N1ModImm<1, 0b000, 0b1111, 0, 1, 0, 1, (outs QPR:$Vd),6287 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,6288 "vmov", "f32", "$Vd, $SIMM", "",6289 [(set QPR:$Vd, (v4f32 (ARMvmovFPImm timm:$SIMM)))]>;6290} // isReMaterializable, isAsCheapAsAMove6291 6292// Add support for bytes replication feature, so it could be GAS compatible.6293multiclass NEONImmReplicateI8InstAlias<ValueType To> {6294 // E.g. instructions below:6295 // "vmov.i32 d0, #0xffffffff"6296 // "vmov.i32 d0, #0xabababab"6297 // "vmov.i16 d0, #0xabab"6298 // are incorrect, but we could deal with such cases.6299 // For last two instructions, for example, it should emit:6300 // "vmov.i8 d0, #0xab"6301 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",6302 (VMOVv8i8 DPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;6303 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",6304 (VMOVv16i8 QPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;6305 // Also add same support for VMVN instructions. So instruction:6306 // "vmvn.i32 d0, #0xabababab"6307 // actually means:6308 // "vmov.i8 d0, #0x54"6309 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",6310 (VMOVv8i8 DPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;6311 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",6312 (VMOVv16i8 QPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;6313}6314 6315defm : NEONImmReplicateI8InstAlias<i16>;6316defm : NEONImmReplicateI8InstAlias<i32>;6317defm : NEONImmReplicateI8InstAlias<i64>;6318 6319// Similar to above for types other than i8, e.g.:6320// "vmov.i32 d0, #0xab00ab00" -> "vmov.i16 d0, #0xab00"6321// "vmvn.i64 q0, #0xab000000ab000000" -> "vmvn.i32 q0, #0xab000000"6322// In this case we do not canonicalize VMVN to VMOV6323multiclass NEONImmReplicateInstAlias<ValueType From, NeonI V8, NeonI V16,6324 NeonI NV8, NeonI NV16, ValueType To> {6325 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",6326 (V8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;6327 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",6328 (V16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;6329 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",6330 (NV8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;6331 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",6332 (NV16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;6333}6334 6335defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,6336 VMVNv4i16, VMVNv8i16, i32>;6337defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,6338 VMVNv4i16, VMVNv8i16, i64>;6339defm : NEONImmReplicateInstAlias<i32, VMOVv2i32, VMOVv4i32,6340 VMVNv2i32, VMVNv4i32, i64>;6341// TODO: add "VMOV <-> VMVN" conversion for cases like6342// "vmov.i32 d0, #0xffaaffaa" -> "vmvn.i16 d0, #0x55"6343// "vmvn.i32 d0, #0xaaffaaff" -> "vmov.i16 d0, #0xff00"6344 6345// On some CPUs the two instructions "vmov.i32 dD, #0" and "vmov.i32 qD, #0"6346// require zero cycles to execute so they should be used wherever possible for6347// setting a register to zero.6348 6349// Even without these pseudo-insts we would probably end up with the correct6350// instruction, but we could not mark the general ones with "isAsCheapAsAMove"6351// since they are sometimes rather expensive (in general).6352 6353let AddedComplexity = 50, isAsCheapAsAMove = 1, isReMaterializable = 1 in {6354 def VMOVD0 : ARMPseudoExpand<(outs DPR:$Vd), (ins), 4, IIC_VMOVImm,6355 [(set DPR:$Vd, (v2i32 ARMimmAllZerosD))],6356 (VMOVv2i32 DPR:$Vd, 0, (ops 14, zero_reg))>,6357 Requires<[HasZCZ]>;6358 def VMOVQ0 : ARMPseudoExpand<(outs QPR:$Vd), (ins), 4, IIC_VMOVImm,6359 [(set QPR:$Vd, (v4i32 ARMimmAllZerosV))],6360 (VMOVv4i32 QPR:$Vd, 0, (ops 14, zero_reg))>,6361 Requires<[HasZCZ]>;6362}6363 6364// VMOV : Vector Get Lane (move scalar to ARM core register)6365 6366def VGETLNs8 : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?},6367 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),6368 IIC_VMOVSI, "vmov", "s8", "$R, $V$lane",6369 [(set GPR:$R, (ARMvgetlanes (v8i8 DPR:$V),6370 imm:$lane))]> {6371 let Inst{21} = lane{2};6372 let Inst{6-5} = lane{1-0};6373}6374def VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1},6375 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),6376 IIC_VMOVSI, "vmov", "s16", "$R, $V$lane",6377 [(set GPR:$R, (ARMvgetlanes (v4i16 DPR:$V),6378 imm:$lane))]> {6379 let Inst{21} = lane{1};6380 let Inst{6} = lane{0};6381}6382def VGETLNu8 : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?},6383 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),6384 IIC_VMOVSI, "vmov", "u8", "$R, $V$lane",6385 [(set GPR:$R, (ARMvgetlaneu (v8i8 DPR:$V),6386 imm:$lane))]> {6387 let Inst{21} = lane{2};6388 let Inst{6-5} = lane{1-0};6389}6390def VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1},6391 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),6392 IIC_VMOVSI, "vmov", "u16", "$R, $V$lane",6393 [(set GPR:$R, (ARMvgetlaneu (v4i16 DPR:$V),6394 imm:$lane))]> {6395 let Inst{21} = lane{1};6396 let Inst{6} = lane{0};6397}6398def VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00,6399 (outs GPR:$R), (ins DPR:$V, VectorIndex32:$lane),6400 IIC_VMOVSI, "vmov", "32", "$R, $V$lane",6401 [(set GPR:$R, (extractelt (v2i32 DPR:$V),6402 imm:$lane))]>,6403 Requires<[HasFPRegs, HasFastVGETLNi32]> {6404 let Inst{21} = lane{0};6405}6406// VGETLNi32 is also legal as just vmov r0,d0[0] without the .32 suffix6407def : InstAlias<"vmov${p} $R, $V$lane",6408 (VGETLNi32 GPR:$R, DPR:$V, VectorIndex32:$lane, pred:$p), 0>,6409 Requires<VGETLNi32.Predicates>;6410let Predicates = [HasNEON] in {6411// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td6412def : Pat<(ARMvgetlanes (v16i8 QPR:$src), imm:$lane),6413 (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src,6414 (DSubReg_i8_reg imm:$lane))),6415 (SubReg_i8_lane imm:$lane))>;6416def : Pat<(ARMvgetlanes (v8i16 QPR:$src), imm:$lane),6417 (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src,6418 (DSubReg_i16_reg imm:$lane))),6419 (SubReg_i16_lane imm:$lane))>;6420def : Pat<(ARMvgetlaneu (v16i8 QPR:$src), imm:$lane),6421 (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src,6422 (DSubReg_i8_reg imm:$lane))),6423 (SubReg_i8_lane imm:$lane))>;6424def : Pat<(ARMvgetlaneu (v8i16 QPR:$src), imm:$lane),6425 (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src,6426 (DSubReg_i16_reg imm:$lane))),6427 (SubReg_i16_lane imm:$lane))>;6428def : Pat<(ARMvgetlaneu (v8f16 QPR:$src), imm:$lane),6429 (VGETLNu16 (v4f16 (EXTRACT_SUBREG QPR:$src,6430 (DSubReg_i16_reg imm:$lane))),6431 (SubReg_i16_lane imm:$lane))>;6432def : Pat<(ARMvgetlaneu (v4f16 DPR:$src), imm:$lane),6433 (VGETLNu16 (v4f16 DPR:$src), imm:$lane)>;6434def : Pat<(ARMvgetlaneu (v8bf16 QPR:$src), imm:$lane),6435 (VGETLNu16 (v4bf16 (EXTRACT_SUBREG QPR:$src,6436 (DSubReg_i16_reg imm:$lane))),6437 (SubReg_i16_lane imm:$lane))>;6438def : Pat<(ARMvgetlaneu (v4bf16 DPR:$src), imm:$lane),6439 (VGETLNu16 (v4bf16 DPR:$src), imm:$lane)>;6440}6441def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),6442 (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src,6443 (DSubReg_i32_reg imm:$lane))),6444 (SubReg_i32_lane imm:$lane))>,6445 Requires<[HasNEON, HasFastVGETLNi32]>;6446def : Pat<(extractelt (v2i32 DPR:$src), imm:$lane),6447 (COPY_TO_REGCLASS6448 (i32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,6449 Requires<[HasNEON, HasSlowVGETLNi32]>;6450def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),6451 (COPY_TO_REGCLASS6452 (i32 (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,6453 Requires<[HasNEON, HasSlowVGETLNi32]>;6454let Predicates = [HasNEON] in {6455def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2),6456 (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)),6457 (SSubReg_f32_reg imm:$src2))>;6458def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2),6459 (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)),6460 (SSubReg_f32_reg imm:$src2))>;6461//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2),6462// (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;6463def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2),6464 (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;6465}6466 6467multiclass ExtractEltEvenF16<ValueType VT4, ValueType VT8> {6468 def : Pat<(extractelt (VT4 DPR:$src), imm_even:$lane),6469 (EXTRACT_SUBREG6470 (v2f32 (COPY_TO_REGCLASS (VT4 DPR:$src), DPR_VFP2)),6471 (SSubReg_f16_reg imm_even:$lane))>;6472 def : Pat<(extractelt (VT8 QPR:$src), imm_even:$lane),6473 (EXTRACT_SUBREG6474 (v4f32 (COPY_TO_REGCLASS (VT8 QPR:$src), QPR_VFP2)),6475 (SSubReg_f16_reg imm_even:$lane))>;6476}6477 6478multiclass ExtractEltOddF16VMOVH<ValueType VT4, ValueType VT8> {6479 def : Pat<(extractelt (VT4 DPR:$src), imm_odd:$lane),6480 (COPY_TO_REGCLASS6481 (VMOVH (EXTRACT_SUBREG6482 (v2f32 (COPY_TO_REGCLASS (VT4 DPR:$src), DPR_VFP2)),6483 (SSubReg_f16_reg imm_odd:$lane))),6484 HPR)>;6485 def : Pat<(extractelt (VT8 QPR:$src), imm_odd:$lane),6486 (COPY_TO_REGCLASS6487 (VMOVH (EXTRACT_SUBREG6488 (v4f32 (COPY_TO_REGCLASS (VT8 QPR:$src), QPR_VFP2)),6489 (SSubReg_f16_reg imm_odd:$lane))),6490 HPR)>;6491}6492 6493let Predicates = [HasNEON] in {6494 defm : ExtractEltEvenF16<v4f16, v8f16>;6495 defm : ExtractEltOddF16VMOVH<v4f16, v8f16>;6496}6497 6498let AddedComplexity = 1, Predicates = [HasNEON, HasBF16, HasFullFP16] in {6499 // If VMOVH (vmovx.f16) is available use it to extract BF16 from the odd lanes6500 defm : ExtractEltOddF16VMOVH<v4bf16, v8bf16>;6501}6502 6503let Predicates = [HasBF16, HasNEON] in {6504 defm : ExtractEltEvenF16<v4bf16, v8bf16>;6505 6506 // Otherwise, if VMOVH is not available resort to extracting the odd lane6507 // into a GPR and then moving to HPR6508 def : Pat<(extractelt (v4bf16 DPR:$src), imm_odd:$lane),6509 (COPY_TO_REGCLASS6510 (VGETLNu16 (v4bf16 DPR:$src), imm:$lane),6511 HPR)>;6512 6513 def : Pat<(extractelt (v8bf16 QPR:$src), imm_odd:$lane),6514 (COPY_TO_REGCLASS6515 (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src,6516 (DSubReg_i16_reg imm:$lane))),6517 (SubReg_i16_lane imm:$lane)),6518 HPR)>;6519}6520 6521// VMOV : Vector Set Lane (move ARM core register to scalar)6522 6523let Constraints = "$src1 = $V" in {6524def VSETLNi8 : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$V),6525 (ins DPR:$src1, GPR:$R, VectorIndex8:$lane),6526 IIC_VMOVISL, "vmov", "8", "$V$lane, $R",6527 [(set DPR:$V, (vector_insert (v8i8 DPR:$src1),6528 GPR:$R, imm:$lane))]> {6529 let Inst{21} = lane{2};6530 let Inst{6-5} = lane{1-0};6531}6532def VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$V),6533 (ins DPR:$src1, GPR:$R, VectorIndex16:$lane),6534 IIC_VMOVISL, "vmov", "16", "$V$lane, $R",6535 [(set DPR:$V, (vector_insert (v4i16 DPR:$src1),6536 GPR:$R, imm:$lane))]> {6537 let Inst{21} = lane{1};6538 let Inst{6} = lane{0};6539}6540def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V),6541 (ins DPR:$src1, GPR:$R, VectorIndex32:$lane),6542 IIC_VMOVISL, "vmov", "32", "$V$lane, $R",6543 [(set DPR:$V, (insertelt (v2i32 DPR:$src1),6544 GPR:$R, imm:$lane))]>,6545 Requires<[HasVFP2]> {6546 let Inst{21} = lane{0};6547 // This instruction is equivalent as6548 // $V = INSERT_SUBREG $src1, $R, translateImmToSubIdx($imm)6549 let isInsertSubreg = 1;6550}6551}6552// VSETLNi32 is also legal as just vmov d0[0],r0 without the .32 suffix6553def : InstAlias<"vmov${p} $V$lane, $R",6554 (VSETLNi32 DPR:$V, GPR:$R, VectorIndex32:$lane, pred:$p), 0>,6555 Requires<VSETLNi32.Predicates>;6556 6557// TODO: for odd lanes we could optimize this a bit by using the VINS6558// FullFP16 instruction when it is available6559multiclass InsertEltF16<ValueType VTScalar, ValueType VT4, ValueType VT8> {6560 def : Pat<(insertelt (VT4 DPR:$src1), (VTScalar HPR:$src2), imm:$lane),6561 (VT4 (VSETLNi16 DPR:$src1,6562 (COPY_TO_REGCLASS HPR:$src2, GPR), imm:$lane))>;6563 def : Pat<(insertelt (VT8 QPR:$src1), (VTScalar HPR:$src2), imm:$lane),6564 (VT8 (INSERT_SUBREG QPR:$src1,6565 (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,6566 (DSubReg_i16_reg imm:$lane))),6567 (COPY_TO_REGCLASS HPR:$src2, GPR),6568 (SubReg_i16_lane imm:$lane))),6569 (DSubReg_i16_reg imm:$lane)))>;6570}6571 6572let Predicates = [HasNEON] in {6573def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane),6574 (v16i8 (INSERT_SUBREG QPR:$src1,6575 (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,6576 (DSubReg_i8_reg imm:$lane))),6577 GPR:$src2, (SubReg_i8_lane imm:$lane))),6578 (DSubReg_i8_reg imm:$lane)))>;6579def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane),6580 (v8i16 (INSERT_SUBREG QPR:$src1,6581 (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,6582 (DSubReg_i16_reg imm:$lane))),6583 GPR:$src2, (SubReg_i16_lane imm:$lane))),6584 (DSubReg_i16_reg imm:$lane)))>;6585def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane),6586 (v4i32 (INSERT_SUBREG QPR:$src1,6587 (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,6588 (DSubReg_i32_reg imm:$lane))),6589 GPR:$src2, (SubReg_i32_lane imm:$lane))),6590 (DSubReg_i32_reg imm:$lane)))>;6591 6592def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)),6593 (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)),6594 SPR:$src2, (SSubReg_f32_reg imm:$src3))>;6595def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)),6596 (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)),6597 SPR:$src2, (SSubReg_f32_reg imm:$src3))>;6598 6599defm : InsertEltF16<f16, v4f16, v8f16>;6600 6601def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),6602 (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;6603 6604def : Pat<(v2f32 (scalar_to_vector SPR:$src)),6605 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;6606def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))),6607 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;6608def : Pat<(v4f32 (scalar_to_vector SPR:$src)),6609 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;6610 6611def : Pat<(v4f16 (scalar_to_vector (f16 HPR:$src))),6612 (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), HPR:$src, ssub_0)>;6613def : Pat<(v8f16 (scalar_to_vector (f16 HPR:$src))),6614 (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), HPR:$src, ssub_0)>;6615 6616def : Pat<(v8i8 (scalar_to_vector GPR:$src)),6617 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;6618def : Pat<(v4i16 (scalar_to_vector GPR:$src)),6619 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;6620def : Pat<(v2i32 (scalar_to_vector GPR:$src)),6621 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;6622 6623def : Pat<(v16i8 (scalar_to_vector GPR:$src)),6624 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),6625 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)),6626 dsub_0)>;6627def : Pat<(v8i16 (scalar_to_vector GPR:$src)),6628 (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)),6629 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)),6630 dsub_0)>;6631def : Pat<(v4i32 (scalar_to_vector GPR:$src)),6632 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),6633 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)),6634 dsub_0)>;6635}6636 6637let Predicates = [HasNEON, HasBF16] in6638defm : InsertEltF16<bf16, v4bf16, v8bf16>;6639 6640// VDUP : Vector Duplicate (from ARM core register to all elements)6641 6642class VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>6643 : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$V), (ins GPR:$R),6644 IIC_VMOVIS, "vdup", Dt, "$V, $R",6645 [(set DPR:$V, (Ty (ARMvdup (i32 GPR:$R))))]>;6646class VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>6647 : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$V), (ins GPR:$R),6648 IIC_VMOVIS, "vdup", Dt, "$V, $R",6649 [(set QPR:$V, (Ty (ARMvdup (i32 GPR:$R))))]>;6650 6651def VDUP8d : VDUPD<0b11101100, 0b00, "8", v8i8>;6652def VDUP16d : VDUPD<0b11101000, 0b01, "16", v4i16>;6653def VDUP32d : VDUPD<0b11101000, 0b00, "32", v2i32>,6654 Requires<[HasNEON, HasFastVDUP32]>;6655def VDUP8q : VDUPQ<0b11101110, 0b00, "8", v16i8>;6656def VDUP16q : VDUPQ<0b11101010, 0b01, "16", v8i16>;6657def VDUP32q : VDUPQ<0b11101010, 0b00, "32", v4i32>;6658 6659// ARMvdup patterns for uarchs with fast VDUP.32.6660def : Pat<(v2f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VDUP32d GPR:$R)>,6661 Requires<[HasNEON,HasFastVDUP32]>;6662def : Pat<(v4f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>,6663 Requires<[HasNEON]>;6664 6665// ARMvdup patterns for uarchs with slow VDUP.32 - use VMOVDRR instead.6666def : Pat<(v2i32 (ARMvdup (i32 GPR:$R))), (VMOVDRR GPR:$R, GPR:$R)>,6667 Requires<[HasNEON,HasSlowVDUP32]>;6668def : Pat<(v2f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VMOVDRR GPR:$R, GPR:$R)>,6669 Requires<[HasNEON,HasSlowVDUP32]>;6670 6671// VDUP : Vector Duplicate Lane (from scalar to all elements)6672 6673class VDUPLND<bits<4> op19_16, string OpcodeStr, string Dt,6674 ValueType Ty, Operand IdxTy>6675 : NVDupLane<op19_16, 0, (outs DPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),6676 IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane",6677 [(set DPR:$Vd, (Ty (ARMvduplane (Ty DPR:$Vm), imm:$lane)))]>;6678 6679class VDUPLNQ<bits<4> op19_16, string OpcodeStr, string Dt,6680 ValueType ResTy, ValueType OpTy, Operand IdxTy>6681 : NVDupLane<op19_16, 1, (outs QPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),6682 IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane",6683 [(set QPR:$Vd, (ResTy (ARMvduplane (OpTy DPR:$Vm),6684 VectorIndex32:$lane)))]>;6685 6686// Inst{19-16} is partially specified depending on the element size.6687 6688def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> {6689 bits<3> lane;6690 let Inst{19-17} = lane{2-0};6691}6692def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> {6693 bits<2> lane;6694 let Inst{19-18} = lane{1-0};6695}6696def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> {6697 bits<1> lane;6698 let Inst{19} = lane{0};6699}6700def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> {6701 bits<3> lane;6702 let Inst{19-17} = lane{2-0};6703}6704def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> {6705 bits<2> lane;6706 let Inst{19-18} = lane{1-0};6707}6708def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> {6709 bits<1> lane;6710 let Inst{19} = lane{0};6711}6712 6713let Predicates = [HasNEON] in {6714def : Pat<(v4f16 (ARMvduplane (v4f16 DPR:$Vm), imm:$lane)),6715 (VDUPLN16d DPR:$Vm, imm:$lane)>;6716 6717def : Pat<(v2f32 (ARMvduplane (v2f32 DPR:$Vm), imm:$lane)),6718 (VDUPLN32d DPR:$Vm, imm:$lane)>;6719 6720def : Pat<(v4f32 (ARMvduplane (v2f32 DPR:$Vm), imm:$lane)),6721 (VDUPLN32q DPR:$Vm, imm:$lane)>;6722 6723def : Pat<(v16i8 (ARMvduplane (v16i8 QPR:$src), imm:$lane)),6724 (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src,6725 (DSubReg_i8_reg imm:$lane))),6726 (SubReg_i8_lane imm:$lane)))>;6727def : Pat<(v8i16 (ARMvduplane (v8i16 QPR:$src), imm:$lane)),6728 (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src,6729 (DSubReg_i16_reg imm:$lane))),6730 (SubReg_i16_lane imm:$lane)))>;6731def : Pat<(v8f16 (ARMvduplane (v8f16 QPR:$src), imm:$lane)),6732 (v8f16 (VDUPLN16q (v4f16 (EXTRACT_SUBREG QPR:$src,6733 (DSubReg_i16_reg imm:$lane))),6734 (SubReg_i16_lane imm:$lane)))>;6735def : Pat<(v4i32 (ARMvduplane (v4i32 QPR:$src), imm:$lane)),6736 (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src,6737 (DSubReg_i32_reg imm:$lane))),6738 (SubReg_i32_lane imm:$lane)))>;6739def : Pat<(v4f32 (ARMvduplane (v4f32 QPR:$src), imm:$lane)),6740 (v4f32 (VDUPLN32q (v2f32 (EXTRACT_SUBREG QPR:$src,6741 (DSubReg_i32_reg imm:$lane))),6742 (SubReg_i32_lane imm:$lane)))>;6743 6744def : Pat<(v4f16 (ARMvdup (f16 HPR:$src))),6745 (v4f16 (VDUPLN16d (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)),6746 (f16 HPR:$src), ssub_0), (i32 0)))>;6747def : Pat<(v2f32 (ARMvdup (f32 SPR:$src))),6748 (v2f32 (VDUPLN32d (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),6749 SPR:$src, ssub_0), (i32 0)))>;6750def : Pat<(v4f32 (ARMvdup (f32 SPR:$src))),6751 (v4f32 (VDUPLN32q (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),6752 SPR:$src, ssub_0), (i32 0)))>;6753def : Pat<(v8f16 (ARMvdup (f16 HPR:$src))),6754 (v8f16 (VDUPLN16q (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)),6755 (f16 HPR:$src), ssub_0), (i32 0)))>;6756}6757 6758let Predicates = [HasNEON, HasBF16] in {6759def : Pat<(v4bf16 (ARMvduplane (v4bf16 DPR:$Vm), imm:$lane)),6760 (VDUPLN16d DPR:$Vm, imm:$lane)>;6761 6762def : Pat<(v8bf16 (ARMvduplane (v8bf16 QPR:$src), imm:$lane)),6763 (v8bf16 (VDUPLN16q (v4bf16 (EXTRACT_SUBREG QPR:$src,6764 (DSubReg_i16_reg imm:$lane))),6765 (SubReg_i16_lane imm:$lane)))>;6766 6767def : Pat<(v4bf16 (ARMvdup (bf16 HPR:$src))),6768 (v4bf16 (VDUPLN16d (INSERT_SUBREG (v4bf16 (IMPLICIT_DEF)),6769 (bf16 HPR:$src), ssub_0), (i32 0)))>;6770def : Pat<(v8bf16 (ARMvdup (bf16 HPR:$src))),6771 (v8bf16 (VDUPLN16q (INSERT_SUBREG (v4bf16 (IMPLICIT_DEF)),6772 (bf16 HPR:$src), ssub_0), (i32 0)))>;6773}6774 6775// VMOVN : Vector Narrowing Move6776defm VMOVN : N2VN_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVN,6777 "vmovn", "i", trunc>;6778// VQMOVN : Vector Saturating Narrowing Move6779defm VQMOVNs : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD,6780 "vqmovn", "s", int_arm_neon_vqmovns>;6781defm VQMOVNu : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD,6782 "vqmovn", "u", int_arm_neon_vqmovnu>;6783defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD,6784 "vqmovun", "s", int_arm_neon_vqmovnsu>;6785// VMOVL : Vector Lengthening Move6786defm VMOVLs : N2VL_QHS<0b01,0b10100,0,1, "vmovl", "s", sext>;6787defm VMOVLu : N2VL_QHS<0b11,0b10100,0,1, "vmovl", "u", zext>;6788 6789let Predicates = [HasNEON] in {6790def : Pat<(v8i16 (anyext (v8i8 DPR:$Vm))), (VMOVLuv8i16 DPR:$Vm)>;6791def : Pat<(v4i32 (anyext (v4i16 DPR:$Vm))), (VMOVLuv4i32 DPR:$Vm)>;6792def : Pat<(v2i64 (anyext (v2i32 DPR:$Vm))), (VMOVLuv2i64 DPR:$Vm)>;6793}6794 6795// Vector Conversions.6796 6797// VCVT : Vector Convert Between Floating-Point and Integers6798def VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",6799 v2i32, v2f32, fp_to_sint>;6800def VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",6801 v2i32, v2f32, fp_to_uint>;6802def VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",6803 v2f32, v2i32, sint_to_fp>;6804def VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",6805 v2f32, v2i32, uint_to_fp>;6806 6807def VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",6808 v4i32, v4f32, fp_to_sint>;6809def VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",6810 v4i32, v4f32, fp_to_uint>;6811def VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",6812 v4f32, v4i32, sint_to_fp>;6813def VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",6814 v4f32, v4i32, uint_to_fp>;6815 6816def VCVTh2sd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16",6817 v4i16, v4f16, fp_to_sint>,6818 Requires<[HasNEON, HasFullFP16]>;6819def VCVTh2ud : N2VD<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16",6820 v4i16, v4f16, fp_to_uint>,6821 Requires<[HasNEON, HasFullFP16]>;6822def VCVTs2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16",6823 v4f16, v4i16, sint_to_fp>,6824 Requires<[HasNEON, HasFullFP16]>;6825def VCVTu2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16",6826 v4f16, v4i16, uint_to_fp>,6827 Requires<[HasNEON, HasFullFP16]>;6828 6829def VCVTh2sq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16",6830 v8i16, v8f16, fp_to_sint>,6831 Requires<[HasNEON, HasFullFP16]>;6832def VCVTh2uq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16",6833 v8i16, v8f16, fp_to_uint>,6834 Requires<[HasNEON, HasFullFP16]>;6835def VCVTs2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16",6836 v8f16, v8i16, sint_to_fp>,6837 Requires<[HasNEON, HasFullFP16]>;6838def VCVTu2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16",6839 v8f16, v8i16, uint_to_fp>,6840 Requires<[HasNEON, HasFullFP16]>;6841 6842// VCVT{A, N, P, M}6843multiclass VCVT_FPI<string op, bits<3> op10_8, SDPatternOperator IntS,6844 SDPatternOperator IntU> {6845 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {6846 def SDf : N2VDIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),6847 "s32.f32", v2i32, v2f32, IntS>, Requires<[HasV8, HasNEON]>;6848 def SQf : N2VQIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),6849 "s32.f32", v4i32, v4f32, IntS>, Requires<[HasV8, HasNEON]>;6850 def UDf : N2VDIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),6851 "u32.f32", v2i32, v2f32, IntU>, Requires<[HasV8, HasNEON]>;6852 def UQf : N2VQIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),6853 "u32.f32", v4i32, v4f32, IntU>, Requires<[HasV8, HasNEON]>;6854 def SDh : N2VDIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),6855 "s16.f16", v4i16, v4f16, IntS>,6856 Requires<[HasV8, HasNEON, HasFullFP16]>;6857 def SQh : N2VQIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),6858 "s16.f16", v8i16, v8f16, IntS>,6859 Requires<[HasV8, HasNEON, HasFullFP16]>;6860 def UDh : N2VDIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),6861 "u16.f16", v4i16, v4f16, IntU>,6862 Requires<[HasV8, HasNEON, HasFullFP16]>;6863 def UQh : N2VQIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),6864 "u16.f16", v8i16, v8f16, IntU>,6865 Requires<[HasV8, HasNEON, HasFullFP16]>;6866 }6867}6868 6869defm VCVTAN : VCVT_FPI<"a", 0b000, int_arm_neon_vcvtas, int_arm_neon_vcvtau>;6870defm VCVTNN : VCVT_FPI<"n", 0b001, int_arm_neon_vcvtns, int_arm_neon_vcvtnu>;6871defm VCVTPN : VCVT_FPI<"p", 0b010, int_arm_neon_vcvtps, int_arm_neon_vcvtpu>;6872defm VCVTMN : VCVT_FPI<"m", 0b011, int_arm_neon_vcvtms, int_arm_neon_vcvtmu>;6873 6874// VCVT : Vector Convert Between Floating-Point and Fixed-Point.6875let DecoderMethod = "DecodeVCVTD" in {6876def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",6877 v2i32, v2f32, int_arm_neon_vcvtfp2fxs>;6878def VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",6879 v2i32, v2f32, int_arm_neon_vcvtfp2fxu>;6880def VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",6881 v2f32, v2i32, int_arm_neon_vcvtfxs2fp>;6882def VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",6883 v2f32, v2i32, int_arm_neon_vcvtfxu2fp>;6884let Predicates = [HasNEON, HasFullFP16] in {6885def VCVTh2xsd : N2VCvtD<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16",6886 v4i16, v4f16, int_arm_neon_vcvtfp2fxs>;6887def VCVTh2xud : N2VCvtD<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16",6888 v4i16, v4f16, int_arm_neon_vcvtfp2fxu>;6889def VCVTxs2hd : N2VCvtD<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16",6890 v4f16, v4i16, int_arm_neon_vcvtfxs2fp>;6891def VCVTxu2hd : N2VCvtD<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16",6892 v4f16, v4i16, int_arm_neon_vcvtfxu2fp>;6893} // Predicates = [HasNEON, HasFullFP16]6894}6895 6896let DecoderMethod = "DecodeVCVTQ" in {6897def VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",6898 v4i32, v4f32, int_arm_neon_vcvtfp2fxs>;6899def VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",6900 v4i32, v4f32, int_arm_neon_vcvtfp2fxu>;6901def VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",6902 v4f32, v4i32, int_arm_neon_vcvtfxs2fp>;6903def VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",6904 v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;6905let Predicates = [HasNEON, HasFullFP16] in {6906def VCVTh2xsq : N2VCvtQ<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16",6907 v8i16, v8f16, int_arm_neon_vcvtfp2fxs>;6908def VCVTh2xuq : N2VCvtQ<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16",6909 v8i16, v8f16, int_arm_neon_vcvtfp2fxu>;6910def VCVTxs2hq : N2VCvtQ<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16",6911 v8f16, v8i16, int_arm_neon_vcvtfxs2fp>;6912def VCVTxu2hq : N2VCvtQ<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16",6913 v8f16, v8i16, int_arm_neon_vcvtfxu2fp>;6914} // Predicates = [HasNEON, HasFullFP16]6915}6916 6917def : NEONInstAlias<"vcvt${p}.s32.f32 $Dd, $Dm, #0",6918 (VCVTf2sd DPR:$Dd, DPR:$Dm, pred:$p)>;6919def : NEONInstAlias<"vcvt${p}.u32.f32 $Dd, $Dm, #0",6920 (VCVTf2ud DPR:$Dd, DPR:$Dm, pred:$p)>;6921def : NEONInstAlias<"vcvt${p}.f32.s32 $Dd, $Dm, #0",6922 (VCVTs2fd DPR:$Dd, DPR:$Dm, pred:$p)>;6923def : NEONInstAlias<"vcvt${p}.f32.u32 $Dd, $Dm, #0",6924 (VCVTu2fd DPR:$Dd, DPR:$Dm, pred:$p)>;6925 6926def : NEONInstAlias<"vcvt${p}.s32.f32 $Qd, $Qm, #0",6927 (VCVTf2sq QPR:$Qd, QPR:$Qm, pred:$p)>;6928def : NEONInstAlias<"vcvt${p}.u32.f32 $Qd, $Qm, #0",6929 (VCVTf2uq QPR:$Qd, QPR:$Qm, pred:$p)>;6930def : NEONInstAlias<"vcvt${p}.f32.s32 $Qd, $Qm, #0",6931 (VCVTs2fq QPR:$Qd, QPR:$Qm, pred:$p)>;6932def : NEONInstAlias<"vcvt${p}.f32.u32 $Qd, $Qm, #0",6933 (VCVTu2fq QPR:$Qd, QPR:$Qm, pred:$p)>;6934 6935def : NEONInstAlias<"vcvt${p}.s16.f16 $Dd, $Dm, #0",6936 (VCVTh2sd DPR:$Dd, DPR:$Dm, pred:$p)>;6937def : NEONInstAlias<"vcvt${p}.u16.f16 $Dd, $Dm, #0",6938 (VCVTh2ud DPR:$Dd, DPR:$Dm, pred:$p)>;6939def : NEONInstAlias<"vcvt${p}.f16.s16 $Dd, $Dm, #0",6940 (VCVTs2hd DPR:$Dd, DPR:$Dm, pred:$p)>;6941def : NEONInstAlias<"vcvt${p}.f16.u16 $Dd, $Dm, #0",6942 (VCVTu2hd DPR:$Dd, DPR:$Dm, pred:$p)>;6943 6944def : NEONInstAlias<"vcvt${p}.s16.f16 $Qd, $Qm, #0",6945 (VCVTh2sq QPR:$Qd, QPR:$Qm, pred:$p)>;6946def : NEONInstAlias<"vcvt${p}.u16.f16 $Qd, $Qm, #0",6947 (VCVTh2uq QPR:$Qd, QPR:$Qm, pred:$p)>;6948def : NEONInstAlias<"vcvt${p}.f16.s16 $Qd, $Qm, #0",6949 (VCVTs2hq QPR:$Qd, QPR:$Qm, pred:$p)>;6950def : NEONInstAlias<"vcvt${p}.f16.u16 $Qd, $Qm, #0",6951 (VCVTu2hq QPR:$Qd, QPR:$Qm, pred:$p)>;6952 6953 6954// VCVT : Vector Convert Between Half-Precision and Single-Precision.6955def VCVTf2h : N2VNInt<0b11, 0b11, 0b01, 0b10, 0b01100, 0, 0,6956 IIC_VUNAQ, "vcvt", "f16.f32",6957 v4i16, v4f32, int_arm_neon_vcvtfp2hf>,6958 Requires<[HasNEON, HasFP16]>;6959def VCVTh2f : N2VLInt<0b11, 0b11, 0b01, 0b10, 0b01110, 0, 0,6960 IIC_VUNAQ, "vcvt", "f32.f16",6961 v4f32, v4i16, int_arm_neon_vcvthf2fp>,6962 Requires<[HasNEON, HasFP16]>;6963 6964def : Pat<(v4f16 (fpround (v4f32 QPR:$src))), (VCVTf2h QPR:$src)>;6965def : Pat<(v4f32 (fpextend (v4f16 DPR:$src))), (VCVTh2f DPR:$src)>;6966 6967// Vector Reverse.6968 6969// VREV64 : Vector Reverse elements within 64-bit doublewords6970 6971class VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>6972 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$Vd),6973 (ins DPR:$Vm), IIC_VMOVD,6974 OpcodeStr, Dt, "$Vd, $Vm", "",6975 [(set DPR:$Vd, (Ty (ARMvrev64 (Ty DPR:$Vm))))]>;6976class VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>6977 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$Vd),6978 (ins QPR:$Vm), IIC_VMOVQ,6979 OpcodeStr, Dt, "$Vd, $Vm", "",6980 [(set QPR:$Vd, (Ty (ARMvrev64 (Ty QPR:$Vm))))]>;6981 6982def VREV64d8 : VREV64D<0b00, "vrev64", "8", v8i8>;6983def VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>;6984def VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>;6985let Predicates = [HasNEON] in {6986def : Pat<(v2f32 (ARMvrev64 (v2f32 DPR:$Vm))), (VREV64d32 DPR:$Vm)>;6987}6988 6989def VREV64q8 : VREV64Q<0b00, "vrev64", "8", v16i8>;6990def VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>;6991def VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>;6992 6993let Predicates = [HasNEON] in {6994 def : Pat<(v4f32 (ARMvrev64 (v4f32 QPR:$Vm))),6995 (VREV64q32 QPR:$Vm)>;6996 def : Pat<(v8f16 (ARMvrev64 (v8f16 QPR:$Vm))),6997 (VREV64q16 QPR:$Vm)>;6998 def : Pat<(v4f16 (ARMvrev64 (v4f16 DPR:$Vm))),6999 (VREV64d16 DPR:$Vm)>;7000 def : Pat<(v8bf16 (ARMvrev64 (v8bf16 QPR:$Vm))),7001 (VREV64q16 QPR:$Vm)>;7002 def : Pat<(v4bf16 (ARMvrev64 (v4bf16 DPR:$Vm))),7003 (VREV64d16 DPR:$Vm)>;7004}7005 7006// VREV32 : Vector Reverse elements within 32-bit words7007 7008class VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>7009 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$Vd),7010 (ins DPR:$Vm), IIC_VMOVD,7011 OpcodeStr, Dt, "$Vd, $Vm", "",7012 [(set DPR:$Vd, (Ty (ARMvrev32 (Ty DPR:$Vm))))]>;7013class VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>7014 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$Vd),7015 (ins QPR:$Vm), IIC_VMOVQ,7016 OpcodeStr, Dt, "$Vd, $Vm", "",7017 [(set QPR:$Vd, (Ty (ARMvrev32 (Ty QPR:$Vm))))]>;7018 7019def VREV32d8 : VREV32D<0b00, "vrev32", "8", v8i8>;7020def VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>;7021 7022def VREV32q8 : VREV32Q<0b00, "vrev32", "8", v16i8>;7023def VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>;7024 7025let Predicates = [HasNEON] in {7026 def : Pat<(v8f16 (ARMvrev32 (v8f16 QPR:$Vm))),7027 (VREV32q16 QPR:$Vm)>;7028 def : Pat<(v4f16 (ARMvrev32 (v4f16 DPR:$Vm))),7029 (VREV32d16 DPR:$Vm)>;7030 def : Pat<(v8bf16 (ARMvrev32 (v8bf16 QPR:$Vm))),7031 (VREV32q16 QPR:$Vm)>;7032 def : Pat<(v4bf16 (ARMvrev32 (v4bf16 DPR:$Vm))),7033 (VREV32d16 DPR:$Vm)>;7034}7035 7036// VREV16 : Vector Reverse elements within 16-bit halfwords7037 7038class VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>7039 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$Vd),7040 (ins DPR:$Vm), IIC_VMOVD,7041 OpcodeStr, Dt, "$Vd, $Vm", "",7042 [(set DPR:$Vd, (Ty (ARMvrev16 (Ty DPR:$Vm))))]>;7043class VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>7044 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$Vd),7045 (ins QPR:$Vm), IIC_VMOVQ,7046 OpcodeStr, Dt, "$Vd, $Vm", "",7047 [(set QPR:$Vd, (Ty (ARMvrev16 (Ty QPR:$Vm))))]>;7048 7049def VREV16d8 : VREV16D<0b00, "vrev16", "8", v8i8>;7050def VREV16q8 : VREV16Q<0b00, "vrev16", "8", v16i8>;7051 7052// Other Vector Shuffles.7053 7054// Aligned extractions: really just dropping registers7055 7056class AlignedVEXTq<ValueType DestTy, ValueType SrcTy, SDNodeXForm LaneCVT>7057 : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))),7058 (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>,7059 Requires<[HasNEON]>;7060 7061def : AlignedVEXTq<v8i8, v16i8, DSubReg_i8_reg>;7062def : AlignedVEXTq<v4i16, v8i16, DSubReg_i16_reg>;7063def : AlignedVEXTq<v2i32, v4i32, DSubReg_i32_reg>;7064def : AlignedVEXTq<v1i64, v2i64, DSubReg_f64_reg>;7065def : AlignedVEXTq<v2f32, v4f32, DSubReg_i32_reg>;7066def : AlignedVEXTq<v4f16, v8f16, DSubReg_i16_reg>;7067def : AlignedVEXTq<v4bf16, v8bf16, DSubReg_i16_reg>;7068 7069 7070// VEXT : Vector Extract7071 7072// All of these have a two-operand InstAlias.7073let TwoOperandAliasConstraint = "$Vn = $Vd" in {7074class VEXTd<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>7075 : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd),7076 (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm,7077 IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",7078 [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn),7079 (Ty DPR:$Vm), imm:$index)))]> {7080 bits<3> index;7081 let Inst{11} = 0b0;7082 let Inst{10-8} = index{2-0};7083}7084 7085class VEXTq<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>7086 : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd),7087 (ins QPR:$Vn, QPR:$Vm, immTy:$index), NVExtFrm,7088 IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",7089 [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn),7090 (Ty QPR:$Vm), imm:$index)))]> {7091 bits<4> index;7092 let Inst{11-8} = index{3-0};7093}7094}7095 7096def VEXTd8 : VEXTd<"vext", "8", v8i8, imm0_7> {7097 let Inst{10-8} = index{2-0};7098}7099def VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> {7100 let Inst{10-9} = index{1-0};7101 let Inst{8} = 0b0;7102}7103let Predicates = [HasNEON] in {7104def : Pat<(v4f16 (NEONvext (v4f16 DPR:$Vn), (v4f16 DPR:$Vm), (i32 imm:$index))),7105 (VEXTd16 DPR:$Vn, DPR:$Vm, imm:$index)>;7106def : Pat<(v4bf16 (NEONvext (v4bf16 DPR:$Vn), (v4bf16 DPR:$Vm), (i32 imm:$index))),7107 (VEXTd16 DPR:$Vn, DPR:$Vm, imm:$index)>;7108}7109 7110def VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> {7111 let Inst{10} = index{0};7112 let Inst{9-8} = 0b00;7113}7114let Predicates = [HasNEON] in {7115def : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn), (v2f32 DPR:$Vm), (i32 imm:$index))),7116 (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>;7117}7118 7119def VEXTq8 : VEXTq<"vext", "8", v16i8, imm0_15> {7120 let Inst{11-8} = index{3-0};7121}7122def VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> {7123 let Inst{11-9} = index{2-0};7124 let Inst{8} = 0b0;7125}7126let Predicates = [HasNEON] in {7127def : Pat<(v8f16 (NEONvext (v8f16 QPR:$Vn), (v8f16 QPR:$Vm), (i32 imm:$index))),7128 (VEXTq16 QPR:$Vn, QPR:$Vm, imm:$index)>;7129def : Pat<(v8bf16 (NEONvext (v8bf16 QPR:$Vn), (v8bf16 QPR:$Vm), (i32 imm:$index))),7130 (VEXTq16 QPR:$Vn, QPR:$Vm, imm:$index)>;7131}7132 7133def VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> {7134 let Inst{11-10} = index{1-0};7135 let Inst{9-8} = 0b00;7136}7137def VEXTq64 : VEXTq<"vext", "64", v2i64, imm0_1> {7138 let Inst{11} = index{0};7139 let Inst{10-8} = 0b000;7140}7141let Predicates = [HasNEON] in {7142def : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn), (v4f32 QPR:$Vm), (i32 imm:$index))),7143 (VEXTq32 QPR:$Vn, QPR:$Vm, imm:$index)>;7144}7145 7146// VTRN : Vector Transpose7147 7148def VTRNd8 : N2VDShuffle<0b00, 0b00001, "vtrn", "8">;7149def VTRNd16 : N2VDShuffle<0b01, 0b00001, "vtrn", "16">;7150def VTRNd32 : N2VDShuffle<0b10, 0b00001, "vtrn", "32">;7151 7152def VTRNq8 : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">;7153def VTRNq16 : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">;7154def VTRNq32 : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">;7155 7156// VUZP : Vector Unzip (Deinterleave)7157 7158def VUZPd8 : N2VDShuffle<0b00, 0b00010, "vuzp", "8">;7159def VUZPd16 : N2VDShuffle<0b01, 0b00010, "vuzp", "16">;7160// vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.7161def : NEONInstAlias<"vuzp${p}.32 $Dd, $Dm",7162 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;7163 7164def VUZPq8 : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">;7165def VUZPq16 : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">;7166def VUZPq32 : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">;7167 7168// VZIP : Vector Zip (Interleave)7169 7170def VZIPd8 : N2VDShuffle<0b00, 0b00011, "vzip", "8">;7171def VZIPd16 : N2VDShuffle<0b01, 0b00011, "vzip", "16">;7172// vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.7173def : NEONInstAlias<"vzip${p}.32 $Dd, $Dm",7174 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;7175 7176def VZIPq8 : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">;7177def VZIPq16 : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">;7178def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">;7179 7180// Vector Table Lookup and Table Extension.7181 7182// VTBL : Vector Table Lookup7183let DecoderMethod = "DecodeTBLInstruction" in {7184def VTBL17185 : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd),7186 (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,7187 "vtbl", "8", "$Vd, $Vn, $Vm", "",7188 [(set DPR:$Vd, (v8i8 (NEONvtbl1 VecListOneD:$Vn, DPR:$Vm)))]>;7189 7190let hasExtraSrcRegAllocReq = 1 in {7191def VTBL27192 : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd),7193 (ins VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB2,7194 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;7195def VTBL37196 : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$Vd),7197 (ins VecListThreeD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB3,7198 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;7199def VTBL47200 : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$Vd),7201 (ins VecListFourD:$Vn, DPR:$Vm),7202 NVTBLFrm, IIC_VTB4,7203 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;7204} // hasExtraSrcRegAllocReq = 17205 7206def VTBL3Pseudo7207 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB3, "", []>;7208def VTBL4Pseudo7209 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB4, "", []>;7210 7211// VTBX : Vector Table Extension7212def VTBX17213 : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$Vd),7214 (ins DPR:$orig, VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX1,7215 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd",7216 [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbx17217 DPR:$orig, VecListOneD:$Vn, DPR:$Vm)))]>;7218let hasExtraSrcRegAllocReq = 1 in {7219def VTBX27220 : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$Vd),7221 (ins DPR:$orig, VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX2,7222 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", []>;7223def VTBX37224 : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$Vd),7225 (ins DPR:$orig, VecListThreeD:$Vn, DPR:$Vm),7226 NVTBLFrm, IIC_VTBX3,7227 "vtbx", "8", "$Vd, $Vn, $Vm",7228 "$orig = $Vd", []>;7229def VTBX47230 : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$Vd),7231 (ins DPR:$orig, VecListFourD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX4,7232 "vtbx", "8", "$Vd, $Vn, $Vm",7233 "$orig = $Vd", []>;7234} // hasExtraSrcRegAllocReq = 17235 7236def VTBX3Pseudo7237 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),7238 IIC_VTBX3, "$orig = $dst", []>;7239def VTBX4Pseudo7240 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),7241 IIC_VTBX4, "$orig = $dst", []>;7242} // DecoderMethod = "DecodeTBLInstruction"7243 7244let Predicates = [HasNEON] in {7245def : Pat<(v8i8 (NEONvtbl2 v8i8:$Vn0, v8i8:$Vn1, v8i8:$Vm)),7246 (v8i8 (VTBL2 (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0,7247 v8i8:$Vn1, dsub_1),7248 v8i8:$Vm))>;7249def : Pat<(v8i8 (int_arm_neon_vtbx2 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,7250 v8i8:$Vm)),7251 (v8i8 (VTBX2 v8i8:$orig,7252 (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0,7253 v8i8:$Vn1, dsub_1),7254 v8i8:$Vm))>;7255 7256def : Pat<(v8i8 (int_arm_neon_vtbl3 v8i8:$Vn0, v8i8:$Vn1,7257 v8i8:$Vn2, v8i8:$Vm)),7258 (v8i8 (VTBL3Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,7259 v8i8:$Vn1, dsub_1,7260 v8i8:$Vn2, dsub_2,7261 (v8i8 (IMPLICIT_DEF)), dsub_3),7262 v8i8:$Vm))>;7263def : Pat<(v8i8 (int_arm_neon_vtbx3 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,7264 v8i8:$Vn2, v8i8:$Vm)),7265 (v8i8 (VTBX3Pseudo v8i8:$orig,7266 (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,7267 v8i8:$Vn1, dsub_1,7268 v8i8:$Vn2, dsub_2,7269 (v8i8 (IMPLICIT_DEF)), dsub_3),7270 v8i8:$Vm))>;7271 7272def : Pat<(v8i8 (int_arm_neon_vtbl4 v8i8:$Vn0, v8i8:$Vn1,7273 v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)),7274 (v8i8 (VTBL4Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,7275 v8i8:$Vn1, dsub_1,7276 v8i8:$Vn2, dsub_2,7277 v8i8:$Vn3, dsub_3),7278 v8i8:$Vm))>;7279def : Pat<(v8i8 (int_arm_neon_vtbx4 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,7280 v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)),7281 (v8i8 (VTBX4Pseudo v8i8:$orig,7282 (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,7283 v8i8:$Vn1, dsub_1,7284 v8i8:$Vn2, dsub_2,7285 v8i8:$Vn3, dsub_3),7286 v8i8:$Vm))>;7287}7288 7289// VRINT : Vector Rounding7290multiclass VRINT_FPI<string op, bits<3> op9_7, SDPatternOperator Int> {7291 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {7292 def Df : N2VDIntnp<0b10, 0b10, 0b100, 0, NoItinerary,7293 !strconcat("vrint", op), "f32",7294 v2f32, v2f32, Int>, Requires<[HasV8, HasNEON]> {7295 let Inst{9-7} = op9_7;7296 }7297 def Qf : N2VQIntnp<0b10, 0b10, 0b100, 0, NoItinerary,7298 !strconcat("vrint", op), "f32",7299 v4f32, v4f32, Int>, Requires<[HasV8, HasNEON]> {7300 let Inst{9-7} = op9_7;7301 }7302 def Dh : N2VDIntnp<0b01, 0b10, 0b100, 0, NoItinerary,7303 !strconcat("vrint", op), "f16",7304 v4f16, v4f16, Int>,7305 Requires<[HasV8, HasNEON, HasFullFP16]> {7306 let Inst{9-7} = op9_7;7307 }7308 def Qh : N2VQIntnp<0b01, 0b10, 0b100, 0, NoItinerary,7309 !strconcat("vrint", op), "f16",7310 v8f16, v8f16, Int>,7311 Requires<[HasV8, HasNEON, HasFullFP16]> {7312 let Inst{9-7} = op9_7;7313 }7314 }7315 7316 def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Dd, $Dm"),7317 (!cast<Instruction>(NAME#"Df") DPR:$Dd, DPR:$Dm)>;7318 def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Qd, $Qm"),7319 (!cast<Instruction>(NAME#"Qf") QPR:$Qd, QPR:$Qm)>;7320 let Predicates = [HasNEON, HasFullFP16] in {7321 def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Dd, $Dm"),7322 (!cast<Instruction>(NAME#"Dh") DPR:$Dd, DPR:$Dm)>;7323 def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Qd, $Qm"),7324 (!cast<Instruction>(NAME#"Qh") QPR:$Qd, QPR:$Qm)>;7325 }7326}7327 7328defm VRINTNN : VRINT_FPI<"n", 0b000, froundeven>;7329defm VRINTXN : VRINT_FPI<"x", 0b001, frint>;7330defm VRINTAN : VRINT_FPI<"a", 0b010, fround>;7331defm VRINTZN : VRINT_FPI<"z", 0b011, ftrunc>;7332defm VRINTMN : VRINT_FPI<"m", 0b101, ffloor>;7333defm VRINTPN : VRINT_FPI<"p", 0b111, fceil>;7334 7335// Cryptography instructions7336let PostEncoderMethod = "NEONThumb2DataIPostEncoder",7337 DecoderNamespace = "v8Crypto", hasSideEffects = 0 in {7338 class AES<string op, bit op7, bit op6, SDPatternOperator Int>7339 : N2VQIntXnp<0b00, 0b00, 0b011, op6, op7, NoItinerary,7340 !strconcat("aes", op), "8", v16i8, v16i8, Int>;7341 class AES2Op<string op, bit op7, bit op6, SDPatternOperator Int>7342 : N2VQIntX2np<0b00, 0b00, 0b011, op6, op7, NoItinerary,7343 !strconcat("aes", op), "8", v16i8, v16i8, Int>;7344 class N2SHA<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,7345 SDPatternOperator Int>7346 : N2VQIntXnp<0b10, op17_16, op10_8, op6, op7, NoItinerary,7347 !strconcat("sha", op), "32", v4i32, v4i32, Int>;7348 class N2SHA2Op<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,7349 SDPatternOperator Int>7350 : N2VQIntX2np<0b10, op17_16, op10_8, op6, op7, NoItinerary,7351 !strconcat("sha", op), "32", v4i32, v4i32, Int>;7352 class N3SHA3Op<string op, bits<5> op27_23, bits<2> op21_20, SDPatternOperator Int>7353 : N3VQInt3np<op27_23, op21_20, 0b1100, 1, 0, N3RegFrm, NoItinerary,7354 !strconcat("sha", op), "32", v4i32, v4i32, Int>;7355}7356 7357let Predicates = [HasV8, HasAES] in {7358let isCommutable = 1 in {7359def AESD : AES2Op<"d", 0, 1, int_arm_neon_aesd>;7360def AESE : AES2Op<"e", 0, 0, int_arm_neon_aese>;7361}7362def AESIMC : AES<"imc", 1, 1, int_arm_neon_aesimc>;7363def AESMC : AES<"mc", 1, 0, int_arm_neon_aesmc>;7364}7365 7366let Predicates = [HasV8, HasSHA2] in {7367def SHA1H : N2SHA<"1h", 0b01, 0b010, 1, 1, null_frag>;7368def SHA1SU1 : N2SHA2Op<"1su1", 0b10, 0b011, 1, 0, int_arm_neon_sha1su1>;7369def SHA256SU0 : N2SHA2Op<"256su0", 0b10, 0b011, 1, 1, int_arm_neon_sha256su0>;7370def SHA1C : N3SHA3Op<"1c", 0b00100, 0b00, null_frag>;7371def SHA1M : N3SHA3Op<"1m", 0b00100, 0b10, null_frag>;7372def SHA1P : N3SHA3Op<"1p", 0b00100, 0b01, null_frag>;7373def SHA1SU0 : N3SHA3Op<"1su0", 0b00100, 0b11, int_arm_neon_sha1su0>;7374def SHA256H : N3SHA3Op<"256h", 0b00110, 0b00, int_arm_neon_sha256h>;7375def SHA256H2 : N3SHA3Op<"256h2", 0b00110, 0b01, int_arm_neon_sha256h2>;7376def SHA256SU1 : N3SHA3Op<"256su1", 0b00110, 0b10, int_arm_neon_sha256su1>;7377}7378 7379let Predicates = [HasNEON] in {7380def : Pat<(i32 (int_arm_neon_sha1h i32:$Rn)),7381 (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG7382 (SHA1H (SUBREG_TO_REG (i64 0),7383 (f32 (COPY_TO_REGCLASS i32:$Rn, SPR)),7384 ssub_0)),7385 ssub_0)), GPR)>;7386 7387def : Pat<(v4i32 (int_arm_neon_sha1c v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),7388 (SHA1C v4i32:$hash_abcd,7389 (SUBREG_TO_REG (i64 0),7390 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),7391 ssub_0),7392 v4i32:$wk)>;7393 7394def : Pat<(v4i32 (int_arm_neon_sha1m v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),7395 (SHA1M v4i32:$hash_abcd,7396 (SUBREG_TO_REG (i64 0),7397 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),7398 ssub_0),7399 v4i32:$wk)>;7400 7401def : Pat<(v4i32 (int_arm_neon_sha1p v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),7402 (SHA1P v4i32:$hash_abcd,7403 (SUBREG_TO_REG (i64 0),7404 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),7405 ssub_0),7406 v4i32:$wk)>;7407}7408 7409//===----------------------------------------------------------------------===//7410// NEON instructions for single-precision FP math7411//===----------------------------------------------------------------------===//7412 7413class N2VSPat<SDNode OpNode, NeonI Inst>7414 : NEONFPPat<(f32 (OpNode SPR:$a)),7415 (EXTRACT_SUBREG7416 (v2f32 (COPY_TO_REGCLASS (Inst7417 (INSERT_SUBREG7418 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7419 SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>;7420 7421class N3VSPat<SDNode OpNode, NeonI Inst>7422 : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),7423 (EXTRACT_SUBREG7424 (v2f32 (COPY_TO_REGCLASS (Inst7425 (INSERT_SUBREG7426 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7427 SPR:$a, ssub_0),7428 (INSERT_SUBREG7429 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7430 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;7431 7432class N3VSPatFP16<SDNode OpNode, NeonI Inst>7433 : NEONFPPat<(f16 (OpNode HPR:$a, HPR:$b)),7434 (EXTRACT_SUBREG7435 (v4f16 (COPY_TO_REGCLASS (Inst7436 (INSERT_SUBREG7437 (v4f16 (COPY_TO_REGCLASS (v4f16 (IMPLICIT_DEF)), DPR_VFP2)),7438 HPR:$a, ssub_0),7439 (INSERT_SUBREG7440 (v4f16 (COPY_TO_REGCLASS (v4f16 (IMPLICIT_DEF)), DPR_VFP2)),7441 HPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;7442 7443class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>7444 : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),7445 (EXTRACT_SUBREG7446 (v2f32 (COPY_TO_REGCLASS (Inst7447 (INSERT_SUBREG7448 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7449 SPR:$acc, ssub_0),7450 (INSERT_SUBREG7451 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7452 SPR:$a, ssub_0),7453 (INSERT_SUBREG7454 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),7455 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;7456 7457class NVCVTIFPat<SDNode OpNode, NeonI Inst>7458 : NEONFPPat<(f32 (OpNode GPR:$a)),7459 (f32 (EXTRACT_SUBREG7460 (v2f32 (Inst7461 (INSERT_SUBREG7462 (v2f32 (IMPLICIT_DEF)),7463 (i32 (COPY_TO_REGCLASS GPR:$a, SPR)), ssub_0))),7464 ssub_0))>;7465class NVCVTFIPat<SDNode OpNode, NeonI Inst>7466 : NEONFPPat<(i32 (OpNode SPR:$a)),7467 (i32 (EXTRACT_SUBREG7468 (v2f32 (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),7469 SPR:$a, ssub_0))),7470 ssub_0))>;7471 7472def : N3VSPat<fadd, VADDfd>;7473def : N3VSPat<fsub, VSUBfd>;7474def : N3VSPat<fmul, VMULfd>;7475def : N3VSMulOpPat<fmul, fadd, VMLAfd>,7476 Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>;7477def : N3VSMulOpPat<fmul, fsub, VMLSfd>,7478 Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>;7479def : N3VSMulOpPat<fmul, fadd, VFMAfd>,7480 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;7481def : N3VSMulOpPat<fmul, fsub, VFMSfd>,7482 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;7483def : N2VSPat<fabs, VABSfd>;7484def : N2VSPat<fneg, VNEGfd>;7485def : N3VSPatFP16<fmaximum, VMAXhd>, Requires<[HasFullFP16]>;7486def : N3VSPatFP16<fminimum, VMINhd>, Requires<[HasFullFP16]>;7487def : N3VSPat<fmaximum, VMAXfd>, Requires<[HasNEON]>;7488def : N3VSPat<fminimum, VMINfd>, Requires<[HasNEON]>;7489def : NVCVTFIPat<fp_to_sint, VCVTf2sd>;7490def : NVCVTFIPat<fp_to_uint, VCVTf2ud>;7491def : NVCVTIFPat<sint_to_fp, VCVTs2fd>;7492def : NVCVTIFPat<uint_to_fp, VCVTu2fd>;7493 7494// NEON doesn't have any f64 conversions, so provide patterns to make7495// sure the VFP conversions match when extracting from a vector.7496def : VFPPat<(f64 (sint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))),7497 (VSITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;7498def : VFPPat<(f64 (sint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))),7499 (VSITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>;7500def : VFPPat<(f64 (uint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))),7501 (VUITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;7502def : VFPPat<(f64 (uint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))),7503 (VUITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>;7504 7505 7506// Prefer VMOVDRR for i32 -> f32 bitcasts, it can write all DPR registers.7507def : Pat<(f32 (bitconvert GPR:$a)),7508 (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>,7509 Requires<[HasNEON, DontUseVMOVSR]>;7510def : Pat<(arm_vmovsr GPR:$a),7511 (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>,7512 Requires<[HasNEON, DontUseVMOVSR]>;7513 7514//===----------------------------------------------------------------------===//7515// Non-Instruction Patterns or Endianess - Revert Patterns7516//===----------------------------------------------------------------------===//7517 7518// bit_convert7519// 64 bit conversions7520let Predicates = [HasNEON] in {7521def : Pat<(f64 (bitconvert (v1i64 DPR:$src))), (f64 DPR:$src)>;7522def : Pat<(v1i64 (bitconvert (f64 DPR:$src))), (v1i64 DPR:$src)>;7523 7524def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>;7525def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>;7526 7527def : Pat<(v4i16 (bitconvert (v4f16 DPR:$src))), (v4i16 DPR:$src)>;7528def : Pat<(v4f16 (bitconvert (v4i16 DPR:$src))), (v4f16 DPR:$src)>;7529 7530def : Pat<(v4i16 (bitconvert (v4bf16 DPR:$src))), (v4i16 DPR:$src)>;7531def : Pat<(v4bf16 (bitconvert (v4i16 DPR:$src))), (v4bf16 DPR:$src)>;7532 7533// 128 bit conversions7534def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>;7535def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>;7536 7537def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>;7538def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>;7539 7540def : Pat<(v8i16 (bitconvert (v8f16 QPR:$src))), (v8i16 QPR:$src)>;7541def : Pat<(v8f16 (bitconvert (v8i16 QPR:$src))), (v8f16 QPR:$src)>;7542 7543def : Pat<(v8i16 (bitconvert (v8bf16 QPR:$src))), (v8i16 QPR:$src)>;7544def : Pat<(v8bf16 (bitconvert (v8i16 QPR:$src))), (v8bf16 QPR:$src)>;7545}7546 7547let Predicates = [IsLE,HasNEON] in {7548 // 64 bit conversions7549 def : Pat<(f64 (bitconvert (v2f32 DPR:$src))), (f64 DPR:$src)>;7550 def : Pat<(f64 (bitconvert (v2i32 DPR:$src))), (f64 DPR:$src)>;7551 def : Pat<(f64 (bitconvert (v4f16 DPR:$src))), (f64 DPR:$src)>;7552 def : Pat<(f64 (bitconvert (v4bf16 DPR:$src))), (f64 DPR:$src)>;7553 def : Pat<(f64 (bitconvert (v4i16 DPR:$src))), (f64 DPR:$src)>;7554 def : Pat<(f64 (bitconvert (v8i8 DPR:$src))), (f64 DPR:$src)>;7555 7556 def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>;7557 def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>;7558 def : Pat<(v1i64 (bitconvert (v4f16 DPR:$src))), (v1i64 DPR:$src)>;7559 def : Pat<(v1i64 (bitconvert (v4bf16 DPR:$src))), (v1i64 DPR:$src)>;7560 def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>;7561 def : Pat<(v1i64 (bitconvert (v8i8 DPR:$src))), (v1i64 DPR:$src)>;7562 7563 def : Pat<(v2f32 (bitconvert (f64 DPR:$src))), (v2f32 DPR:$src)>;7564 def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>;7565 def : Pat<(v2f32 (bitconvert (v4f16 DPR:$src))), (v2f32 DPR:$src)>;7566 def : Pat<(v2f32 (bitconvert (v4bf16 DPR:$src))), (v2f32 DPR:$src)>;7567 def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>;7568 def : Pat<(v2f32 (bitconvert (v8i8 DPR:$src))), (v2f32 DPR:$src)>;7569 7570 def : Pat<(v2i32 (bitconvert (f64 DPR:$src))), (v2i32 DPR:$src)>;7571 def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>;7572 def : Pat<(v2i32 (bitconvert (v4f16 DPR:$src))), (v2i32 DPR:$src)>;7573 def : Pat<(v2i32 (bitconvert (v4bf16 DPR:$src))), (v2i32 DPR:$src)>;7574 def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>;7575 def : Pat<(v2i32 (bitconvert (v8i8 DPR:$src))), (v2i32 DPR:$src)>;7576 7577 def : Pat<(v4f16 (bitconvert (f64 DPR:$src))), (v4f16 DPR:$src)>;7578 def : Pat<(v4f16 (bitconvert (v1i64 DPR:$src))), (v4f16 DPR:$src)>;7579 def : Pat<(v4f16 (bitconvert (v2f32 DPR:$src))), (v4f16 DPR:$src)>;7580 def : Pat<(v4f16 (bitconvert (v2i32 DPR:$src))), (v4f16 DPR:$src)>;7581 def : Pat<(v4f16 (bitconvert (v8i8 DPR:$src))), (v4f16 DPR:$src)>;7582 7583 def : Pat<(v4bf16 (bitconvert (f64 DPR:$src))), (v4bf16 DPR:$src)>;7584 def : Pat<(v4bf16 (bitconvert (v1i64 DPR:$src))), (v4bf16 DPR:$src)>;7585 def : Pat<(v4bf16 (bitconvert (v2f32 DPR:$src))), (v4bf16 DPR:$src)>;7586 def : Pat<(v4bf16 (bitconvert (v2i32 DPR:$src))), (v4bf16 DPR:$src)>;7587 def : Pat<(v4bf16 (bitconvert (v8i8 DPR:$src))), (v4bf16 DPR:$src)>;7588 7589 def : Pat<(v4i16 (bitconvert (f64 DPR:$src))), (v4i16 DPR:$src)>;7590 def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>;7591 def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>;7592 def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>;7593 def : Pat<(v4i16 (bitconvert (v8i8 DPR:$src))), (v4i16 DPR:$src)>;7594 7595 def : Pat<(v8i8 (bitconvert (f64 DPR:$src))), (v8i8 DPR:$src)>;7596 def : Pat<(v8i8 (bitconvert (v1i64 DPR:$src))), (v8i8 DPR:$src)>;7597 def : Pat<(v8i8 (bitconvert (v2f32 DPR:$src))), (v8i8 DPR:$src)>;7598 def : Pat<(v8i8 (bitconvert (v2i32 DPR:$src))), (v8i8 DPR:$src)>;7599 def : Pat<(v8i8 (bitconvert (v4f16 DPR:$src))), (v8i8 DPR:$src)>;7600 def : Pat<(v8i8 (bitconvert (v4bf16 DPR:$src))), (v8i8 DPR:$src)>;7601 def : Pat<(v8i8 (bitconvert (v4i16 DPR:$src))), (v8i8 DPR:$src)>;7602 7603 // 128 bit conversions7604 def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>;7605 def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>;7606 def : Pat<(v2f64 (bitconvert (v8f16 QPR:$src))), (v2f64 QPR:$src)>;7607 def : Pat<(v2f64 (bitconvert (v8bf16 QPR:$src))), (v2f64 QPR:$src)>;7608 def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>;7609 def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>;7610 7611 def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>;7612 def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>;7613 def : Pat<(v2i64 (bitconvert (v8f16 QPR:$src))), (v2i64 QPR:$src)>;7614 def : Pat<(v2i64 (bitconvert (v8bf16 QPR:$src))), (v2i64 QPR:$src)>;7615 def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>;7616 def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>;7617 7618 def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>;7619 def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>;7620 def : Pat<(v4f32 (bitconvert (v8f16 QPR:$src))), (v4f32 QPR:$src)>;7621 def : Pat<(v4f32 (bitconvert (v8bf16 QPR:$src))), (v4f32 QPR:$src)>;7622 def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>;7623 def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>;7624 7625 def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>;7626 def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>;7627 def : Pat<(v4i32 (bitconvert (v8f16 QPR:$src))), (v4i32 QPR:$src)>;7628 def : Pat<(v4i32 (bitconvert (v8bf16 QPR:$src))), (v4i32 QPR:$src)>;7629 def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>;7630 def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>;7631 7632 def : Pat<(v8f16 (bitconvert (v2f64 QPR:$src))), (v8f16 QPR:$src)>;7633 def : Pat<(v8f16 (bitconvert (v2i64 QPR:$src))), (v8f16 QPR:$src)>;7634 def : Pat<(v8f16 (bitconvert (v4f32 QPR:$src))), (v8f16 QPR:$src)>;7635 def : Pat<(v8f16 (bitconvert (v4i32 QPR:$src))), (v8f16 QPR:$src)>;7636 def : Pat<(v8f16 (bitconvert (v16i8 QPR:$src))), (v8f16 QPR:$src)>;7637 7638 def : Pat<(v8bf16 (bitconvert (v2f64 QPR:$src))), (v8bf16 QPR:$src)>;7639 def : Pat<(v8bf16 (bitconvert (v2i64 QPR:$src))), (v8bf16 QPR:$src)>;7640 def : Pat<(v8bf16 (bitconvert (v4f32 QPR:$src))), (v8bf16 QPR:$src)>;7641 def : Pat<(v8bf16 (bitconvert (v4i32 QPR:$src))), (v8bf16 QPR:$src)>;7642 def : Pat<(v8bf16 (bitconvert (v16i8 QPR:$src))), (v8bf16 QPR:$src)>;7643 7644 def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>;7645 def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>;7646 def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>;7647 def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>;7648 def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>;7649 7650 def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>;7651 def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>;7652 def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>;7653 def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>;7654 def : Pat<(v16i8 (bitconvert (v8f16 QPR:$src))), (v16i8 QPR:$src)>;7655 def : Pat<(v16i8 (bitconvert (v8bf16 QPR:$src))), (v16i8 QPR:$src)>;7656 def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>;7657}7658 7659let Predicates = [IsBE,HasNEON] in {7660 // 64 bit conversions7661 def : Pat<(f64 (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>;7662 def : Pat<(f64 (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>;7663 def : Pat<(f64 (bitconvert (v4f16 DPR:$src))), (VREV64d16 DPR:$src)>;7664 def : Pat<(f64 (bitconvert (v4bf16 DPR:$src))), (VREV64d16 DPR:$src)>;7665 def : Pat<(f64 (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>;7666 def : Pat<(f64 (bitconvert (v8i8 DPR:$src))), (VREV64d8 DPR:$src)>;7667 7668 def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>;7669 def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>;7670 def : Pat<(v1i64 (bitconvert (v4f16 DPR:$src))), (VREV64d16 DPR:$src)>;7671 def : Pat<(v1i64 (bitconvert (v4bf16 DPR:$src))), (VREV64d16 DPR:$src)>;7672 def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>;7673 def : Pat<(v1i64 (bitconvert (v8i8 DPR:$src))), (VREV64d8 DPR:$src)>;7674 7675 def : Pat<(v2f32 (bitconvert (f64 DPR:$src))), (VREV64d32 DPR:$src)>;7676 def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>;7677 def : Pat<(v2f32 (bitconvert (v4f16 DPR:$src))), (VREV32d16 DPR:$src)>;7678 def : Pat<(v2f32 (bitconvert (v4bf16 DPR:$src))), (VREV32d16 DPR:$src)>;7679 def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>;7680 def : Pat<(v2f32 (bitconvert (v8i8 DPR:$src))), (VREV32d8 DPR:$src)>;7681 7682 def : Pat<(v2i32 (bitconvert (f64 DPR:$src))), (VREV64d32 DPR:$src)>;7683 def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>;7684 def : Pat<(v2i32 (bitconvert (v4f16 DPR:$src))), (VREV32d16 DPR:$src)>;7685 def : Pat<(v2i32 (bitconvert (v4bf16 DPR:$src))), (VREV32d16 DPR:$src)>;7686 def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>;7687 def : Pat<(v2i32 (bitconvert (v8i8 DPR:$src))), (VREV32d8 DPR:$src)>;7688 7689 def : Pat<(v4f16 (bitconvert (f64 DPR:$src))), (VREV64d16 DPR:$src)>;7690 def : Pat<(v4f16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>;7691 def : Pat<(v4f16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>;7692 def : Pat<(v4f16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>;7693 def : Pat<(v4f16 (bitconvert (v8i8 DPR:$src))), (VREV16d8 DPR:$src)>;7694 7695 def : Pat<(v4bf16 (bitconvert (f64 DPR:$src))), (VREV64d16 DPR:$src)>;7696 def : Pat<(v4bf16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>;7697 def : Pat<(v4bf16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>;7698 def : Pat<(v4bf16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>;7699 def : Pat<(v4bf16 (bitconvert (v8i8 DPR:$src))), (VREV16d8 DPR:$src)>;7700 7701 def : Pat<(v4i16 (bitconvert (f64 DPR:$src))), (VREV64d16 DPR:$src)>;7702 def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>;7703 def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>;7704 def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>;7705 def : Pat<(v4i16 (bitconvert (v8i8 DPR:$src))), (VREV16d8 DPR:$src)>;7706 7707 def : Pat<(v8i8 (bitconvert (f64 DPR:$src))), (VREV64d8 DPR:$src)>;7708 def : Pat<(v8i8 (bitconvert (v1i64 DPR:$src))), (VREV64d8 DPR:$src)>;7709 def : Pat<(v8i8 (bitconvert (v2f32 DPR:$src))), (VREV32d8 DPR:$src)>;7710 def : Pat<(v8i8 (bitconvert (v2i32 DPR:$src))), (VREV32d8 DPR:$src)>;7711 def : Pat<(v8i8 (bitconvert (v4f16 DPR:$src))), (VREV16d8 DPR:$src)>;7712 def : Pat<(v8i8 (bitconvert (v4bf16 DPR:$src))), (VREV16d8 DPR:$src)>;7713 def : Pat<(v8i8 (bitconvert (v4i16 DPR:$src))), (VREV16d8 DPR:$src)>;7714 7715 // 128 bit conversions7716 def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>;7717 def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>;7718 def : Pat<(v2f64 (bitconvert (v8f16 QPR:$src))), (VREV64q16 QPR:$src)>;7719 def : Pat<(v2f64 (bitconvert (v8bf16 QPR:$src))), (VREV64q16 QPR:$src)>;7720 def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>;7721 def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (VREV64q8 QPR:$src)>;7722 7723 def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>;7724 def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>;7725 def : Pat<(v2i64 (bitconvert (v8f16 QPR:$src))), (VREV64q16 QPR:$src)>;7726 def : Pat<(v2i64 (bitconvert (v8bf16 QPR:$src))), (VREV64q16 QPR:$src)>;7727 def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>;7728 def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (VREV64q8 QPR:$src)>;7729 7730 def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>;7731 def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>;7732 def : Pat<(v4f32 (bitconvert (v8f16 QPR:$src))), (VREV32q16 QPR:$src)>;7733 def : Pat<(v4f32 (bitconvert (v8bf16 QPR:$src))), (VREV32q16 QPR:$src)>;7734 def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>;7735 def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (VREV32q8 QPR:$src)>;7736 7737 def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>;7738 def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>;7739 def : Pat<(v4i32 (bitconvert (v8f16 QPR:$src))), (VREV32q16 QPR:$src)>;7740 def : Pat<(v4i32 (bitconvert (v8bf16 QPR:$src))), (VREV32q16 QPR:$src)>;7741 def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>;7742 def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (VREV32q8 QPR:$src)>;7743 7744 def : Pat<(v8f16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>;7745 def : Pat<(v8f16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>;7746 def : Pat<(v8f16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>;7747 def : Pat<(v8f16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>;7748 def : Pat<(v8f16 (bitconvert (v16i8 QPR:$src))), (VREV16q8 QPR:$src)>;7749 7750 def : Pat<(v8bf16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>;7751 def : Pat<(v8bf16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>;7752 def : Pat<(v8bf16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>;7753 def : Pat<(v8bf16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>;7754 def : Pat<(v8bf16 (bitconvert (v16i8 QPR:$src))), (VREV16q8 QPR:$src)>;7755 7756 def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>;7757 def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>;7758 def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>;7759 def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>;7760 def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (VREV16q8 QPR:$src)>;7761 7762 def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (VREV64q8 QPR:$src)>;7763 def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (VREV64q8 QPR:$src)>;7764 def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (VREV32q8 QPR:$src)>;7765 def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (VREV32q8 QPR:$src)>;7766 def : Pat<(v16i8 (bitconvert (v8f16 QPR:$src))), (VREV16q8 QPR:$src)>;7767 def : Pat<(v16i8 (bitconvert (v8bf16 QPR:$src))), (VREV16q8 QPR:$src)>;7768 def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (VREV16q8 QPR:$src)>;7769}7770 7771let Predicates = [HasNEON] in {7772 // Here we match the specific SDNode type 'ARMVectorRegCastImpl'7773 // rather than the more general 'ARMVectorRegCast' which would also7774 // match some bitconverts. If we use the latter in cases where the7775 // input and output types are the same, the bitconvert gets elided7776 // and we end up generating a nonsense match of nothing.7777 7778 foreach VT = [ v16i8, v8i16, v8f16, v8bf16, v4i32, v4f32, v2i64, v2f64 ] in7779 foreach VT2 = [ v16i8, v8i16, v8f16, v8bf16, v4i32, v4f32, v2i64, v2f64 ] in7780 def : Pat<(VT (ARMVectorRegCastImpl (VT2 QPR:$src))), (VT QPR:$src)>;7781 7782 foreach VT = [ v8i8, v4i16, v4f16, v4bf16, v2i32, v2f32, v1i64, f64 ] in7783 foreach VT2 = [ v8i8, v4i16, v4f16, v4bf16, v2i32, v2f32, v1i64, f64 ] in7784 def : Pat<(VT (ARMVectorRegCastImpl (VT2 DPR:$src))), (VT DPR:$src)>;7785}7786 7787// Use VLD1/VST1 + VREV for non-word-aligned v2f64 load/store on Big Endian7788let Predicates = [IsBE,HasNEON] in {7789def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)),7790 (VREV64q8 (VLD1q8 addrmode6:$addr))>;7791def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr),7792 (VST1q8 addrmode6:$addr, (VREV64q8 QPR:$value))>;7793def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)),7794 (VREV64q16 (VLD1q16 addrmode6:$addr))>;7795def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),7796 (VST1q16 addrmode6:$addr, (VREV64q16 QPR:$value))>;7797}7798 7799// Fold extracting an element out of a v2i32 into a vfp register.7800def : Pat<(f32 (bitconvert (i32 (extractelt (v2i32 DPR:$src), imm:$lane)))),7801 (f32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>,7802 Requires<[HasNEON]>;7803 7804// Vector lengthening move with load, matching extending loads.7805 7806// extload, zextload and sextload for a standard lengthening load. Example:7807// Lengthen_Single<"8", "i16", "8"> =7808// Pat<(v8i16 (extloadvi8 addrmode6:$addr))7809// (VMOVLuv8i16 (VLD1d8 addrmode6:$addr,7810// (f64 (IMPLICIT_DEF)), (i32 0)))>;7811multiclass Lengthen_Single<string DestLanes, string DestTy, string SrcTy> {7812 let AddedComplexity = 10 in {7813 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7814 (!cast<PatFrag>("extloadvi" # SrcTy) addrmode6:$addr)),7815 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)7816 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>,7817 Requires<[HasNEON]>;7818 7819 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7820 (!cast<PatFrag>("zextloadvi" # SrcTy) addrmode6:$addr)),7821 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)7822 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>,7823 Requires<[HasNEON]>;7824 7825 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7826 (!cast<PatFrag>("sextloadvi" # SrcTy) addrmode6:$addr)),7827 (!cast<Instruction>("VMOVLsv" # DestLanes # DestTy)7828 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>,7829 Requires<[HasNEON]>;7830 }7831}7832 7833// extload, zextload and sextload for a lengthening load which only uses7834// half the lanes available. Example:7835// Lengthen_HalfSingle<"4", "i16", "8", "i16", "i8"> =7836// Pat<(v4i16 (extloadvi8 addrmode6oneL32:$addr)),7837// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr,7838// (f64 (IMPLICIT_DEF)), (i32 0))),7839// dsub_0)>;7840multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy,7841 string InsnLanes, string InsnTy> {7842 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7843 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),7844 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)7845 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7846 dsub_0)>,7847 Requires<[HasNEON]>;7848 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7849 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),7850 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)7851 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7852 dsub_0)>,7853 Requires<[HasNEON]>;7854 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7855 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),7856 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy)7857 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7858 dsub_0)>,7859 Requires<[HasNEON]>;7860}7861 7862// The following class definition is basically a copy of the7863// Lengthen_HalfSingle definition above, however with an additional parameter7864// "RevLanes" to select the correct VREV32dXX instruction. This is to convert7865// data loaded by VLD1LN into proper vector format in big endian mode.7866multiclass Lengthen_HalfSingle_Big_Endian<string DestLanes, string DestTy, string SrcTy,7867 string InsnLanes, string InsnTy, string RevLanes> {7868 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7869 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),7870 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)7871 (!cast<Instruction>("VREV32d" # RevLanes)7872 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7873 dsub_0)>,7874 Requires<[HasNEON]>;7875 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7876 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),7877 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)7878 (!cast<Instruction>("VREV32d" # RevLanes)7879 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7880 dsub_0)>,7881 Requires<[HasNEON]>;7882 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7883 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),7884 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy)7885 (!cast<Instruction>("VREV32d" # RevLanes)7886 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7887 dsub_0)>,7888 Requires<[HasNEON]>;7889}7890 7891// extload, zextload and sextload for a lengthening load followed by another7892// lengthening load, to quadruple the initial length.7893//7894// Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32"> =7895// Pat<(v4i32 (extloadvi8 addrmode6oneL32:$addr))7896// (EXTRACT_SUBREG (VMOVLuv4i327897// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr,7898// (f64 (IMPLICIT_DEF)),7899// (i32 0))),7900// dsub_0)),7901// dsub_0)>;7902multiclass Lengthen_Double<string DestLanes, string DestTy, string SrcTy,7903 string Insn1Lanes, string Insn1Ty, string Insn2Lanes,7904 string Insn2Ty> {7905 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7906 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),7907 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7908 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7909 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7910 dsub_0))>,7911 Requires<[HasNEON]>;7912 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7913 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),7914 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7915 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7916 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7917 dsub_0))>,7918 Requires<[HasNEON]>;7919 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7920 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),7921 (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)7922 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)7923 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7924 dsub_0))>,7925 Requires<[HasNEON]>;7926}7927 7928// The following class definition is basically a copy of the7929// Lengthen_Double definition above, however with an additional parameter7930// "RevLanes" to select the correct VREV32dXX instruction. This is to convert7931// data loaded by VLD1LN into proper vector format in big endian mode.7932multiclass Lengthen_Double_Big_Endian<string DestLanes, string DestTy, string SrcTy,7933 string Insn1Lanes, string Insn1Ty, string Insn2Lanes,7934 string Insn2Ty, string RevLanes> {7935 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7936 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),7937 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7938 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7939 (!cast<Instruction>("VREV32d" # RevLanes)7940 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7941 dsub_0))>,7942 Requires<[HasNEON]>;7943 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7944 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),7945 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7946 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7947 (!cast<Instruction>("VREV32d" # RevLanes)7948 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7949 dsub_0))>,7950 Requires<[HasNEON]>;7951 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7952 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),7953 (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)7954 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)7955 (!cast<Instruction>("VREV32d" # RevLanes)7956 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),7957 dsub_0))>,7958 Requires<[HasNEON]>;7959}7960 7961// extload, zextload and sextload for a lengthening load followed by another7962// lengthening load, to quadruple the initial length, but which ends up only7963// requiring half the available lanes (a 64-bit outcome instead of a 128-bit).7964//7965// Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> =7966// Pat<(v2i32 (extloadvi8 addrmode6:$addr))7967// (EXTRACT_SUBREG (VMOVLuv4i327968// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd16 addrmode6:$addr,7969// (f64 (IMPLICIT_DEF)), (i32 0))),7970// dsub_0)),7971// dsub_0)>;7972multiclass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy,7973 string Insn1Lanes, string Insn1Ty, string Insn2Lanes,7974 string Insn2Ty> {7975 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7976 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)),7977 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7978 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7979 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7980 dsub_0)),7981 dsub_0)>,7982 Requires<[HasNEON]>;7983 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7984 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)),7985 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)7986 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)7987 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7988 dsub_0)),7989 dsub_0)>,7990 Requires<[HasNEON]>;7991 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)7992 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)),7993 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)7994 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)7995 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),7996 dsub_0)),7997 dsub_0)>,7998 Requires<[HasNEON]>;7999}8000 8001// The following class definition is basically a copy of the8002// Lengthen_HalfDouble definition above, however with an additional VREV16d88003// instruction to convert data loaded by VLD1LN into proper vector format8004// in big endian mode.8005multiclass Lengthen_HalfDouble_Big_Endian<string DestLanes, string DestTy, string SrcTy,8006 string Insn1Lanes, string Insn1Ty, string Insn2Lanes,8007 string Insn2Ty> {8008 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)8009 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)),8010 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)8011 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)8012 (VREV16d8 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),8013 dsub_0)),8014 dsub_0)>,8015 Requires<[HasNEON]>;8016 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)8017 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)),8018 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)8019 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)8020 (VREV16d8 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),8021 dsub_0)),8022 dsub_0)>,8023 Requires<[HasNEON]>;8024 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)8025 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)),8026 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)8027 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)8028 (VREV16d8 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),8029 dsub_0)),8030 dsub_0)>,8031 Requires<[HasNEON]>;8032}8033 8034defm : Lengthen_Single<"8", "i16", "8">; // v8i8 -> v8i168035defm : Lengthen_Single<"4", "i32", "16">; // v4i16 -> v4i328036defm : Lengthen_Single<"2", "i64", "32">; // v2i32 -> v2i648037 8038let Predicates = [HasNEON,IsLE] in {8039 defm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i168040 defm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i328041 8042 // Double lengthening - v4i8 -> v4i16 -> v4i328043 defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">;8044 // v2i8 -> v2i16 -> v2i328045 defm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">;8046 // v2i16 -> v2i32 -> v2i648047 defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">;8048}8049 8050let Predicates = [HasNEON,IsBE] in {8051 defm : Lengthen_HalfSingle_Big_Endian<"4", "i16", "i8", "8", "i16", "8">; // v4i8 -> v4i168052 defm : Lengthen_HalfSingle_Big_Endian<"2", "i32", "i16", "4", "i32", "16">; // v2i16 -> v2i328053 8054 // Double lengthening - v4i8 -> v4i16 -> v4i328055 defm : Lengthen_Double_Big_Endian<"4", "i32", "i8", "8", "i16", "4", "i32", "8">;8056 // v2i8 -> v2i16 -> v2i328057 defm : Lengthen_HalfDouble_Big_Endian<"2", "i32", "i8", "8", "i16", "4", "i32">;8058 // v2i16 -> v2i32 -> v2i648059 defm : Lengthen_Double_Big_Endian<"2", "i64", "i16", "4", "i32", "2", "i64", "16">;8060}8061 8062// Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i648063let Predicates = [HasNEON,IsLE] in {8064 def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)),8065 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i168066 (VLD1LNd16 addrmode6:$addr,8067 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;8068 def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)),8069 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i168070 (VLD1LNd16 addrmode6:$addr,8071 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;8072 def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)),8073 (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i168074 (VLD1LNd16 addrmode6:$addr,8075 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;8076}8077// The following patterns are basically a copy of the patterns above,8078// however with an additional VREV16d instruction to convert data8079// loaded by VLD1LN into proper vector format in big endian mode.8080let Predicates = [HasNEON,IsBE] in {8081 def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)),8082 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i168083 (VREV16d88084 (VLD1LNd16 addrmode6:$addr,8085 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;8086 def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)),8087 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i168088 (VREV16d88089 (VLD1LNd16 addrmode6:$addr,8090 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;8091 def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)),8092 (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i168093 (VREV16d88094 (VLD1LNd16 addrmode6:$addr,8095 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;8096}8097 8098let Predicates = [HasNEON] in {8099def : Pat<(v2i64 (concat_vectors DPR:$Dn, DPR:$Dm)),8100 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8101def : Pat<(v4i32 (concat_vectors DPR:$Dn, DPR:$Dm)),8102 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8103def : Pat<(v8i16 (concat_vectors DPR:$Dn, DPR:$Dm)),8104 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8105def : Pat<(v16i8 (concat_vectors DPR:$Dn, DPR:$Dm)),8106 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8107def : Pat<(v4f32 (concat_vectors DPR:$Dn, DPR:$Dm)),8108 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8109def : Pat<(v8f16 (concat_vectors DPR:$Dn, DPR:$Dm)),8110 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8111def : Pat<(v8bf16 (concat_vectors DPR:$Dn, DPR:$Dm)),8112 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;8113}8114 8115//===----------------------------------------------------------------------===//8116// Assembler aliases8117//8118 8119def : VFP2InstAlias<"fmdhr${p} $Dd, $Rn",8120 (VSETLNi32 DPR:$Dd, GPR:$Rn, 1, pred:$p)>;8121def : VFP2InstAlias<"fmdlr${p} $Dd, $Rn",8122 (VSETLNi32 DPR:$Dd, GPR:$Rn, 0, pred:$p)>;8123 8124// VAND/VBIC/VEOR/VORR accept but do not require a type suffix.8125defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",8126 (VANDd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;8127defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",8128 (VANDq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;8129defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",8130 (VBICd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;8131defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",8132 (VBICq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;8133defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",8134 (VEORd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;8135defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",8136 (VEORq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;8137defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",8138 (VORRd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;8139defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",8140 (VORRq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;8141// ... two-operand aliases8142defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",8143 (VANDd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;8144defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",8145 (VANDq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;8146defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",8147 (VEORd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;8148defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",8149 (VEORq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;8150defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",8151 (VORRd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;8152defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",8153 (VORRq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;8154// ... immediates8155def : NEONInstAlias<"vand${p}.i16 $Vd, $imm",8156 (VBICiv4i16 DPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>;8157def : NEONInstAlias<"vand${p}.i32 $Vd, $imm",8158 (VBICiv2i32 DPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>;8159def : NEONInstAlias<"vand${p}.i16 $Vd, $imm",8160 (VBICiv8i16 QPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>;8161def : NEONInstAlias<"vand${p}.i32 $Vd, $imm",8162 (VBICiv4i32 QPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>;8163 8164 8165// VLD1 single-lane pseudo-instructions. These need special handling for8166// the lane index that an InstAlias can't handle, so we use these instead.8167def VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr",8168 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8169 pred:$p)>;8170def VLD1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr",8171 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8172 pred:$p)>;8173def VLD1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr",8174 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8175 pred:$p)>;8176 8177def VLD1LNdWB_fixed_Asm_8 :8178 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr!",8179 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8180 pred:$p)>;8181def VLD1LNdWB_fixed_Asm_16 :8182 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr!",8183 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8184 pred:$p)>;8185def VLD1LNdWB_fixed_Asm_32 :8186 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr!",8187 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8188 pred:$p)>;8189def VLD1LNdWB_register_Asm_8 :8190 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr, $Rm",8191 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8192 rGPR:$Rm, pred:$p)>;8193def VLD1LNdWB_register_Asm_16 :8194 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr, $Rm",8195 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8196 rGPR:$Rm, pred:$p)>;8197def VLD1LNdWB_register_Asm_32 :8198 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr, $Rm",8199 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8200 rGPR:$Rm, pred:$p)>;8201 8202let mayStore = 1 in {8203 8204// VST1 single-lane pseudo-instructions. These need special handling for8205// the lane index that an InstAlias can't handle, so we use these instead.8206def VST1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr",8207 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8208 pred:$p)>;8209def VST1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr",8210 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8211 pred:$p)>;8212def VST1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr",8213 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8214 pred:$p)>;8215 8216def VST1LNdWB_fixed_Asm_8 :8217 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr!",8218 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8219 pred:$p)>;8220def VST1LNdWB_fixed_Asm_16 :8221 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr!",8222 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8223 pred:$p)>;8224def VST1LNdWB_fixed_Asm_32 :8225 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr!",8226 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8227 pred:$p)>;8228def VST1LNdWB_register_Asm_8 :8229 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr, $Rm",8230 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,8231 rGPR:$Rm, pred:$p)>;8232def VST1LNdWB_register_Asm_16 :8233 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr, $Rm",8234 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,8235 rGPR:$Rm, pred:$p)>;8236def VST1LNdWB_register_Asm_32 :8237 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr, $Rm",8238 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,8239 rGPR:$Rm, pred:$p)>;8240 8241}8242 8243// VLD2 single-lane pseudo-instructions. These need special handling for8244// the lane index that an InstAlias can't handle, so we use these instead.8245def VLD2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr",8246 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8247 pred:$p)>;8248def VLD2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",8249 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8250 pred:$p)>;8251def VLD2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",8252 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, pred:$p)>;8253def VLD2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",8254 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8255 pred:$p)>;8256def VLD2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",8257 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8258 pred:$p)>;8259 8260def VLD2LNdWB_fixed_Asm_8 :8261 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr!",8262 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8263 pred:$p)>;8264def VLD2LNdWB_fixed_Asm_16 :8265 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",8266 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8267 pred:$p)>;8268def VLD2LNdWB_fixed_Asm_32 :8269 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",8270 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,8271 pred:$p)>;8272def VLD2LNqWB_fixed_Asm_16 :8273 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",8274 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8275 pred:$p)>;8276def VLD2LNqWB_fixed_Asm_32 :8277 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",8278 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8279 pred:$p)>;8280def VLD2LNdWB_register_Asm_8 :8281 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr, $Rm",8282 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8283 rGPR:$Rm, pred:$p)>;8284def VLD2LNdWB_register_Asm_16 :8285 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",8286 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8287 rGPR:$Rm, pred:$p)>;8288def VLD2LNdWB_register_Asm_32 :8289 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",8290 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,8291 rGPR:$Rm, pred:$p)>;8292def VLD2LNqWB_register_Asm_16 :8293 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",8294 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8295 rGPR:$Rm, pred:$p)>;8296def VLD2LNqWB_register_Asm_32 :8297 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",8298 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8299 rGPR:$Rm, pred:$p)>;8300 8301let mayStore = 1 in {8302 8303// VST2 single-lane pseudo-instructions. These need special handling for8304// the lane index that an InstAlias can't handle, so we use these instead.8305def VST2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr",8306 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8307 pred:$p)>;8308def VST2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",8309 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8310 pred:$p)>;8311def VST2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",8312 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,8313 pred:$p)>;8314def VST2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",8315 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8316 pred:$p)>;8317def VST2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",8318 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8319 pred:$p)>;8320 8321def VST2LNdWB_fixed_Asm_8 :8322 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr!",8323 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8324 pred:$p)>;8325def VST2LNdWB_fixed_Asm_16 :8326 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",8327 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8328 pred:$p)>;8329def VST2LNdWB_fixed_Asm_32 :8330 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",8331 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,8332 pred:$p)>;8333def VST2LNqWB_fixed_Asm_16 :8334 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",8335 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8336 pred:$p)>;8337def VST2LNqWB_fixed_Asm_32 :8338 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",8339 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8340 pred:$p)>;8341def VST2LNdWB_register_Asm_8 :8342 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr, $Rm",8343 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,8344 rGPR:$Rm, pred:$p)>;8345def VST2LNdWB_register_Asm_16 :8346 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",8347 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,8348 rGPR:$Rm, pred:$p)>;8349def VST2LNdWB_register_Asm_32 :8350 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",8351 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,8352 rGPR:$Rm, pred:$p)>;8353def VST2LNqWB_register_Asm_16 :8354 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",8355 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,8356 rGPR:$Rm, pred:$p)>;8357def VST2LNqWB_register_Asm_32 :8358 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",8359 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,8360 rGPR:$Rm, pred:$p)>;8361 8362}8363 8364// VLD3 all-lanes pseudo-instructions. These need special handling for8365// the lane index that an InstAlias can't handle, so we use these instead.8366def VLD3DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",8367 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8368 pred:$p)>;8369def VLD3DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8370 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8371 pred:$p)>;8372def VLD3DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8373 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8374 pred:$p)>;8375def VLD3DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",8376 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8377 pred:$p)>;8378def VLD3DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8379 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8380 pred:$p)>;8381def VLD3DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8382 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8383 pred:$p)>;8384 8385def VLD3DUPdWB_fixed_Asm_8 :8386 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",8387 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8388 pred:$p)>;8389def VLD3DUPdWB_fixed_Asm_16 :8390 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8391 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8392 pred:$p)>;8393def VLD3DUPdWB_fixed_Asm_32 :8394 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8395 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8396 pred:$p)>;8397def VLD3DUPqWB_fixed_Asm_8 :8398 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",8399 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8400 pred:$p)>;8401def VLD3DUPqWB_fixed_Asm_16 :8402 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8403 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8404 pred:$p)>;8405def VLD3DUPqWB_fixed_Asm_32 :8406 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8407 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8408 pred:$p)>;8409def VLD3DUPdWB_register_Asm_8 :8410 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",8411 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8412 rGPR:$Rm, pred:$p)>;8413def VLD3DUPdWB_register_Asm_16 :8414 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8415 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8416 rGPR:$Rm, pred:$p)>;8417def VLD3DUPdWB_register_Asm_32 :8418 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8419 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,8420 rGPR:$Rm, pred:$p)>;8421def VLD3DUPqWB_register_Asm_8 :8422 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",8423 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8424 rGPR:$Rm, pred:$p)>;8425def VLD3DUPqWB_register_Asm_16 :8426 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8427 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8428 rGPR:$Rm, pred:$p)>;8429def VLD3DUPqWB_register_Asm_32 :8430 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8431 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,8432 rGPR:$Rm, pred:$p)>;8433 8434 8435// VLD3 single-lane pseudo-instructions. These need special handling for8436// the lane index that an InstAlias can't handle, so we use these instead.8437def VLD3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",8438 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8439 pred:$p)>;8440def VLD3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8441 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,8442 pred:$p)>;8443def VLD3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8444 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8445 pred:$p)>;8446def VLD3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8447 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,8448 pred:$p)>;8449def VLD3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8450 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8451 pred:$p)>;8452 8453def VLD3LNdWB_fixed_Asm_8 :8454 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",8455 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8456 pred:$p)>;8457def VLD3LNdWB_fixed_Asm_16 :8458 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8459 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,8460 pred:$p)>;8461def VLD3LNdWB_fixed_Asm_32 :8462 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8463 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8464 pred:$p)>;8465def VLD3LNqWB_fixed_Asm_16 :8466 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8467 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,8468 pred:$p)>;8469def VLD3LNqWB_fixed_Asm_32 :8470 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8471 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8472 pred:$p)>;8473def VLD3LNdWB_register_Asm_8 :8474 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",8475 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8476 rGPR:$Rm, pred:$p)>;8477def VLD3LNdWB_register_Asm_16 :8478 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8479 (ins VecListThreeDHWordIndexed:$list,8480 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;8481def VLD3LNdWB_register_Asm_32 :8482 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8483 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8484 rGPR:$Rm, pred:$p)>;8485def VLD3LNqWB_register_Asm_16 :8486 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8487 (ins VecListThreeQHWordIndexed:$list,8488 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;8489def VLD3LNqWB_register_Asm_32 :8490 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8491 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8492 rGPR:$Rm, pred:$p)>;8493 8494// VLD3 multiple structure pseudo-instructions. These need special handling for8495// the vector operands that the normal instructions don't yet model.8496// FIXME: Remove these when the register classes and instructions are updated.8497def VLD3dAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",8498 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8499def VLD3dAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8500 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8501def VLD3dAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8502 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8503def VLD3qAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",8504 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8505def VLD3qAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",8506 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8507def VLD3qAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",8508 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8509 8510def VLD3dWB_fixed_Asm_8 :8511 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",8512 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8513def VLD3dWB_fixed_Asm_16 :8514 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8515 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8516def VLD3dWB_fixed_Asm_32 :8517 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8518 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8519def VLD3qWB_fixed_Asm_8 :8520 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",8521 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8522def VLD3qWB_fixed_Asm_16 :8523 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",8524 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8525def VLD3qWB_fixed_Asm_32 :8526 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",8527 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8528def VLD3dWB_register_Asm_8 :8529 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",8530 (ins VecListThreeD:$list, addrmode6align64:$addr,8531 rGPR:$Rm, pred:$p)>;8532def VLD3dWB_register_Asm_16 :8533 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8534 (ins VecListThreeD:$list, addrmode6align64:$addr,8535 rGPR:$Rm, pred:$p)>;8536def VLD3dWB_register_Asm_32 :8537 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8538 (ins VecListThreeD:$list, addrmode6align64:$addr,8539 rGPR:$Rm, pred:$p)>;8540def VLD3qWB_register_Asm_8 :8541 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",8542 (ins VecListThreeQ:$list, addrmode6align64:$addr,8543 rGPR:$Rm, pred:$p)>;8544def VLD3qWB_register_Asm_16 :8545 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",8546 (ins VecListThreeQ:$list, addrmode6align64:$addr,8547 rGPR:$Rm, pred:$p)>;8548def VLD3qWB_register_Asm_32 :8549 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",8550 (ins VecListThreeQ:$list, addrmode6align64:$addr,8551 rGPR:$Rm, pred:$p)>;8552 8553let mayStore = 1 in {8554 8555// VST3 single-lane pseudo-instructions. These need special handling for8556// the lane index that an InstAlias can't handle, so we use these instead.8557def VST3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",8558 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8559 pred:$p)>;8560def VST3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",8561 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,8562 pred:$p)>;8563def VST3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",8564 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8565 pred:$p)>;8566def VST3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",8567 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,8568 pred:$p)>;8569def VST3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",8570 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8571 pred:$p)>;8572 8573def VST3LNdWB_fixed_Asm_8 :8574 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",8575 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8576 pred:$p)>;8577def VST3LNdWB_fixed_Asm_16 :8578 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",8579 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,8580 pred:$p)>;8581def VST3LNdWB_fixed_Asm_32 :8582 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",8583 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8584 pred:$p)>;8585def VST3LNqWB_fixed_Asm_16 :8586 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",8587 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,8588 pred:$p)>;8589def VST3LNqWB_fixed_Asm_32 :8590 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",8591 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8592 pred:$p)>;8593def VST3LNdWB_register_Asm_8 :8594 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",8595 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,8596 rGPR:$Rm, pred:$p)>;8597def VST3LNdWB_register_Asm_16 :8598 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",8599 (ins VecListThreeDHWordIndexed:$list,8600 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;8601def VST3LNdWB_register_Asm_32 :8602 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",8603 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,8604 rGPR:$Rm, pred:$p)>;8605def VST3LNqWB_register_Asm_16 :8606 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",8607 (ins VecListThreeQHWordIndexed:$list,8608 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;8609def VST3LNqWB_register_Asm_32 :8610 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",8611 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,8612 rGPR:$Rm, pred:$p)>;8613 8614 8615// VST3 multiple structure pseudo-instructions. These need special handling for8616// the vector operands that the normal instructions don't yet model.8617// FIXME: Remove these when the register classes and instructions are updated.8618def VST3dAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",8619 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8620def VST3dAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",8621 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8622def VST3dAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",8623 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8624def VST3qAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",8625 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8626def VST3qAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",8627 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8628def VST3qAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",8629 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8630 8631def VST3dWB_fixed_Asm_8 :8632 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",8633 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8634def VST3dWB_fixed_Asm_16 :8635 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",8636 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8637def VST3dWB_fixed_Asm_32 :8638 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",8639 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;8640def VST3qWB_fixed_Asm_8 :8641 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",8642 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8643def VST3qWB_fixed_Asm_16 :8644 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",8645 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8646def VST3qWB_fixed_Asm_32 :8647 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",8648 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;8649def VST3dWB_register_Asm_8 :8650 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",8651 (ins VecListThreeD:$list, addrmode6align64:$addr,8652 rGPR:$Rm, pred:$p)>;8653def VST3dWB_register_Asm_16 :8654 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",8655 (ins VecListThreeD:$list, addrmode6align64:$addr,8656 rGPR:$Rm, pred:$p)>;8657def VST3dWB_register_Asm_32 :8658 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",8659 (ins VecListThreeD:$list, addrmode6align64:$addr,8660 rGPR:$Rm, pred:$p)>;8661def VST3qWB_register_Asm_8 :8662 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",8663 (ins VecListThreeQ:$list, addrmode6align64:$addr,8664 rGPR:$Rm, pred:$p)>;8665def VST3qWB_register_Asm_16 :8666 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",8667 (ins VecListThreeQ:$list, addrmode6align64:$addr,8668 rGPR:$Rm, pred:$p)>;8669def VST3qWB_register_Asm_32 :8670 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",8671 (ins VecListThreeQ:$list, addrmode6align64:$addr,8672 rGPR:$Rm, pred:$p)>;8673 8674}8675 8676// VLD4 all-lanes pseudo-instructions. These need special handling for8677// the lane index that an InstAlias can't handle, so we use these instead.8678def VLD4DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",8679 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,8680 pred:$p)>;8681def VLD4DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8682 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,8683 pred:$p)>;8684def VLD4DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8685 (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr,8686 pred:$p)>;8687def VLD4DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",8688 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,8689 pred:$p)>;8690def VLD4DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8691 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,8692 pred:$p)>;8693def VLD4DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8694 (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr,8695 pred:$p)>;8696 8697def VLD4DUPdWB_fixed_Asm_8 :8698 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",8699 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,8700 pred:$p)>;8701def VLD4DUPdWB_fixed_Asm_16 :8702 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8703 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,8704 pred:$p)>;8705def VLD4DUPdWB_fixed_Asm_32 :8706 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8707 (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr,8708 pred:$p)>;8709def VLD4DUPqWB_fixed_Asm_8 :8710 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",8711 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,8712 pred:$p)>;8713def VLD4DUPqWB_fixed_Asm_16 :8714 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8715 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,8716 pred:$p)>;8717def VLD4DUPqWB_fixed_Asm_32 :8718 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8719 (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr,8720 pred:$p)>;8721def VLD4DUPdWB_register_Asm_8 :8722 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",8723 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,8724 rGPR:$Rm, pred:$p)>;8725def VLD4DUPdWB_register_Asm_16 :8726 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8727 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,8728 rGPR:$Rm, pred:$p)>;8729def VLD4DUPdWB_register_Asm_32 :8730 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8731 (ins VecListFourDAllLanes:$list,8732 addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>;8733def VLD4DUPqWB_register_Asm_8 :8734 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",8735 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,8736 rGPR:$Rm, pred:$p)>;8737def VLD4DUPqWB_register_Asm_16 :8738 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8739 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,8740 rGPR:$Rm, pred:$p)>;8741def VLD4DUPqWB_register_Asm_32 :8742 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8743 (ins VecListFourQAllLanes:$list,8744 addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>;8745 8746 8747// VLD4 single-lane pseudo-instructions. These need special handling for8748// the lane index that an InstAlias can't handle, so we use these instead.8749def VLD4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",8750 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8751 pred:$p)>;8752def VLD4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8753 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8754 pred:$p)>;8755def VLD4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8756 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,8757 pred:$p)>;8758def VLD4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8759 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8760 pred:$p)>;8761def VLD4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8762 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,8763 pred:$p)>;8764 8765def VLD4LNdWB_fixed_Asm_8 :8766 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",8767 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8768 pred:$p)>;8769def VLD4LNdWB_fixed_Asm_16 :8770 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8771 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8772 pred:$p)>;8773def VLD4LNdWB_fixed_Asm_32 :8774 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8775 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,8776 pred:$p)>;8777def VLD4LNqWB_fixed_Asm_16 :8778 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8779 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8780 pred:$p)>;8781def VLD4LNqWB_fixed_Asm_32 :8782 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8783 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,8784 pred:$p)>;8785def VLD4LNdWB_register_Asm_8 :8786 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",8787 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8788 rGPR:$Rm, pred:$p)>;8789def VLD4LNdWB_register_Asm_16 :8790 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8791 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8792 rGPR:$Rm, pred:$p)>;8793def VLD4LNdWB_register_Asm_32 :8794 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8795 (ins VecListFourDWordIndexed:$list,8796 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;8797def VLD4LNqWB_register_Asm_16 :8798 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8799 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8800 rGPR:$Rm, pred:$p)>;8801def VLD4LNqWB_register_Asm_32 :8802 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8803 (ins VecListFourQWordIndexed:$list,8804 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;8805 8806 8807 8808// VLD4 multiple structure pseudo-instructions. These need special handling for8809// the vector operands that the normal instructions don't yet model.8810// FIXME: Remove these when the register classes and instructions are updated.8811def VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",8812 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8813 pred:$p)>;8814def VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8815 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8816 pred:$p)>;8817def VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8818 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8819 pred:$p)>;8820def VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",8821 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8822 pred:$p)>;8823def VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",8824 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8825 pred:$p)>;8826def VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",8827 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8828 pred:$p)>;8829 8830def VLD4dWB_fixed_Asm_8 :8831 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",8832 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8833 pred:$p)>;8834def VLD4dWB_fixed_Asm_16 :8835 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8836 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8837 pred:$p)>;8838def VLD4dWB_fixed_Asm_32 :8839 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8840 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8841 pred:$p)>;8842def VLD4qWB_fixed_Asm_8 :8843 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",8844 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8845 pred:$p)>;8846def VLD4qWB_fixed_Asm_16 :8847 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",8848 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8849 pred:$p)>;8850def VLD4qWB_fixed_Asm_32 :8851 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",8852 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8853 pred:$p)>;8854def VLD4dWB_register_Asm_8 :8855 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",8856 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8857 rGPR:$Rm, pred:$p)>;8858def VLD4dWB_register_Asm_16 :8859 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8860 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8861 rGPR:$Rm, pred:$p)>;8862def VLD4dWB_register_Asm_32 :8863 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8864 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8865 rGPR:$Rm, pred:$p)>;8866def VLD4qWB_register_Asm_8 :8867 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",8868 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8869 rGPR:$Rm, pred:$p)>;8870def VLD4qWB_register_Asm_16 :8871 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",8872 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8873 rGPR:$Rm, pred:$p)>;8874def VLD4qWB_register_Asm_32 :8875 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",8876 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8877 rGPR:$Rm, pred:$p)>;8878 8879let mayStore = 1 in {8880 8881// VST4 single-lane pseudo-instructions. These need special handling for8882// the lane index that an InstAlias can't handle, so we use these instead.8883def VST4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",8884 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8885 pred:$p)>;8886def VST4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",8887 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8888 pred:$p)>;8889def VST4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",8890 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,8891 pred:$p)>;8892def VST4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",8893 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8894 pred:$p)>;8895def VST4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",8896 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,8897 pred:$p)>;8898 8899def VST4LNdWB_fixed_Asm_8 :8900 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",8901 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8902 pred:$p)>;8903def VST4LNdWB_fixed_Asm_16 :8904 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",8905 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8906 pred:$p)>;8907def VST4LNdWB_fixed_Asm_32 :8908 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",8909 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,8910 pred:$p)>;8911def VST4LNqWB_fixed_Asm_16 :8912 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",8913 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8914 pred:$p)>;8915def VST4LNqWB_fixed_Asm_32 :8916 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",8917 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,8918 pred:$p)>;8919def VST4LNdWB_register_Asm_8 :8920 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",8921 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,8922 rGPR:$Rm, pred:$p)>;8923def VST4LNdWB_register_Asm_16 :8924 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",8925 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,8926 rGPR:$Rm, pred:$p)>;8927def VST4LNdWB_register_Asm_32 :8928 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",8929 (ins VecListFourDWordIndexed:$list,8930 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;8931def VST4LNqWB_register_Asm_16 :8932 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",8933 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,8934 rGPR:$Rm, pred:$p)>;8935def VST4LNqWB_register_Asm_32 :8936 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",8937 (ins VecListFourQWordIndexed:$list,8938 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;8939 8940 8941// VST4 multiple structure pseudo-instructions. These need special handling for8942// the vector operands that the normal instructions don't yet model.8943// FIXME: Remove these when the register classes and instructions are updated.8944def VST4dAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",8945 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8946 pred:$p)>;8947def VST4dAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",8948 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8949 pred:$p)>;8950def VST4dAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",8951 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8952 pred:$p)>;8953def VST4qAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",8954 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8955 pred:$p)>;8956def VST4qAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",8957 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8958 pred:$p)>;8959def VST4qAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",8960 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8961 pred:$p)>;8962 8963def VST4dWB_fixed_Asm_8 :8964 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",8965 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8966 pred:$p)>;8967def VST4dWB_fixed_Asm_16 :8968 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",8969 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8970 pred:$p)>;8971def VST4dWB_fixed_Asm_32 :8972 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",8973 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8974 pred:$p)>;8975def VST4qWB_fixed_Asm_8 :8976 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",8977 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8978 pred:$p)>;8979def VST4qWB_fixed_Asm_16 :8980 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",8981 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8982 pred:$p)>;8983def VST4qWB_fixed_Asm_32 :8984 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",8985 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,8986 pred:$p)>;8987def VST4dWB_register_Asm_8 :8988 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",8989 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8990 rGPR:$Rm, pred:$p)>;8991def VST4dWB_register_Asm_16 :8992 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",8993 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8994 rGPR:$Rm, pred:$p)>;8995def VST4dWB_register_Asm_32 :8996 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",8997 (ins VecListFourD:$list, addrmode6align64or128or256:$addr,8998 rGPR:$Rm, pred:$p)>;8999def VST4qWB_register_Asm_8 :9000 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",9001 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,9002 rGPR:$Rm, pred:$p)>;9003def VST4qWB_register_Asm_16 :9004 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",9005 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,9006 rGPR:$Rm, pred:$p)>;9007def VST4qWB_register_Asm_32 :9008 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",9009 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,9010 rGPR:$Rm, pred:$p)>;9011}9012 9013// VMOV/VMVN takes an optional datatype suffix9014defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",9015 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;9016defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",9017 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;9018 9019defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",9020 (VMVNd DPR:$Vd, DPR:$Vm, pred:$p)>;9021defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",9022 (VMVNq QPR:$Vd, QPR:$Vm, pred:$p)>;9023 9024// VCLT (register) is an assembler alias for VCGT w/ the operands reversed.9025// D-register versions.9026def : NEONInstAlias<"vcle${p}.s8 $Dd, $Dn, $Dm",9027 (VCGEsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9028def : NEONInstAlias<"vcle${p}.s16 $Dd, $Dn, $Dm",9029 (VCGEsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9030def : NEONInstAlias<"vcle${p}.s32 $Dd, $Dn, $Dm",9031 (VCGEsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9032def : NEONInstAlias<"vcle${p}.u8 $Dd, $Dn, $Dm",9033 (VCGEuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9034def : NEONInstAlias<"vcle${p}.u16 $Dd, $Dn, $Dm",9035 (VCGEuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9036def : NEONInstAlias<"vcle${p}.u32 $Dd, $Dn, $Dm",9037 (VCGEuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9038def : NEONInstAlias<"vcle${p}.f32 $Dd, $Dn, $Dm",9039 (VCGEfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9040let Predicates = [HasNEON, HasFullFP16] in9041def : NEONInstAlias<"vcle${p}.f16 $Dd, $Dn, $Dm",9042 (VCGEhd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9043// Q-register versions.9044def : NEONInstAlias<"vcle${p}.s8 $Qd, $Qn, $Qm",9045 (VCGEsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9046def : NEONInstAlias<"vcle${p}.s16 $Qd, $Qn, $Qm",9047 (VCGEsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9048def : NEONInstAlias<"vcle${p}.s32 $Qd, $Qn, $Qm",9049 (VCGEsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9050def : NEONInstAlias<"vcle${p}.u8 $Qd, $Qn, $Qm",9051 (VCGEuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9052def : NEONInstAlias<"vcle${p}.u16 $Qd, $Qn, $Qm",9053 (VCGEuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9054def : NEONInstAlias<"vcle${p}.u32 $Qd, $Qn, $Qm",9055 (VCGEuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9056def : NEONInstAlias<"vcle${p}.f32 $Qd, $Qn, $Qm",9057 (VCGEfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9058let Predicates = [HasNEON, HasFullFP16] in9059def : NEONInstAlias<"vcle${p}.f16 $Qd, $Qn, $Qm",9060 (VCGEhq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9061 9062// VCLT (register) is an assembler alias for VCGT w/ the operands reversed.9063// D-register versions.9064def : NEONInstAlias<"vclt${p}.s8 $Dd, $Dn, $Dm",9065 (VCGTsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9066def : NEONInstAlias<"vclt${p}.s16 $Dd, $Dn, $Dm",9067 (VCGTsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9068def : NEONInstAlias<"vclt${p}.s32 $Dd, $Dn, $Dm",9069 (VCGTsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9070def : NEONInstAlias<"vclt${p}.u8 $Dd, $Dn, $Dm",9071 (VCGTuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9072def : NEONInstAlias<"vclt${p}.u16 $Dd, $Dn, $Dm",9073 (VCGTuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9074def : NEONInstAlias<"vclt${p}.u32 $Dd, $Dn, $Dm",9075 (VCGTuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9076def : NEONInstAlias<"vclt${p}.f32 $Dd, $Dn, $Dm",9077 (VCGTfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9078let Predicates = [HasNEON, HasFullFP16] in9079def : NEONInstAlias<"vclt${p}.f16 $Dd, $Dn, $Dm",9080 (VCGThd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;9081// Q-register versions.9082def : NEONInstAlias<"vclt${p}.s8 $Qd, $Qn, $Qm",9083 (VCGTsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9084def : NEONInstAlias<"vclt${p}.s16 $Qd, $Qn, $Qm",9085 (VCGTsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9086def : NEONInstAlias<"vclt${p}.s32 $Qd, $Qn, $Qm",9087 (VCGTsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9088def : NEONInstAlias<"vclt${p}.u8 $Qd, $Qn, $Qm",9089 (VCGTuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9090def : NEONInstAlias<"vclt${p}.u16 $Qd, $Qn, $Qm",9091 (VCGTuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9092def : NEONInstAlias<"vclt${p}.u32 $Qd, $Qn, $Qm",9093 (VCGTuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9094def : NEONInstAlias<"vclt${p}.f32 $Qd, $Qn, $Qm",9095 (VCGTfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9096let Predicates = [HasNEON, HasFullFP16] in9097def : NEONInstAlias<"vclt${p}.f16 $Qd, $Qn, $Qm",9098 (VCGThq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;9099 9100// VSWP allows, but does not require, a type suffix.9101defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",9102 (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>;9103defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",9104 (VSWPq QPR:$Vd, QPR:$Vm, pred:$p)>;9105 9106// VBIF, VBIT, and VBSL allow, but do not require, a type suffix.9107defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",9108 (VBIFd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;9109defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",9110 (VBITd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;9111defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",9112 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;9113defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",9114 (VBIFq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;9115defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",9116 (VBITq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;9117defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",9118 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;9119 9120// "vmov Rd, #-imm" can be handled via "vmvn".9121def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",9122 (VMVNv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;9123def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",9124 (VMVNv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;9125def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",9126 (VMOVv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;9127def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",9128 (VMOVv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;9129 9130// 'gas' compatibility aliases for quad-word instructions. Strictly speaking,9131// these should restrict to just the Q register variants, but the register9132// classes are enough to match correctly regardless, so we keep it simple9133// and just use MnemonicAlias.9134def : NEONMnemonicAlias<"vbicq", "vbic">;9135def : NEONMnemonicAlias<"vandq", "vand">;9136def : NEONMnemonicAlias<"veorq", "veor">;9137def : NEONMnemonicAlias<"vorrq", "vorr">;9138 9139def : NEONMnemonicAlias<"vmovq", "vmov">;9140def : NEONMnemonicAlias<"vmvnq", "vmvn">;9141// Explicit versions for floating point so that the FPImm variants get9142// handled early. The parser gets confused otherwise.9143def : NEONMnemonicAlias<"vmovq.f32", "vmov.f32">;9144def : NEONMnemonicAlias<"vmovq.f64", "vmov.f64">;9145 9146def : NEONMnemonicAlias<"vaddq", "vadd">;9147def : NEONMnemonicAlias<"vsubq", "vsub">;9148 9149def : NEONMnemonicAlias<"vminq", "vmin">;9150def : NEONMnemonicAlias<"vmaxq", "vmax">;9151 9152def : NEONMnemonicAlias<"vmulq", "vmul">;9153 9154def : NEONMnemonicAlias<"vabsq", "vabs">;9155 9156def : NEONMnemonicAlias<"vshlq", "vshl">;9157def : NEONMnemonicAlias<"vshrq", "vshr">;9158 9159def : NEONMnemonicAlias<"vcvtq", "vcvt">;9160 9161def : NEONMnemonicAlias<"vcleq", "vcle">;9162def : NEONMnemonicAlias<"vceqq", "vceq">;9163 9164def : NEONMnemonicAlias<"vzipq", "vzip">;9165def : NEONMnemonicAlias<"vswpq", "vswp">;9166 9167def : NEONMnemonicAlias<"vrecpeq.f32", "vrecpe.f32">;9168def : NEONMnemonicAlias<"vrecpeq.u32", "vrecpe.u32">;9169 9170 9171// Alias for loading floating point immediates that aren't representable9172// using the vmov.f32 encoding but the bitpattern is representable using9173// the .i32 encoding.9174def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",9175 (VMOVv4i32 QPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;9176def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",9177 (VMOVv2i32 DPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;9178 9179// ARMv8.6a BFloat16 instructions.9180let Predicates = [HasBF16, HasNEON] in {9181class BF16VDOT<bits<5> op27_23, bits<2> op21_20, bit op6,9182 dag oops, dag iops, list<dag> pattern>9183 : N3Vnp<op27_23, op21_20, 0b1101, op6, 0, oops, iops,9184 N3RegFrm, IIC_VDOTPROD, "", "", pattern>9185{9186 let DecoderNamespace = "VFPV8";9187}9188 9189class BF16VDOTS<bit Q, RegisterClass RegTy, string opc, ValueType AccumTy, ValueType InputTy>9190 : BF16VDOT<0b11000, 0b00, Q, (outs RegTy:$dst),9191 (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm),9192 [(set (AccumTy RegTy:$dst),9193 (int_arm_neon_bfdot (AccumTy RegTy:$Vd),9194 (InputTy RegTy:$Vn),9195 (InputTy RegTy:$Vm)))]> {9196 let Constraints = "$dst = $Vd";9197 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm");9198 let DecoderNamespace = "VFPV8";9199}9200 9201multiclass BF16VDOTI<bit Q, RegisterClass RegTy, string opc, ValueType AccumTy,9202 ValueType InputTy, dag RHS> {9203 9204 def "" : BF16VDOT<0b11100, 0b00, Q, (outs RegTy:$dst),9205 (ins RegTy:$Vd, RegTy:$Vn,9206 DPR_VFP2:$Vm, VectorIndex32:$lane), []> {9207 bit lane;9208 let Inst{5} = lane;9209 let Constraints = "$dst = $Vd";9210 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm$lane");9211 let DecoderNamespace = "VFPV8";9212 }9213 9214 def : Pat<9215 (AccumTy (int_arm_neon_bfdot (AccumTy RegTy:$Vd),9216 (InputTy RegTy:$Vn),9217 (InputTy (bitconvert (AccumTy9218 (ARMvduplane (AccumTy RegTy:$Vm),9219 VectorIndex32:$lane)))))),9220 (!cast<Instruction>(NAME) RegTy:$Vd, RegTy:$Vn, RHS, VectorIndex32:$lane)>;9221}9222 9223def BF16VDOTS_VDOTD : BF16VDOTS<0, DPR, "vdot", v2f32, v4bf16>;9224def BF16VDOTS_VDOTQ : BF16VDOTS<1, QPR, "vdot", v4f32, v8bf16>;9225 9226defm BF16VDOTI_VDOTD : BF16VDOTI<0, DPR, "vdot", v2f32, v4bf16, (v2f32 DPR_VFP2:$Vm)>;9227defm BF16VDOTI_VDOTQ : BF16VDOTI<1, QPR, "vdot", v4f32, v8bf16, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;9228 9229class BF16MM<bit Q, RegisterClass RegTy,9230 string opc>9231 : N3Vnp<0b11000, 0b00, 0b1100, Q, 0,9232 (outs RegTy:$dst), (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm),9233 N3RegFrm, IIC_VDOTPROD, "", "",9234 [(set (v4f32 QPR:$dst), (int_arm_neon_bfmmla (v4f32 QPR:$Vd),9235 (v8bf16 QPR:$Vn),9236 (v8bf16 QPR:$Vm)))]> {9237 let Constraints = "$dst = $Vd";9238 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm");9239 let DecoderNamespace = "VFPV8";9240}9241 9242def VMMLA : BF16MM<1, QPR, "vmmla">;9243 9244class VBF16MALQ<bit T, string suffix, SDPatternOperator OpNode>9245 : N3VCP8<0b00, 0b11, T, 1,9246 (outs QPR:$dst), (ins QPR:$Vd, QPR:$Vn, QPR:$Vm),9247 NoItinerary, "vfma" # suffix, "bf16", "$Vd, $Vn, $Vm", "",9248 [(set (v4f32 QPR:$dst),9249 (OpNode (v4f32 QPR:$Vd),9250 (v8bf16 QPR:$Vn),9251 (v8bf16 QPR:$Vm)))]> {9252 let Constraints = "$dst = $Vd";9253 let DecoderNamespace = "VFPV8";9254}9255 9256def VBF16MALTQ: VBF16MALQ<1, "t", int_arm_neon_bfmlalt>;9257def VBF16MALBQ: VBF16MALQ<0, "b", int_arm_neon_bfmlalb>;9258 9259multiclass VBF16MALQI<bit T, string suffix, SDPatternOperator OpNode> {9260 def "" : N3VLaneCP8<0, 0b11, T, 1, (outs QPR:$dst),9261 (ins QPR:$Vd, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx),9262 IIC_VMACD, "vfma" # suffix, "bf16", "$Vd, $Vn, $Vm$idx", "", []> {9263 bits<2> idx;9264 let Inst{5} = idx{1};9265 let Inst{3} = idx{0};9266 let Constraints = "$dst = $Vd";9267 let DecoderNamespace = "VFPV8";9268 }9269 9270 def : Pat<9271 (v4f32 (OpNode (v4f32 QPR:$Vd),9272 (v8bf16 QPR:$Vn),9273 (v8bf16 (ARMvduplane (v8bf16 QPR:$Vm),9274 VectorIndex16:$lane)))),9275 (!cast<Instruction>(NAME) QPR:$Vd,9276 QPR:$Vn,9277 (EXTRACT_SUBREG QPR:$Vm,9278 (DSubReg_i16_reg VectorIndex16:$lane)),9279 (SubReg_i16_lane VectorIndex16:$lane))>;9280}9281 9282defm VBF16MALTQI: VBF16MALQI<1, "t", int_arm_neon_bfmlalt>;9283defm VBF16MALBQI: VBF16MALQI<0, "b", int_arm_neon_bfmlalb>;9284 9285def BF16_VCVT : N2V<0b11, 0b11, 0b01, 0b10, 0b01100, 1, 0,9286 (outs DPR:$Vd), (ins QPR:$Vm),9287 NoItinerary, "vcvt", "bf16.f32", "$Vd, $Vm", "", []>;9288}9289// End of BFloat16 instructions9290