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