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