brintos

brintos / llvm-project-archived public Read only

0
0
Text · 442.9 KiB · 90e74a5 Raw
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