]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMInstrNEON.td
MFV r316902: 7745 print error if lzc_* is called before libzfs_core_init
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARM / ARMInstrNEON.td
1 //===-- ARMInstrNEON.td - NEON support for ARM -------------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the ARM NEON instruction set.
11 //
12 //===----------------------------------------------------------------------===//
13
14
15 //===----------------------------------------------------------------------===//
16 // NEON-specific Operands.
17 //===----------------------------------------------------------------------===//
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 nImmSplatNotI16AsmOperand : AsmOperandClass { let Name = "NEONi16splatNot"; }
38 def nImmSplatNotI16 : Operand<i32> {
39   let ParserMatchClass = nImmSplatNotI16AsmOperand;
40 }
41 def nImmSplatNotI32AsmOperand : AsmOperandClass { let Name = "NEONi32splatNot"; }
42 def nImmSplatNotI32 : Operand<i32> {
43   let ParserMatchClass = nImmSplatNotI32AsmOperand;
44 }
45 def nImmVMOVI32AsmOperand : AsmOperandClass { let Name = "NEONi32vmov"; }
46 def nImmVMOVI32 : Operand<i32> {
47   let PrintMethod = "printNEONModImmOperand";
48   let ParserMatchClass = nImmVMOVI32AsmOperand;
49 }
50
51 def nImmVMOVI16AsmOperandByteReplicate :
52   AsmOperandClass {
53   let Name = "NEONi16vmovByteReplicate";
54   let PredicateMethod = "isNEONi16ByteReplicate";
55   let RenderMethod = "addNEONvmovByteReplicateOperands";
56 }
57 def nImmVMOVI32AsmOperandByteReplicate :
58   AsmOperandClass {
59   let Name = "NEONi32vmovByteReplicate";
60   let PredicateMethod = "isNEONi32ByteReplicate";
61   let RenderMethod = "addNEONvmovByteReplicateOperands";
62 }
63 def nImmVMVNI16AsmOperandByteReplicate :
64   AsmOperandClass {
65   let Name = "NEONi16invByteReplicate";
66   let PredicateMethod = "isNEONi16ByteReplicate";
67   let RenderMethod = "addNEONinvByteReplicateOperands";
68 }
69 def nImmVMVNI32AsmOperandByteReplicate :
70   AsmOperandClass {
71   let Name = "NEONi32invByteReplicate";
72   let PredicateMethod = "isNEONi32ByteReplicate";
73   let RenderMethod = "addNEONinvByteReplicateOperands";
74 }
75
76 def nImmVMOVI16ByteReplicate : Operand<i32> {
77   let PrintMethod = "printNEONModImmOperand";
78   let ParserMatchClass = nImmVMOVI16AsmOperandByteReplicate;
79 }
80 def nImmVMOVI32ByteReplicate : Operand<i32> {
81   let PrintMethod = "printNEONModImmOperand";
82   let ParserMatchClass = nImmVMOVI32AsmOperandByteReplicate;
83 }
84 def nImmVMVNI16ByteReplicate : Operand<i32> {
85   let PrintMethod = "printNEONModImmOperand";
86   let ParserMatchClass = nImmVMVNI16AsmOperandByteReplicate;
87 }
88 def nImmVMVNI32ByteReplicate : Operand<i32> {
89   let PrintMethod = "printNEONModImmOperand";
90   let ParserMatchClass = nImmVMVNI32AsmOperandByteReplicate;
91 }
92
93 def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; }
94 def nImmVMOVI32Neg : Operand<i32> {
95   let PrintMethod = "printNEONModImmOperand";
96   let ParserMatchClass = nImmVMOVI32NegAsmOperand;
97 }
98 def nImmVMOVF32 : Operand<i32> {
99   let PrintMethod = "printFPImmOperand";
100   let ParserMatchClass = FPImmOperand;
101 }
102 def nImmSplatI64AsmOperand : AsmOperandClass { let Name = "NEONi64splat"; }
103 def nImmSplatI64 : Operand<i32> {
104   let PrintMethod = "printNEONModImmOperand";
105   let ParserMatchClass = nImmSplatI64AsmOperand;
106 }
107
108 def VectorIndex8Operand  : AsmOperandClass { let Name = "VectorIndex8"; }
109 def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; }
110 def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; }
111 def VectorIndex64Operand : AsmOperandClass { let Name = "VectorIndex64"; }
112 def VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{
113   return ((uint64_t)Imm) < 8;
114 }]> {
115   let ParserMatchClass = VectorIndex8Operand;
116   let PrintMethod = "printVectorIndex";
117   let MIOperandInfo = (ops i32imm);
118 }
119 def VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{
120   return ((uint64_t)Imm) < 4;
121 }]> {
122   let ParserMatchClass = VectorIndex16Operand;
123   let PrintMethod = "printVectorIndex";
124   let MIOperandInfo = (ops i32imm);
125 }
126 def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{
127   return ((uint64_t)Imm) < 2;
128 }]> {
129   let ParserMatchClass = VectorIndex32Operand;
130   let PrintMethod = "printVectorIndex";
131   let MIOperandInfo = (ops i32imm);
132 }
133 def VectorIndex64 : Operand<i32>, ImmLeaf<i32, [{
134   return ((uint64_t)Imm) < 1;
135 }]> {
136   let ParserMatchClass = VectorIndex64Operand;
137   let PrintMethod = "printVectorIndex";
138   let MIOperandInfo = (ops i32imm);
139 }
140
141 // Register list of one D register.
142 def VecListOneDAsmOperand : AsmOperandClass {
143   let Name = "VecListOneD";
144   let ParserMethod = "parseVectorList";
145   let RenderMethod = "addVecListOperands";
146 }
147 def VecListOneD : RegisterOperand<DPR, "printVectorListOne"> {
148   let ParserMatchClass = VecListOneDAsmOperand;
149 }
150 // Register list of two sequential D registers.
151 def VecListDPairAsmOperand : AsmOperandClass {
152   let Name = "VecListDPair";
153   let ParserMethod = "parseVectorList";
154   let RenderMethod = "addVecListOperands";
155 }
156 def VecListDPair : RegisterOperand<DPair, "printVectorListTwo"> {
157   let ParserMatchClass = VecListDPairAsmOperand;
158 }
159 // Register list of three sequential D registers.
160 def VecListThreeDAsmOperand : AsmOperandClass {
161   let Name = "VecListThreeD";
162   let ParserMethod = "parseVectorList";
163   let RenderMethod = "addVecListOperands";
164 }
165 def VecListThreeD : RegisterOperand<DPR, "printVectorListThree"> {
166   let ParserMatchClass = VecListThreeDAsmOperand;
167 }
168 // Register list of four sequential D registers.
169 def VecListFourDAsmOperand : AsmOperandClass {
170   let Name = "VecListFourD";
171   let ParserMethod = "parseVectorList";
172   let RenderMethod = "addVecListOperands";
173 }
174 def VecListFourD : RegisterOperand<DPR, "printVectorListFour"> {
175   let ParserMatchClass = VecListFourDAsmOperand;
176 }
177 // Register list of two D registers spaced by 2 (two sequential Q registers).
178 def VecListDPairSpacedAsmOperand : AsmOperandClass {
179   let Name = "VecListDPairSpaced";
180   let ParserMethod = "parseVectorList";
181   let RenderMethod = "addVecListOperands";
182 }
183 def VecListDPairSpaced : RegisterOperand<DPair, "printVectorListTwoSpaced"> {
184   let ParserMatchClass = VecListDPairSpacedAsmOperand;
185 }
186 // Register list of three D registers spaced by 2 (three Q registers).
187 def VecListThreeQAsmOperand : AsmOperandClass {
188   let Name = "VecListThreeQ";
189   let ParserMethod = "parseVectorList";
190   let RenderMethod = "addVecListOperands";
191 }
192 def VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> {
193   let ParserMatchClass = VecListThreeQAsmOperand;
194 }
195 // Register list of three D registers spaced by 2 (three Q registers).
196 def VecListFourQAsmOperand : AsmOperandClass {
197   let Name = "VecListFourQ";
198   let ParserMethod = "parseVectorList";
199   let RenderMethod = "addVecListOperands";
200 }
201 def VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> {
202   let ParserMatchClass = VecListFourQAsmOperand;
203 }
204
205 // Register list of one D register, with "all lanes" subscripting.
206 def VecListOneDAllLanesAsmOperand : AsmOperandClass {
207   let Name = "VecListOneDAllLanes";
208   let ParserMethod = "parseVectorList";
209   let RenderMethod = "addVecListOperands";
210 }
211 def VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> {
212   let ParserMatchClass = VecListOneDAllLanesAsmOperand;
213 }
214 // Register list of two D registers, with "all lanes" subscripting.
215 def VecListDPairAllLanesAsmOperand : AsmOperandClass {
216   let Name = "VecListDPairAllLanes";
217   let ParserMethod = "parseVectorList";
218   let RenderMethod = "addVecListOperands";
219 }
220 def VecListDPairAllLanes : RegisterOperand<DPair,
221                                            "printVectorListTwoAllLanes"> {
222   let ParserMatchClass = VecListDPairAllLanesAsmOperand;
223 }
224 // Register list of two D registers spaced by 2 (two sequential Q registers).
225 def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass {
226   let Name = "VecListDPairSpacedAllLanes";
227   let ParserMethod = "parseVectorList";
228   let RenderMethod = "addVecListOperands";
229 }
230 def VecListDPairSpacedAllLanes : RegisterOperand<DPair,
231                                          "printVectorListTwoSpacedAllLanes"> {
232   let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand;
233 }
234 // Register list of three D registers, with "all lanes" subscripting.
235 def VecListThreeDAllLanesAsmOperand : AsmOperandClass {
236   let Name = "VecListThreeDAllLanes";
237   let ParserMethod = "parseVectorList";
238   let RenderMethod = "addVecListOperands";
239 }
240 def VecListThreeDAllLanes : RegisterOperand<DPR,
241                                             "printVectorListThreeAllLanes"> {
242   let ParserMatchClass = VecListThreeDAllLanesAsmOperand;
243 }
244 // Register list of three D registers spaced by 2 (three sequential Q regs).
245 def VecListThreeQAllLanesAsmOperand : AsmOperandClass {
246   let Name = "VecListThreeQAllLanes";
247   let ParserMethod = "parseVectorList";
248   let RenderMethod = "addVecListOperands";
249 }
250 def VecListThreeQAllLanes : RegisterOperand<DPR,
251                                          "printVectorListThreeSpacedAllLanes"> {
252   let ParserMatchClass = VecListThreeQAllLanesAsmOperand;
253 }
254 // Register list of four D registers, with "all lanes" subscripting.
255 def VecListFourDAllLanesAsmOperand : AsmOperandClass {
256   let Name = "VecListFourDAllLanes";
257   let ParserMethod = "parseVectorList";
258   let RenderMethod = "addVecListOperands";
259 }
260 def VecListFourDAllLanes : RegisterOperand<DPR, "printVectorListFourAllLanes"> {
261   let ParserMatchClass = VecListFourDAllLanesAsmOperand;
262 }
263 // Register list of four D registers spaced by 2 (four sequential Q regs).
264 def VecListFourQAllLanesAsmOperand : AsmOperandClass {
265   let Name = "VecListFourQAllLanes";
266   let ParserMethod = "parseVectorList";
267   let RenderMethod = "addVecListOperands";
268 }
269 def VecListFourQAllLanes : RegisterOperand<DPR,
270                                          "printVectorListFourSpacedAllLanes"> {
271   let ParserMatchClass = VecListFourQAllLanesAsmOperand;
272 }
273
274
275 // Register list of one D register, with byte lane subscripting.
276 def VecListOneDByteIndexAsmOperand : AsmOperandClass {
277   let Name = "VecListOneDByteIndexed";
278   let ParserMethod = "parseVectorList";
279   let RenderMethod = "addVecListIndexedOperands";
280 }
281 def VecListOneDByteIndexed : Operand<i32> {
282   let ParserMatchClass = VecListOneDByteIndexAsmOperand;
283   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
284 }
285 // ...with half-word lane subscripting.
286 def VecListOneDHWordIndexAsmOperand : AsmOperandClass {
287   let Name = "VecListOneDHWordIndexed";
288   let ParserMethod = "parseVectorList";
289   let RenderMethod = "addVecListIndexedOperands";
290 }
291 def VecListOneDHWordIndexed : Operand<i32> {
292   let ParserMatchClass = VecListOneDHWordIndexAsmOperand;
293   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
294 }
295 // ...with word lane subscripting.
296 def VecListOneDWordIndexAsmOperand : AsmOperandClass {
297   let Name = "VecListOneDWordIndexed";
298   let ParserMethod = "parseVectorList";
299   let RenderMethod = "addVecListIndexedOperands";
300 }
301 def VecListOneDWordIndexed : Operand<i32> {
302   let ParserMatchClass = VecListOneDWordIndexAsmOperand;
303   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
304 }
305
306 // Register list of two D registers with byte lane subscripting.
307 def VecListTwoDByteIndexAsmOperand : AsmOperandClass {
308   let Name = "VecListTwoDByteIndexed";
309   let ParserMethod = "parseVectorList";
310   let RenderMethod = "addVecListIndexedOperands";
311 }
312 def VecListTwoDByteIndexed : Operand<i32> {
313   let ParserMatchClass = VecListTwoDByteIndexAsmOperand;
314   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
315 }
316 // ...with half-word lane subscripting.
317 def VecListTwoDHWordIndexAsmOperand : AsmOperandClass {
318   let Name = "VecListTwoDHWordIndexed";
319   let ParserMethod = "parseVectorList";
320   let RenderMethod = "addVecListIndexedOperands";
321 }
322 def VecListTwoDHWordIndexed : Operand<i32> {
323   let ParserMatchClass = VecListTwoDHWordIndexAsmOperand;
324   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
325 }
326 // ...with word lane subscripting.
327 def VecListTwoDWordIndexAsmOperand : AsmOperandClass {
328   let Name = "VecListTwoDWordIndexed";
329   let ParserMethod = "parseVectorList";
330   let RenderMethod = "addVecListIndexedOperands";
331 }
332 def VecListTwoDWordIndexed : Operand<i32> {
333   let ParserMatchClass = VecListTwoDWordIndexAsmOperand;
334   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
335 }
336 // Register list of two Q registers with half-word lane subscripting.
337 def VecListTwoQHWordIndexAsmOperand : AsmOperandClass {
338   let Name = "VecListTwoQHWordIndexed";
339   let ParserMethod = "parseVectorList";
340   let RenderMethod = "addVecListIndexedOperands";
341 }
342 def VecListTwoQHWordIndexed : Operand<i32> {
343   let ParserMatchClass = VecListTwoQHWordIndexAsmOperand;
344   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
345 }
346 // ...with word lane subscripting.
347 def VecListTwoQWordIndexAsmOperand : AsmOperandClass {
348   let Name = "VecListTwoQWordIndexed";
349   let ParserMethod = "parseVectorList";
350   let RenderMethod = "addVecListIndexedOperands";
351 }
352 def VecListTwoQWordIndexed : Operand<i32> {
353   let ParserMatchClass = VecListTwoQWordIndexAsmOperand;
354   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
355 }
356
357
358 // Register list of three D registers with byte lane subscripting.
359 def VecListThreeDByteIndexAsmOperand : AsmOperandClass {
360   let Name = "VecListThreeDByteIndexed";
361   let ParserMethod = "parseVectorList";
362   let RenderMethod = "addVecListIndexedOperands";
363 }
364 def VecListThreeDByteIndexed : Operand<i32> {
365   let ParserMatchClass = VecListThreeDByteIndexAsmOperand;
366   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
367 }
368 // ...with half-word lane subscripting.
369 def VecListThreeDHWordIndexAsmOperand : AsmOperandClass {
370   let Name = "VecListThreeDHWordIndexed";
371   let ParserMethod = "parseVectorList";
372   let RenderMethod = "addVecListIndexedOperands";
373 }
374 def VecListThreeDHWordIndexed : Operand<i32> {
375   let ParserMatchClass = VecListThreeDHWordIndexAsmOperand;
376   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
377 }
378 // ...with word lane subscripting.
379 def VecListThreeDWordIndexAsmOperand : AsmOperandClass {
380   let Name = "VecListThreeDWordIndexed";
381   let ParserMethod = "parseVectorList";
382   let RenderMethod = "addVecListIndexedOperands";
383 }
384 def VecListThreeDWordIndexed : Operand<i32> {
385   let ParserMatchClass = VecListThreeDWordIndexAsmOperand;
386   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
387 }
388 // Register list of three Q registers with half-word lane subscripting.
389 def VecListThreeQHWordIndexAsmOperand : AsmOperandClass {
390   let Name = "VecListThreeQHWordIndexed";
391   let ParserMethod = "parseVectorList";
392   let RenderMethod = "addVecListIndexedOperands";
393 }
394 def VecListThreeQHWordIndexed : Operand<i32> {
395   let ParserMatchClass = VecListThreeQHWordIndexAsmOperand;
396   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
397 }
398 // ...with word lane subscripting.
399 def VecListThreeQWordIndexAsmOperand : AsmOperandClass {
400   let Name = "VecListThreeQWordIndexed";
401   let ParserMethod = "parseVectorList";
402   let RenderMethod = "addVecListIndexedOperands";
403 }
404 def VecListThreeQWordIndexed : Operand<i32> {
405   let ParserMatchClass = VecListThreeQWordIndexAsmOperand;
406   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
407 }
408
409 // Register list of four D registers with byte lane subscripting.
410 def VecListFourDByteIndexAsmOperand : AsmOperandClass {
411   let Name = "VecListFourDByteIndexed";
412   let ParserMethod = "parseVectorList";
413   let RenderMethod = "addVecListIndexedOperands";
414 }
415 def VecListFourDByteIndexed : Operand<i32> {
416   let ParserMatchClass = VecListFourDByteIndexAsmOperand;
417   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
418 }
419 // ...with half-word lane subscripting.
420 def VecListFourDHWordIndexAsmOperand : AsmOperandClass {
421   let Name = "VecListFourDHWordIndexed";
422   let ParserMethod = "parseVectorList";
423   let RenderMethod = "addVecListIndexedOperands";
424 }
425 def VecListFourDHWordIndexed : Operand<i32> {
426   let ParserMatchClass = VecListFourDHWordIndexAsmOperand;
427   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
428 }
429 // ...with word lane subscripting.
430 def VecListFourDWordIndexAsmOperand : AsmOperandClass {
431   let Name = "VecListFourDWordIndexed";
432   let ParserMethod = "parseVectorList";
433   let RenderMethod = "addVecListIndexedOperands";
434 }
435 def VecListFourDWordIndexed : Operand<i32> {
436   let ParserMatchClass = VecListFourDWordIndexAsmOperand;
437   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
438 }
439 // Register list of four Q registers with half-word lane subscripting.
440 def VecListFourQHWordIndexAsmOperand : AsmOperandClass {
441   let Name = "VecListFourQHWordIndexed";
442   let ParserMethod = "parseVectorList";
443   let RenderMethod = "addVecListIndexedOperands";
444 }
445 def VecListFourQHWordIndexed : Operand<i32> {
446   let ParserMatchClass = VecListFourQHWordIndexAsmOperand;
447   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
448 }
449 // ...with word lane subscripting.
450 def VecListFourQWordIndexAsmOperand : AsmOperandClass {
451   let Name = "VecListFourQWordIndexed";
452   let ParserMethod = "parseVectorList";
453   let RenderMethod = "addVecListIndexedOperands";
454 }
455 def VecListFourQWordIndexed : Operand<i32> {
456   let ParserMatchClass = VecListFourQWordIndexAsmOperand;
457   let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
458 }
459
460 def dword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
461   return cast<LoadSDNode>(N)->getAlignment() >= 8;
462 }]>;
463 def dword_alignedstore : PatFrag<(ops node:$val, node:$ptr),
464                                  (store node:$val, node:$ptr), [{
465   return cast<StoreSDNode>(N)->getAlignment() >= 8;
466 }]>;
467 def word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
468   return cast<LoadSDNode>(N)->getAlignment() == 4;
469 }]>;
470 def word_alignedstore : PatFrag<(ops node:$val, node:$ptr),
471                                  (store node:$val, node:$ptr), [{
472   return cast<StoreSDNode>(N)->getAlignment() == 4;
473 }]>;
474 def hword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
475   return cast<LoadSDNode>(N)->getAlignment() == 2;
476 }]>;
477 def hword_alignedstore : PatFrag<(ops node:$val, node:$ptr),
478                                  (store node:$val, node:$ptr), [{
479   return cast<StoreSDNode>(N)->getAlignment() == 2;
480 }]>;
481 def byte_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
482   return cast<LoadSDNode>(N)->getAlignment() == 1;
483 }]>;
484 def byte_alignedstore : PatFrag<(ops node:$val, node:$ptr),
485                              (store node:$val, node:$ptr), [{
486   return cast<StoreSDNode>(N)->getAlignment() == 1;
487 }]>;
488 def non_word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
489   return cast<LoadSDNode>(N)->getAlignment() < 4;
490 }]>;
491 def non_word_alignedstore : PatFrag<(ops node:$val, node:$ptr),
492                                     (store node:$val, node:$ptr), [{
493   return cast<StoreSDNode>(N)->getAlignment() < 4;
494 }]>;
495
496 //===----------------------------------------------------------------------===//
497 // NEON-specific DAG Nodes.
498 //===----------------------------------------------------------------------===//
499
500 def SDTARMVCMP    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>;
501 def SDTARMVCMPZ   : SDTypeProfile<1, 1, []>;
502
503 def NEONvceq      : SDNode<"ARMISD::VCEQ", SDTARMVCMP>;
504 def NEONvceqz     : SDNode<"ARMISD::VCEQZ", SDTARMVCMPZ>;
505 def NEONvcge      : SDNode<"ARMISD::VCGE", SDTARMVCMP>;
506 def NEONvcgez     : SDNode<"ARMISD::VCGEZ", SDTARMVCMPZ>;
507 def NEONvclez     : SDNode<"ARMISD::VCLEZ", SDTARMVCMPZ>;
508 def NEONvcgeu     : SDNode<"ARMISD::VCGEU", SDTARMVCMP>;
509 def NEONvcgt      : SDNode<"ARMISD::VCGT", SDTARMVCMP>;
510 def NEONvcgtz     : SDNode<"ARMISD::VCGTZ", SDTARMVCMPZ>;
511 def NEONvcltz     : SDNode<"ARMISD::VCLTZ", SDTARMVCMPZ>;
512 def NEONvcgtu     : SDNode<"ARMISD::VCGTU", SDTARMVCMP>;
513 def NEONvtst      : SDNode<"ARMISD::VTST", SDTARMVCMP>;
514
515 // Types for vector shift by immediates.  The "SHX" version is for long and
516 // narrow operations where the source and destination vectors have different
517 // types.  The "SHINS" version is for shift and insert operations.
518 def SDTARMVSH     : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
519                                          SDTCisVT<2, i32>]>;
520 def SDTARMVSHX    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
521                                          SDTCisVT<2, i32>]>;
522 def SDTARMVSHINS  : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
523                                          SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
524
525 def NEONvshl      : SDNode<"ARMISD::VSHL", SDTARMVSH>;
526 def NEONvshrs     : SDNode<"ARMISD::VSHRs", SDTARMVSH>;
527 def NEONvshru     : SDNode<"ARMISD::VSHRu", SDTARMVSH>;
528 def NEONvshrn     : SDNode<"ARMISD::VSHRN", SDTARMVSHX>;
529
530 def NEONvrshrs    : SDNode<"ARMISD::VRSHRs", SDTARMVSH>;
531 def NEONvrshru    : SDNode<"ARMISD::VRSHRu", SDTARMVSH>;
532 def NEONvrshrn    : SDNode<"ARMISD::VRSHRN", SDTARMVSHX>;
533
534 def NEONvqshls    : SDNode<"ARMISD::VQSHLs", SDTARMVSH>;
535 def NEONvqshlu    : SDNode<"ARMISD::VQSHLu", SDTARMVSH>;
536 def NEONvqshlsu   : SDNode<"ARMISD::VQSHLsu", SDTARMVSH>;
537 def NEONvqshrns   : SDNode<"ARMISD::VQSHRNs", SDTARMVSHX>;
538 def NEONvqshrnu   : SDNode<"ARMISD::VQSHRNu", SDTARMVSHX>;
539 def NEONvqshrnsu  : SDNode<"ARMISD::VQSHRNsu", SDTARMVSHX>;
540
541 def NEONvqrshrns  : SDNode<"ARMISD::VQRSHRNs", SDTARMVSHX>;
542 def NEONvqrshrnu  : SDNode<"ARMISD::VQRSHRNu", SDTARMVSHX>;
543 def NEONvqrshrnsu : SDNode<"ARMISD::VQRSHRNsu", SDTARMVSHX>;
544
545 def NEONvsli      : SDNode<"ARMISD::VSLI", SDTARMVSHINS>;
546 def NEONvsri      : SDNode<"ARMISD::VSRI", SDTARMVSHINS>;
547
548 def SDTARMVGETLN  : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>,
549                                          SDTCisVT<2, i32>]>;
550 def NEONvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>;
551 def NEONvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>;
552
553 def SDTARMVMOVIMM : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
554 def NEONvmovImm   : SDNode<"ARMISD::VMOVIMM", SDTARMVMOVIMM>;
555 def NEONvmvnImm   : SDNode<"ARMISD::VMVNIMM", SDTARMVMOVIMM>;
556 def NEONvmovFPImm : SDNode<"ARMISD::VMOVFPIMM", SDTARMVMOVIMM>;
557
558 def SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
559                                            SDTCisVT<2, i32>]>;
560 def NEONvorrImm   : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>;
561 def NEONvbicImm   : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>;
562
563 def NEONvbsl      : SDNode<"ARMISD::VBSL",
564                            SDTypeProfile<1, 3, [SDTCisVec<0>,
565                                                 SDTCisSameAs<0, 1>,
566                                                 SDTCisSameAs<0, 2>,
567                                                 SDTCisSameAs<0, 3>]>>;
568
569 def NEONvdup      : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
570
571 // VDUPLANE can produce a quad-register result from a double-register source,
572 // so the result is not constrained to match the source.
573 def NEONvduplane  : SDNode<"ARMISD::VDUPLANE",
574                            SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
575                                                 SDTCisVT<2, i32>]>>;
576
577 def SDTARMVEXT    : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
578                                          SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
579 def NEONvext      : SDNode<"ARMISD::VEXT", SDTARMVEXT>;
580
581 def SDTARMVSHUF   : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
582 def NEONvrev64    : SDNode<"ARMISD::VREV64", SDTARMVSHUF>;
583 def NEONvrev32    : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
584 def NEONvrev16    : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
585
586 def SDTARMVSHUF2  : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
587                                          SDTCisSameAs<0, 2>,
588                                          SDTCisSameAs<0, 3>]>;
589 def NEONzip       : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>;
590 def NEONuzp       : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>;
591 def NEONtrn       : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>;
592
593 def SDTARMVMULL   : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
594                                          SDTCisSameAs<1, 2>]>;
595 def NEONvmulls    : SDNode<"ARMISD::VMULLs", SDTARMVMULL>;
596 def NEONvmullu    : SDNode<"ARMISD::VMULLu", SDTARMVMULL>;
597
598 def SDTARMVTBL1   : SDTypeProfile<1, 2, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>,
599                                          SDTCisVT<2, v8i8>]>;
600 def SDTARMVTBL2   : SDTypeProfile<1, 3, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>,
601                                          SDTCisVT<2, v8i8>, SDTCisVT<3, v8i8>]>;
602 def NEONvtbl1     : SDNode<"ARMISD::VTBL1", SDTARMVTBL1>;
603 def NEONvtbl2     : SDNode<"ARMISD::VTBL2", SDTARMVTBL2>;
604
605
606 def NEONimmAllZerosV: PatLeaf<(NEONvmovImm (i32 timm)), [{
607   ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
608   unsigned EltBits = 0;
609   uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits);
610   return (EltBits == 32 && EltVal == 0);
611 }]>;
612
613 def NEONimmAllOnesV: PatLeaf<(NEONvmovImm (i32 timm)), [{
614   ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
615   unsigned EltBits = 0;
616   uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits);
617   return (EltBits == 8 && EltVal == 0xff);
618 }]>;
619
620 //===----------------------------------------------------------------------===//
621 // NEON load / store instructions
622 //===----------------------------------------------------------------------===//
623
624 // Use VLDM to load a Q register as a D register pair.
625 // This is a pseudo instruction that is expanded to VLDMD after reg alloc.
626 def VLDMQIA
627   : PseudoVFPLdStM<(outs DPair:$dst), (ins GPR:$Rn),
628                     IIC_fpLoad_m, "",
629                    [(set DPair:$dst, (v2f64 (word_alignedload GPR:$Rn)))]>;
630
631 // Use VSTM to store a Q register as a D register pair.
632 // This is a pseudo instruction that is expanded to VSTMD after reg alloc.
633 def VSTMQIA
634   : PseudoVFPLdStM<(outs), (ins DPair:$src, GPR:$Rn),
635                     IIC_fpStore_m, "",
636                    [(word_alignedstore (v2f64 DPair:$src), GPR:$Rn)]>;
637
638 // Classes for VLD* pseudo-instructions with multi-register operands.
639 // These are expanded to real instructions after register allocation.
640 class VLDQPseudo<InstrItinClass itin>
641   : PseudoNLdSt<(outs QPR:$dst), (ins addrmode6:$addr), itin, "">;
642 class VLDQWBPseudo<InstrItinClass itin>
643   : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
644                 (ins addrmode6:$addr, am6offset:$offset), itin,
645                 "$addr.addr = $wb">;
646 class VLDQWBfixedPseudo<InstrItinClass itin>
647   : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
648                 (ins addrmode6:$addr), itin,
649                 "$addr.addr = $wb">;
650 class VLDQWBregisterPseudo<InstrItinClass itin>
651   : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
652                 (ins addrmode6:$addr, rGPR:$offset), itin,
653                 "$addr.addr = $wb">;
654
655 class VLDQQPseudo<InstrItinClass itin>
656   : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">;
657 class VLDQQWBPseudo<InstrItinClass itin>
658   : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
659                 (ins addrmode6:$addr, am6offset:$offset), itin,
660                 "$addr.addr = $wb">;
661 class VLDQQWBfixedPseudo<InstrItinClass itin>
662   : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
663                 (ins addrmode6:$addr), itin,
664                 "$addr.addr = $wb">;
665 class VLDQQWBregisterPseudo<InstrItinClass itin>
666   : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
667                 (ins addrmode6:$addr, rGPR:$offset), itin,
668                 "$addr.addr = $wb">;
669
670
671 class VLDQQQQPseudo<InstrItinClass itin>
672   : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin,
673                 "$src = $dst">;
674 class VLDQQQQWBPseudo<InstrItinClass itin>
675   : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),
676                 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,
677                 "$addr.addr = $wb, $src = $dst">;
678
679 let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
680
681 //   VLD1     : Vector Load (multiple single elements)
682 class VLD1D<bits<4> op7_4, string Dt, Operand AddrMode>
683   : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd),
684           (ins AddrMode:$Rn), IIC_VLD1,
685           "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD1]> {
686   let Rm = 0b1111;
687   let Inst{4} = Rn{4};
688   let DecoderMethod = "DecodeVLDST1Instruction";
689 }
690 class VLD1Q<bits<4> op7_4, string Dt, Operand AddrMode>
691   : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd),
692           (ins AddrMode:$Rn), IIC_VLD1x2,
693           "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD2]> {
694   let Rm = 0b1111;
695   let Inst{5-4} = Rn{5-4};
696   let DecoderMethod = "DecodeVLDST1Instruction";
697 }
698
699 def  VLD1d8   : VLD1D<{0,0,0,?}, "8",  addrmode6align64>;
700 def  VLD1d16  : VLD1D<{0,1,0,?}, "16", addrmode6align64>;
701 def  VLD1d32  : VLD1D<{1,0,0,?}, "32", addrmode6align64>;
702 def  VLD1d64  : VLD1D<{1,1,0,?}, "64", addrmode6align64>;
703
704 def  VLD1q8   : VLD1Q<{0,0,?,?}, "8",  addrmode6align64or128>;
705 def  VLD1q16  : VLD1Q<{0,1,?,?}, "16", addrmode6align64or128>;
706 def  VLD1q32  : VLD1Q<{1,0,?,?}, "32", addrmode6align64or128>;
707 def  VLD1q64  : VLD1Q<{1,1,?,?}, "64", addrmode6align64or128>;
708
709 // ...with address register writeback:
710 multiclass VLD1DWB<bits<4> op7_4, string Dt, Operand AddrMode> {
711   def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
712                      (ins AddrMode:$Rn), IIC_VLD1u,
713                      "vld1", Dt, "$Vd, $Rn!",
714                      "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
715     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
716     let Inst{4} = Rn{4};
717     let DecoderMethod = "DecodeVLDST1Instruction";
718   }
719   def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
720                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1u,
721                         "vld1", Dt, "$Vd, $Rn, $Rm",
722                         "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
723     let Inst{4} = Rn{4};
724     let DecoderMethod = "DecodeVLDST1Instruction";
725   }
726 }
727 multiclass VLD1QWB<bits<4> op7_4, string Dt, Operand AddrMode> {
728   def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),
729                     (ins AddrMode:$Rn), IIC_VLD1x2u,
730                      "vld1", Dt, "$Vd, $Rn!",
731                      "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {
732     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
733     let Inst{5-4} = Rn{5-4};
734     let DecoderMethod = "DecodeVLDST1Instruction";
735   }
736   def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),
737                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,
738                         "vld1", Dt, "$Vd, $Rn, $Rm",
739                         "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {
740     let Inst{5-4} = Rn{5-4};
741     let DecoderMethod = "DecodeVLDST1Instruction";
742   }
743 }
744
745 defm VLD1d8wb  : VLD1DWB<{0,0,0,?}, "8",  addrmode6align64>;
746 defm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16", addrmode6align64>;
747 defm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32", addrmode6align64>;
748 defm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64", addrmode6align64>;
749 defm VLD1q8wb  : VLD1QWB<{0,0,?,?}, "8",  addrmode6align64or128>;
750 defm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16", addrmode6align64or128>;
751 defm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32", addrmode6align64or128>;
752 defm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64", addrmode6align64or128>;
753
754 // ...with 3 registers
755 class VLD1D3<bits<4> op7_4, string Dt, Operand AddrMode>
756   : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd),
757           (ins AddrMode:$Rn), IIC_VLD1x3, "vld1", Dt,
758           "$Vd, $Rn", "", []>, Sched<[WriteVLD3]> {
759   let Rm = 0b1111;
760   let Inst{4} = Rn{4};
761   let DecoderMethod = "DecodeVLDST1Instruction";
762 }
763 multiclass VLD1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> {
764   def _fixed : NLdSt<0,0b10,0b0110, op7_4, (outs VecListThreeD:$Vd, GPR:$wb),
765                     (ins AddrMode:$Rn), IIC_VLD1x2u,
766                      "vld1", Dt, "$Vd, $Rn!",
767                      "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {
768     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
769     let Inst{4} = Rn{4};
770     let DecoderMethod = "DecodeVLDST1Instruction";
771   }
772   def _register : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd, GPR:$wb),
773                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,
774                         "vld1", Dt, "$Vd, $Rn, $Rm",
775                         "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {
776     let Inst{4} = Rn{4};
777     let DecoderMethod = "DecodeVLDST1Instruction";
778   }
779 }
780
781 def VLD1d8T      : VLD1D3<{0,0,0,?}, "8",  addrmode6align64>;
782 def VLD1d16T     : VLD1D3<{0,1,0,?}, "16", addrmode6align64>;
783 def VLD1d32T     : VLD1D3<{1,0,0,?}, "32", addrmode6align64>;
784 def VLD1d64T     : VLD1D3<{1,1,0,?}, "64", addrmode6align64>;
785
786 defm VLD1d8Twb  : VLD1D3WB<{0,0,0,?}, "8",  addrmode6align64>;
787 defm VLD1d16Twb : VLD1D3WB<{0,1,0,?}, "16", addrmode6align64>;
788 defm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32", addrmode6align64>;
789 defm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64", addrmode6align64>;
790
791 def VLD1d64TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;
792 def VLD1d64TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;
793 def VLD1d64TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>;
794
795 // ...with 4 registers
796 class VLD1D4<bits<4> op7_4, string Dt, Operand AddrMode>
797   : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd),
798           (ins AddrMode:$Rn), IIC_VLD1x4, "vld1", Dt,
799           "$Vd, $Rn", "", []>, Sched<[WriteVLD4]> {
800   let Rm = 0b1111;
801   let Inst{5-4} = Rn{5-4};
802   let DecoderMethod = "DecodeVLDST1Instruction";
803 }
804 multiclass VLD1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> {
805   def _fixed : NLdSt<0,0b10,0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb),
806                     (ins AddrMode:$Rn), IIC_VLD1x2u,
807                      "vld1", Dt, "$Vd, $Rn!",
808                      "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {
809     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
810     let Inst{5-4} = Rn{5-4};
811     let DecoderMethod = "DecodeVLDST1Instruction";
812   }
813   def _register : NLdSt<0,0b10,0b0010,op7_4, (outs VecListFourD:$Vd, GPR:$wb),
814                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u,
815                         "vld1", Dt, "$Vd, $Rn, $Rm",
816                         "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {
817     let Inst{5-4} = Rn{5-4};
818     let DecoderMethod = "DecodeVLDST1Instruction";
819   }
820 }
821
822 def VLD1d8Q      : VLD1D4<{0,0,?,?}, "8",  addrmode6align64or128or256>;
823 def VLD1d16Q     : VLD1D4<{0,1,?,?}, "16", addrmode6align64or128or256>;
824 def VLD1d32Q     : VLD1D4<{1,0,?,?}, "32", addrmode6align64or128or256>;
825 def VLD1d64Q     : VLD1D4<{1,1,?,?}, "64", addrmode6align64or128or256>;
826
827 defm VLD1d8Qwb   : VLD1D4WB<{0,0,?,?}, "8",  addrmode6align64or128or256>;
828 defm VLD1d16Qwb  : VLD1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>;
829 defm VLD1d32Qwb  : VLD1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>;
830 defm VLD1d64Qwb  : VLD1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>;
831
832 def VLD1d64QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;
833 def VLD1d64QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;
834 def VLD1d64QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>;
835
836 //   VLD2     : Vector Load (multiple 2-element structures)
837 class VLD2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,
838            InstrItinClass itin, Operand AddrMode>
839   : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd),
840           (ins AddrMode:$Rn), itin,
841           "vld2", Dt, "$Vd, $Rn", "", []> {
842   let Rm = 0b1111;
843   let Inst{5-4} = Rn{5-4};
844   let DecoderMethod = "DecodeVLDST2Instruction";
845 }
846
847 def  VLD2d8   : VLD2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2,
848                      addrmode6align64or128>, Sched<[WriteVLD2]>;
849 def  VLD2d16  : VLD2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2,
850                      addrmode6align64or128>, Sched<[WriteVLD2]>;
851 def  VLD2d32  : VLD2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2,
852                      addrmode6align64or128>, Sched<[WriteVLD2]>;
853
854 def  VLD2q8   : VLD2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2,
855                      addrmode6align64or128or256>, Sched<[WriteVLD4]>;
856 def  VLD2q16  : VLD2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2,
857                      addrmode6align64or128or256>, Sched<[WriteVLD4]>;
858 def  VLD2q32  : VLD2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2,
859                      addrmode6align64or128or256>, Sched<[WriteVLD4]>;
860
861 def  VLD2q8Pseudo  : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;
862 def  VLD2q16Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;
863 def  VLD2q32Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>;
864
865 // ...with address register writeback:
866 multiclass VLD2WB<bits<4> op11_8, bits<4> op7_4, string Dt,
867                   RegisterOperand VdTy, InstrItinClass itin, Operand AddrMode> {
868   def _fixed : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),
869                      (ins AddrMode:$Rn), itin,
870                      "vld2", Dt, "$Vd, $Rn!",
871                      "$Rn.addr = $wb", []> {
872     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
873     let Inst{5-4} = Rn{5-4};
874     let DecoderMethod = "DecodeVLDST2Instruction";
875   }
876   def _register : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),
877                         (ins AddrMode:$Rn, rGPR:$Rm), itin,
878                         "vld2", Dt, "$Vd, $Rn, $Rm",
879                         "$Rn.addr = $wb", []> {
880     let Inst{5-4} = Rn{5-4};
881     let DecoderMethod = "DecodeVLDST2Instruction";
882   }
883 }
884
885 defm VLD2d8wb  : VLD2WB<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2u,
886                         addrmode6align64or128>, Sched<[WriteVLD2]>;
887 defm VLD2d16wb : VLD2WB<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2u,
888                         addrmode6align64or128>, Sched<[WriteVLD2]>;
889 defm VLD2d32wb : VLD2WB<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2u,
890                         addrmode6align64or128>, Sched<[WriteVLD2]>;
891
892 defm VLD2q8wb  : VLD2WB<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2u,
893                         addrmode6align64or128or256>, Sched<[WriteVLD4]>;
894 defm VLD2q16wb : VLD2WB<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2u,
895                         addrmode6align64or128or256>, Sched<[WriteVLD4]>;
896 defm VLD2q32wb : VLD2WB<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2u,
897                         addrmode6align64or128or256>, Sched<[WriteVLD4]>;
898
899 def VLD2q8PseudoWB_fixed     : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
900 def VLD2q16PseudoWB_fixed    : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
901 def VLD2q32PseudoWB_fixed    : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
902 def VLD2q8PseudoWB_register  : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
903 def VLD2q16PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
904 def VLD2q32PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>;
905
906 // ...with double-spaced registers
907 def  VLD2b8    : VLD2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2,
908                       addrmode6align64or128>, Sched<[WriteVLD2]>;
909 def  VLD2b16   : VLD2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2,
910                       addrmode6align64or128>, Sched<[WriteVLD2]>;
911 def  VLD2b32   : VLD2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2,
912                       addrmode6align64or128>, Sched<[WriteVLD2]>;
913 defm VLD2b8wb  : VLD2WB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2u,
914                         addrmode6align64or128>, Sched<[WriteVLD2]>;
915 defm VLD2b16wb : VLD2WB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2u,
916                         addrmode6align64or128>, Sched<[WriteVLD2]>;
917 defm VLD2b32wb : VLD2WB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2u,
918                         addrmode6align64or128>, Sched<[WriteVLD2]>;
919
920 //   VLD3     : Vector Load (multiple 3-element structures)
921 class VLD3D<bits<4> op11_8, bits<4> op7_4, string Dt>
922   : NLdSt<0, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
923           (ins addrmode6:$Rn), IIC_VLD3,
924           "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []>, Sched<[WriteVLD3]> {
925   let Rm = 0b1111;
926   let Inst{4} = Rn{4};
927   let DecoderMethod = "DecodeVLDST3Instruction";
928 }
929
930 def  VLD3d8   : VLD3D<0b0100, {0,0,0,?}, "8">;
931 def  VLD3d16  : VLD3D<0b0100, {0,1,0,?}, "16">;
932 def  VLD3d32  : VLD3D<0b0100, {1,0,0,?}, "32">;
933
934 def  VLD3d8Pseudo  : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
935 def  VLD3d16Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
936 def  VLD3d32Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
937
938 // ...with address register writeback:
939 class VLD3DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
940   : NLdSt<0, 0b10, op11_8, op7_4,
941           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
942           (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD3u,
943           "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm",
944           "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> {
945   let Inst{4} = Rn{4};
946   let DecoderMethod = "DecodeVLDST3Instruction";
947 }
948
949 def VLD3d8_UPD  : VLD3DWB<0b0100, {0,0,0,?}, "8">;
950 def VLD3d16_UPD : VLD3DWB<0b0100, {0,1,0,?}, "16">;
951 def VLD3d32_UPD : VLD3DWB<0b0100, {1,0,0,?}, "32">;
952
953 def VLD3d8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
954 def VLD3d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
955 def VLD3d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
956
957 // ...with double-spaced registers:
958 def VLD3q8      : VLD3D<0b0101, {0,0,0,?}, "8">;
959 def VLD3q16     : VLD3D<0b0101, {0,1,0,?}, "16">;
960 def VLD3q32     : VLD3D<0b0101, {1,0,0,?}, "32">;
961 def VLD3q8_UPD  : VLD3DWB<0b0101, {0,0,0,?}, "8">;
962 def VLD3q16_UPD : VLD3DWB<0b0101, {0,1,0,?}, "16">;
963 def VLD3q32_UPD : VLD3DWB<0b0101, {1,0,0,?}, "32">;
964
965 def VLD3q8Pseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
966 def VLD3q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
967 def VLD3q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
968
969 // ...alternate versions to be allocated odd register numbers:
970 def VLD3q8oddPseudo   : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
971 def VLD3q16oddPseudo  : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
972 def VLD3q32oddPseudo  : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>;
973
974 def VLD3q8oddPseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
975 def VLD3q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
976 def VLD3q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>;
977
978 //   VLD4     : Vector Load (multiple 4-element structures)
979 class VLD4D<bits<4> op11_8, bits<4> op7_4, string Dt>
980   : NLdSt<0, 0b10, op11_8, op7_4,
981           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
982           (ins addrmode6:$Rn), IIC_VLD4,
983           "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []>,
984     Sched<[WriteVLD4]> {
985   let Rm = 0b1111;
986   let Inst{5-4} = Rn{5-4};
987   let DecoderMethod = "DecodeVLDST4Instruction";
988 }
989
990 def  VLD4d8   : VLD4D<0b0000, {0,0,?,?}, "8">;
991 def  VLD4d16  : VLD4D<0b0000, {0,1,?,?}, "16">;
992 def  VLD4d32  : VLD4D<0b0000, {1,0,?,?}, "32">;
993
994 def  VLD4d8Pseudo  : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
995 def  VLD4d16Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
996 def  VLD4d32Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
997
998 // ...with address register writeback:
999 class VLD4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1000   : NLdSt<0, 0b10, op11_8, op7_4,
1001           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
1002           (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD4u,
1003           "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm",
1004           "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> {
1005   let Inst{5-4} = Rn{5-4};
1006   let DecoderMethod = "DecodeVLDST4Instruction";
1007 }
1008
1009 def VLD4d8_UPD  : VLD4DWB<0b0000, {0,0,?,?}, "8">;
1010 def VLD4d16_UPD : VLD4DWB<0b0000, {0,1,?,?}, "16">;
1011 def VLD4d32_UPD : VLD4DWB<0b0000, {1,0,?,?}, "32">;
1012
1013 def VLD4d8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1014 def VLD4d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1015 def VLD4d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1016
1017 // ...with double-spaced registers:
1018 def VLD4q8      : VLD4D<0b0001, {0,0,?,?}, "8">;
1019 def VLD4q16     : VLD4D<0b0001, {0,1,?,?}, "16">;
1020 def VLD4q32     : VLD4D<0b0001, {1,0,?,?}, "32">;
1021 def VLD4q8_UPD  : VLD4DWB<0b0001, {0,0,?,?}, "8">;
1022 def VLD4q16_UPD : VLD4DWB<0b0001, {0,1,?,?}, "16">;
1023 def VLD4q32_UPD : VLD4DWB<0b0001, {1,0,?,?}, "32">;
1024
1025 def VLD4q8Pseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1026 def VLD4q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1027 def VLD4q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1028
1029 // ...alternate versions to be allocated odd register numbers:
1030 def VLD4q8oddPseudo   : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
1031 def VLD4q16oddPseudo  : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
1032 def VLD4q32oddPseudo  : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>;
1033
1034 def VLD4q8oddPseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1035 def VLD4q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1036 def VLD4q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>;
1037
1038 } // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1
1039
1040 // Classes for VLD*LN pseudo-instructions with multi-register operands.
1041 // These are expanded to real instructions after register allocation.
1042 class VLDQLNPseudo<InstrItinClass itin>
1043   : PseudoNLdSt<(outs QPR:$dst),
1044                 (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),
1045                 itin, "$src = $dst">;
1046 class VLDQLNWBPseudo<InstrItinClass itin>
1047   : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
1048                 (ins addrmode6:$addr, am6offset:$offset, QPR:$src,
1049                  nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
1050 class VLDQQLNPseudo<InstrItinClass itin>
1051   : PseudoNLdSt<(outs QQPR:$dst),
1052                 (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),
1053                 itin, "$src = $dst">;
1054 class VLDQQLNWBPseudo<InstrItinClass itin>
1055   : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
1056                 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,
1057                  nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
1058 class VLDQQQQLNPseudo<InstrItinClass itin>
1059   : PseudoNLdSt<(outs QQQQPR:$dst),
1060                 (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),
1061                 itin, "$src = $dst">;
1062 class VLDQQQQLNWBPseudo<InstrItinClass itin>
1063   : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),
1064                 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,
1065                  nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
1066
1067 //   VLD1LN   : Vector Load (single element to one lane)
1068 class VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
1069              PatFrag LoadOp>
1070   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),
1071           (ins addrmode6:$Rn, DPR:$src, nohash_imm:$lane),
1072           IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",
1073           "$src = $Vd",
1074           [(set DPR:$Vd, (vector_insert (Ty DPR:$src),
1075                                          (i32 (LoadOp addrmode6:$Rn)),
1076                                          imm:$lane))]> {
1077   let Rm = 0b1111;
1078   let DecoderMethod = "DecodeVLD1LN";
1079 }
1080 class VLD1LN32<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
1081              PatFrag LoadOp>
1082   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),
1083           (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane),
1084           IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",
1085           "$src = $Vd",
1086           [(set DPR:$Vd, (vector_insert (Ty DPR:$src),
1087                                          (i32 (LoadOp addrmode6oneL32:$Rn)),
1088                                          imm:$lane))]>, Sched<[WriteVLD1]> {
1089   let Rm = 0b1111;
1090   let DecoderMethod = "DecodeVLD1LN";
1091 }
1092 class VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln>,
1093                                                     Sched<[WriteVLD1]> {
1094   let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src),
1095                                                (i32 (LoadOp addrmode6:$addr)),
1096                                                imm:$lane))];
1097 }
1098
1099 def VLD1LNd8  : VLD1LN<0b0000, {?,?,?,0}, "8", v8i8, extloadi8> {
1100   let Inst{7-5} = lane{2-0};
1101 }
1102 def VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> {
1103   let Inst{7-6} = lane{1-0};
1104   let Inst{5-4} = Rn{5-4};
1105 }
1106 def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> {
1107   let Inst{7} = lane{0};
1108   let Inst{5-4} = Rn{5-4};
1109 }
1110
1111 def VLD1LNq8Pseudo  : VLD1QLNPseudo<v16i8, extloadi8>;
1112 def VLD1LNq16Pseudo : VLD1QLNPseudo<v8i16, extloadi16>;
1113 def VLD1LNq32Pseudo : VLD1QLNPseudo<v4i32, load>;
1114
1115 def : Pat<(vector_insert (v2f32 DPR:$src),
1116                          (f32 (load addrmode6:$addr)), imm:$lane),
1117           (VLD1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;
1118 def : Pat<(vector_insert (v4f32 QPR:$src),
1119                          (f32 (load addrmode6:$addr)), imm:$lane),
1120           (VLD1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;
1121
1122 // A 64-bit subvector insert to the first 128-bit vector position
1123 // is a subregister copy that needs no instruction.
1124 def : Pat<(insert_subvector undef, (v1i64 DPR:$src), (i32 0)),
1125           (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1126 def : Pat<(insert_subvector undef, (v2i32 DPR:$src), (i32 0)),
1127           (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1128 def : Pat<(insert_subvector undef, (v2f32 DPR:$src), (i32 0)),
1129           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1130 def : Pat<(insert_subvector undef, (v4i16 DPR:$src), (i32 0)),
1131           (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1132 def : Pat<(insert_subvector undef, (v4f16 DPR:$src), (i32 0)),
1133           (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1134 def : Pat<(insert_subvector (v16i8 undef), (v8i8 DPR:$src), (i32 0)),
1135           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
1136
1137
1138 let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
1139
1140 // ...with address register writeback:
1141 class VLD1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1142   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, GPR:$wb),
1143           (ins addrmode6:$Rn, am6offset:$Rm,
1144            DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt,
1145           "\\{$Vd[$lane]\\}, $Rn$Rm",
1146           "$src = $Vd, $Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
1147   let DecoderMethod = "DecodeVLD1LN";
1148 }
1149
1150 def VLD1LNd8_UPD  : VLD1LNWB<0b0000, {?,?,?,0}, "8"> {
1151   let Inst{7-5} = lane{2-0};
1152 }
1153 def VLD1LNd16_UPD : VLD1LNWB<0b0100, {?,?,0,?}, "16"> {
1154   let Inst{7-6} = lane{1-0};
1155   let Inst{4}   = Rn{4};
1156 }
1157 def VLD1LNd32_UPD : VLD1LNWB<0b1000, {?,0,?,?}, "32"> {
1158   let Inst{7} = lane{0};
1159   let Inst{5} = Rn{4};
1160   let Inst{4} = Rn{4};
1161 }
1162
1163 def VLD1LNq8Pseudo_UPD  : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;
1164 def VLD1LNq16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;
1165 def VLD1LNq32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>;
1166
1167 //   VLD2LN   : Vector Load (single 2-element structure to one lane)
1168 class VLD2LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1169   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2),
1170           (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, nohash_imm:$lane),
1171           IIC_VLD2ln, "vld2", Dt, "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn",
1172           "$src1 = $Vd, $src2 = $dst2", []>, Sched<[WriteVLD1]> {
1173   let Rm = 0b1111;
1174   let Inst{4}   = Rn{4};
1175   let DecoderMethod = "DecodeVLD2LN";
1176 }
1177
1178 def VLD2LNd8  : VLD2LN<0b0001, {?,?,?,?}, "8"> {
1179   let Inst{7-5} = lane{2-0};
1180 }
1181 def VLD2LNd16 : VLD2LN<0b0101, {?,?,0,?}, "16"> {
1182   let Inst{7-6} = lane{1-0};
1183 }
1184 def VLD2LNd32 : VLD2LN<0b1001, {?,0,0,?}, "32"> {
1185   let Inst{7} = lane{0};
1186 }
1187
1188 def VLD2LNd8Pseudo  : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;
1189 def VLD2LNd16Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;
1190 def VLD2LNd32Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;
1191
1192 // ...with double-spaced registers:
1193 def VLD2LNq16 : VLD2LN<0b0101, {?,?,1,?}, "16"> {
1194   let Inst{7-6} = lane{1-0};
1195 }
1196 def VLD2LNq32 : VLD2LN<0b1001, {?,1,0,?}, "32"> {
1197   let Inst{7} = lane{0};
1198 }
1199
1200 def VLD2LNq16Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;
1201 def VLD2LNq32Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>;
1202
1203 // ...with address register writeback:
1204 class VLD2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1205   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb),
1206           (ins addrmode6:$Rn, am6offset:$Rm,
1207            DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2lnu, "vld2", Dt,
1208           "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm",
1209           "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> {
1210   let Inst{4}   = Rn{4};
1211   let DecoderMethod = "DecodeVLD2LN";
1212 }
1213
1214 def VLD2LNd8_UPD  : VLD2LNWB<0b0001, {?,?,?,?}, "8"> {
1215   let Inst{7-5} = lane{2-0};
1216 }
1217 def VLD2LNd16_UPD : VLD2LNWB<0b0101, {?,?,0,?}, "16"> {
1218   let Inst{7-6} = lane{1-0};
1219 }
1220 def VLD2LNd32_UPD : VLD2LNWB<0b1001, {?,0,0,?}, "32"> {
1221   let Inst{7} = lane{0};
1222 }
1223
1224 def VLD2LNd8Pseudo_UPD  : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;
1225 def VLD2LNd16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;
1226 def VLD2LNd32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;
1227
1228 def VLD2LNq16_UPD : VLD2LNWB<0b0101, {?,?,1,?}, "16"> {
1229   let Inst{7-6} = lane{1-0};
1230 }
1231 def VLD2LNq32_UPD : VLD2LNWB<0b1001, {?,1,0,?}, "32"> {
1232   let Inst{7} = lane{0};
1233 }
1234
1235 def VLD2LNq16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;
1236 def VLD2LNq32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>;
1237
1238 //   VLD3LN   : Vector Load (single 3-element structure to one lane)
1239 class VLD3LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1240   : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
1241           (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3,
1242           nohash_imm:$lane), IIC_VLD3ln, "vld3", Dt,
1243           "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn",
1244           "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []>, Sched<[WriteVLD2]> {
1245   let Rm = 0b1111;
1246   let DecoderMethod = "DecodeVLD3LN";
1247 }
1248
1249 def VLD3LNd8  : VLD3LN<0b0010, {?,?,?,0}, "8"> {
1250   let Inst{7-5} = lane{2-0};
1251 }
1252 def VLD3LNd16 : VLD3LN<0b0110, {?,?,0,0}, "16"> {
1253   let Inst{7-6} = lane{1-0};
1254 }
1255 def VLD3LNd32 : VLD3LN<0b1010, {?,0,0,0}, "32"> {
1256   let Inst{7}   = lane{0};
1257 }
1258
1259 def VLD3LNd8Pseudo  : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;
1260 def VLD3LNd16Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;
1261 def VLD3LNd32Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;
1262
1263 // ...with double-spaced registers:
1264 def VLD3LNq16 : VLD3LN<0b0110, {?,?,1,0}, "16"> {
1265   let Inst{7-6} = lane{1-0};
1266 }
1267 def VLD3LNq32 : VLD3LN<0b1010, {?,1,0,0}, "32"> {
1268   let Inst{7}   = lane{0};
1269 }
1270
1271 def VLD3LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;
1272 def VLD3LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>;
1273
1274 // ...with address register writeback:
1275 class VLD3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1276   : NLdStLn<1, 0b10, op11_8, op7_4,
1277           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
1278           (ins addrmode6:$Rn, am6offset:$Rm,
1279            DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane),
1280           IIC_VLD3lnu, "vld3", Dt,
1281           "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm",
1282           "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb",
1283           []>, Sched<[WriteVLD2]> {
1284   let DecoderMethod = "DecodeVLD3LN";
1285 }
1286
1287 def VLD3LNd8_UPD  : VLD3LNWB<0b0010, {?,?,?,0}, "8"> {
1288   let Inst{7-5} = lane{2-0};
1289 }
1290 def VLD3LNd16_UPD : VLD3LNWB<0b0110, {?,?,0,0}, "16"> {
1291   let Inst{7-6} = lane{1-0};
1292 }
1293 def VLD3LNd32_UPD : VLD3LNWB<0b1010, {?,0,0,0}, "32"> {
1294   let Inst{7} = lane{0};
1295 }
1296
1297 def VLD3LNd8Pseudo_UPD  : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;
1298 def VLD3LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;
1299 def VLD3LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;
1300
1301 def VLD3LNq16_UPD : VLD3LNWB<0b0110, {?,?,1,0}, "16"> {
1302   let Inst{7-6} = lane{1-0};
1303 }
1304 def VLD3LNq32_UPD : VLD3LNWB<0b1010, {?,1,0,0}, "32"> {
1305   let Inst{7} = lane{0};
1306 }
1307
1308 def VLD3LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;
1309 def VLD3LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>;
1310
1311 //   VLD4LN   : Vector Load (single 4-element structure to one lane)
1312 class VLD4LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1313   : NLdStLn<1, 0b10, op11_8, op7_4,
1314           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
1315           (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
1316           nohash_imm:$lane), IIC_VLD4ln, "vld4", Dt,
1317           "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn",
1318           "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>,
1319     Sched<[WriteVLD2]> {
1320   let Rm = 0b1111;
1321   let Inst{4} = Rn{4};
1322   let DecoderMethod = "DecodeVLD4LN";
1323 }
1324
1325 def VLD4LNd8  : VLD4LN<0b0011, {?,?,?,?}, "8"> {
1326   let Inst{7-5} = lane{2-0};
1327 }
1328 def VLD4LNd16 : VLD4LN<0b0111, {?,?,0,?}, "16"> {
1329   let Inst{7-6} = lane{1-0};
1330 }
1331 def VLD4LNd32 : VLD4LN<0b1011, {?,0,?,?}, "32"> {
1332   let Inst{7} = lane{0};
1333   let Inst{5} = Rn{5};
1334 }
1335
1336 def VLD4LNd8Pseudo  : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;
1337 def VLD4LNd16Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;
1338 def VLD4LNd32Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;
1339
1340 // ...with double-spaced registers:
1341 def VLD4LNq16 : VLD4LN<0b0111, {?,?,1,?}, "16"> {
1342   let Inst{7-6} = lane{1-0};
1343 }
1344 def VLD4LNq32 : VLD4LN<0b1011, {?,1,?,?}, "32"> {
1345   let Inst{7} = lane{0};
1346   let Inst{5} = Rn{5};
1347 }
1348
1349 def VLD4LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;
1350 def VLD4LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>;
1351
1352 // ...with address register writeback:
1353 class VLD4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1354   : NLdStLn<1, 0b10, op11_8, op7_4,
1355           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
1356           (ins addrmode6:$Rn, am6offset:$Rm,
1357            DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),
1358           IIC_VLD4lnu, "vld4", Dt,
1359 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn$Rm",
1360 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb",
1361           []> {
1362   let Inst{4}   = Rn{4};
1363   let DecoderMethod = "DecodeVLD4LN"  ;
1364 }
1365
1366 def VLD4LNd8_UPD  : VLD4LNWB<0b0011, {?,?,?,?}, "8"> {
1367   let Inst{7-5} = lane{2-0};
1368 }
1369 def VLD4LNd16_UPD : VLD4LNWB<0b0111, {?,?,0,?}, "16"> {
1370   let Inst{7-6} = lane{1-0};
1371 }
1372 def VLD4LNd32_UPD : VLD4LNWB<0b1011, {?,0,?,?}, "32"> {
1373   let Inst{7} = lane{0};
1374   let Inst{5} = Rn{5};
1375 }
1376
1377 def VLD4LNd8Pseudo_UPD  : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;
1378 def VLD4LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;
1379 def VLD4LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;
1380
1381 def VLD4LNq16_UPD : VLD4LNWB<0b0111, {?,?,1,?}, "16"> {
1382   let Inst{7-6} = lane{1-0};
1383 }
1384 def VLD4LNq32_UPD : VLD4LNWB<0b1011, {?,1,?,?}, "32"> {
1385   let Inst{7} = lane{0};
1386   let Inst{5} = Rn{5};
1387 }
1388
1389 def VLD4LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;
1390 def VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>;
1391
1392 } // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1
1393
1394 //   VLD1DUP  : Vector Load (single element to all lanes)
1395 class VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp,
1396               Operand AddrMode>
1397   : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd),
1398           (ins AddrMode:$Rn),
1399           IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "",
1400           [(set VecListOneDAllLanes:$Vd,
1401                 (Ty (NEONvdup (i32 (LoadOp AddrMode:$Rn)))))]>,
1402    Sched<[WriteVLD2]> {
1403   let Rm = 0b1111;
1404   let Inst{4} = Rn{4};
1405   let DecoderMethod = "DecodeVLD1DupInstruction";
1406 }
1407 def VLD1DUPd8  : VLD1DUP<{0,0,0,?}, "8", v8i8, extloadi8,
1408                          addrmode6dupalignNone>;
1409 def VLD1DUPd16 : VLD1DUP<{0,1,0,?}, "16", v4i16, extloadi16,
1410                          addrmode6dupalign16>;
1411 def VLD1DUPd32 : VLD1DUP<{1,0,0,?}, "32", v2i32, load,
1412                          addrmode6dupalign32>;
1413
1414 def : Pat<(v2f32 (NEONvdup (f32 (load addrmode6dup:$addr)))),
1415           (VLD1DUPd32 addrmode6:$addr)>;
1416
1417 class VLD1QDUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp,
1418                Operand AddrMode>
1419   : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListDPairAllLanes:$Vd),
1420           (ins AddrMode:$Rn), IIC_VLD1dup,
1421           "vld1", Dt, "$Vd, $Rn", "",
1422           [(set VecListDPairAllLanes:$Vd,
1423                 (Ty (NEONvdup (i32 (LoadOp AddrMode:$Rn)))))]> {
1424   let Rm = 0b1111;
1425   let Inst{4} = Rn{4};
1426   let DecoderMethod = "DecodeVLD1DupInstruction";
1427 }
1428
1429 def VLD1DUPq8  : VLD1QDUP<{0,0,1,0}, "8", v16i8, extloadi8,
1430                           addrmode6dupalignNone>;
1431 def VLD1DUPq16 : VLD1QDUP<{0,1,1,?}, "16", v8i16, extloadi16,
1432                           addrmode6dupalign16>;
1433 def VLD1DUPq32 : VLD1QDUP<{1,0,1,?}, "32", v4i32, load,
1434                           addrmode6dupalign32>;
1435
1436 def : Pat<(v4f32 (NEONvdup (f32 (load addrmode6dup:$addr)))),
1437           (VLD1DUPq32 addrmode6:$addr)>;
1438
1439 let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
1440 // ...with address register writeback:
1441 multiclass VLD1DUPWB<bits<4> op7_4, string Dt, Operand AddrMode> {
1442   def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,
1443                      (outs VecListOneDAllLanes:$Vd, GPR:$wb),
1444                      (ins AddrMode:$Rn), IIC_VLD1dupu,
1445                      "vld1", Dt, "$Vd, $Rn!",
1446                      "$Rn.addr = $wb", []> {
1447     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1448     let Inst{4} = Rn{4};
1449     let DecoderMethod = "DecodeVLD1DupInstruction";
1450   }
1451   def _register : NLdSt<1, 0b10, 0b1100, op7_4,
1452                         (outs VecListOneDAllLanes:$Vd, GPR:$wb),
1453                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu,
1454                         "vld1", Dt, "$Vd, $Rn, $Rm",
1455                         "$Rn.addr = $wb", []> {
1456     let Inst{4} = Rn{4};
1457     let DecoderMethod = "DecodeVLD1DupInstruction";
1458   }
1459 }
1460 multiclass VLD1QDUPWB<bits<4> op7_4, string Dt, Operand AddrMode> {
1461   def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,
1462                      (outs VecListDPairAllLanes:$Vd, GPR:$wb),
1463                      (ins AddrMode:$Rn), IIC_VLD1dupu,
1464                      "vld1", Dt, "$Vd, $Rn!",
1465                      "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
1466     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1467     let Inst{4} = Rn{4};
1468     let DecoderMethod = "DecodeVLD1DupInstruction";
1469   }
1470   def _register : NLdSt<1, 0b10, 0b1100, op7_4,
1471                         (outs VecListDPairAllLanes:$Vd, GPR:$wb),
1472                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu,
1473                         "vld1", Dt, "$Vd, $Rn, $Rm",
1474                         "$Rn.addr = $wb", []> {
1475     let Inst{4} = Rn{4};
1476     let DecoderMethod = "DecodeVLD1DupInstruction";
1477   }
1478 }
1479
1480 defm VLD1DUPd8wb  : VLD1DUPWB<{0,0,0,0}, "8", addrmode6dupalignNone>;
1481 defm VLD1DUPd16wb : VLD1DUPWB<{0,1,0,?}, "16", addrmode6dupalign16>;
1482 defm VLD1DUPd32wb : VLD1DUPWB<{1,0,0,?}, "32", addrmode6dupalign32>;
1483
1484 defm VLD1DUPq8wb  : VLD1QDUPWB<{0,0,1,0}, "8", addrmode6dupalignNone>;
1485 defm VLD1DUPq16wb : VLD1QDUPWB<{0,1,1,?}, "16", addrmode6dupalign16>;
1486 defm VLD1DUPq32wb : VLD1QDUPWB<{1,0,1,?}, "32", addrmode6dupalign32>;
1487
1488 //   VLD2DUP  : Vector Load (single 2-element structure to all lanes)
1489 class VLD2DUP<bits<4> op7_4, string Dt, RegisterOperand VdTy, Operand AddrMode>
1490   : NLdSt<1, 0b10, 0b1101, op7_4, (outs VdTy:$Vd),
1491           (ins AddrMode:$Rn), IIC_VLD2dup,
1492           "vld2", Dt, "$Vd, $Rn", "", []> {
1493   let Rm = 0b1111;
1494   let Inst{4} = Rn{4};
1495   let DecoderMethod = "DecodeVLD2DupInstruction";
1496 }
1497
1498 def VLD2DUPd8  : VLD2DUP<{0,0,0,?}, "8",  VecListDPairAllLanes,
1499                          addrmode6dupalign16>;
1500 def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes,
1501                          addrmode6dupalign32>;
1502 def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes,
1503                          addrmode6dupalign64>;
1504
1505 // HACK this one, VLD2DUPd8x2 must be changed at the same time with VLD2b8 or
1506 // "vld2.8 {d0[], d2[]}, [r4:32]" will become "vld2.8 {d0, d2}, [r4:32]".
1507 // ...with double-spaced registers
1508 def VLD2DUPd8x2  : VLD2DUP<{0,0,1,?}, "8",  VecListDPairSpacedAllLanes,
1509                            addrmode6dupalign16>;
1510 def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes,
1511                            addrmode6dupalign32>;
1512 def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes,
1513                            addrmode6dupalign64>;
1514
1515 // ...with address register writeback:
1516 multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy,
1517                      Operand AddrMode> {
1518   def _fixed : NLdSt<1, 0b10, 0b1101, op7_4,
1519                      (outs VdTy:$Vd, GPR:$wb),
1520                      (ins AddrMode:$Rn), IIC_VLD2dupu,
1521                      "vld2", Dt, "$Vd, $Rn!",
1522                      "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
1523     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1524     let Inst{4} = Rn{4};
1525     let DecoderMethod = "DecodeVLD2DupInstruction";
1526   }
1527   def _register : NLdSt<1, 0b10, 0b1101, op7_4,
1528                         (outs VdTy:$Vd, GPR:$wb),
1529                         (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD2dupu,
1530                         "vld2", Dt, "$Vd, $Rn, $Rm",
1531                         "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> {
1532     let Inst{4} = Rn{4};
1533     let DecoderMethod = "DecodeVLD2DupInstruction";
1534   }
1535 }
1536
1537 defm VLD2DUPd8wb    : VLD2DUPWB<{0,0,0,0}, "8",  VecListDPairAllLanes,
1538                                 addrmode6dupalign16>;
1539 defm VLD2DUPd16wb   : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes,
1540                                 addrmode6dupalign32>;
1541 defm VLD2DUPd32wb   : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes,
1542                                 addrmode6dupalign64>;
1543
1544 defm VLD2DUPd8x2wb  : VLD2DUPWB<{0,0,1,0}, "8",  VecListDPairSpacedAllLanes,
1545                                 addrmode6dupalign16>;
1546 defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes,
1547                                 addrmode6dupalign32>;
1548 defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes,
1549                                 addrmode6dupalign64>;
1550
1551 //   VLD3DUP  : Vector Load (single 3-element structure to all lanes)
1552 class VLD3DUP<bits<4> op7_4, string Dt>
1553   : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
1554           (ins addrmode6dup:$Rn), IIC_VLD3dup,
1555           "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []>,
1556     Sched<[WriteVLD2]> {
1557   let Rm = 0b1111;
1558   let Inst{4} = 0;
1559   let DecoderMethod = "DecodeVLD3DupInstruction";
1560 }
1561
1562 def VLD3DUPd8  : VLD3DUP<{0,0,0,?}, "8">;
1563 def VLD3DUPd16 : VLD3DUP<{0,1,0,?}, "16">;
1564 def VLD3DUPd32 : VLD3DUP<{1,0,0,?}, "32">;
1565
1566 def VLD3DUPd8Pseudo  : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;
1567 def VLD3DUPd16Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;
1568 def VLD3DUPd32Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>;
1569
1570 // ...with double-spaced registers (not used for codegen):
1571 def VLD3DUPq8  : VLD3DUP<{0,0,1,?}, "8">;
1572 def VLD3DUPq16 : VLD3DUP<{0,1,1,?}, "16">;
1573 def VLD3DUPq32 : VLD3DUP<{1,0,1,?}, "32">;
1574
1575 // ...with address register writeback:
1576 class VLD3DUPWB<bits<4> op7_4, string Dt, Operand AddrMode>
1577   : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
1578           (ins AddrMode:$Rn, am6offset:$Rm), IIC_VLD3dupu,
1579           "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm",
1580           "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {
1581   let Inst{4} = 0;
1582   let DecoderMethod = "DecodeVLD3DupInstruction";
1583 }
1584
1585 def VLD3DUPd8_UPD  : VLD3DUPWB<{0,0,0,0}, "8",  addrmode6dupalign64>;
1586 def VLD3DUPd16_UPD : VLD3DUPWB<{0,1,0,?}, "16", addrmode6dupalign64>;
1587 def VLD3DUPd32_UPD : VLD3DUPWB<{1,0,0,?}, "32", addrmode6dupalign64>;
1588
1589 def VLD3DUPq8_UPD  : VLD3DUPWB<{0,0,1,0}, "8",  addrmode6dupalign64>;
1590 def VLD3DUPq16_UPD : VLD3DUPWB<{0,1,1,?}, "16", addrmode6dupalign64>;
1591 def VLD3DUPq32_UPD : VLD3DUPWB<{1,0,1,?}, "32", addrmode6dupalign64>;
1592
1593 def VLD3DUPd8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;
1594 def VLD3DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;
1595 def VLD3DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>;
1596
1597 //   VLD4DUP  : Vector Load (single 4-element structure to all lanes)
1598 class VLD4DUP<bits<4> op7_4, string Dt>
1599   : NLdSt<1, 0b10, 0b1111, op7_4,
1600           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
1601           (ins addrmode6dup:$Rn), IIC_VLD4dup,
1602           "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> {
1603   let Rm = 0b1111;
1604   let Inst{4} = Rn{4};
1605   let DecoderMethod = "DecodeVLD4DupInstruction";
1606 }
1607
1608 def VLD4DUPd8  : VLD4DUP<{0,0,0,?}, "8">;
1609 def VLD4DUPd16 : VLD4DUP<{0,1,0,?}, "16">;
1610 def VLD4DUPd32 : VLD4DUP<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }
1611
1612 def VLD4DUPd8Pseudo  : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;
1613 def VLD4DUPd16Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;
1614 def VLD4DUPd32Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>;
1615
1616 // ...with double-spaced registers (not used for codegen):
1617 def VLD4DUPq8  : VLD4DUP<{0,0,1,?}, "8">;
1618 def VLD4DUPq16 : VLD4DUP<{0,1,1,?}, "16">;
1619 def VLD4DUPq32 : VLD4DUP<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }
1620
1621 // ...with address register writeback:
1622 class VLD4DUPWB<bits<4> op7_4, string Dt>
1623   : NLdSt<1, 0b10, 0b1111, op7_4,
1624           (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
1625           (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD4dupu,
1626           "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm",
1627           "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> {
1628   let Inst{4} = Rn{4};
1629   let DecoderMethod = "DecodeVLD4DupInstruction";
1630 }
1631
1632 def VLD4DUPd8_UPD  : VLD4DUPWB<{0,0,0,0}, "8">;
1633 def VLD4DUPd16_UPD : VLD4DUPWB<{0,1,0,?}, "16">;
1634 def VLD4DUPd32_UPD : VLD4DUPWB<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }
1635
1636 def VLD4DUPq8_UPD  : VLD4DUPWB<{0,0,1,0}, "8">;
1637 def VLD4DUPq16_UPD : VLD4DUPWB<{0,1,1,?}, "16">;
1638 def VLD4DUPq32_UPD : VLD4DUPWB<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }
1639
1640 def VLD4DUPd8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;
1641 def VLD4DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;
1642 def VLD4DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>;
1643
1644 } // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1
1645
1646 let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {
1647
1648 // Classes for VST* pseudo-instructions with multi-register operands.
1649 // These are expanded to real instructions after register allocation.
1650 class VSTQPseudo<InstrItinClass itin>
1651   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src), itin, "">;
1652 class VSTQWBPseudo<InstrItinClass itin>
1653   : PseudoNLdSt<(outs GPR:$wb),
1654                 (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin,
1655                 "$addr.addr = $wb">;
1656 class VSTQWBfixedPseudo<InstrItinClass itin>
1657   : PseudoNLdSt<(outs GPR:$wb),
1658                 (ins addrmode6:$addr, QPR:$src), itin,
1659                 "$addr.addr = $wb">;
1660 class VSTQWBregisterPseudo<InstrItinClass itin>
1661   : PseudoNLdSt<(outs GPR:$wb),
1662                 (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin,
1663                 "$addr.addr = $wb">;
1664 class VSTQQPseudo<InstrItinClass itin>
1665   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">;
1666 class VSTQQWBPseudo<InstrItinClass itin>
1667   : PseudoNLdSt<(outs GPR:$wb),
1668                 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src), itin,
1669                 "$addr.addr = $wb">;
1670 class VSTQQWBfixedPseudo<InstrItinClass itin>
1671   : PseudoNLdSt<(outs GPR:$wb),
1672                 (ins addrmode6:$addr, QQPR:$src), itin,
1673                 "$addr.addr = $wb">;
1674 class VSTQQWBregisterPseudo<InstrItinClass itin>
1675   : PseudoNLdSt<(outs GPR:$wb),
1676                 (ins addrmode6:$addr, rGPR:$offset, QQPR:$src), itin,
1677                 "$addr.addr = $wb">;
1678
1679 class VSTQQQQPseudo<InstrItinClass itin>
1680   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src), itin, "">;
1681 class VSTQQQQWBPseudo<InstrItinClass itin>
1682   : PseudoNLdSt<(outs GPR:$wb),
1683                 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,
1684                 "$addr.addr = $wb">;
1685
1686 //   VST1     : Vector Store (multiple single elements)
1687 class VST1D<bits<4> op7_4, string Dt, Operand AddrMode>
1688   : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins AddrMode:$Rn, VecListOneD:$Vd),
1689           IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST1]> {
1690   let Rm = 0b1111;
1691   let Inst{4} = Rn{4};
1692   let DecoderMethod = "DecodeVLDST1Instruction";
1693 }
1694 class VST1Q<bits<4> op7_4, string Dt, Operand AddrMode>
1695   : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins AddrMode:$Rn, VecListDPair:$Vd),
1696           IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST2]> {
1697   let Rm = 0b1111;
1698   let Inst{5-4} = Rn{5-4};
1699   let DecoderMethod = "DecodeVLDST1Instruction";
1700 }
1701
1702 def  VST1d8   : VST1D<{0,0,0,?}, "8",  addrmode6align64>;
1703 def  VST1d16  : VST1D<{0,1,0,?}, "16", addrmode6align64>;
1704 def  VST1d32  : VST1D<{1,0,0,?}, "32", addrmode6align64>;
1705 def  VST1d64  : VST1D<{1,1,0,?}, "64", addrmode6align64>;
1706
1707 def  VST1q8   : VST1Q<{0,0,?,?}, "8",  addrmode6align64or128>;
1708 def  VST1q16  : VST1Q<{0,1,?,?}, "16", addrmode6align64or128>;
1709 def  VST1q32  : VST1Q<{1,0,?,?}, "32", addrmode6align64or128>;
1710 def  VST1q64  : VST1Q<{1,1,?,?}, "64", addrmode6align64or128>;
1711
1712 // ...with address register writeback:
1713 multiclass VST1DWB<bits<4> op7_4, string Dt, Operand AddrMode> {
1714   def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb),
1715                      (ins AddrMode:$Rn, VecListOneD:$Vd), IIC_VLD1u,
1716                      "vst1", Dt, "$Vd, $Rn!",
1717                      "$Rn.addr = $wb", []>, Sched<[WriteVST1]> {
1718     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1719     let Inst{4} = Rn{4};
1720     let DecoderMethod = "DecodeVLDST1Instruction";
1721   }
1722   def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb),
1723                         (ins AddrMode:$Rn, rGPR:$Rm, VecListOneD:$Vd),
1724                         IIC_VLD1u,
1725                         "vst1", Dt, "$Vd, $Rn, $Rm",
1726                         "$Rn.addr = $wb", []>, Sched<[WriteVST1]> {
1727     let Inst{4} = Rn{4};
1728     let DecoderMethod = "DecodeVLDST1Instruction";
1729   }
1730 }
1731 multiclass VST1QWB<bits<4> op7_4, string Dt, Operand AddrMode> {
1732   def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),
1733                     (ins AddrMode:$Rn, VecListDPair:$Vd), IIC_VLD1x2u,
1734                      "vst1", Dt, "$Vd, $Rn!",
1735                      "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {
1736     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1737     let Inst{5-4} = Rn{5-4};
1738     let DecoderMethod = "DecodeVLDST1Instruction";
1739   }
1740   def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),
1741                         (ins AddrMode:$Rn, rGPR:$Rm, VecListDPair:$Vd),
1742                         IIC_VLD1x2u,
1743                         "vst1", Dt, "$Vd, $Rn, $Rm",
1744                         "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {
1745     let Inst{5-4} = Rn{5-4};
1746     let DecoderMethod = "DecodeVLDST1Instruction";
1747   }
1748 }
1749
1750 defm VST1d8wb  : VST1DWB<{0,0,0,?}, "8",  addrmode6align64>;
1751 defm VST1d16wb : VST1DWB<{0,1,0,?}, "16", addrmode6align64>;
1752 defm VST1d32wb : VST1DWB<{1,0,0,?}, "32", addrmode6align64>;
1753 defm VST1d64wb : VST1DWB<{1,1,0,?}, "64", addrmode6align64>;
1754
1755 defm VST1q8wb  : VST1QWB<{0,0,?,?}, "8",  addrmode6align64or128>;
1756 defm VST1q16wb : VST1QWB<{0,1,?,?}, "16", addrmode6align64or128>;
1757 defm VST1q32wb : VST1QWB<{1,0,?,?}, "32", addrmode6align64or128>;
1758 defm VST1q64wb : VST1QWB<{1,1,?,?}, "64", addrmode6align64or128>;
1759
1760 // ...with 3 registers
1761 class VST1D3<bits<4> op7_4, string Dt, Operand AddrMode>
1762   : NLdSt<0, 0b00, 0b0110, op7_4, (outs),
1763           (ins AddrMode:$Rn, VecListThreeD:$Vd),
1764           IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST3]> {
1765   let Rm = 0b1111;
1766   let Inst{4} = Rn{4};
1767   let DecoderMethod = "DecodeVLDST1Instruction";
1768 }
1769 multiclass VST1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> {
1770   def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),
1771                     (ins AddrMode:$Rn, VecListThreeD:$Vd), IIC_VLD1x3u,
1772                      "vst1", Dt, "$Vd, $Rn!",
1773                      "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {
1774     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1775     let Inst{5-4} = Rn{5-4};
1776     let DecoderMethod = "DecodeVLDST1Instruction";
1777   }
1778   def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),
1779                         (ins AddrMode:$Rn, rGPR:$Rm, VecListThreeD:$Vd),
1780                         IIC_VLD1x3u,
1781                         "vst1", Dt, "$Vd, $Rn, $Rm",
1782                         "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {
1783     let Inst{5-4} = Rn{5-4};
1784     let DecoderMethod = "DecodeVLDST1Instruction";
1785   }
1786 }
1787
1788 def VST1d8T     : VST1D3<{0,0,0,?}, "8",  addrmode6align64>;
1789 def VST1d16T    : VST1D3<{0,1,0,?}, "16", addrmode6align64>;
1790 def VST1d32T    : VST1D3<{1,0,0,?}, "32", addrmode6align64>;
1791 def VST1d64T    : VST1D3<{1,1,0,?}, "64", addrmode6align64>;
1792
1793 defm VST1d8Twb  : VST1D3WB<{0,0,0,?}, "8",  addrmode6align64>;
1794 defm VST1d16Twb : VST1D3WB<{0,1,0,?}, "16", addrmode6align64>;
1795 defm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32", addrmode6align64>;
1796 defm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64", addrmode6align64>;
1797
1798 def VST1d64TPseudo            : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>;
1799 def VST1d64TPseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;
1800 def VST1d64TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>;
1801
1802 // ...with 4 registers
1803 class VST1D4<bits<4> op7_4, string Dt, Operand AddrMode>
1804   : NLdSt<0, 0b00, 0b0010, op7_4, (outs),
1805           (ins AddrMode:$Rn, VecListFourD:$Vd),
1806           IIC_VST1x4, "vst1", Dt, "$Vd, $Rn", "",
1807           []>, Sched<[WriteVST4]> {
1808   let Rm = 0b1111;
1809   let Inst{5-4} = Rn{5-4};
1810   let DecoderMethod = "DecodeVLDST1Instruction";
1811 }
1812 multiclass VST1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> {
1813   def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),
1814                     (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1x4u,
1815                      "vst1", Dt, "$Vd, $Rn!",
1816                      "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {
1817     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1818     let Inst{5-4} = Rn{5-4};
1819     let DecoderMethod = "DecodeVLDST1Instruction";
1820   }
1821   def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),
1822                         (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd),
1823                         IIC_VLD1x4u,
1824                         "vst1", Dt, "$Vd, $Rn, $Rm",
1825                         "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {
1826     let Inst{5-4} = Rn{5-4};
1827     let DecoderMethod = "DecodeVLDST1Instruction";
1828   }
1829 }
1830
1831 def VST1d8Q     : VST1D4<{0,0,?,?}, "8",  addrmode6align64or128or256>;
1832 def VST1d16Q    : VST1D4<{0,1,?,?}, "16", addrmode6align64or128or256>;
1833 def VST1d32Q    : VST1D4<{1,0,?,?}, "32", addrmode6align64or128or256>;
1834 def VST1d64Q    : VST1D4<{1,1,?,?}, "64", addrmode6align64or128or256>;
1835
1836 defm VST1d8Qwb  : VST1D4WB<{0,0,?,?}, "8",  addrmode6align64or128or256>;
1837 defm VST1d16Qwb : VST1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>;
1838 defm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>;
1839 defm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>;
1840
1841 def VST1d64QPseudo            : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>;
1842 def VST1d64QPseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;
1843 def VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>;
1844
1845 //   VST2     : Vector Store (multiple 2-element structures)
1846 class VST2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,
1847             InstrItinClass itin, Operand AddrMode>
1848   : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins AddrMode:$Rn, VdTy:$Vd),
1849           itin, "vst2", Dt, "$Vd, $Rn", "", []> {
1850   let Rm = 0b1111;
1851   let Inst{5-4} = Rn{5-4};
1852   let DecoderMethod = "DecodeVLDST2Instruction";
1853 }
1854
1855 def  VST2d8   : VST2<0b1000, {0,0,?,?}, "8",  VecListDPair, IIC_VST2,
1856                      addrmode6align64or128>, Sched<[WriteVST2]>;
1857 def  VST2d16  : VST2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VST2,
1858                      addrmode6align64or128>, Sched<[WriteVST2]>;
1859 def  VST2d32  : VST2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VST2,
1860                      addrmode6align64or128>, Sched<[WriteVST2]>;
1861
1862 def  VST2q8   : VST2<0b0011, {0,0,?,?}, "8",  VecListFourD, IIC_VST2x2,
1863                      addrmode6align64or128or256>, Sched<[WriteVST4]>;
1864 def  VST2q16  : VST2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VST2x2,
1865                      addrmode6align64or128or256>, Sched<[WriteVST4]>;
1866 def  VST2q32  : VST2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VST2x2,
1867                      addrmode6align64or128or256>, Sched<[WriteVST4]>;
1868
1869 def  VST2q8Pseudo  : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;
1870 def  VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;
1871 def  VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>;
1872
1873 // ...with address register writeback:
1874 multiclass VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt,
1875                    RegisterOperand VdTy, Operand AddrMode> {
1876   def _fixed : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1877                      (ins AddrMode:$Rn, VdTy:$Vd), IIC_VLD1u,
1878                      "vst2", Dt, "$Vd, $Rn!",
1879                      "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {
1880     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1881     let Inst{5-4} = Rn{5-4};
1882     let DecoderMethod = "DecodeVLDST2Instruction";
1883   }
1884   def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1885                         (ins AddrMode:$Rn, rGPR:$Rm, VdTy:$Vd), IIC_VLD1u,
1886                         "vst2", Dt, "$Vd, $Rn, $Rm",
1887                         "$Rn.addr = $wb", []>, Sched<[WriteVST2]> {
1888     let Inst{5-4} = Rn{5-4};
1889     let DecoderMethod = "DecodeVLDST2Instruction";
1890   }
1891 }
1892 multiclass VST2QWB<bits<4> op7_4, string Dt, Operand AddrMode> {
1893   def _fixed : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
1894                      (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1u,
1895                      "vst2", Dt, "$Vd, $Rn!",
1896                      "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {
1897     let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1898     let Inst{5-4} = Rn{5-4};
1899     let DecoderMethod = "DecodeVLDST2Instruction";
1900   }
1901   def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
1902                         (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd),
1903                         IIC_VLD1u,
1904                         "vst2", Dt, "$Vd, $Rn, $Rm",
1905                         "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {
1906     let Inst{5-4} = Rn{5-4};
1907     let DecoderMethod = "DecodeVLDST2Instruction";
1908   }
1909 }
1910
1911 defm VST2d8wb    : VST2DWB<0b1000, {0,0,?,?}, "8",  VecListDPair,
1912                            addrmode6align64or128>;
1913 defm VST2d16wb   : VST2DWB<0b1000, {0,1,?,?}, "16", VecListDPair,
1914                            addrmode6align64or128>;
1915 defm VST2d32wb   : VST2DWB<0b1000, {1,0,?,?}, "32", VecListDPair,
1916                            addrmode6align64or128>;
1917
1918 defm VST2q8wb    : VST2QWB<{0,0,?,?}, "8", addrmode6align64or128or256>;
1919 defm VST2q16wb   : VST2QWB<{0,1,?,?}, "16", addrmode6align64or128or256>;
1920 defm VST2q32wb   : VST2QWB<{1,0,?,?}, "32", addrmode6align64or128or256>;
1921
1922 def VST2q8PseudoWB_fixed     : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1923 def VST2q16PseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1924 def VST2q32PseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1925 def VST2q8PseudoWB_register  : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1926 def VST2q16PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1927 def VST2q32PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>;
1928
1929 // ...with double-spaced registers
1930 def VST2b8      : VST2<0b1001, {0,0,?,?}, "8",  VecListDPairSpaced, IIC_VST2,
1931                       addrmode6align64or128>;
1932 def VST2b16     : VST2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VST2,
1933                       addrmode6align64or128>;
1934 def VST2b32     : VST2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VST2,
1935                       addrmode6align64or128>;
1936 defm VST2b8wb   : VST2DWB<0b1001, {0,0,?,?}, "8",  VecListDPairSpaced,
1937                           addrmode6align64or128>;
1938 defm VST2b16wb  : VST2DWB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced,
1939                           addrmode6align64or128>;
1940 defm VST2b32wb  : VST2DWB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced,
1941                           addrmode6align64or128>;
1942
1943 //   VST3     : Vector Store (multiple 3-element structures)
1944 class VST3D<bits<4> op11_8, bits<4> op7_4, string Dt>
1945   : NLdSt<0, 0b00, op11_8, op7_4, (outs),
1946           (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3,
1947           "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []>, Sched<[WriteVST3]> {
1948   let Rm = 0b1111;
1949   let Inst{4} = Rn{4};
1950   let DecoderMethod = "DecodeVLDST3Instruction";
1951 }
1952
1953 def  VST3d8   : VST3D<0b0100, {0,0,0,?}, "8">;
1954 def  VST3d16  : VST3D<0b0100, {0,1,0,?}, "16">;
1955 def  VST3d32  : VST3D<0b0100, {1,0,0,?}, "32">;
1956
1957 def  VST3d8Pseudo  : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1958 def  VST3d16Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1959 def  VST3d32Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1960
1961 // ...with address register writeback:
1962 class VST3DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1963   : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1964           (ins addrmode6:$Rn, am6offset:$Rm,
1965            DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3u,
1966           "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm",
1967           "$Rn.addr = $wb", []>, Sched<[WriteVST3]> {
1968   let Inst{4} = Rn{4};
1969   let DecoderMethod = "DecodeVLDST3Instruction";
1970 }
1971
1972 def VST3d8_UPD  : VST3DWB<0b0100, {0,0,0,?}, "8">;
1973 def VST3d16_UPD : VST3DWB<0b0100, {0,1,0,?}, "16">;
1974 def VST3d32_UPD : VST3DWB<0b0100, {1,0,0,?}, "32">;
1975
1976 def VST3d8Pseudo_UPD  : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1977 def VST3d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1978 def VST3d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1979
1980 // ...with double-spaced registers:
1981 def VST3q8      : VST3D<0b0101, {0,0,0,?}, "8">;
1982 def VST3q16     : VST3D<0b0101, {0,1,0,?}, "16">;
1983 def VST3q32     : VST3D<0b0101, {1,0,0,?}, "32">;
1984 def VST3q8_UPD  : VST3DWB<0b0101, {0,0,0,?}, "8">;
1985 def VST3q16_UPD : VST3DWB<0b0101, {0,1,0,?}, "16">;
1986 def VST3q32_UPD : VST3DWB<0b0101, {1,0,0,?}, "32">;
1987
1988 def VST3q8Pseudo_UPD  : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1989 def VST3q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1990 def VST3q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1991
1992 // ...alternate versions to be allocated odd register numbers:
1993 def VST3q8oddPseudo   : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1994 def VST3q16oddPseudo  : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1995 def VST3q32oddPseudo  : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>;
1996
1997 def VST3q8oddPseudo_UPD  : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1998 def VST3q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
1999 def VST3q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>;
2000
2001 //   VST4     : Vector Store (multiple 4-element structures)
2002 class VST4D<bits<4> op11_8, bits<4> op7_4, string Dt>
2003   : NLdSt<0, 0b00, op11_8, op7_4, (outs),
2004           (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4),
2005           IIC_VST4, "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn",
2006           "", []>, Sched<[WriteVST4]> {
2007   let Rm = 0b1111;
2008   let Inst{5-4} = Rn{5-4};
2009   let DecoderMethod = "DecodeVLDST4Instruction";
2010 }
2011
2012 def  VST4d8   : VST4D<0b0000, {0,0,?,?}, "8">;
2013 def  VST4d16  : VST4D<0b0000, {0,1,?,?}, "16">;
2014 def  VST4d32  : VST4D<0b0000, {1,0,?,?}, "32">;
2015
2016 def  VST4d8Pseudo  : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2017 def  VST4d16Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2018 def  VST4d32Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2019
2020 // ...with address register writeback:
2021 class VST4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2022   : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
2023           (ins addrmode6:$Rn, am6offset:$Rm,
2024            DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST4u,
2025            "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
2026           "$Rn.addr = $wb", []>, Sched<[WriteVST4]> {
2027   let Inst{5-4} = Rn{5-4};
2028   let DecoderMethod = "DecodeVLDST4Instruction";
2029 }
2030
2031 def VST4d8_UPD  : VST4DWB<0b0000, {0,0,?,?}, "8">;
2032 def VST4d16_UPD : VST4DWB<0b0000, {0,1,?,?}, "16">;
2033 def VST4d32_UPD : VST4DWB<0b0000, {1,0,?,?}, "32">;
2034
2035 def VST4d8Pseudo_UPD  : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2036 def VST4d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2037 def VST4d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2038
2039 // ...with double-spaced registers:
2040 def VST4q8      : VST4D<0b0001, {0,0,?,?}, "8">;
2041 def VST4q16     : VST4D<0b0001, {0,1,?,?}, "16">;
2042 def VST4q32     : VST4D<0b0001, {1,0,?,?}, "32">;
2043 def VST4q8_UPD  : VST4DWB<0b0001, {0,0,?,?}, "8">;
2044 def VST4q16_UPD : VST4DWB<0b0001, {0,1,?,?}, "16">;
2045 def VST4q32_UPD : VST4DWB<0b0001, {1,0,?,?}, "32">;
2046
2047 def VST4q8Pseudo_UPD  : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2048 def VST4q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2049 def VST4q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2050
2051 // ...alternate versions to be allocated odd register numbers:
2052 def VST4q8oddPseudo   : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2053 def VST4q16oddPseudo  : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2054 def VST4q32oddPseudo  : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>;
2055
2056 def VST4q8oddPseudo_UPD  : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2057 def VST4q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2058 def VST4q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>;
2059
2060 } // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1
2061
2062 // Classes for VST*LN pseudo-instructions with multi-register operands.
2063 // These are expanded to real instructions after register allocation.
2064 class VSTQLNPseudo<InstrItinClass itin>
2065   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),
2066                 itin, "">;
2067 class VSTQLNWBPseudo<InstrItinClass itin>
2068   : PseudoNLdSt<(outs GPR:$wb),
2069                 (ins addrmode6:$addr, am6offset:$offset, QPR:$src,
2070                  nohash_imm:$lane), itin, "$addr.addr = $wb">;
2071 class VSTQQLNPseudo<InstrItinClass itin>
2072   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),
2073                 itin, "">;
2074 class VSTQQLNWBPseudo<InstrItinClass itin>
2075   : PseudoNLdSt<(outs GPR:$wb),
2076                 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,
2077                  nohash_imm:$lane), itin, "$addr.addr = $wb">;
2078 class VSTQQQQLNPseudo<InstrItinClass itin>
2079   : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),
2080                 itin, "">;
2081 class VSTQQQQLNWBPseudo<InstrItinClass itin>
2082   : PseudoNLdSt<(outs GPR:$wb),
2083                 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,
2084                  nohash_imm:$lane), itin, "$addr.addr = $wb">;
2085
2086 //   VST1LN   : Vector Store (single element from one lane)
2087 class VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
2088              PatFrag StoreOp, SDNode ExtractOp, Operand AddrMode>
2089   : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2090           (ins AddrMode:$Rn, DPR:$Vd, nohash_imm:$lane),
2091           IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "",
2092           [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), AddrMode:$Rn)]>,
2093      Sched<[WriteVST1]> {
2094   let Rm = 0b1111;
2095   let DecoderMethod = "DecodeVST1LN";
2096 }
2097 class VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>
2098   : VSTQLNPseudo<IIC_VST1ln>, Sched<[WriteVST1]> {
2099   let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),
2100                           addrmode6:$addr)];
2101 }
2102
2103 def VST1LNd8  : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8,
2104                        NEONvgetlaneu, addrmode6> {
2105   let Inst{7-5} = lane{2-0};
2106 }
2107 def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16,
2108                        NEONvgetlaneu, addrmode6> {
2109   let Inst{7-6} = lane{1-0};
2110   let Inst{4}   = Rn{4};
2111 }
2112
2113 def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt,
2114                        addrmode6oneL32> {
2115   let Inst{7}   = lane{0};
2116   let Inst{5-4} = Rn{5-4};
2117 }
2118
2119 def VST1LNq8Pseudo  : VST1QLNPseudo<v16i8, truncstorei8, NEONvgetlaneu>;
2120 def VST1LNq16Pseudo : VST1QLNPseudo<v8i16, truncstorei16, NEONvgetlaneu>;
2121 def VST1LNq32Pseudo : VST1QLNPseudo<v4i32, store, extractelt>;
2122
2123 def : Pat<(store (extractelt (v2f32 DPR:$src), imm:$lane), addrmode6:$addr),
2124           (VST1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;
2125 def : Pat<(store (extractelt (v4f32 QPR:$src), imm:$lane), addrmode6:$addr),
2126           (VST1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;
2127
2128 // ...with address register writeback:
2129 class VST1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
2130                PatFrag StoreOp, SDNode ExtractOp, Operand AdrMode>
2131   : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2132           (ins AdrMode:$Rn, am6offset:$Rm,
2133            DPR:$Vd, nohash_imm:$lane), IIC_VST1lnu, "vst1", Dt,
2134           "\\{$Vd[$lane]\\}, $Rn$Rm",
2135           "$Rn.addr = $wb",
2136           [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane),
2137                                   AdrMode:$Rn, am6offset:$Rm))]>,
2138     Sched<[WriteVST1]> {
2139   let DecoderMethod = "DecodeVST1LN";
2140 }
2141 class VST1QLNWBPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>
2142   : VSTQLNWBPseudo<IIC_VST1lnu>, Sched<[WriteVST1]> {
2143   let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),
2144                                         addrmode6:$addr, am6offset:$offset))];
2145 }
2146
2147 def VST1LNd8_UPD  : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8,
2148                              NEONvgetlaneu, addrmode6> {
2149   let Inst{7-5} = lane{2-0};
2150 }
2151 def VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16,
2152                              NEONvgetlaneu, addrmode6> {
2153   let Inst{7-6} = lane{1-0};
2154   let Inst{4}   = Rn{4};
2155 }
2156 def VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store,
2157                              extractelt, addrmode6oneL32> {
2158   let Inst{7}   = lane{0};
2159   let Inst{5-4} = Rn{5-4};
2160 }
2161
2162 def VST1LNq8Pseudo_UPD  : VST1QLNWBPseudo<v16i8, post_truncsti8, NEONvgetlaneu>;
2163 def VST1LNq16Pseudo_UPD : VST1QLNWBPseudo<v8i16, post_truncsti16,NEONvgetlaneu>;
2164 def VST1LNq32Pseudo_UPD : VST1QLNWBPseudo<v4i32, post_store, extractelt>;
2165
2166 let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {
2167
2168 //   VST2LN   : Vector Store (single 2-element structure from one lane)
2169 class VST2LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2170   : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2171           (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, nohash_imm:$lane),
2172           IIC_VST2ln, "vst2", Dt, "\\{$Vd[$lane], $src2[$lane]\\}, $Rn",
2173           "", []>, Sched<[WriteVST1]> {
2174   let Rm = 0b1111;
2175   let Inst{4}   = Rn{4};
2176   let DecoderMethod = "DecodeVST2LN";
2177 }
2178
2179 def VST2LNd8  : VST2LN<0b0001, {?,?,?,?}, "8"> {
2180   let Inst{7-5} = lane{2-0};
2181 }
2182 def VST2LNd16 : VST2LN<0b0101, {?,?,0,?}, "16"> {
2183   let Inst{7-6} = lane{1-0};
2184 }
2185 def VST2LNd32 : VST2LN<0b1001, {?,0,0,?}, "32"> {
2186   let Inst{7}   = lane{0};
2187 }
2188
2189 def VST2LNd8Pseudo  : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;
2190 def VST2LNd16Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;
2191 def VST2LNd32Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;
2192
2193 // ...with double-spaced registers:
2194 def VST2LNq16 : VST2LN<0b0101, {?,?,1,?}, "16"> {
2195   let Inst{7-6} = lane{1-0};
2196   let Inst{4}   = Rn{4};
2197 }
2198 def VST2LNq32 : VST2LN<0b1001, {?,1,0,?}, "32"> {
2199   let Inst{7}   = lane{0};
2200   let Inst{4}   = Rn{4};
2201 }
2202
2203 def VST2LNq16Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;
2204 def VST2LNq32Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>;
2205
2206 // ...with address register writeback:
2207 class VST2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2208   : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2209           (ins addrmode6:$Rn, am6offset:$Rm,
2210            DPR:$Vd, DPR:$src2, nohash_imm:$lane), IIC_VST2lnu, "vst2", Dt,
2211           "\\{$Vd[$lane], $src2[$lane]\\}, $Rn$Rm",
2212           "$Rn.addr = $wb", []> {
2213   let Inst{4}   = Rn{4};
2214   let DecoderMethod = "DecodeVST2LN";
2215 }
2216
2217 def VST2LNd8_UPD  : VST2LNWB<0b0001, {?,?,?,?}, "8"> {
2218   let Inst{7-5} = lane{2-0};
2219 }
2220 def VST2LNd16_UPD : VST2LNWB<0b0101, {?,?,0,?}, "16"> {
2221   let Inst{7-6} = lane{1-0};
2222 }
2223 def VST2LNd32_UPD : VST2LNWB<0b1001, {?,0,0,?}, "32"> {
2224   let Inst{7}   = lane{0};
2225 }
2226
2227 def VST2LNd8Pseudo_UPD  : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;
2228 def VST2LNd16Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;
2229 def VST2LNd32Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;
2230
2231 def VST2LNq16_UPD : VST2LNWB<0b0101, {?,?,1,?}, "16"> {
2232   let Inst{7-6} = lane{1-0};
2233 }
2234 def VST2LNq32_UPD : VST2LNWB<0b1001, {?,1,0,?}, "32"> {
2235   let Inst{7}   = lane{0};
2236 }
2237
2238 def VST2LNq16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;
2239 def VST2LNq32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>;
2240
2241 //   VST3LN   : Vector Store (single 3-element structure from one lane)
2242 class VST3LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2243   : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2244           (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3,
2245            nohash_imm:$lane), IIC_VST3ln, "vst3", Dt,
2246           "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []>,
2247     Sched<[WriteVST2]> {
2248   let Rm = 0b1111;
2249   let DecoderMethod = "DecodeVST3LN";
2250 }
2251
2252 def VST3LNd8  : VST3LN<0b0010, {?,?,?,0}, "8"> {
2253   let Inst{7-5} = lane{2-0};
2254 }
2255 def VST3LNd16 : VST3LN<0b0110, {?,?,0,0}, "16"> {
2256   let Inst{7-6} = lane{1-0};
2257 }
2258 def VST3LNd32 : VST3LN<0b1010, {?,0,0,0}, "32"> {
2259   let Inst{7}   = lane{0};
2260 }
2261
2262 def VST3LNd8Pseudo  : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;
2263 def VST3LNd16Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;
2264 def VST3LNd32Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>;
2265
2266 // ...with double-spaced registers:
2267 def VST3LNq16 : VST3LN<0b0110, {?,?,1,0}, "16"> {
2268   let Inst{7-6} = lane{1-0};
2269 }
2270 def VST3LNq32 : VST3LN<0b1010, {?,1,0,0}, "32"> {
2271   let Inst{7}   = lane{0};
2272 }
2273
2274 def VST3LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;
2275 def VST3LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;
2276
2277 // ...with address register writeback:
2278 class VST3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2279   : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2280           (ins addrmode6:$Rn, am6offset:$Rm,
2281            DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane),
2282           IIC_VST3lnu, "vst3", Dt,
2283           "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm",
2284           "$Rn.addr = $wb", []> {
2285   let DecoderMethod = "DecodeVST3LN";
2286 }
2287
2288 def VST3LNd8_UPD  : VST3LNWB<0b0010, {?,?,?,0}, "8"> {
2289   let Inst{7-5} = lane{2-0};
2290 }
2291 def VST3LNd16_UPD : VST3LNWB<0b0110, {?,?,0,0}, "16"> {
2292   let Inst{7-6} = lane{1-0};
2293 }
2294 def VST3LNd32_UPD : VST3LNWB<0b1010, {?,0,0,0}, "32"> {
2295   let Inst{7}   = lane{0};
2296 }
2297
2298 def VST3LNd8Pseudo_UPD  : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;
2299 def VST3LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;
2300 def VST3LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;
2301
2302 def VST3LNq16_UPD : VST3LNWB<0b0110, {?,?,1,0}, "16"> {
2303   let Inst{7-6} = lane{1-0};
2304 }
2305 def VST3LNq32_UPD : VST3LNWB<0b1010, {?,1,0,0}, "32"> {
2306   let Inst{7}   = lane{0};
2307 }
2308
2309 def VST3LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;
2310 def VST3LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>;
2311
2312 //   VST4LN   : Vector Store (single 4-element structure from one lane)
2313 class VST4LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2314   : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2315           (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4,
2316            nohash_imm:$lane), IIC_VST4ln, "vst4", Dt,
2317           "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn",
2318           "", []>, Sched<[WriteVST2]> {
2319   let Rm = 0b1111;
2320   let Inst{4} = Rn{4};
2321   let DecoderMethod = "DecodeVST4LN";
2322 }
2323
2324 def VST4LNd8  : VST4LN<0b0011, {?,?,?,?}, "8"> {
2325   let Inst{7-5} = lane{2-0};
2326 }
2327 def VST4LNd16 : VST4LN<0b0111, {?,?,0,?}, "16"> {
2328   let Inst{7-6} = lane{1-0};
2329 }
2330 def VST4LNd32 : VST4LN<0b1011, {?,0,?,?}, "32"> {
2331   let Inst{7}   = lane{0};
2332   let Inst{5} = Rn{5};
2333 }
2334
2335 def VST4LNd8Pseudo  : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;
2336 def VST4LNd16Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;
2337 def VST4LNd32Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;
2338
2339 // ...with double-spaced registers:
2340 def VST4LNq16 : VST4LN<0b0111, {?,?,1,?}, "16"> {
2341   let Inst{7-6} = lane{1-0};
2342 }
2343 def VST4LNq32 : VST4LN<0b1011, {?,1,?,?}, "32"> {
2344   let Inst{7}   = lane{0};
2345   let Inst{5} = Rn{5};
2346 }
2347
2348 def VST4LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;
2349 def VST4LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>;
2350
2351 // ...with address register writeback:
2352 class VST4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2353   : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2354           (ins addrmode6:$Rn, am6offset:$Rm,
2355            DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),
2356           IIC_VST4lnu, "vst4", Dt,
2357   "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm",
2358           "$Rn.addr = $wb", []> {
2359   let Inst{4} = Rn{4};
2360   let DecoderMethod = "DecodeVST4LN";
2361 }
2362
2363 def VST4LNd8_UPD  : VST4LNWB<0b0011, {?,?,?,?}, "8"> {
2364   let Inst{7-5} = lane{2-0};
2365 }
2366 def VST4LNd16_UPD : VST4LNWB<0b0111, {?,?,0,?}, "16"> {
2367   let Inst{7-6} = lane{1-0};
2368 }
2369 def VST4LNd32_UPD : VST4LNWB<0b1011, {?,0,?,?}, "32"> {
2370   let Inst{7}   = lane{0};
2371   let Inst{5} = Rn{5};
2372 }
2373
2374 def VST4LNd8Pseudo_UPD  : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;
2375 def VST4LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;
2376 def VST4LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;
2377
2378 def VST4LNq16_UPD : VST4LNWB<0b0111, {?,?,1,?}, "16"> {
2379   let Inst{7-6} = lane{1-0};
2380 }
2381 def VST4LNq32_UPD : VST4LNWB<0b1011, {?,1,?,?}, "32"> {
2382   let Inst{7}   = lane{0};
2383   let Inst{5} = Rn{5};
2384 }
2385
2386 def VST4LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;
2387 def VST4LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>;
2388
2389 } // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1
2390
2391 // Use vld1/vst1 for unaligned f64 load / store
2392 def : Pat<(f64 (hword_alignedload addrmode6:$addr)),
2393           (VLD1d16 addrmode6:$addr)>, Requires<[IsLE]>;
2394 def : Pat<(hword_alignedstore (f64 DPR:$value), addrmode6:$addr),
2395           (VST1d16 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>;
2396 def : Pat<(f64 (byte_alignedload addrmode6:$addr)),
2397           (VLD1d8 addrmode6:$addr)>, Requires<[IsLE]>;
2398 def : Pat<(byte_alignedstore (f64 DPR:$value), addrmode6:$addr),
2399           (VST1d8 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>;
2400 def : Pat<(f64 (non_word_alignedload addrmode6:$addr)),
2401           (VLD1d64 addrmode6:$addr)>, Requires<[IsBE]>;
2402 def : Pat<(non_word_alignedstore (f64 DPR:$value), addrmode6:$addr),
2403           (VST1d64 addrmode6:$addr, DPR:$value)>, Requires<[IsBE]>;
2404
2405 // Use vld1/vst1 for Q and QQ. Also use them for unaligned v2f64
2406 // load / store if it's legal.
2407 def : Pat<(v2f64 (dword_alignedload addrmode6:$addr)),
2408           (VLD1q64 addrmode6:$addr)>;
2409 def : Pat<(dword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2410           (VST1q64 addrmode6:$addr, QPR:$value)>;
2411 def : Pat<(v2f64 (word_alignedload addrmode6:$addr)),
2412           (VLD1q32 addrmode6:$addr)>, Requires<[IsLE]>;
2413 def : Pat<(word_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2414           (VST1q32 addrmode6:$addr, QPR:$value)>, Requires<[IsLE]>;
2415 def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)),
2416           (VLD1q16 addrmode6:$addr)>, Requires<[IsLE]>;
2417 def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2418           (VST1q16 addrmode6:$addr, QPR:$value)>, Requires<[IsLE]>;
2419 def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)),
2420           (VLD1q8 addrmode6:$addr)>, Requires<[IsLE]>;
2421 def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2422           (VST1q8 addrmode6:$addr, QPR:$value)>, Requires<[IsLE]>;
2423
2424 //===----------------------------------------------------------------------===//
2425 // NEON pattern fragments
2426 //===----------------------------------------------------------------------===//
2427
2428 // Extract D sub-registers of Q registers.
2429 def DSubReg_i8_reg  : SDNodeXForm<imm, [{
2430   assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2431   return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, SDLoc(N),
2432                                    MVT::i32);
2433 }]>;
2434 def DSubReg_i16_reg : SDNodeXForm<imm, [{
2435   assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2436   return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, SDLoc(N),
2437                                    MVT::i32);
2438 }]>;
2439 def DSubReg_i32_reg : SDNodeXForm<imm, [{
2440   assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2441   return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, SDLoc(N),
2442                                    MVT::i32);
2443 }]>;
2444 def DSubReg_f64_reg : SDNodeXForm<imm, [{
2445   assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2446   return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), SDLoc(N),
2447                                    MVT::i32);
2448 }]>;
2449
2450 // Extract S sub-registers of Q/D registers.
2451 def SSubReg_f32_reg : SDNodeXForm<imm, [{
2452   assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering");
2453   return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), SDLoc(N),
2454                                    MVT::i32);
2455 }]>;
2456
2457 // Translate lane numbers from Q registers to D subregs.
2458 def SubReg_i8_lane  : SDNodeXForm<imm, [{
2459   return CurDAG->getTargetConstant(N->getZExtValue() & 7, SDLoc(N), MVT::i32);
2460 }]>;
2461 def SubReg_i16_lane : SDNodeXForm<imm, [{
2462   return CurDAG->getTargetConstant(N->getZExtValue() & 3, SDLoc(N), MVT::i32);
2463 }]>;
2464 def SubReg_i32_lane : SDNodeXForm<imm, [{
2465   return CurDAG->getTargetConstant(N->getZExtValue() & 1, SDLoc(N), MVT::i32);
2466 }]>;
2467
2468 //===----------------------------------------------------------------------===//
2469 // Instruction Classes
2470 //===----------------------------------------------------------------------===//
2471
2472 // Basic 2-register operations: double- and quad-register.
2473 class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2474            bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
2475            string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
2476   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
2477         (ins DPR:$Vm), IIC_VUNAD, OpcodeStr, Dt,"$Vd, $Vm", "",
2478         [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm))))]>;
2479 class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2480            bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
2481            string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
2482   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
2483         (ins QPR:$Vm), IIC_VUNAQ, OpcodeStr, Dt,"$Vd, $Vm", "",
2484         [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm))))]>;
2485
2486 // Basic 2-register intrinsics, both double- and quad-register.
2487 class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2488               bits<2> op17_16, bits<5> op11_7, bit op4,
2489               InstrItinClass itin, string OpcodeStr, string Dt,
2490               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2491   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
2492         (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2493         [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
2494 class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2495               bits<2> op17_16, bits<5> op11_7, bit op4,
2496               InstrItinClass itin, string OpcodeStr, string Dt,
2497               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2498   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
2499         (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2500         [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2501
2502 // Same as above, but not predicated.
2503 class N2VDIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7,
2504               InstrItinClass itin, string OpcodeStr, string Dt,
2505               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2506   : N2Vnp<op19_18, op17_16, op10_8, op7, 0,  (outs DPR:$Vd), (ins DPR:$Vm),
2507           itin, OpcodeStr, Dt,
2508           [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
2509
2510 class N2VQIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7,
2511               InstrItinClass itin, string OpcodeStr, string Dt,
2512               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2513   : N2Vnp<op19_18, op17_16, op10_8, op7, 1,  (outs QPR:$Vd), (ins QPR:$Vm),
2514           itin, OpcodeStr, Dt,
2515           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2516
2517 // Similar to NV2VQIntnp with some more encoding bits exposed (crypto).
2518 class N2VQIntXnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,
2519               bit op7, InstrItinClass itin, string OpcodeStr, string Dt,
2520               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2521   : N2Vnp<op19_18, op17_16, op10_8, op7, op6,  (outs QPR:$Vd), (ins QPR:$Vm),
2522           itin, OpcodeStr, Dt,
2523           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2524
2525 // Same as N2VQIntXnp but with Vd as a src register.
2526 class N2VQIntX2np<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,
2527               bit op7, InstrItinClass itin, string OpcodeStr, string Dt,
2528               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2529   : N2Vnp<op19_18, op17_16, op10_8, op7, op6,
2530           (outs QPR:$Vd), (ins QPR:$src, QPR:$Vm),
2531           itin, OpcodeStr, Dt,
2532           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vm))))]> {
2533   let Constraints = "$src = $Vd";
2534 }
2535
2536 // Narrow 2-register operations.
2537 class N2VN<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2538            bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2539            InstrItinClass itin, string OpcodeStr, string Dt,
2540            ValueType TyD, ValueType TyQ, SDNode OpNode>
2541   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),
2542         (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2543         [(set DPR:$Vd, (TyD (OpNode (TyQ QPR:$Vm))))]>;
2544
2545 // Narrow 2-register intrinsics.
2546 class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2547               bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2548               InstrItinClass itin, string OpcodeStr, string Dt,
2549               ValueType TyD, ValueType TyQ, SDPatternOperator IntOp>
2550   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),
2551         (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2552         [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vm))))]>;
2553
2554 // Long 2-register operations (currently only used for VMOVL).
2555 class N2VL<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2556            bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2557            InstrItinClass itin, string OpcodeStr, string Dt,
2558            ValueType TyQ, ValueType TyD, SDNode OpNode>
2559   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),
2560         (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2561         [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vm))))]>;
2562
2563 // Long 2-register intrinsics.
2564 class N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2565               bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2566               InstrItinClass itin, string OpcodeStr, string Dt,
2567               ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>
2568   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),
2569         (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2570         [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vm))))]>;
2571
2572 // 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register.
2573 class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>
2574   : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$Vd, DPR:$Vm),
2575         (ins DPR:$src1, DPR:$src2), IIC_VPERMD,
2576         OpcodeStr, Dt, "$Vd, $Vm",
2577         "$src1 = $Vd, $src2 = $Vm", []>;
2578 class N2VQShuffle<bits<2> op19_18, bits<5> op11_7,
2579                   InstrItinClass itin, string OpcodeStr, string Dt>
2580   : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$Vd, QPR:$Vm),
2581         (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm",
2582         "$src1 = $Vd, $src2 = $Vm", []>;
2583
2584 // Basic 3-register operations: double- and quad-register.
2585 class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2586            InstrItinClass itin, string OpcodeStr, string Dt,
2587            ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2588   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2589         (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2590         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2591         [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {
2592   // All of these have a two-operand InstAlias.
2593   let TwoOperandAliasConstraint = "$Vn = $Vd";
2594   let isCommutable = Commutable;
2595 }
2596 // Same as N3VD but no data type.
2597 class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2598            InstrItinClass itin, string OpcodeStr,
2599            ValueType ResTy, ValueType OpTy,
2600            SDNode OpNode, bit Commutable>
2601   : N3VX<op24, op23, op21_20, op11_8, 0, op4,
2602          (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2603          OpcodeStr, "$Vd, $Vn, $Vm", "",
2604          [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>{
2605   // All of these have a two-operand InstAlias.
2606   let TwoOperandAliasConstraint = "$Vn = $Vd";
2607   let isCommutable = Commutable;
2608 }
2609
2610 class N3VDSL<bits<2> op21_20, bits<4> op11_8,
2611              InstrItinClass itin, string OpcodeStr, string Dt,
2612              ValueType Ty, SDNode ShOp>
2613   : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2614         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2615         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2616         [(set (Ty DPR:$Vd),
2617               (Ty (ShOp (Ty DPR:$Vn),
2618                         (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),imm:$lane)))))]> {
2619   // All of these have a two-operand InstAlias.
2620   let TwoOperandAliasConstraint = "$Vn = $Vd";
2621   let isCommutable = 0;
2622 }
2623 class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
2624                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
2625   : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2626         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2627         NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane","",
2628         [(set (Ty DPR:$Vd),
2629               (Ty (ShOp (Ty DPR:$Vn),
2630                         (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {
2631   // All of these have a two-operand InstAlias.
2632   let TwoOperandAliasConstraint = "$Vn = $Vd";
2633   let isCommutable = 0;
2634 }
2635
2636 class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2637            InstrItinClass itin, string OpcodeStr, string Dt,
2638            ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2639   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2640         (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2641         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2642         [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {
2643   // All of these have a two-operand InstAlias.
2644   let TwoOperandAliasConstraint = "$Vn = $Vd";
2645   let isCommutable = Commutable;
2646 }
2647 class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2648            InstrItinClass itin, string OpcodeStr,
2649            ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2650   : N3VX<op24, op23, op21_20, op11_8, 1, op4,
2651          (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2652          OpcodeStr, "$Vd, $Vn, $Vm", "",
2653          [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>{
2654   // All of these have a two-operand InstAlias.
2655   let TwoOperandAliasConstraint = "$Vn = $Vd";
2656   let isCommutable = Commutable;
2657 }
2658 class N3VQSL<bits<2> op21_20, bits<4> op11_8,
2659              InstrItinClass itin, string OpcodeStr, string Dt,
2660              ValueType ResTy, ValueType OpTy, SDNode ShOp>
2661   : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2662         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2663         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2664         [(set (ResTy QPR:$Vd),
2665               (ResTy (ShOp (ResTy QPR:$Vn),
2666                            (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2667                                                 imm:$lane)))))]> {
2668   // All of these have a two-operand InstAlias.
2669   let TwoOperandAliasConstraint = "$Vn = $Vd";
2670   let isCommutable = 0;
2671 }
2672 class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
2673                ValueType ResTy, ValueType OpTy, SDNode ShOp>
2674   : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2675         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2676         NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane", "",
2677         [(set (ResTy QPR:$Vd),
2678               (ResTy (ShOp (ResTy QPR:$Vn),
2679                            (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2680                                                 imm:$lane)))))]> {
2681   // All of these have a two-operand InstAlias.
2682   let TwoOperandAliasConstraint = "$Vn = $Vd";
2683   let isCommutable = 0;
2684 }
2685
2686 // Basic 3-register intrinsics, both double- and quad-register.
2687 class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2688               Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2689               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>
2690   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2691         (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin,
2692         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2693         [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {
2694   // All of these have a two-operand InstAlias.
2695   let TwoOperandAliasConstraint = "$Vn = $Vd";
2696   let isCommutable = Commutable;
2697 }
2698
2699 class N3VDIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2700                 bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2701                 string Dt, ValueType ResTy, ValueType OpTy,
2702                 SDPatternOperator IntOp, bit Commutable>
2703   : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2704           (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt,
2705           [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2706
2707 class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2708                 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
2709   : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2710         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2711         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2712         [(set (Ty DPR:$Vd),
2713               (Ty (IntOp (Ty DPR:$Vn),
2714                          (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),
2715                                            imm:$lane)))))]> {
2716   let isCommutable = 0;
2717 }
2718
2719 class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2720                   string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
2721   : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2722         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2723         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2724         [(set (Ty DPR:$Vd),
2725               (Ty (IntOp (Ty DPR:$Vn),
2726                          (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {
2727   let isCommutable = 0;
2728 }
2729 class N3VDIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2730               Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2731               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2732   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2733         (outs DPR:$Vd), (ins DPR:$Vm, DPR:$Vn), f, itin,
2734         OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",
2735         [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (OpTy DPR:$Vn))))]> {
2736   let TwoOperandAliasConstraint = "$Vm = $Vd";
2737   let isCommutable = 0;
2738 }
2739
2740 class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2741               Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2742               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>
2743   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2744         (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin,
2745         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2746         [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {
2747   // All of these have a two-operand InstAlias.
2748   let TwoOperandAliasConstraint = "$Vn = $Vd";
2749   let isCommutable = Commutable;
2750 }
2751
2752 class N3VQIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2753                 bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2754                 string Dt, ValueType ResTy, ValueType OpTy,
2755                 SDPatternOperator IntOp, bit Commutable>
2756   : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2757           (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt,
2758           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
2759
2760 // Same as N3VQIntnp but with Vd as a src register.
2761 class N3VQInt3np<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2762                 bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2763                 string Dt, ValueType ResTy, ValueType OpTy,
2764                 SDPatternOperator IntOp, bit Commutable>
2765   : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2766           (outs QPR:$Vd), (ins QPR:$src, QPR:$Vn, QPR:$Vm),
2767           f, itin, OpcodeStr, Dt,
2768           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vn),
2769                                        (OpTy QPR:$Vm))))]> {
2770   let Constraints = "$src = $Vd";
2771 }
2772
2773 class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2774                 string OpcodeStr, string Dt,
2775                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2776   : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2777         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2778         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2779         [(set (ResTy QPR:$Vd),
2780               (ResTy (IntOp (ResTy QPR:$Vn),
2781                             (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2782                                                  imm:$lane)))))]> {
2783   let isCommutable = 0;
2784 }
2785 class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2786                   string OpcodeStr, string Dt,
2787                   ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2788   : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2789         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2790         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2791         [(set (ResTy QPR:$Vd),
2792               (ResTy (IntOp (ResTy QPR:$Vn),
2793                             (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2794                                                  imm:$lane)))))]> {
2795   let isCommutable = 0;
2796 }
2797 class N3VQIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2798               Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2799               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2800   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2801         (outs QPR:$Vd), (ins QPR:$Vm, QPR:$Vn), f, itin,
2802         OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",
2803         [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (OpTy QPR:$Vn))))]> {
2804   let TwoOperandAliasConstraint = "$Vm = $Vd";
2805   let isCommutable = 0;
2806 }
2807
2808 // Multiply-Add/Sub operations: double- and quad-register.
2809 class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2810                 InstrItinClass itin, string OpcodeStr, string Dt,
2811                 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode>
2812   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2813         (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2814         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2815         [(set DPR:$Vd, (Ty (OpNode DPR:$src1,
2816                              (Ty (MulOp DPR:$Vn, DPR:$Vm)))))]>;
2817
2818 class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2819                   string OpcodeStr, string Dt,
2820                   ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
2821   : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2822         (outs DPR:$Vd),
2823         (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2824         NVMulSLFrm, itin,
2825         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2826         [(set (Ty DPR:$Vd),
2827               (Ty (ShOp (Ty DPR:$src1),
2828                         (Ty (MulOp DPR:$Vn,
2829                                    (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),
2830                                                      imm:$lane)))))))]>;
2831 class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2832                     string OpcodeStr, string Dt,
2833                     ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
2834   : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2835         (outs DPR:$Vd),
2836         (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2837         NVMulSLFrm, itin,
2838         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2839         [(set (Ty DPR:$Vd),
2840               (Ty (ShOp (Ty DPR:$src1),
2841                         (Ty (MulOp DPR:$Vn,
2842                                    (Ty (NEONvduplane (Ty DPR_8:$Vm),
2843                                                      imm:$lane)))))))]>;
2844
2845 class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2846                 InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,
2847                 SDPatternOperator MulOp, SDPatternOperator OpNode>
2848   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2849         (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2850         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2851         [(set QPR:$Vd, (Ty (OpNode QPR:$src1,
2852                              (Ty (MulOp QPR:$Vn, QPR:$Vm)))))]>;
2853 class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2854                   string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
2855                   SDPatternOperator MulOp, SDPatternOperator ShOp>
2856   : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2857         (outs QPR:$Vd),
2858         (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2859         NVMulSLFrm, itin,
2860         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2861         [(set (ResTy QPR:$Vd),
2862               (ResTy (ShOp (ResTy QPR:$src1),
2863                            (ResTy (MulOp QPR:$Vn,
2864                                    (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2865                                                         imm:$lane)))))))]>;
2866 class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2867                     string OpcodeStr, string Dt,
2868                     ValueType ResTy, ValueType OpTy,
2869                     SDPatternOperator MulOp, SDPatternOperator ShOp>
2870   : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2871         (outs QPR:$Vd),
2872         (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2873         NVMulSLFrm, itin,
2874         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2875         [(set (ResTy QPR:$Vd),
2876               (ResTy (ShOp (ResTy QPR:$src1),
2877                            (ResTy (MulOp QPR:$Vn,
2878                                    (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2879                                                         imm:$lane)))))))]>;
2880
2881 // Neon Intrinsic-Op instructions (VABA): double- and quad-register.
2882 class N3VDIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2883                 InstrItinClass itin, string OpcodeStr, string Dt,
2884                 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>
2885   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2886         (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2887         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2888         [(set DPR:$Vd, (Ty (OpNode DPR:$src1,
2889                              (Ty (IntOp (Ty DPR:$Vn), (Ty DPR:$Vm))))))]>;
2890 class N3VQIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2891                 InstrItinClass itin, string OpcodeStr, string Dt,
2892                 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>
2893   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2894         (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2895         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2896         [(set QPR:$Vd, (Ty (OpNode QPR:$src1,
2897                              (Ty (IntOp (Ty QPR:$Vn), (Ty QPR:$Vm))))))]>;
2898
2899 // Neon 3-argument intrinsics, both double- and quad-register.
2900 // The destination register is also used as the first source operand register.
2901 class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2902                InstrItinClass itin, string OpcodeStr, string Dt,
2903                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2904   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2905         (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2906         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2907         [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$src1),
2908                                       (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2909 class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2910                InstrItinClass itin, string OpcodeStr, string Dt,
2911                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2912   : N3V<op24, op23, op21_20, op11_8, 1, op4,
2913         (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2914         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2915         [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src1),
2916                                       (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
2917
2918 // Long Multiply-Add/Sub operations.
2919 class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2920                 InstrItinClass itin, string OpcodeStr, string Dt,
2921                 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2922   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2923         (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2924         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2925         [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),
2926                                 (TyQ (MulOp (TyD DPR:$Vn),
2927                                             (TyD DPR:$Vm)))))]>;
2928 class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
2929                   InstrItinClass itin, string OpcodeStr, string Dt,
2930                   ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2931   : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
2932         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2933         NVMulSLFrm, itin,
2934         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2935         [(set QPR:$Vd,
2936           (OpNode (TyQ QPR:$src1),
2937                   (TyQ (MulOp (TyD DPR:$Vn),
2938                               (TyD (NEONvduplane (TyD DPR_VFP2:$Vm),
2939                                                  imm:$lane))))))]>;
2940 class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2941                     InstrItinClass itin, string OpcodeStr, string Dt,
2942                     ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2943   : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
2944         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2945         NVMulSLFrm, itin,
2946         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2947         [(set QPR:$Vd,
2948           (OpNode (TyQ QPR:$src1),
2949                   (TyQ (MulOp (TyD DPR:$Vn),
2950                               (TyD (NEONvduplane (TyD DPR_8:$Vm),
2951                                                  imm:$lane))))))]>;
2952
2953 // Long Intrinsic-Op vector operations with explicit extend (VABAL).
2954 class N3VLIntExtOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2955                    InstrItinClass itin, string OpcodeStr, string Dt,
2956                    ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,
2957                    SDNode OpNode>
2958   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2959         (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2960         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2961         [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),
2962                                 (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),
2963                                                         (TyD DPR:$Vm)))))))]>;
2964
2965 // Neon Long 3-argument intrinsic.  The destination register is
2966 // a quad-register and is also used as the first source operand register.
2967 class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2968                InstrItinClass itin, string OpcodeStr, string Dt,
2969                ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>
2970   : N3V<op24, op23, op21_20, op11_8, 0, op4,
2971         (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2972         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2973         [(set QPR:$Vd,
2974           (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$Vn), (TyD DPR:$Vm))))]>;
2975 class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2976                  string OpcodeStr, string Dt,
2977                  ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2978   : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
2979         (outs QPR:$Vd),
2980         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2981         NVMulSLFrm, itin,
2982         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2983         [(set (ResTy QPR:$Vd),
2984               (ResTy (IntOp (ResTy QPR:$src1),
2985                             (OpTy DPR:$Vn),
2986                             (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2987                                                 imm:$lane)))))]>;
2988 class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2989                    InstrItinClass itin, string OpcodeStr, string Dt,
2990                    ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2991   : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
2992         (outs QPR:$Vd),
2993         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2994         NVMulSLFrm, itin,
2995         OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2996         [(set (ResTy QPR:$Vd),
2997               (ResTy (IntOp (ResTy QPR:$src1),
2998                             (OpTy DPR:$Vn),
2999                             (OpTy (NEONvduplane (OpTy DPR_8:$Vm),
3000                                                 imm:$lane)))))]>;
3001
3002 // Narrowing 3-register intrinsics.
3003 class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3004               string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ,
3005               SDPatternOperator IntOp, bit Commutable>
3006   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3007         (outs DPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINi4D,
3008         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3009         [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vn), (TyQ QPR:$Vm))))]> {
3010   let isCommutable = Commutable;
3011 }
3012
3013 // Long 3-register operations.
3014 class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3015            InstrItinClass itin, string OpcodeStr, string Dt,
3016            ValueType TyQ, ValueType TyD, SDNode OpNode, bit Commutable>
3017   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3018         (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
3019         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3020         [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {
3021   let isCommutable = Commutable;
3022 }
3023
3024 class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
3025              InstrItinClass itin, string OpcodeStr, string Dt,
3026              ValueType TyQ, ValueType TyD, SDNode OpNode>
3027   : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
3028         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
3029         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
3030         [(set QPR:$Vd,
3031           (TyQ (OpNode (TyD DPR:$Vn),
3032                        (TyD (NEONvduplane (TyD DPR_VFP2:$Vm),imm:$lane)))))]>;
3033 class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
3034                InstrItinClass itin, string OpcodeStr, string Dt,
3035                ValueType TyQ, ValueType TyD, SDNode OpNode>
3036   : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
3037         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
3038         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
3039         [(set QPR:$Vd,
3040           (TyQ (OpNode (TyD DPR:$Vn),
3041                        (TyD (NEONvduplane (TyD DPR_8:$Vm), imm:$lane)))))]>;
3042
3043 // Long 3-register operations with explicitly extended operands.
3044 class N3VLExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3045               InstrItinClass itin, string OpcodeStr, string Dt,
3046               ValueType TyQ, ValueType TyD, SDNode OpNode, SDNode ExtOp,
3047               bit Commutable>
3048   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3049         (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
3050         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3051         [(set QPR:$Vd, (OpNode (TyQ (ExtOp (TyD DPR:$Vn))),
3052                                 (TyQ (ExtOp (TyD DPR:$Vm)))))]> {
3053   let isCommutable = Commutable;
3054 }
3055
3056 // Long 3-register intrinsics with explicit extend (VABDL).
3057 class N3VLIntExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3058                  InstrItinClass itin, string OpcodeStr, string Dt,
3059                  ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,
3060                  bit Commutable>
3061   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3062         (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
3063         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3064         [(set QPR:$Vd, (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),
3065                                                 (TyD DPR:$Vm))))))]> {
3066   let isCommutable = Commutable;
3067 }
3068
3069 // Long 3-register intrinsics.
3070 class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3071               InstrItinClass itin, string OpcodeStr, string Dt,
3072               ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, bit Commutable>
3073   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3074         (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
3075         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3076         [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {
3077   let isCommutable = Commutable;
3078 }
3079
3080 // Same as above, but not predicated.
3081 class N3VLIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
3082                 bit op4, InstrItinClass itin, string OpcodeStr,
3083                 string Dt, ValueType ResTy, ValueType OpTy,
3084                 SDPatternOperator IntOp, bit Commutable>
3085   : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
3086           (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt,
3087           [(set QPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
3088
3089 class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
3090                 string OpcodeStr, string Dt,
3091                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3092   : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
3093         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
3094         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
3095         [(set (ResTy QPR:$Vd),
3096               (ResTy (IntOp (OpTy DPR:$Vn),
3097                             (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
3098                                                 imm:$lane)))))]>;
3099 class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
3100                   InstrItinClass itin, string OpcodeStr, string Dt,
3101                   ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3102   : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
3103         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
3104         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
3105         [(set (ResTy QPR:$Vd),
3106               (ResTy (IntOp (OpTy DPR:$Vn),
3107                             (OpTy (NEONvduplane (OpTy DPR_8:$Vm),
3108                                                 imm:$lane)))))]>;
3109
3110 // Wide 3-register operations.
3111 class N3VW<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
3112            string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD,
3113            SDNode OpNode, SDNode ExtOp, bit Commutable>
3114   : N3V<op24, op23, op21_20, op11_8, 0, op4,
3115         (outs QPR:$Vd), (ins QPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VSUBiD,
3116         OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
3117         [(set QPR:$Vd, (OpNode (TyQ QPR:$Vn),
3118                                 (TyQ (ExtOp (TyD DPR:$Vm)))))]> {
3119   // All of these have a two-operand InstAlias.
3120   let TwoOperandAliasConstraint = "$Vn = $Vd";
3121   let isCommutable = Commutable;
3122 }
3123
3124 // Pairwise long 2-register intrinsics, both double- and quad-register.
3125 class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3126                 bits<2> op17_16, bits<5> op11_7, bit op4,
3127                 string OpcodeStr, string Dt,
3128                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3129   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
3130         (ins DPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
3131         [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
3132 class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3133                 bits<2> op17_16, bits<5> op11_7, bit op4,
3134                 string OpcodeStr, string Dt,
3135                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3136   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
3137         (ins QPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
3138         [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
3139
3140 // Pairwise long 2-register accumulate intrinsics,
3141 // both double- and quad-register.
3142 // The destination register is also used as the first source operand register.
3143 class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3144                  bits<2> op17_16, bits<5> op11_7, bit op4,
3145                  string OpcodeStr, string Dt,
3146                  ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3147   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
3148         (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vm), IIC_VPALiD,
3149         OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",
3150         [(set DPR:$Vd, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$Vm))))]>;
3151 class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3152                  bits<2> op17_16, bits<5> op11_7, bit op4,
3153                  string OpcodeStr, string Dt,
3154                  ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3155   : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4,
3156         (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vm), IIC_VPALiQ,
3157         OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",
3158         [(set QPR:$Vd, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$Vm))))]>;
3159
3160 // Shift by immediate,
3161 // both double- and quad-register.
3162 let TwoOperandAliasConstraint = "$Vm = $Vd" in {
3163 class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3164              Format f, InstrItinClass itin, Operand ImmTy,
3165              string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>
3166   : N2VImm<op24, op23, op11_8, op7, 0, op4,
3167            (outs DPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), f, itin,
3168            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3169            [(set DPR:$Vd, (Ty (OpNode (Ty DPR:$Vm), (i32 imm:$SIMM))))]>;
3170 class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3171              Format f, InstrItinClass itin, Operand ImmTy,
3172              string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>
3173   : N2VImm<op24, op23, op11_8, op7, 1, op4,
3174            (outs QPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), f, itin,
3175            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3176            [(set QPR:$Vd, (Ty (OpNode (Ty QPR:$Vm), (i32 imm:$SIMM))))]>;
3177 }
3178
3179 // Long shift by immediate.
3180 class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
3181              string OpcodeStr, string Dt,
3182              ValueType ResTy, ValueType OpTy, Operand ImmTy,
3183              SDPatternOperator OpNode>
3184   : N2VImm<op24, op23, op11_8, op7, op6, op4,
3185            (outs QPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), N2RegVShLFrm,
3186            IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3187            [(set QPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm), ImmTy:$SIMM)))]>;
3188
3189 // Narrow shift by immediate.
3190 class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
3191              InstrItinClass itin, string OpcodeStr, string Dt,
3192              ValueType ResTy, ValueType OpTy, Operand ImmTy,
3193              SDPatternOperator OpNode>
3194   : N2VImm<op24, op23, op11_8, op7, op6, op4,
3195            (outs DPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, itin,
3196            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3197            [(set DPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm),
3198                                           (i32 ImmTy:$SIMM))))]>;
3199
3200 // Shift right by immediate and accumulate,
3201 // both double- and quad-register.
3202 let TwoOperandAliasConstraint = "$Vm = $Vd" in {
3203 class N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3204                 Operand ImmTy, string OpcodeStr, string Dt,
3205                 ValueType Ty, SDNode ShOp>
3206   : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),
3207            (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,
3208            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3209            [(set DPR:$Vd, (Ty (add DPR:$src1,
3210                                 (Ty (ShOp DPR:$Vm, (i32 imm:$SIMM))))))]>;
3211 class N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3212                 Operand ImmTy, string OpcodeStr, string Dt,
3213                 ValueType Ty, SDNode ShOp>
3214   : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),
3215            (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,
3216            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3217            [(set QPR:$Vd, (Ty (add QPR:$src1,
3218                                 (Ty (ShOp QPR:$Vm, (i32 imm:$SIMM))))))]>;
3219 }
3220
3221 // Shift by immediate and insert,
3222 // both double- and quad-register.
3223 let TwoOperandAliasConstraint = "$Vm = $Vd" in {
3224 class N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3225                 Operand ImmTy, Format f, string OpcodeStr, string Dt,
3226                 ValueType Ty,SDNode ShOp>
3227   : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),
3228            (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiD,
3229            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3230            [(set DPR:$Vd, (Ty (ShOp DPR:$src1, DPR:$Vm, (i32 imm:$SIMM))))]>;
3231 class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3232                 Operand ImmTy, Format f, string OpcodeStr, string Dt,
3233                 ValueType Ty,SDNode ShOp>
3234   : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),
3235            (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiQ,
3236            OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3237            [(set QPR:$Vd, (Ty (ShOp QPR:$src1, QPR:$Vm, (i32 imm:$SIMM))))]>;
3238 }
3239
3240 // Convert, with fractional bits immediate,
3241 // both double- and quad-register.
3242 class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3243               string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
3244               SDPatternOperator IntOp>
3245   : N2VImm<op24, op23, op11_8, op7, 0, op4,
3246            (outs DPR:$Vd), (ins DPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,
3247            IIC_VUNAD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3248            [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (i32 imm:$SIMM))))]>;
3249 class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3250               string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
3251               SDPatternOperator IntOp>
3252   : N2VImm<op24, op23, op11_8, op7, 1, op4,
3253            (outs QPR:$Vd), (ins QPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,
3254            IIC_VUNAQ, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3255            [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (i32 imm:$SIMM))))]>;
3256
3257 //===----------------------------------------------------------------------===//
3258 // Multiclasses
3259 //===----------------------------------------------------------------------===//
3260
3261 // Abbreviations used in multiclass suffixes:
3262 //   Q = quarter int (8 bit) elements
3263 //   H = half int (16 bit) elements
3264 //   S = single int (32 bit) elements
3265 //   D = double int (64 bit) elements
3266
3267 // Neon 2-register vector operations and intrinsics.
3268
3269 // Neon 2-register comparisons.
3270 //   source operand element sizes of 8, 16 and 32 bits:
3271 multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3272                        bits<5> op11_7, bit op4, string opc, string Dt,
3273                        string asm, SDNode OpNode> {
3274   // 64-bit vector types.
3275   def v8i8  : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4,
3276                   (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3277                   opc, !strconcat(Dt, "8"), asm, "",
3278                   [(set DPR:$Vd, (v8i8 (OpNode (v8i8 DPR:$Vm))))]>;
3279   def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,
3280                   (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3281                   opc, !strconcat(Dt, "16"), asm, "",
3282                   [(set DPR:$Vd, (v4i16 (OpNode (v4i16 DPR:$Vm))))]>;
3283   def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
3284                   (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3285                   opc, !strconcat(Dt, "32"), asm, "",
3286                   [(set DPR:$Vd, (v2i32 (OpNode (v2i32 DPR:$Vm))))]>;
3287   def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
3288                   (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3289                   opc, "f32", asm, "",
3290                   [(set DPR:$Vd, (v2i32 (OpNode (v2f32 DPR:$Vm))))]> {
3291     let Inst{10} = 1; // overwrite F = 1
3292   }
3293   def v4f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,
3294                   (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3295                   opc, "f16", asm, "",
3296                   [(set DPR:$Vd, (v4i16 (OpNode (v4f16 DPR:$Vm))))]>,
3297               Requires<[HasNEON,HasFullFP16]> {
3298     let Inst{10} = 1; // overwrite F = 1
3299   }
3300
3301   // 128-bit vector types.
3302   def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4,
3303                   (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3304                   opc, !strconcat(Dt, "8"), asm, "",
3305                   [(set QPR:$Vd, (v16i8 (OpNode (v16i8 QPR:$Vm))))]>;
3306   def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,
3307                   (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3308                   opc, !strconcat(Dt, "16"), asm, "",
3309                   [(set QPR:$Vd, (v8i16 (OpNode (v8i16 QPR:$Vm))))]>;
3310   def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
3311                   (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3312                   opc, !strconcat(Dt, "32"), asm, "",
3313                   [(set QPR:$Vd, (v4i32 (OpNode (v4i32 QPR:$Vm))))]>;
3314   def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
3315                   (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3316                   opc, "f32", asm, "",
3317                   [(set QPR:$Vd, (v4i32 (OpNode (v4f32 QPR:$Vm))))]> {
3318     let Inst{10} = 1; // overwrite F = 1
3319   }
3320   def v8f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,
3321                   (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3322                   opc, "f16", asm, "",
3323                   [(set QPR:$Vd, (v8i16 (OpNode (v8f16 QPR:$Vm))))]>,
3324               Requires<[HasNEON,HasFullFP16]> {
3325     let Inst{10} = 1; // overwrite F = 1
3326   }
3327 }
3328
3329
3330 // Neon 2-register vector intrinsics,
3331 //   element sizes of 8, 16 and 32 bits:
3332 multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3333                       bits<5> op11_7, bit op4,
3334                       InstrItinClass itinD, InstrItinClass itinQ,
3335                       string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3336   // 64-bit vector types.
3337   def v8i8  : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3338                       itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
3339   def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3340                       itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>;
3341   def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3342                       itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>;
3343
3344   // 128-bit vector types.
3345   def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3346                       itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>;
3347   def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3348                       itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>;
3349   def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3350                       itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>;
3351 }
3352
3353
3354 // Neon Narrowing 2-register vector operations,
3355 //   source operand element sizes of 16, 32 and 64 bits:
3356 multiclass N2VN_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3357                     bits<5> op11_7, bit op6, bit op4,
3358                     InstrItinClass itin, string OpcodeStr, string Dt,
3359                     SDNode OpNode> {
3360   def v8i8  : N2VN<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,
3361                    itin, OpcodeStr, !strconcat(Dt, "16"),
3362                    v8i8, v8i16, OpNode>;
3363   def v4i16 : N2VN<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,
3364                    itin, OpcodeStr, !strconcat(Dt, "32"),
3365                    v4i16, v4i32, OpNode>;
3366   def v2i32 : N2VN<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,
3367                    itin, OpcodeStr, !strconcat(Dt, "64"),
3368                    v2i32, v2i64, OpNode>;
3369 }
3370
3371 // Neon Narrowing 2-register vector intrinsics,
3372 //   source operand element sizes of 16, 32 and 64 bits:
3373 multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3374                        bits<5> op11_7, bit op6, bit op4,
3375                        InstrItinClass itin, string OpcodeStr, string Dt,
3376                        SDPatternOperator IntOp> {
3377   def v8i8  : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,
3378                       itin, OpcodeStr, !strconcat(Dt, "16"),
3379                       v8i8, v8i16, IntOp>;
3380   def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,
3381                       itin, OpcodeStr, !strconcat(Dt, "32"),
3382                       v4i16, v4i32, IntOp>;
3383   def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,
3384                       itin, OpcodeStr, !strconcat(Dt, "64"),
3385                       v2i32, v2i64, IntOp>;
3386 }
3387
3388
3389 // Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL).
3390 //   source operand element sizes of 16, 32 and 64 bits:
3391 multiclass N2VL_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4,
3392                     string OpcodeStr, string Dt, SDNode OpNode> {
3393   def v8i16 : N2VL<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3394                    OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode>;
3395   def v4i32 : N2VL<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3396                    OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;
3397   def v2i64 : N2VL<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3398                    OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;
3399 }
3400
3401
3402 // Neon 3-register vector operations.
3403
3404 // First with only element sizes of 8, 16 and 32 bits:
3405 multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3406                    InstrItinClass itinD16, InstrItinClass itinD32,
3407                    InstrItinClass itinQ16, InstrItinClass itinQ32,
3408                    string OpcodeStr, string Dt,
3409                    SDNode OpNode, bit Commutable = 0> {
3410   // 64-bit vector types.
3411   def v8i8  : N3VD<op24, op23, 0b00, op11_8, op4, itinD16,
3412                    OpcodeStr, !strconcat(Dt, "8"),
3413                    v8i8, v8i8, OpNode, Commutable>;
3414   def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16,
3415                    OpcodeStr, !strconcat(Dt, "16"),
3416                    v4i16, v4i16, OpNode, Commutable>;
3417   def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32,
3418                    OpcodeStr, !strconcat(Dt, "32"),
3419                    v2i32, v2i32, OpNode, Commutable>;
3420
3421   // 128-bit vector types.
3422   def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16,
3423                    OpcodeStr, !strconcat(Dt, "8"),
3424                    v16i8, v16i8, OpNode, Commutable>;
3425   def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16,
3426                    OpcodeStr, !strconcat(Dt, "16"),
3427                    v8i16, v8i16, OpNode, Commutable>;
3428   def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32,
3429                    OpcodeStr, !strconcat(Dt, "32"),
3430                    v4i32, v4i32, OpNode, Commutable>;
3431 }
3432
3433 multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, SDNode ShOp> {
3434   def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, "i16", v4i16, ShOp>;
3435   def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, "i32", v2i32, ShOp>;
3436   def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, "i16", v8i16, v4i16, ShOp>;
3437   def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, "i32",
3438                      v4i32, v2i32, ShOp>;
3439 }
3440
3441 // ....then also with element size 64 bits:
3442 multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3443                     InstrItinClass itinD, InstrItinClass itinQ,
3444                     string OpcodeStr, string Dt,
3445                     SDNode OpNode, bit Commutable = 0>
3446   : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ,
3447             OpcodeStr, Dt, OpNode, Commutable> {
3448   def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD,
3449                    OpcodeStr, !strconcat(Dt, "64"),
3450                    v1i64, v1i64, OpNode, Commutable>;
3451   def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ,
3452                    OpcodeStr, !strconcat(Dt, "64"),
3453                    v2i64, v2i64, OpNode, Commutable>;
3454 }
3455
3456
3457 // Neon 3-register vector intrinsics.
3458
3459 // First with only element sizes of 16 and 32 bits:
3460 multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3461                      InstrItinClass itinD16, InstrItinClass itinD32,
3462                      InstrItinClass itinQ16, InstrItinClass itinQ32,
3463                      string OpcodeStr, string Dt,
3464                      SDPatternOperator IntOp, bit Commutable = 0> {
3465   // 64-bit vector types.
3466   def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, f, itinD16,
3467                       OpcodeStr, !strconcat(Dt, "16"),
3468                       v4i16, v4i16, IntOp, Commutable>;
3469   def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, f, itinD32,
3470                       OpcodeStr, !strconcat(Dt, "32"),
3471                       v2i32, v2i32, IntOp, Commutable>;
3472
3473   // 128-bit vector types.
3474   def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, f, itinQ16,
3475                       OpcodeStr, !strconcat(Dt, "16"),
3476                       v8i16, v8i16, IntOp, Commutable>;
3477   def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, f, itinQ32,
3478                       OpcodeStr, !strconcat(Dt, "32"),
3479                       v4i32, v4i32, IntOp, Commutable>;
3480 }
3481 multiclass N3VInt_HSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3482                      InstrItinClass itinD16, InstrItinClass itinD32,
3483                      InstrItinClass itinQ16, InstrItinClass itinQ32,
3484                      string OpcodeStr, string Dt,
3485                      SDPatternOperator IntOp> {
3486   // 64-bit vector types.
3487   def v4i16 : N3VDIntSh<op24, op23, 0b01, op11_8, op4, f, itinD16,
3488                       OpcodeStr, !strconcat(Dt, "16"),
3489                       v4i16, v4i16, IntOp>;
3490   def v2i32 : N3VDIntSh<op24, op23, 0b10, op11_8, op4, f, itinD32,
3491                       OpcodeStr, !strconcat(Dt, "32"),
3492                       v2i32, v2i32, IntOp>;
3493
3494   // 128-bit vector types.
3495   def v8i16 : N3VQIntSh<op24, op23, 0b01, op11_8, op4, f, itinQ16,
3496                       OpcodeStr, !strconcat(Dt, "16"),
3497                       v8i16, v8i16, IntOp>;
3498   def v4i32 : N3VQIntSh<op24, op23, 0b10, op11_8, op4, f, itinQ32,
3499                       OpcodeStr, !strconcat(Dt, "32"),
3500                       v4i32, v4i32, IntOp>;
3501 }
3502
3503 multiclass N3VIntSL_HS<bits<4> op11_8,
3504                        InstrItinClass itinD16, InstrItinClass itinD32,
3505                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3506                        string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3507   def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16,
3508                           OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>;
3509   def v2i32 : N3VDIntSL<0b10, op11_8, itinD32,
3510                         OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>;
3511   def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16,
3512                           OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;
3513   def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32,
3514                         OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>;
3515 }
3516
3517 // ....then also with element size of 8 bits:
3518 multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3519                       InstrItinClass itinD16, InstrItinClass itinD32,
3520                       InstrItinClass itinQ16, InstrItinClass itinQ32,
3521                       string OpcodeStr, string Dt,
3522                       SDPatternOperator IntOp, bit Commutable = 0>
3523   : N3VInt_HS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3524               OpcodeStr, Dt, IntOp, Commutable> {
3525   def v8i8  : N3VDInt<op24, op23, 0b00, op11_8, op4, f, itinD16,
3526                       OpcodeStr, !strconcat(Dt, "8"),
3527                       v8i8, v8i8, IntOp, Commutable>;
3528   def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, f, itinQ16,
3529                       OpcodeStr, !strconcat(Dt, "8"),
3530                       v16i8, v16i8, IntOp, Commutable>;
3531 }
3532 multiclass N3VInt_QHSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3533                       InstrItinClass itinD16, InstrItinClass itinD32,
3534                       InstrItinClass itinQ16, InstrItinClass itinQ32,
3535                       string OpcodeStr, string Dt,
3536                       SDPatternOperator IntOp>
3537   : N3VInt_HSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3538               OpcodeStr, Dt, IntOp> {
3539   def v8i8  : N3VDIntSh<op24, op23, 0b00, op11_8, op4, f, itinD16,
3540                       OpcodeStr, !strconcat(Dt, "8"),
3541                       v8i8, v8i8, IntOp>;
3542   def v16i8 : N3VQIntSh<op24, op23, 0b00, op11_8, op4, f, itinQ16,
3543                       OpcodeStr, !strconcat(Dt, "8"),
3544                       v16i8, v16i8, IntOp>;
3545 }
3546
3547
3548 // ....then also with element size of 64 bits:
3549 multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3550                        InstrItinClass itinD16, InstrItinClass itinD32,
3551                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3552                        string OpcodeStr, string Dt,
3553                        SDPatternOperator IntOp, bit Commutable = 0>
3554   : N3VInt_QHS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3555                OpcodeStr, Dt, IntOp, Commutable> {
3556   def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, f, itinD32,
3557                       OpcodeStr, !strconcat(Dt, "64"),
3558                       v1i64, v1i64, IntOp, Commutable>;
3559   def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, f, itinQ32,
3560                       OpcodeStr, !strconcat(Dt, "64"),
3561                       v2i64, v2i64, IntOp, Commutable>;
3562 }
3563 multiclass N3VInt_QHSDSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3564                        InstrItinClass itinD16, InstrItinClass itinD32,
3565                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3566                        string OpcodeStr, string Dt,
3567                        SDPatternOperator IntOp>
3568   : N3VInt_QHSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3569                OpcodeStr, Dt, IntOp> {
3570   def v1i64 : N3VDIntSh<op24, op23, 0b11, op11_8, op4, f, itinD32,
3571                       OpcodeStr, !strconcat(Dt, "64"),
3572                       v1i64, v1i64, IntOp>;
3573   def v2i64 : N3VQIntSh<op24, op23, 0b11, op11_8, op4, f, itinQ32,
3574                       OpcodeStr, !strconcat(Dt, "64"),
3575                       v2i64, v2i64, IntOp>;
3576 }
3577
3578 // Neon Narrowing 3-register vector intrinsics,
3579 //   source operand element sizes of 16, 32 and 64 bits:
3580 multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3581                        string OpcodeStr, string Dt,
3582                        SDPatternOperator IntOp, bit Commutable = 0> {
3583   def v8i8  : N3VNInt<op24, op23, 0b00, op11_8, op4,
3584                       OpcodeStr, !strconcat(Dt, "16"),
3585                       v8i8, v8i16, IntOp, Commutable>;
3586   def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4,
3587                       OpcodeStr, !strconcat(Dt, "32"),
3588                       v4i16, v4i32, IntOp, Commutable>;
3589   def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4,
3590                       OpcodeStr, !strconcat(Dt, "64"),
3591                       v2i32, v2i64, IntOp, Commutable>;
3592 }
3593
3594
3595 // Neon Long 3-register vector operations.
3596
3597 multiclass N3VL_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3598                     InstrItinClass itin16, InstrItinClass itin32,
3599                     string OpcodeStr, string Dt,
3600                     SDNode OpNode, bit Commutable = 0> {
3601   def v8i16 : N3VL<op24, op23, 0b00, op11_8, op4, itin16,
3602                    OpcodeStr, !strconcat(Dt, "8"),
3603                    v8i16, v8i8, OpNode, Commutable>;
3604   def v4i32 : N3VL<op24, op23, 0b01, op11_8, op4, itin16,
3605                    OpcodeStr, !strconcat(Dt, "16"),
3606                    v4i32, v4i16, OpNode, Commutable>;
3607   def v2i64 : N3VL<op24, op23, 0b10, op11_8, op4, itin32,
3608                    OpcodeStr, !strconcat(Dt, "32"),
3609                    v2i64, v2i32, OpNode, Commutable>;
3610 }
3611
3612 multiclass N3VLSL_HS<bit op24, bits<4> op11_8,
3613                      InstrItinClass itin, string OpcodeStr, string Dt,
3614                      SDNode OpNode> {
3615   def v4i16 : N3VLSL16<op24, 0b01, op11_8, itin, OpcodeStr,
3616                        !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;
3617   def v2i32 : N3VLSL<op24, 0b10, op11_8, itin, OpcodeStr,
3618                      !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;
3619 }
3620
3621 multiclass N3VLExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3622                        InstrItinClass itin16, InstrItinClass itin32,
3623                        string OpcodeStr, string Dt,
3624                        SDNode OpNode, SDNode ExtOp, bit Commutable = 0> {
3625   def v8i16 : N3VLExt<op24, op23, 0b00, op11_8, op4, itin16,
3626                       OpcodeStr, !strconcat(Dt, "8"),
3627                       v8i16, v8i8, OpNode, ExtOp, Commutable>;
3628   def v4i32 : N3VLExt<op24, op23, 0b01, op11_8, op4, itin16,
3629                       OpcodeStr, !strconcat(Dt, "16"),
3630                       v4i32, v4i16, OpNode, ExtOp, Commutable>;
3631   def v2i64 : N3VLExt<op24, op23, 0b10, op11_8, op4, itin32,
3632                       OpcodeStr, !strconcat(Dt, "32"),
3633                       v2i64, v2i32, OpNode, ExtOp, Commutable>;
3634 }
3635
3636 // Neon Long 3-register vector intrinsics.
3637
3638 // First with only element sizes of 16 and 32 bits:
3639 multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
3640                       InstrItinClass itin16, InstrItinClass itin32,
3641                       string OpcodeStr, string Dt,
3642                       SDPatternOperator IntOp, bit Commutable = 0> {
3643   def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin16,
3644                       OpcodeStr, !strconcat(Dt, "16"),
3645                       v4i32, v4i16, IntOp, Commutable>;
3646   def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin32,
3647                       OpcodeStr, !strconcat(Dt, "32"),
3648                       v2i64, v2i32, IntOp, Commutable>;
3649 }
3650
3651 multiclass N3VLIntSL_HS<bit op24, bits<4> op11_8,
3652                         InstrItinClass itin, string OpcodeStr, string Dt,
3653                         SDPatternOperator IntOp> {
3654   def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin,
3655                           OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
3656   def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin,
3657                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3658 }
3659
3660 // ....then also with element size of 8 bits:
3661 multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3662                        InstrItinClass itin16, InstrItinClass itin32,
3663                        string OpcodeStr, string Dt,
3664                        SDPatternOperator IntOp, bit Commutable = 0>
3665   : N3VLInt_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt,
3666                IntOp, Commutable> {
3667   def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin16,
3668                       OpcodeStr, !strconcat(Dt, "8"),
3669                       v8i16, v8i8, IntOp, Commutable>;
3670 }
3671
3672 // ....with explicit extend (VABDL).
3673 multiclass N3VLIntExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3674                        InstrItinClass itin, string OpcodeStr, string Dt,
3675                        SDPatternOperator IntOp, SDNode ExtOp, bit Commutable = 0> {
3676   def v8i16 : N3VLIntExt<op24, op23, 0b00, op11_8, op4, itin,
3677                          OpcodeStr, !strconcat(Dt, "8"),
3678                          v8i16, v8i8, IntOp, ExtOp, Commutable>;
3679   def v4i32 : N3VLIntExt<op24, op23, 0b01, op11_8, op4, itin,
3680                          OpcodeStr, !strconcat(Dt, "16"),
3681                          v4i32, v4i16, IntOp, ExtOp, Commutable>;
3682   def v2i64 : N3VLIntExt<op24, op23, 0b10, op11_8, op4, itin,
3683                          OpcodeStr, !strconcat(Dt, "32"),
3684                          v2i64, v2i32, IntOp, ExtOp, Commutable>;
3685 }
3686
3687
3688 // Neon Wide 3-register vector intrinsics,
3689 //   source operand element sizes of 8, 16 and 32 bits:
3690 multiclass N3VW_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3691                     string OpcodeStr, string Dt,
3692                     SDNode OpNode, SDNode ExtOp, bit Commutable = 0> {
3693   def v8i16 : N3VW<op24, op23, 0b00, op11_8, op4,
3694                    OpcodeStr, !strconcat(Dt, "8"),
3695                    v8i16, v8i8, OpNode, ExtOp, Commutable>;
3696   def v4i32 : N3VW<op24, op23, 0b01, op11_8, op4,
3697                    OpcodeStr, !strconcat(Dt, "16"),
3698                    v4i32, v4i16, OpNode, ExtOp, Commutable>;
3699   def v2i64 : N3VW<op24, op23, 0b10, op11_8, op4,
3700                    OpcodeStr, !strconcat(Dt, "32"),
3701                    v2i64, v2i32, OpNode, ExtOp, Commutable>;
3702 }
3703
3704
3705 // Neon Multiply-Op vector operations,
3706 //   element sizes of 8, 16 and 32 bits:
3707 multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3708                         InstrItinClass itinD16, InstrItinClass itinD32,
3709                         InstrItinClass itinQ16, InstrItinClass itinQ32,
3710                         string OpcodeStr, string Dt, SDNode OpNode> {
3711   // 64-bit vector types.
3712   def v8i8  : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16,
3713                         OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>;
3714   def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16,
3715                         OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>;
3716   def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32,
3717                         OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>;
3718
3719   // 128-bit vector types.
3720   def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16,
3721                         OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>;
3722   def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16,
3723                         OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>;
3724   def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32,
3725                         OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>;
3726 }
3727
3728 multiclass N3VMulOpSL_HS<bits<4> op11_8,
3729                          InstrItinClass itinD16, InstrItinClass itinD32,
3730                          InstrItinClass itinQ16, InstrItinClass itinQ32,
3731                          string OpcodeStr, string Dt, SDPatternOperator ShOp> {
3732   def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16,
3733                             OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>;
3734   def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,
3735                           OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>;
3736   def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16,
3737                             OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16,
3738                             mul, ShOp>;
3739   def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32,
3740                           OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32,
3741                           mul, ShOp>;
3742 }
3743
3744 // Neon Intrinsic-Op vector operations,
3745 //   element sizes of 8, 16 and 32 bits:
3746 multiclass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3747                         InstrItinClass itinD, InstrItinClass itinQ,
3748                         string OpcodeStr, string Dt, SDPatternOperator IntOp,
3749                         SDNode OpNode> {
3750   // 64-bit vector types.
3751   def v8i8  : N3VDIntOp<op24, op23, 0b00, op11_8, op4, itinD,
3752                         OpcodeStr, !strconcat(Dt, "8"), v8i8, IntOp, OpNode>;
3753   def v4i16 : N3VDIntOp<op24, op23, 0b01, op11_8, op4, itinD,
3754                         OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp, OpNode>;
3755   def v2i32 : N3VDIntOp<op24, op23, 0b10, op11_8, op4, itinD,
3756                         OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp, OpNode>;
3757
3758   // 128-bit vector types.
3759   def v16i8 : N3VQIntOp<op24, op23, 0b00, op11_8, op4, itinQ,
3760                         OpcodeStr, !strconcat(Dt, "8"), v16i8, IntOp, OpNode>;
3761   def v8i16 : N3VQIntOp<op24, op23, 0b01, op11_8, op4, itinQ,
3762                         OpcodeStr, !strconcat(Dt, "16"), v8i16, IntOp, OpNode>;
3763   def v4i32 : N3VQIntOp<op24, op23, 0b10, op11_8, op4, itinQ,
3764                         OpcodeStr, !strconcat(Dt, "32"), v4i32, IntOp, OpNode>;
3765 }
3766
3767 // Neon 3-argument intrinsics,
3768 //   element sizes of 16 and 32 bits:
3769 multiclass N3VInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
3770                        InstrItinClass itinD16, InstrItinClass itinD32,
3771                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3772                        string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3773   // 64-bit vector types.
3774   def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD16,
3775                        OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
3776   def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD32,
3777                        OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
3778
3779   // 128-bit vector types.
3780   def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ16,
3781                        OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
3782   def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ32,
3783                        OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
3784 }
3785
3786 //   element sizes of 8, 16 and 32 bits:
3787 multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3788                        InstrItinClass itinD16, InstrItinClass itinD32,
3789                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3790                        string OpcodeStr, string Dt, SDPatternOperator IntOp>
3791            :N3VInt3_HS <op24, op23, op11_8, op4, itinD16, itinD32,
3792                         itinQ16, itinQ32, OpcodeStr, Dt, IntOp>{
3793   // 64-bit vector types.
3794   def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD16,
3795                        OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
3796   // 128-bit vector types.
3797   def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ16,
3798                        OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
3799 }
3800
3801 // Neon Long Multiply-Op vector operations,
3802 //   element sizes of 8, 16 and 32 bits:
3803 multiclass N3VLMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3804                          InstrItinClass itin16, InstrItinClass itin32,
3805                          string OpcodeStr, string Dt, SDNode MulOp,
3806                          SDNode OpNode> {
3807   def v8i16 : N3VLMulOp<op24, op23, 0b00, op11_8, op4, itin16, OpcodeStr,
3808                         !strconcat(Dt, "8"), v8i16, v8i8, MulOp, OpNode>;
3809   def v4i32 : N3VLMulOp<op24, op23, 0b01, op11_8, op4, itin16, OpcodeStr,
3810                         !strconcat(Dt, "16"), v4i32, v4i16, MulOp, OpNode>;
3811   def v2i64 : N3VLMulOp<op24, op23, 0b10, op11_8, op4, itin32, OpcodeStr,
3812                         !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;
3813 }
3814
3815 multiclass N3VLMulOpSL_HS<bit op24, bits<4> op11_8, string OpcodeStr,
3816                           string Dt, SDNode MulOp, SDNode OpNode> {
3817   def v4i16 : N3VLMulOpSL16<op24, 0b01, op11_8, IIC_VMACi16D, OpcodeStr,
3818                             !strconcat(Dt,"16"), v4i32, v4i16, MulOp, OpNode>;
3819   def v2i32 : N3VLMulOpSL<op24, 0b10, op11_8, IIC_VMACi32D, OpcodeStr,
3820                           !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;
3821 }
3822
3823
3824 // Neon Long 3-argument intrinsics.
3825
3826 // First with only element sizes of 16 and 32 bits:
3827 multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
3828                        InstrItinClass itin16, InstrItinClass itin32,
3829                        string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3830   def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, itin16,
3831                        OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
3832   def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, itin32,
3833                        OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3834 }
3835
3836 multiclass N3VLInt3SL_HS<bit op24, bits<4> op11_8,
3837                          string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3838   def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D,
3839                            OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>;
3840   def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D,
3841                          OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3842 }
3843
3844 // ....then also with element size of 8 bits:
3845 multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3846                         InstrItinClass itin16, InstrItinClass itin32,
3847                         string OpcodeStr, string Dt, SDPatternOperator IntOp>
3848   : N3VLInt3_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, IntOp> {
3849   def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, itin16,
3850                        OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>;
3851 }
3852
3853 // ....with explicit extend (VABAL).
3854 multiclass N3VLIntExtOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3855                             InstrItinClass itin, string OpcodeStr, string Dt,
3856                             SDPatternOperator IntOp, SDNode ExtOp, SDNode OpNode> {
3857   def v8i16 : N3VLIntExtOp<op24, op23, 0b00, op11_8, op4, itin,
3858                            OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8,
3859                            IntOp, ExtOp, OpNode>;
3860   def v4i32 : N3VLIntExtOp<op24, op23, 0b01, op11_8, op4, itin,
3861                            OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16,
3862                            IntOp, ExtOp, OpNode>;
3863   def v2i64 : N3VLIntExtOp<op24, op23, 0b10, op11_8, op4, itin,
3864                            OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32,
3865                            IntOp, ExtOp, OpNode>;
3866 }
3867
3868
3869 // Neon Pairwise long 2-register intrinsics,
3870 //   element sizes of 8, 16 and 32 bits:
3871 multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3872                         bits<5> op11_7, bit op4,
3873                         string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3874   // 64-bit vector types.
3875   def v8i8  : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3876                         OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
3877   def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3878                         OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
3879   def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3880                         OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
3881
3882   // 128-bit vector types.
3883   def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3884                         OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
3885   def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3886                         OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
3887   def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3888                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
3889 }
3890
3891
3892 // Neon Pairwise long 2-register accumulate intrinsics,
3893 //   element sizes of 8, 16 and 32 bits:
3894 multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3895                          bits<5> op11_7, bit op4,
3896                          string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3897   // 64-bit vector types.
3898   def v8i8  : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3899                          OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
3900   def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3901                          OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
3902   def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3903                          OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
3904
3905   // 128-bit vector types.
3906   def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3907                          OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
3908   def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3909                          OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
3910   def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3911                          OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
3912 }
3913
3914
3915 // Neon 2-register vector shift by immediate,
3916 //   with f of either N2RegVShLFrm or N2RegVShRFrm
3917 //   element sizes of 8, 16, 32 and 64 bits:
3918 multiclass N2VShL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3919                        InstrItinClass itin, string OpcodeStr, string Dt,
3920                        SDNode OpNode> {
3921   // 64-bit vector types.
3922   def v8i8  : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3923                      OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
3924     let Inst{21-19} = 0b001; // imm6 = 001xxx
3925   }
3926   def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3927                      OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
3928     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3929   }
3930   def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3931                      OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
3932     let Inst{21} = 0b1;      // imm6 = 1xxxxx
3933   }
3934   def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,
3935                      OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
3936                              // imm6 = xxxxxx
3937
3938   // 128-bit vector types.
3939   def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3940                      OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
3941     let Inst{21-19} = 0b001; // imm6 = 001xxx
3942   }
3943   def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3944                      OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
3945     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3946   }
3947   def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3948                      OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
3949     let Inst{21} = 0b1;      // imm6 = 1xxxxx
3950   }
3951   def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,
3952                      OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
3953                              // imm6 = xxxxxx
3954 }
3955 multiclass N2VShR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3956                        InstrItinClass itin, string OpcodeStr, string Dt,
3957                        string baseOpc, SDNode OpNode> {
3958   // 64-bit vector types.
3959   def v8i8  : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,
3960                      OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
3961     let Inst{21-19} = 0b001; // imm6 = 001xxx
3962   }
3963   def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,
3964                      OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
3965     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3966   }
3967   def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,
3968                      OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
3969     let Inst{21} = 0b1;      // imm6 = 1xxxxx
3970   }
3971   def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,
3972                      OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
3973                              // imm6 = xxxxxx
3974
3975   // 128-bit vector types.
3976   def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,
3977                      OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
3978     let Inst{21-19} = 0b001; // imm6 = 001xxx
3979   }
3980   def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,
3981                      OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
3982     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3983   }
3984   def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,
3985                      OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
3986     let Inst{21} = 0b1;      // imm6 = 1xxxxx
3987   }
3988   def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,
3989                      OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
3990                              // imm6 = xxxxxx
3991 }
3992
3993 // Neon Shift-Accumulate vector operations,
3994 //   element sizes of 8, 16, 32 and 64 bits:
3995 multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3996                          string OpcodeStr, string Dt, SDNode ShOp> {
3997   // 64-bit vector types.
3998   def v8i8  : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm8,
3999                         OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> {
4000     let Inst{21-19} = 0b001; // imm6 = 001xxx
4001   }
4002   def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm16,
4003                         OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> {
4004     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4005   }
4006   def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm32,
4007                         OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> {
4008     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4009   }
4010   def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4, shr_imm64,
4011                         OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>;
4012                              // imm6 = xxxxxx
4013
4014   // 128-bit vector types.
4015   def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm8,
4016                         OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> {
4017     let Inst{21-19} = 0b001; // imm6 = 001xxx
4018   }
4019   def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm16,
4020                         OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> {
4021     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4022   }
4023   def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm32,
4024                         OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> {
4025     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4026   }
4027   def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4, shr_imm64,
4028                         OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>;
4029                              // imm6 = xxxxxx
4030 }
4031
4032 // Neon Shift-Insert vector operations,
4033 //   with f of either N2RegVShLFrm or N2RegVShRFrm
4034 //   element sizes of 8, 16, 32 and 64 bits:
4035 multiclass N2VShInsL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
4036                           string OpcodeStr> {
4037   // 64-bit vector types.
4038   def v8i8  : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
4039                         N2RegVShLFrm, OpcodeStr, "8", v8i8, NEONvsli> {
4040     let Inst{21-19} = 0b001; // imm6 = 001xxx
4041   }
4042   def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
4043                         N2RegVShLFrm, OpcodeStr, "16", v4i16, NEONvsli> {
4044     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4045   }
4046   def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
4047                         N2RegVShLFrm, OpcodeStr, "32", v2i32, NEONvsli> {
4048     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4049   }
4050   def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, i32imm,
4051                         N2RegVShLFrm, OpcodeStr, "64", v1i64, NEONvsli>;
4052                              // imm6 = xxxxxx
4053
4054   // 128-bit vector types.
4055   def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
4056                         N2RegVShLFrm, OpcodeStr, "8", v16i8, NEONvsli> {
4057     let Inst{21-19} = 0b001; // imm6 = 001xxx
4058   }
4059   def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
4060                         N2RegVShLFrm, OpcodeStr, "16", v8i16, NEONvsli> {
4061     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4062   }
4063   def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
4064                         N2RegVShLFrm, OpcodeStr, "32", v4i32, NEONvsli> {
4065     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4066   }
4067   def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, i32imm,
4068                         N2RegVShLFrm, OpcodeStr, "64", v2i64, NEONvsli>;
4069                              // imm6 = xxxxxx
4070 }
4071 multiclass N2VShInsR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
4072                           string OpcodeStr> {
4073   // 64-bit vector types.
4074   def v8i8  : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm8,
4075                         N2RegVShRFrm, OpcodeStr, "8", v8i8, NEONvsri> {
4076     let Inst{21-19} = 0b001; // imm6 = 001xxx
4077   }
4078   def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm16,
4079                         N2RegVShRFrm, OpcodeStr, "16", v4i16, NEONvsri> {
4080     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4081   }
4082   def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm32,
4083                         N2RegVShRFrm, OpcodeStr, "32", v2i32, NEONvsri> {
4084     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4085   }
4086   def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, shr_imm64,
4087                         N2RegVShRFrm, OpcodeStr, "64", v1i64, NEONvsri>;
4088                              // imm6 = xxxxxx
4089
4090   // 128-bit vector types.
4091   def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm8,
4092                         N2RegVShRFrm, OpcodeStr, "8", v16i8, NEONvsri> {
4093     let Inst{21-19} = 0b001; // imm6 = 001xxx
4094   }
4095   def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm16,
4096                         N2RegVShRFrm, OpcodeStr, "16", v8i16, NEONvsri> {
4097     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4098   }
4099   def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm32,
4100                         N2RegVShRFrm, OpcodeStr, "32", v4i32, NEONvsri> {
4101     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4102   }
4103   def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, shr_imm64,
4104                         N2RegVShRFrm, OpcodeStr, "64", v2i64, NEONvsri>;
4105                              // imm6 = xxxxxx
4106 }
4107
4108 // Neon Shift Long operations,
4109 //   element sizes of 8, 16, 32 bits:
4110 multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
4111                       bit op4, string OpcodeStr, string Dt,
4112                       SDPatternOperator OpNode> {
4113   def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
4114               OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, imm1_7, OpNode> {
4115     let Inst{21-19} = 0b001; // imm6 = 001xxx
4116   }
4117   def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
4118                OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, imm1_15, OpNode> {
4119     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4120   }
4121   def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
4122                OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, imm1_31, OpNode> {
4123     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4124   }
4125 }
4126
4127 // Neon Shift Narrow operations,
4128 //   element sizes of 16, 32, 64 bits:
4129 multiclass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
4130                       bit op4, InstrItinClass itin, string OpcodeStr, string Dt,
4131                       SDPatternOperator OpNode> {
4132   def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
4133                     OpcodeStr, !strconcat(Dt, "16"),
4134                     v8i8, v8i16, shr_imm8, OpNode> {
4135     let Inst{21-19} = 0b001; // imm6 = 001xxx
4136   }
4137   def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
4138                      OpcodeStr, !strconcat(Dt, "32"),
4139                      v4i16, v4i32, shr_imm16, OpNode> {
4140     let Inst{21-20} = 0b01;  // imm6 = 01xxxx
4141   }
4142   def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
4143                      OpcodeStr, !strconcat(Dt, "64"),
4144                      v2i32, v2i64, shr_imm32, OpNode> {
4145     let Inst{21} = 0b1;      // imm6 = 1xxxxx
4146   }
4147 }
4148
4149 //===----------------------------------------------------------------------===//
4150 // Instruction Definitions.
4151 //===----------------------------------------------------------------------===//
4152
4153 // Vector Add Operations.
4154
4155 //   VADD     : Vector Add (integer and floating-point)
4156 defm VADD     : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i",
4157                          add, 1>;
4158 def  VADDfd   : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32",
4159                      v2f32, v2f32, fadd, 1>;
4160 def  VADDfq   : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32",
4161                      v4f32, v4f32, fadd, 1>;
4162 def  VADDhd   : N3VD<0, 0, 0b01, 0b1101, 0, IIC_VBIND, "vadd", "f16",
4163                      v4f16, v4f16, fadd, 1>,
4164                 Requires<[HasNEON,HasFullFP16]>;
4165 def  VADDhq   : N3VQ<0, 0, 0b01, 0b1101, 0, IIC_VBINQ, "vadd", "f16",
4166                      v8f16, v8f16, fadd, 1>,
4167                 Requires<[HasNEON,HasFullFP16]>;
4168 //   VADDL    : Vector Add Long (Q = D + D)
4169 defm VADDLs   : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
4170                             "vaddl", "s", add, sext, 1>;
4171 defm VADDLu   : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
4172                             "vaddl", "u", add, zext, 1>;
4173 //   VADDW    : Vector Add Wide (Q = Q + D)
4174 defm VADDWs   : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>;
4175 defm VADDWu   : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zext, 0>;
4176 //   VHADD    : Vector Halving Add
4177 defm VHADDs   : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm,
4178                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4179                            "vhadd", "s", int_arm_neon_vhadds, 1>;
4180 defm VHADDu   : N3VInt_QHS<1, 0, 0b0000, 0, N3RegFrm,
4181                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4182                            "vhadd", "u", int_arm_neon_vhaddu, 1>;
4183 //   VRHADD   : Vector Rounding Halving Add
4184 defm VRHADDs  : N3VInt_QHS<0, 0, 0b0001, 0, N3RegFrm,
4185                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4186                            "vrhadd", "s", int_arm_neon_vrhadds, 1>;
4187 defm VRHADDu  : N3VInt_QHS<1, 0, 0b0001, 0, N3RegFrm,
4188                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4189                            "vrhadd", "u", int_arm_neon_vrhaddu, 1>;
4190 //   VQADD    : Vector Saturating Add
4191 defm VQADDs   : N3VInt_QHSD<0, 0, 0b0000, 1, N3RegFrm,
4192                             IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4193                             "vqadd", "s", int_arm_neon_vqadds, 1>;
4194 defm VQADDu   : N3VInt_QHSD<1, 0, 0b0000, 1, N3RegFrm,
4195                             IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4196                             "vqadd", "u", int_arm_neon_vqaddu, 1>;
4197 //   VADDHN   : Vector Add and Narrow Returning High Half (D = Q + Q)
4198 defm VADDHN   : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i", null_frag, 1>;
4199 //   VRADDHN  : Vector Rounding Add and Narrow Returning High Half (D = Q + Q)
4200 defm VRADDHN  : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i",
4201                             int_arm_neon_vraddhn, 1>;
4202
4203 def : Pat<(v8i8  (trunc (NEONvshru (add (v8i16 QPR:$Vn), QPR:$Vm), 8))),
4204           (VADDHNv8i8 QPR:$Vn, QPR:$Vm)>;
4205 def : Pat<(v4i16 (trunc (NEONvshru (add (v4i32 QPR:$Vn), QPR:$Vm), 16))),
4206           (VADDHNv4i16 QPR:$Vn, QPR:$Vm)>;
4207 def : Pat<(v2i32 (trunc (NEONvshru (add (v2i64 QPR:$Vn), QPR:$Vm), 32))),
4208           (VADDHNv2i32 QPR:$Vn, QPR:$Vm)>;
4209
4210 // Vector Multiply Operations.
4211
4212 //   VMUL     : Vector Multiply (integer, polynomial and floating-point)
4213 defm VMUL     : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D,
4214                         IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>;
4215 def  VMULpd   : N3VDInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16D, "vmul",
4216                         "p8", v8i8, v8i8, int_arm_neon_vmulp, 1>;
4217 def  VMULpq   : N3VQInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16Q, "vmul",
4218                         "p8", v16i8, v16i8, int_arm_neon_vmulp, 1>;
4219 def  VMULfd   : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VFMULD, "vmul", "f32",
4220                      v2f32, v2f32, fmul, 1>;
4221 def  VMULfq   : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VFMULQ, "vmul", "f32",
4222                      v4f32, v4f32, fmul, 1>;
4223 def  VMULhd   : N3VD<1, 0, 0b01, 0b1101, 1, IIC_VFMULD, "vmul", "f16",
4224                      v4f16, v4f16, fmul, 1>,
4225                 Requires<[HasNEON,HasFullFP16]>;
4226 def  VMULhq   : N3VQ<1, 0, 0b01, 0b1101, 1, IIC_VFMULQ, "vmul", "f16",
4227                      v8f16, v8f16, fmul, 1>,
4228                 Requires<[HasNEON,HasFullFP16]>;
4229 defm VMULsl   : N3VSL_HS<0b1000, "vmul", mul>;
4230 def  VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;
4231 def  VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32,
4232                        v2f32, fmul>;
4233 def  VMULslhd : N3VDSL16<0b01, 0b1001, "vmul", "f16", v4f16, fmul>,
4234                 Requires<[HasNEON,HasFullFP16]>;
4235 def  VMULslhq : N3VQSL16<0b01, 0b1001, "vmul", "f16", v8f16,
4236                        v4f16, fmul>,
4237                 Requires<[HasNEON,HasFullFP16]>;
4238
4239 def : Pat<(v8i16 (mul (v8i16 QPR:$src1),
4240                       (v8i16 (NEONvduplane (v8i16 QPR:$src2), imm:$lane)))),
4241           (v8i16 (VMULslv8i16 (v8i16 QPR:$src1),
4242                               (v4i16 (EXTRACT_SUBREG QPR:$src2,
4243                                       (DSubReg_i16_reg imm:$lane))),
4244                               (SubReg_i16_lane imm:$lane)))>;
4245 def : Pat<(v4i32 (mul (v4i32 QPR:$src1),
4246                       (v4i32 (NEONvduplane (v4i32 QPR:$src2), imm:$lane)))),
4247           (v4i32 (VMULslv4i32 (v4i32 QPR:$src1),
4248                               (v2i32 (EXTRACT_SUBREG QPR:$src2,
4249                                       (DSubReg_i32_reg imm:$lane))),
4250                               (SubReg_i32_lane imm:$lane)))>;
4251 def : Pat<(v4f32 (fmul (v4f32 QPR:$src1),
4252                        (v4f32 (NEONvduplane (v4f32 QPR:$src2), imm:$lane)))),
4253           (v4f32 (VMULslfq (v4f32 QPR:$src1),
4254                            (v2f32 (EXTRACT_SUBREG QPR:$src2,
4255                                    (DSubReg_i32_reg imm:$lane))),
4256                            (SubReg_i32_lane imm:$lane)))>;
4257
4258
4259 def : Pat<(v2f32 (fmul DPR:$Rn, (NEONvdup (f32 SPR:$Rm)))),
4260           (VMULslfd DPR:$Rn,
4261             (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),
4262             (i32 0))>;
4263 def : Pat<(v4f32 (fmul QPR:$Rn, (NEONvdup (f32 SPR:$Rm)))),
4264           (VMULslfq QPR:$Rn,
4265             (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),
4266             (i32 0))>;
4267
4268
4269 //   VQDMULH  : Vector Saturating Doubling Multiply Returning High Half
4270 defm VQDMULH  : N3VInt_HS<0, 0, 0b1011, 0, N3RegFrm, IIC_VMULi16D, IIC_VMULi32D,
4271                           IIC_VMULi16Q, IIC_VMULi32Q,
4272                           "vqdmulh", "s", int_arm_neon_vqdmulh, 1>;
4273 defm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D,
4274                             IIC_VMULi16Q, IIC_VMULi32Q,
4275                             "vqdmulh", "s",  int_arm_neon_vqdmulh>;
4276 def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1),
4277                                        (v8i16 (NEONvduplane (v8i16 QPR:$src2),
4278                                                             imm:$lane)))),
4279           (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1),
4280                                  (v4i16 (EXTRACT_SUBREG QPR:$src2,
4281                                          (DSubReg_i16_reg imm:$lane))),
4282                                  (SubReg_i16_lane imm:$lane)))>;
4283 def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1),
4284                                        (v4i32 (NEONvduplane (v4i32 QPR:$src2),
4285                                                             imm:$lane)))),
4286           (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1),
4287                                  (v2i32 (EXTRACT_SUBREG QPR:$src2,
4288                                          (DSubReg_i32_reg imm:$lane))),
4289                                  (SubReg_i32_lane imm:$lane)))>;
4290
4291 //   VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half
4292 defm VQRDMULH   : N3VInt_HS<1, 0, 0b1011, 0, N3RegFrm,
4293                             IIC_VMULi16D,IIC_VMULi32D,IIC_VMULi16Q,IIC_VMULi32Q,
4294                             "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>;
4295 defm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D,
4296                               IIC_VMULi16Q, IIC_VMULi32Q,
4297                               "vqrdmulh", "s",  int_arm_neon_vqrdmulh>;
4298 def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1),
4299                                         (v8i16 (NEONvduplane (v8i16 QPR:$src2),
4300                                                              imm:$lane)))),
4301           (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1),
4302                                   (v4i16 (EXTRACT_SUBREG QPR:$src2,
4303                                           (DSubReg_i16_reg imm:$lane))),
4304                                   (SubReg_i16_lane imm:$lane)))>;
4305 def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1),
4306                                         (v4i32 (NEONvduplane (v4i32 QPR:$src2),
4307                                                              imm:$lane)))),
4308           (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1),
4309                                   (v2i32 (EXTRACT_SUBREG QPR:$src2,
4310                                           (DSubReg_i32_reg imm:$lane))),
4311                                   (SubReg_i32_lane imm:$lane)))>;
4312
4313 //   VMULL    : Vector Multiply Long (integer and polynomial) (Q = D * D)
4314 let PostEncoderMethod = "NEONThumb2DataIPostEncoder",
4315     DecoderNamespace = "NEONData" in {
4316   defm VMULLs   : N3VL_QHS<0,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,
4317                            "vmull", "s", NEONvmulls, 1>;
4318   defm VMULLu   : N3VL_QHS<1,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,
4319                            "vmull", "u", NEONvmullu, 1>;
4320   def  VMULLp8   :  N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8",
4321                             v8i16, v8i8, int_arm_neon_vmullp, 1>;
4322   def  VMULLp64  : N3VLIntnp<0b00101, 0b10, 0b1110, 0, 0, NoItinerary,
4323                           "vmull", "p64", v2i64, v1i64, int_arm_neon_vmullp, 1>,
4324                     Requires<[HasV8, HasCrypto]>;
4325 }
4326 defm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", NEONvmulls>;
4327 defm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", NEONvmullu>;
4328
4329 //   VQDMULL  : Vector Saturating Doubling Multiply Long (Q = D * D)
4330 defm VQDMULL  : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, IIC_VMULi32D,
4331                            "vqdmull", "s", int_arm_neon_vqdmull, 1>;
4332 defm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D,
4333                              "vqdmull", "s", int_arm_neon_vqdmull>;
4334
4335 // Vector Multiply-Accumulate and Multiply-Subtract Operations.
4336
4337 //   VMLA     : Vector Multiply Accumulate (integer and floating-point)
4338 defm VMLA     : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4339                              IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
4340 def  VMLAfd   : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32",
4341                           v2f32, fmul_su, fadd_mlx>,
4342                 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4343 def  VMLAfq   : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32",
4344                           v4f32, fmul_su, fadd_mlx>,
4345                 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4346 def  VMLAhd   : N3VDMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACD, "vmla", "f16",
4347                           v4f16, fmul_su, fadd_mlx>,
4348                 Requires<[HasNEON, HasFullFP16, UseFPVMLx, DontUseFusedMAC]>;
4349 def  VMLAhq   : N3VQMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACQ, "vmla", "f16",
4350                           v8f16, fmul_su, fadd_mlx>,
4351                 Requires<[HasNEON, HasFullFP16, UseFPVMLx, DontUseFusedMAC]>;
4352 defm VMLAsl   : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D,
4353                               IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
4354 def  VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32",
4355                             v2f32, fmul_su, fadd_mlx>,
4356                 Requires<[HasNEON, UseFPVMLx]>;
4357 def  VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32",
4358                             v4f32, v2f32, fmul_su, fadd_mlx>,
4359                 Requires<[HasNEON, UseFPVMLx]>;
4360 def  VMLAslhd : N3VDMulOpSL16<0b01, 0b0001, IIC_VMACD, "vmla", "f16",
4361                             v4f16, fmul, fadd>,
4362                 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;
4363 def  VMLAslhq : N3VQMulOpSL16<0b01, 0b0001, IIC_VMACQ, "vmla", "f16",
4364                             v8f16, v4f16, fmul, fadd>,
4365                 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;
4366
4367 def : Pat<(v8i16 (add (v8i16 QPR:$src1),
4368                   (mul (v8i16 QPR:$src2),
4369                        (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
4370           (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
4371                               (v4i16 (EXTRACT_SUBREG QPR:$src3,
4372                                       (DSubReg_i16_reg imm:$lane))),
4373                               (SubReg_i16_lane imm:$lane)))>;
4374
4375 def : Pat<(v4i32 (add (v4i32 QPR:$src1),
4376                   (mul (v4i32 QPR:$src2),
4377                        (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
4378           (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
4379                               (v2i32 (EXTRACT_SUBREG QPR:$src3,
4380                                       (DSubReg_i32_reg imm:$lane))),
4381                               (SubReg_i32_lane imm:$lane)))>;
4382
4383 def : Pat<(v4f32 (fadd_mlx (v4f32 QPR:$src1),
4384                   (fmul_su (v4f32 QPR:$src2),
4385                         (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
4386           (v4f32 (VMLAslfq (v4f32 QPR:$src1),
4387                            (v4f32 QPR:$src2),
4388                            (v2f32 (EXTRACT_SUBREG QPR:$src3,
4389                                    (DSubReg_i32_reg imm:$lane))),
4390                            (SubReg_i32_lane imm:$lane)))>,
4391           Requires<[HasNEON, UseFPVMLx]>;
4392
4393 //   VMLAL    : Vector Multiply Accumulate Long (Q += D * D)
4394 defm VMLALs   : N3VLMulOp_QHS<0,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,
4395                               "vmlal", "s", NEONvmulls, add>;
4396 defm VMLALu   : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,
4397                               "vmlal", "u", NEONvmullu, add>;
4398
4399 defm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", NEONvmulls, add>;
4400 defm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", NEONvmullu, add>;
4401
4402 let Predicates = [HasNEON, HasV8_1a] in {
4403   // v8.1a Neon Rounding Double Multiply-Op vector operations,
4404   // VQRDMLAH : Vector Saturating Rounding Doubling Multiply Accumulate Long
4405   //            (Q += D * D)
4406   defm VQRDMLAH : N3VInt3_HS<1, 0, 0b1011, 1, IIC_VMACi16D, IIC_VMACi32D,
4407                              IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",
4408                              null_frag>;
4409   def : Pat<(v4i16 (int_arm_neon_vqadds
4410                      (v4i16 DPR:$src1),
4411                      (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn),
4412                                                    (v4i16 DPR:$Vm))))),
4413             (v4i16 (VQRDMLAHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
4414   def : Pat<(v2i32 (int_arm_neon_vqadds
4415                      (v2i32 DPR:$src1),
4416                      (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn),
4417                                                    (v2i32 DPR:$Vm))))),
4418             (v2i32 (VQRDMLAHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
4419   def : Pat<(v8i16 (int_arm_neon_vqadds
4420                      (v8i16 QPR:$src1),
4421                      (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn),
4422                                                    (v8i16 QPR:$Vm))))),
4423             (v8i16 (VQRDMLAHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
4424   def : Pat<(v4i32 (int_arm_neon_vqadds
4425                      (v4i32 QPR:$src1),
4426                      (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn),
4427                                                    (v4i32 QPR:$Vm))))),
4428             (v4i32 (VQRDMLAHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
4429
4430   defm VQRDMLAHsl : N3VMulOpSL_HS<0b1110, IIC_VMACi16D, IIC_VMACi32D,
4431                                   IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",
4432                                   null_frag>;
4433   def : Pat<(v4i16 (int_arm_neon_vqadds
4434                      (v4i16 DPR:$src1),
4435                      (v4i16 (int_arm_neon_vqrdmulh
4436                               (v4i16 DPR:$Vn),
4437                               (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4438                                                    imm:$lane)))))),
4439             (v4i16 (VQRDMLAHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm,
4440                                     imm:$lane))>;
4441   def : Pat<(v2i32 (int_arm_neon_vqadds
4442                      (v2i32 DPR:$src1),
4443                      (v2i32 (int_arm_neon_vqrdmulh
4444                               (v2i32 DPR:$Vn),
4445                               (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4446                                                    imm:$lane)))))),
4447             (v2i32 (VQRDMLAHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,
4448                                     imm:$lane))>;
4449   def : Pat<(v8i16 (int_arm_neon_vqadds
4450                      (v8i16 QPR:$src1),
4451                      (v8i16 (int_arm_neon_vqrdmulh
4452                               (v8i16 QPR:$src2),
4453                               (v8i16 (NEONvduplane (v8i16 QPR:$src3),
4454                                                    imm:$lane)))))),
4455             (v8i16 (VQRDMLAHslv8i16 (v8i16 QPR:$src1),
4456                                     (v8i16 QPR:$src2),
4457                                     (v4i16 (EXTRACT_SUBREG
4458                                              QPR:$src3,
4459                                              (DSubReg_i16_reg imm:$lane))),
4460                                     (SubReg_i16_lane imm:$lane)))>;
4461   def : Pat<(v4i32 (int_arm_neon_vqadds
4462                      (v4i32 QPR:$src1),
4463                      (v4i32 (int_arm_neon_vqrdmulh 
4464                               (v4i32 QPR:$src2),
4465                               (v4i32 (NEONvduplane (v4i32 QPR:$src3), 
4466                                                    imm:$lane)))))),
4467             (v4i32 (VQRDMLAHslv4i32 (v4i32 QPR:$src1),
4468                                     (v4i32 QPR:$src2),
4469                                     (v2i32 (EXTRACT_SUBREG
4470                                              QPR:$src3,
4471                                              (DSubReg_i32_reg imm:$lane))),
4472                                     (SubReg_i32_lane imm:$lane)))>;
4473
4474   //   VQRDMLSH : Vector Saturating Rounding Doubling Multiply Subtract Long
4475   //              (Q -= D * D)
4476   defm VQRDMLSH : N3VInt3_HS<1, 0, 0b1100, 1, IIC_VMACi16D, IIC_VMACi32D,
4477                              IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",
4478                              null_frag>;
4479   def : Pat<(v4i16 (int_arm_neon_vqsubs
4480                      (v4i16 DPR:$src1),
4481                      (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn),
4482                                                    (v4i16 DPR:$Vm))))),
4483             (v4i16 (VQRDMLSHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
4484   def : Pat<(v2i32 (int_arm_neon_vqsubs
4485                      (v2i32 DPR:$src1),
4486                      (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn),
4487                                                    (v2i32 DPR:$Vm))))),
4488             (v2i32 (VQRDMLSHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
4489   def : Pat<(v8i16 (int_arm_neon_vqsubs
4490                      (v8i16 QPR:$src1),
4491                      (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn),
4492                                                    (v8i16 QPR:$Vm))))),
4493             (v8i16 (VQRDMLSHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
4494   def : Pat<(v4i32 (int_arm_neon_vqsubs
4495                      (v4i32 QPR:$src1),
4496                      (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn),
4497                                                    (v4i32 QPR:$Vm))))),
4498             (v4i32 (VQRDMLSHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
4499
4500   defm VQRDMLSHsl : N3VMulOpSL_HS<0b1111, IIC_VMACi16D, IIC_VMACi32D,
4501                                   IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",
4502                                   null_frag>;
4503   def : Pat<(v4i16 (int_arm_neon_vqsubs
4504                      (v4i16 DPR:$src1),
4505                      (v4i16 (int_arm_neon_vqrdmulh
4506                               (v4i16 DPR:$Vn),
4507                               (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4508                                                    imm:$lane)))))),
4509             (v4i16 (VQRDMLSHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane))>;
4510   def : Pat<(v2i32 (int_arm_neon_vqsubs
4511                      (v2i32 DPR:$src1),
4512                      (v2i32 (int_arm_neon_vqrdmulh
4513                               (v2i32 DPR:$Vn),
4514                               (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4515                                                    imm:$lane)))))),
4516             (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, 
4517                                     imm:$lane))>;
4518   def : Pat<(v8i16 (int_arm_neon_vqsubs
4519                      (v8i16 QPR:$src1),
4520                      (v8i16 (int_arm_neon_vqrdmulh
4521                               (v8i16 QPR:$src2),
4522                               (v8i16 (NEONvduplane (v8i16 QPR:$src3), 
4523                                                    imm:$lane)))))),
4524             (v8i16 (VQRDMLSHslv8i16 (v8i16 QPR:$src1),
4525                                     (v8i16 QPR:$src2),
4526                                     (v4i16 (EXTRACT_SUBREG 
4527                                              QPR:$src3,
4528                                              (DSubReg_i16_reg imm:$lane))),
4529                                     (SubReg_i16_lane imm:$lane)))>;
4530   def : Pat<(v4i32 (int_arm_neon_vqsubs
4531                      (v4i32 QPR:$src1),
4532                      (v4i32 (int_arm_neon_vqrdmulh
4533                               (v4i32 QPR:$src2),
4534                               (v4i32 (NEONvduplane (v4i32 QPR:$src3),
4535                                                     imm:$lane)))))),
4536             (v4i32 (VQRDMLSHslv4i32 (v4i32 QPR:$src1),
4537                                     (v4i32 QPR:$src2),
4538                                     (v2i32 (EXTRACT_SUBREG 
4539                                              QPR:$src3,
4540                                              (DSubReg_i32_reg imm:$lane))),
4541                                     (SubReg_i32_lane imm:$lane)))>;
4542 }
4543 //   VQDMLAL  : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D)
4544 defm VQDMLAL  : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4545                             "vqdmlal", "s", null_frag>;
4546 defm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", null_frag>;
4547
4548 def : Pat<(v4i32 (int_arm_neon_vqadds (v4i32 QPR:$src1),
4549                      (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4550                                                   (v4i16 DPR:$Vm))))),
4551           (VQDMLALv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4552 def : Pat<(v2i64 (int_arm_neon_vqadds (v2i64 QPR:$src1),
4553                      (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4554                                                   (v2i32 DPR:$Vm))))),
4555           (VQDMLALv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4556 def : Pat<(v4i32 (int_arm_neon_vqadds (v4i32 QPR:$src1),
4557                      (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4558                                 (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4559                                                      imm:$lane)))))),
4560           (VQDMLALslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;
4561 def : Pat<(v2i64 (int_arm_neon_vqadds (v2i64 QPR:$src1),
4562                      (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4563                                 (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4564                                                      imm:$lane)))))),
4565           (VQDMLALslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;
4566
4567 //   VMLS     : Vector Multiply Subtract (integer and floating-point)
4568 defm VMLS     : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4569                              IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
4570 def  VMLSfd   : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32",
4571                           v2f32, fmul_su, fsub_mlx>,
4572                 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4573 def  VMLSfq   : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32",
4574                           v4f32, fmul_su, fsub_mlx>,
4575                 Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4576 def  VMLShd   : N3VDMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACD, "vmls", "f16",
4577                           v4f16, fmul, fsub>,
4578                 Requires<[HasNEON, HasFullFP16, UseFPVMLx, DontUseFusedMAC]>;
4579 def  VMLShq   : N3VQMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACQ, "vmls", "f16",
4580                           v8f16, fmul, fsub>,
4581                 Requires<[HasNEON, HasFullFP16, UseFPVMLx, DontUseFusedMAC]>;
4582 defm VMLSsl   : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D,
4583                               IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
4584 def  VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32",
4585                             v2f32, fmul_su, fsub_mlx>,
4586                 Requires<[HasNEON, UseFPVMLx]>;
4587 def  VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32",
4588                             v4f32, v2f32, fmul_su, fsub_mlx>,
4589                 Requires<[HasNEON, UseFPVMLx]>;
4590 def  VMLSslhd : N3VDMulOpSL16<0b01, 0b0101, IIC_VMACD, "vmls", "f16",
4591                             v4f16, fmul, fsub>,
4592                 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;
4593 def  VMLSslhq : N3VQMulOpSL16<0b01, 0b0101, IIC_VMACQ, "vmls", "f16",
4594                             v8f16, v4f16, fmul, fsub>,
4595                 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>;
4596
4597 def : Pat<(v8i16 (sub (v8i16 QPR:$src1),
4598                   (mul (v8i16 QPR:$src2),
4599                        (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
4600           (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
4601                               (v4i16 (EXTRACT_SUBREG QPR:$src3,
4602                                       (DSubReg_i16_reg imm:$lane))),
4603                               (SubReg_i16_lane imm:$lane)))>;
4604
4605 def : Pat<(v4i32 (sub (v4i32 QPR:$src1),
4606                   (mul (v4i32 QPR:$src2),
4607                      (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
4608           (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
4609                               (v2i32 (EXTRACT_SUBREG QPR:$src3,
4610                                       (DSubReg_i32_reg imm:$lane))),
4611                               (SubReg_i32_lane imm:$lane)))>;
4612
4613 def : Pat<(v4f32 (fsub_mlx (v4f32 QPR:$src1),
4614                   (fmul_su (v4f32 QPR:$src2),
4615                         (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
4616           (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2),
4617                            (v2f32 (EXTRACT_SUBREG QPR:$src3,
4618                                    (DSubReg_i32_reg imm:$lane))),
4619                            (SubReg_i32_lane imm:$lane)))>,
4620           Requires<[HasNEON, UseFPVMLx]>;
4621
4622 //   VMLSL    : Vector Multiply Subtract Long (Q -= D * D)
4623 defm VMLSLs   : N3VLMulOp_QHS<0,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,
4624                               "vmlsl", "s", NEONvmulls, sub>;
4625 defm VMLSLu   : N3VLMulOp_QHS<1,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,
4626                               "vmlsl", "u", NEONvmullu, sub>;
4627
4628 defm VMLSLsls : N3VLMulOpSL_HS<0, 0b0110, "vmlsl", "s", NEONvmulls, sub>;
4629 defm VMLSLslu : N3VLMulOpSL_HS<1, 0b0110, "vmlsl", "u", NEONvmullu, sub>;
4630
4631 //   VQDMLSL  : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D)
4632 defm VQDMLSL  : N3VLInt3_HS<0, 1, 0b1011, 0, IIC_VMACi16D, IIC_VMACi32D,
4633                             "vqdmlsl", "s", null_frag>;
4634 defm VQDMLSLsl: N3VLInt3SL_HS<0, 0b0111, "vqdmlsl", "s", null_frag>;
4635
4636 def : Pat<(v4i32 (int_arm_neon_vqsubs (v4i32 QPR:$src1),
4637                      (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4638                                                   (v4i16 DPR:$Vm))))),
4639           (VQDMLSLv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4640 def : Pat<(v2i64 (int_arm_neon_vqsubs (v2i64 QPR:$src1),
4641                      (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4642                                                   (v2i32 DPR:$Vm))))),
4643           (VQDMLSLv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4644 def : Pat<(v4i32 (int_arm_neon_vqsubs (v4i32 QPR:$src1),
4645                      (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4646                                 (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4647                                                      imm:$lane)))))),
4648           (VQDMLSLslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;
4649 def : Pat<(v2i64 (int_arm_neon_vqsubs (v2i64 QPR:$src1),
4650                      (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4651                                 (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4652                                                      imm:$lane)))))),
4653           (VQDMLSLslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;
4654
4655 // Fused Vector Multiply-Accumulate and Fused Multiply-Subtract Operations.
4656 def  VFMAfd   : N3VDMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACD, "vfma", "f32",
4657                           v2f32, fmul_su, fadd_mlx>,
4658                 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4659
4660 def  VFMAfq   : N3VQMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACQ, "vfma", "f32",
4661                           v4f32, fmul_su, fadd_mlx>,
4662                 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4663 def  VFMAhd   : N3VDMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACD, "vfma", "f16",
4664                           v4f16, fmul, fadd>,
4665                 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;
4666
4667 def  VFMAhq   : N3VQMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACQ, "vfma", "f16",
4668                           v8f16, fmul, fadd>,
4669                 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;
4670
4671 //   Fused Vector Multiply Subtract (floating-point)
4672 def  VFMSfd   : N3VDMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACD, "vfms", "f32",
4673                           v2f32, fmul_su, fsub_mlx>,
4674                 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4675 def  VFMSfq   : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32",
4676                           v4f32, fmul_su, fsub_mlx>,
4677                 Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4678 def  VFMShd   : N3VDMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACD, "vfms", "f16",
4679                           v4f16, fmul, fsub>,
4680                 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;
4681 def  VFMShq   : N3VQMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACQ, "vfms", "f16",
4682                           v8f16, fmul, fsub>,
4683                 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>;
4684
4685 // Match @llvm.fma.* intrinsics
4686 def : Pat<(v2f32 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)),
4687           (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4688           Requires<[HasVFP4]>;
4689 def : Pat<(v4f32 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)),
4690           (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4691           Requires<[HasVFP4]>;
4692 def : Pat<(v2f32 (fma (fneg DPR:$Vn), DPR:$Vm, DPR:$src1)),
4693           (VFMSfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4694       Requires<[HasVFP4]>;
4695 def : Pat<(v4f32 (fma (fneg QPR:$Vn), QPR:$Vm, QPR:$src1)),
4696           (VFMSfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4697       Requires<[HasVFP4]>;
4698
4699 // ARMv8.2a dot product instructions.
4700 // We put them in the VFPV8 decoder namespace because the ARM and Thumb
4701 // encodings are the same and thus no further bit twiddling is necessary
4702 // in the disassembler.
4703 let Predicates = [HasDotProd], DecoderNamespace = "VFPV8" in {
4704
4705 def VUDOTD : N3Vnp<0b11000, 0b10, 0b1101, 0b0, 0b1,
4706                   (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm),
4707                   N3RegFrm, IIC_VDOTPROD, "vudot", "u8", []>;
4708 def VSDOTD : N3Vnp<0b11000, 0b10, 0b1101, 0b0, 0b0,
4709                   (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm),
4710                   N3RegFrm, IIC_VDOTPROD, "vsdot", "s8", []>;
4711 def VUDOTQ : N3Vnp<0b11000, 0b10, 0b1101, 0b1, 0b1,
4712                   (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm),
4713                   N3RegFrm, IIC_VDOTPROD, "vudot", "u8", []>;
4714 def VSDOTQ : N3Vnp<0b11000, 0b10, 0b1101, 0b1, 0b0,
4715                   (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm),
4716                   N3RegFrm, IIC_VDOTPROD, "vsdot", "s8", []>;
4717
4718 // Indexed dot product instructions:
4719 class DOTI<string opc, string dt, bit Q, bit U, RegisterClass Ty> :
4720   N3Vnp<0b11100, 0b10, 0b1101, Q, U,
4721        (outs Ty:$Vd), (ins Ty:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
4722        N3RegFrm, IIC_VDOTPROD, opc, dt, []> {
4723   bit lane;
4724   let Inst{5} = lane;
4725   let AsmString = !strconcat(opc, ".", dt, "\t$Vd, $Vn, $Vm$lane");
4726 }
4727
4728 def VUDOTDI : DOTI<"vudot", "u8", 0b0, 0b1, DPR>;
4729 def VSDOTDI : DOTI<"vsdot", "s8", 0b0, 0b0, DPR>;
4730 def VUDOTQI : DOTI<"vudot", "u8", 0b1, 0b1, QPR>;
4731 def VSDOTQI : DOTI<"vsdot", "s8", 0b1, 0b0, QPR>;
4732
4733 }  // HasDotProd
4734
4735 // ARMv8.3 complex operations
4736 class BaseN3VCP8ComplexTied<bit op21, bit op4, bit s, bit q,
4737                             InstrItinClass itin, dag oops, dag iops,
4738                             string opc, string dt, list<dag> pattern>
4739   : N3VCP8<{?,?}, {op21,s}, q, op4, oops,
4740            iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "$src1 = $Vd", pattern>{
4741   bits<2> rot;
4742   let Inst{24-23} = rot;
4743 }
4744
4745 class BaseN3VCP8ComplexOdd<bit op23, bit op21, bit op4, bit s, bit q,
4746                            InstrItinClass itin, dag oops, dag iops, string opc,
4747                             string dt, list<dag> pattern>
4748   : N3VCP8<{?,op23}, {op21,s}, q, op4, oops,
4749            iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "", pattern> {
4750   bits<1> rot;
4751   let Inst{24} = rot;
4752 }
4753
4754 class BaseN3VCP8ComplexTiedLane32<bit op4, bit s, bit q, InstrItinClass itin,
4755                                   dag oops, dag iops, string opc, string dt,
4756                                   list<dag> pattern>
4757   : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt,
4758                "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> {
4759   bits<2> rot;
4760   bit lane;
4761
4762   let Inst{21-20} = rot;
4763   let Inst{5} = lane;
4764 }
4765
4766 class BaseN3VCP8ComplexTiedLane64<bit op4, bit s, bit q, InstrItinClass itin,
4767                             dag oops, dag iops, string opc, string dt,
4768                             list<dag> pattern>
4769   : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt,
4770                "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> {
4771   bits<2> rot;
4772   bit lane;
4773
4774   let Inst{21-20} = rot;
4775   let Inst{5} = Vm{4};
4776   // This is needed because the lane operand does not have any bits in the
4777   // encoding (it only has one possible value), so we need to manually set it
4778   // to it's default value.
4779   let DecoderMethod = "DecodeNEONComplexLane64Instruction";
4780 }
4781
4782 multiclass N3VCP8ComplexTied<bit op21, bit op4,
4783                        string OpcodeStr, SDPatternOperator Op> {
4784   let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {
4785   def v4f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 0, IIC_VMACD, (outs DPR:$Vd),
4786               (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot),
4787               OpcodeStr, "f16", []>;
4788   def v8f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 1, IIC_VMACQ, (outs QPR:$Vd),
4789               (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot),
4790               OpcodeStr, "f16", []>;
4791   }
4792   let Predicates = [HasNEON,HasV8_3a] in {
4793   def v2f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 0, IIC_VMACD, (outs DPR:$Vd),
4794               (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot),
4795               OpcodeStr, "f32", []>;
4796   def v4f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 1, IIC_VMACQ, (outs QPR:$Vd),
4797               (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot),
4798               OpcodeStr, "f32", []>;
4799   }
4800 }
4801
4802 multiclass N3VCP8ComplexOdd<bit op23, bit op21, bit op4,
4803                        string OpcodeStr, SDPatternOperator Op> {
4804   let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {
4805   def v4f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 0, IIC_VMACD,
4806               (outs DPR:$Vd),
4807               (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot),
4808               OpcodeStr, "f16", []>;
4809   def v8f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 1, IIC_VMACQ,
4810               (outs QPR:$Vd),
4811               (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot),
4812               OpcodeStr, "f16", []>;
4813   }
4814   let Predicates = [HasNEON,HasV8_3a] in {
4815   def v2f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 0, IIC_VMACD,
4816               (outs DPR:$Vd),
4817               (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot),
4818               OpcodeStr, "f32", []>;
4819   def v4f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 1, IIC_VMACQ,
4820               (outs QPR:$Vd),
4821               (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot),
4822               OpcodeStr, "f32", []>;
4823   }
4824 }
4825
4826 // These instructions index by pairs of lanes, so the VectorIndexes are twice
4827 // as wide as the data types.
4828 multiclass N3VCP8ComplexTiedLane<bit op4, string OpcodeStr,
4829                                  SDPatternOperator Op> {
4830   let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in {
4831   def v4f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 0, IIC_VMACD,
4832                       (outs DPR:$Vd),
4833                       (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,
4834                       VectorIndex32:$lane, complexrotateop:$rot),
4835                       OpcodeStr, "f16", []>;
4836   def v8f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 1, IIC_VMACQ,
4837                       (outs QPR:$Vd),
4838                       (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm,
4839                       VectorIndex32:$lane, complexrotateop:$rot),
4840                       OpcodeStr, "f16", []>;
4841   }
4842   let Predicates = [HasNEON,HasV8_3a] in {
4843   def v2f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 0, IIC_VMACD,
4844                       (outs DPR:$Vd),
4845                       (ins DPR:$src1, DPR:$Vn, DPR:$Vm, VectorIndex64:$lane,
4846                       complexrotateop:$rot),
4847                       OpcodeStr, "f32", []>;
4848   def v4f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 1, IIC_VMACQ,
4849                       (outs QPR:$Vd),
4850                       (ins QPR:$src1, QPR:$Vn, DPR:$Vm, VectorIndex64:$lane,
4851                       complexrotateop:$rot),
4852                       OpcodeStr, "f32", []>;
4853   }
4854 }
4855
4856 defm VCMLA : N3VCP8ComplexTied<1, 0, "vcmla", null_frag>;
4857 defm VCADD : N3VCP8ComplexOdd<1, 0, 0, "vcadd", null_frag>;
4858 defm VCMLA : N3VCP8ComplexTiedLane<0, "vcmla", null_frag>;
4859
4860 // Vector Subtract Operations.
4861
4862 //   VSUB     : Vector Subtract (integer and floating-point)
4863 defm VSUB     : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ,
4864                          "vsub", "i", sub, 0>;
4865 def  VSUBfd   : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32",
4866                      v2f32, v2f32, fsub, 0>;
4867 def  VSUBfq   : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32",
4868                      v4f32, v4f32, fsub, 0>;
4869 def  VSUBhd   : N3VD<0, 0, 0b11, 0b1101, 0, IIC_VBIND, "vsub", "f16",
4870                      v4f16, v4f16, fsub, 0>,
4871                 Requires<[HasNEON,HasFullFP16]>;
4872 def  VSUBhq   : N3VQ<0, 0, 0b11, 0b1101, 0, IIC_VBINQ, "vsub", "f16",
4873                      v8f16, v8f16, fsub, 0>,
4874                 Requires<[HasNEON,HasFullFP16]>;
4875 //   VSUBL    : Vector Subtract Long (Q = D - D)
4876 defm VSUBLs   : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
4877                             "vsubl", "s", sub, sext, 0>;
4878 defm VSUBLu   : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
4879                             "vsubl", "u", sub, zext, 0>;
4880 //   VSUBW    : Vector Subtract Wide (Q = Q - D)
4881 defm VSUBWs   : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>;
4882 defm VSUBWu   : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zext, 0>;
4883 //   VHSUB    : Vector Halving Subtract
4884 defm VHSUBs   : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm,
4885                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4886                            "vhsub", "s", int_arm_neon_vhsubs, 0>;
4887 defm VHSUBu   : N3VInt_QHS<1, 0, 0b0010, 0, N3RegFrm,
4888                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4889                            "vhsub", "u", int_arm_neon_vhsubu, 0>;
4890 //   VQSUB    : Vector Saturing Subtract
4891 defm VQSUBs   : N3VInt_QHSD<0, 0, 0b0010, 1, N3RegFrm,
4892                             IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4893                             "vqsub", "s", int_arm_neon_vqsubs, 0>;
4894 defm VQSUBu   : N3VInt_QHSD<1, 0, 0b0010, 1, N3RegFrm,
4895                             IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4896                             "vqsub", "u", int_arm_neon_vqsubu, 0>;
4897 //   VSUBHN   : Vector Subtract and Narrow Returning High Half (D = Q - Q)
4898 defm VSUBHN   : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i", null_frag, 0>;
4899 //   VRSUBHN  : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q)
4900 defm VRSUBHN  : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i",
4901                             int_arm_neon_vrsubhn, 0>;
4902
4903 def : Pat<(v8i8  (trunc (NEONvshru (sub (v8i16 QPR:$Vn), QPR:$Vm), 8))),
4904           (VSUBHNv8i8 QPR:$Vn, QPR:$Vm)>;
4905 def : Pat<(v4i16 (trunc (NEONvshru (sub (v4i32 QPR:$Vn), QPR:$Vm), 16))),
4906           (VSUBHNv4i16 QPR:$Vn, QPR:$Vm)>;
4907 def : Pat<(v2i32 (trunc (NEONvshru (sub (v2i64 QPR:$Vn), QPR:$Vm), 32))),
4908           (VSUBHNv2i32 QPR:$Vn, QPR:$Vm)>;
4909
4910 // Vector Comparisons.
4911
4912 //   VCEQ     : Vector Compare Equal
4913 defm VCEQ     : N3V_QHS<1, 0, 0b1000, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4914                         IIC_VSUBi4Q, "vceq", "i", NEONvceq, 1>;
4915 def  VCEQfd   : N3VD<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32,
4916                      NEONvceq, 1>;
4917 def  VCEQfq   : N3VQ<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32,
4918                      NEONvceq, 1>;
4919 def  VCEQhd   : N3VD<0,0,0b01,0b1110,0, IIC_VBIND, "vceq", "f16", v4i16, v4f16,
4920                      NEONvceq, 1>,
4921                 Requires<[HasNEON, HasFullFP16]>;
4922 def  VCEQhq   : N3VQ<0,0,0b01,0b1110,0, IIC_VBINQ, "vceq", "f16", v8i16, v8f16,
4923                      NEONvceq, 1>,
4924                 Requires<[HasNEON, HasFullFP16]>;
4925
4926 let TwoOperandAliasConstraint = "$Vm = $Vd" in
4927 defm VCEQz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i",
4928                             "$Vd, $Vm, #0", NEONvceqz>;
4929
4930 //   VCGE     : Vector Compare Greater Than or Equal
4931 defm VCGEs    : N3V_QHS<0, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4932                         IIC_VSUBi4Q, "vcge", "s", NEONvcge, 0>;
4933 defm VCGEu    : N3V_QHS<1, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4934                         IIC_VSUBi4Q, "vcge", "u", NEONvcgeu, 0>;
4935 def  VCGEfd   : N3VD<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32", v2i32, v2f32,
4936                      NEONvcge, 0>;
4937 def  VCGEfq   : N3VQ<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32,
4938                      NEONvcge, 0>;
4939 def  VCGEhd   : N3VD<1,0,0b01,0b1110,0, IIC_VBIND, "vcge", "f16", v4i16, v4f16,
4940                      NEONvcge, 0>,
4941                 Requires<[HasNEON, HasFullFP16]>;
4942 def  VCGEhq   : N3VQ<1,0,0b01,0b1110,0, IIC_VBINQ, "vcge", "f16", v8i16, v8f16,
4943                      NEONvcge, 0>,
4944                 Requires<[HasNEON, HasFullFP16]>;
4945
4946 let TwoOperandAliasConstraint = "$Vm = $Vd" in {
4947 defm VCGEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s",
4948                             "$Vd, $Vm, #0", NEONvcgez>;
4949 defm VCLEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s",
4950                             "$Vd, $Vm, #0", NEONvclez>;
4951 }
4952
4953 //   VCGT     : Vector Compare Greater Than
4954 defm VCGTs    : N3V_QHS<0, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4955                         IIC_VSUBi4Q, "vcgt", "s", NEONvcgt, 0>;
4956 defm VCGTu    : N3V_QHS<1, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4957                         IIC_VSUBi4Q, "vcgt", "u", NEONvcgtu, 0>;
4958 def  VCGTfd   : N3VD<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32,
4959                      NEONvcgt, 0>;
4960 def  VCGTfq   : N3VQ<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32,
4961                      NEONvcgt, 0>;
4962 def  VCGThd   : N3VD<1,0,0b11,0b1110,0, IIC_VBIND, "vcgt", "f16", v4i16, v4f16,
4963                      NEONvcgt, 0>,
4964                 Requires<[HasNEON, HasFullFP16]>;
4965 def  VCGThq   : N3VQ<1,0,0b11,0b1110,0, IIC_VBINQ, "vcgt", "f16", v8i16, v8f16,
4966                      NEONvcgt, 0>,
4967                 Requires<[HasNEON, HasFullFP16]>;
4968
4969 let TwoOperandAliasConstraint = "$Vm = $Vd" in {
4970 defm VCGTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s",
4971                             "$Vd, $Vm, #0", NEONvcgtz>;
4972 defm VCLTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s",
4973                             "$Vd, $Vm, #0", NEONvcltz>;
4974 }
4975
4976 //   VACGE    : Vector Absolute Compare Greater Than or Equal (aka VCAGE)
4977 def  VACGEfd   : N3VDInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge",
4978                         "f32", v2i32, v2f32, int_arm_neon_vacge, 0>;
4979 def  VACGEfq   : N3VQInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge",
4980                         "f32", v4i32, v4f32, int_arm_neon_vacge, 0>;
4981 def  VACGEhd   : N3VDInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge",
4982                         "f16", v4i16, v4f16, int_arm_neon_vacge, 0>,
4983                  Requires<[HasNEON, HasFullFP16]>;
4984 def  VACGEhq   : N3VQInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge",
4985                         "f16", v8i16, v8f16, int_arm_neon_vacge, 0>,
4986                  Requires<[HasNEON, HasFullFP16]>;
4987 //   VACGT    : Vector Absolute Compare Greater Than (aka VCAGT)
4988 def  VACGTfd   : N3VDInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt",
4989                         "f32", v2i32, v2f32, int_arm_neon_vacgt, 0>;
4990 def  VACGTfq   : N3VQInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt",
4991                         "f32", v4i32, v4f32, int_arm_neon_vacgt, 0>;
4992 def  VACGThd   : N3VDInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt",
4993                         "f16", v4i16, v4f16, int_arm_neon_vacgt, 0>,
4994                  Requires<[HasNEON, HasFullFP16]>;
4995 def  VACGThq   : N3VQInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt",
4996                         "f16", v8f16, v8f16, int_arm_neon_vacgt, 0>,
4997                  Requires<[HasNEON, HasFullFP16]>;
4998 //   VTST     : Vector Test Bits
4999 defm VTST     : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
5000                         IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;
5001
5002 def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",
5003                    (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
5004 def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",
5005                    (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
5006 def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",
5007                    (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
5008 def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",
5009                    (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
5010 let Predicates = [HasNEON, HasFullFP16] in {
5011 def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm",
5012                    (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
5013 def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm",
5014                    (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
5015 def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm",
5016                    (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
5017 def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm",
5018                    (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
5019 }
5020
5021 def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",
5022                    (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
5023 def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",
5024                    (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
5025 def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",
5026                    (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
5027 def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",
5028                    (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
5029 let Predicates = [HasNEON, HasFullFP16] in {
5030 def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm",
5031                    (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
5032 def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm",
5033                    (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
5034 def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm",
5035                    (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
5036 def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm",
5037                    (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
5038 }
5039
5040 // Vector Bitwise Operations.
5041
5042 def vnotd : PatFrag<(ops node:$in),
5043                     (xor node:$in, (bitconvert (v8i8 NEONimmAllOnesV)))>;
5044 def vnotq : PatFrag<(ops node:$in),
5045                     (xor node:$in, (bitconvert (v16i8 NEONimmAllOnesV)))>;
5046
5047
5048 //   VAND     : Vector Bitwise AND
5049 def  VANDd    : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand",
5050                       v2i32, v2i32, and, 1>;
5051 def  VANDq    : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand",
5052                       v4i32, v4i32, and, 1>;
5053
5054 //   VEOR     : Vector Bitwise Exclusive OR
5055 def  VEORd    : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor",
5056                       v2i32, v2i32, xor, 1>;
5057 def  VEORq    : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor",
5058                       v4i32, v4i32, xor, 1>;
5059
5060 //   VORR     : Vector Bitwise OR
5061 def  VORRd    : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr",
5062                       v2i32, v2i32, or, 1>;
5063 def  VORRq    : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr",
5064                       v4i32, v4i32, or, 1>;
5065
5066 def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1,
5067                           (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
5068                           IIC_VMOVImm,
5069                           "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
5070                           [(set DPR:$Vd,
5071                             (v4i16 (NEONvorrImm DPR:$src, timm:$SIMM)))]> {
5072   let Inst{9} = SIMM{9};
5073 }
5074
5075 def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1,
5076                           (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),
5077                           IIC_VMOVImm,
5078                           "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",
5079                           [(set DPR:$Vd,
5080                             (v2i32 (NEONvorrImm DPR:$src, timm:$SIMM)))]> {
5081   let Inst{10-9} = SIMM{10-9};
5082 }
5083
5084 def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1,
5085                           (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
5086                           IIC_VMOVImm,
5087                           "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
5088                           [(set QPR:$Vd,
5089                             (v8i16 (NEONvorrImm QPR:$src, timm:$SIMM)))]> {
5090   let Inst{9} = SIMM{9};
5091 }
5092
5093 def VORRiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 0, 1,
5094                           (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),
5095                           IIC_VMOVImm,
5096                           "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",
5097                           [(set QPR:$Vd,
5098                             (v4i32 (NEONvorrImm QPR:$src, timm:$SIMM)))]> {
5099   let Inst{10-9} = SIMM{10-9};
5100 }
5101
5102
5103 //   VBIC     : Vector Bitwise Bit Clear (AND NOT)
5104 let TwoOperandAliasConstraint = "$Vn = $Vd" in {
5105 def  VBICd    : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
5106                      (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,
5107                      "vbic", "$Vd, $Vn, $Vm", "",
5108                      [(set DPR:$Vd, (v2i32 (and DPR:$Vn,
5109                                                  (vnotd DPR:$Vm))))]>;
5110 def  VBICq    : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
5111                      (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,
5112                      "vbic", "$Vd, $Vn, $Vm", "",
5113                      [(set QPR:$Vd, (v4i32 (and QPR:$Vn,
5114                                                  (vnotq QPR:$Vm))))]>;
5115 }
5116
5117 def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1,
5118                           (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
5119                           IIC_VMOVImm,
5120                           "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
5121                           [(set DPR:$Vd,
5122                             (v4i16 (NEONvbicImm DPR:$src, timm:$SIMM)))]> {
5123   let Inst{9} = SIMM{9};
5124 }
5125
5126 def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1,
5127                           (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),
5128                           IIC_VMOVImm,
5129                           "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",
5130                           [(set DPR:$Vd,
5131                             (v2i32 (NEONvbicImm DPR:$src, timm:$SIMM)))]> {
5132   let Inst{10-9} = SIMM{10-9};
5133 }
5134
5135 def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1,
5136                           (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
5137                           IIC_VMOVImm,
5138                           "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
5139                           [(set QPR:$Vd,
5140                             (v8i16 (NEONvbicImm QPR:$src, timm:$SIMM)))]> {
5141   let Inst{9} = SIMM{9};
5142 }
5143
5144 def VBICiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 1, 1,
5145                           (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),
5146                           IIC_VMOVImm,
5147                           "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",
5148                           [(set QPR:$Vd,
5149                             (v4i32 (NEONvbicImm QPR:$src, timm:$SIMM)))]> {
5150   let Inst{10-9} = SIMM{10-9};
5151 }
5152
5153 //   VORN     : Vector Bitwise OR NOT
5154 def  VORNd    : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$Vd),
5155                      (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,
5156                      "vorn", "$Vd, $Vn, $Vm", "",
5157                      [(set DPR:$Vd, (v2i32 (or DPR:$Vn,
5158                                                 (vnotd DPR:$Vm))))]>;
5159 def  VORNq    : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd),
5160                      (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,
5161                      "vorn", "$Vd, $Vn, $Vm", "",
5162                      [(set QPR:$Vd, (v4i32 (or QPR:$Vn,
5163                                                 (vnotq QPR:$Vm))))]>;
5164
5165 //   VMVN     : Vector Bitwise NOT (Immediate)
5166
5167 let isReMaterializable = 1 in {
5168
5169 def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd),
5170                          (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5171                          "vmvn", "i16", "$Vd, $SIMM", "",
5172                          [(set DPR:$Vd, (v4i16 (NEONvmvnImm timm:$SIMM)))]> {
5173   let Inst{9} = SIMM{9};
5174 }
5175
5176 def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd),
5177                          (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5178                          "vmvn", "i16", "$Vd, $SIMM", "",
5179                          [(set QPR:$Vd, (v8i16 (NEONvmvnImm timm:$SIMM)))]> {
5180   let Inst{9} = SIMM{9};
5181 }
5182
5183 def VMVNv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 1, 1, (outs DPR:$Vd),
5184                          (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5185                          "vmvn", "i32", "$Vd, $SIMM", "",
5186                          [(set DPR:$Vd, (v2i32 (NEONvmvnImm timm:$SIMM)))]> {
5187   let Inst{11-8} = SIMM{11-8};
5188 }
5189
5190 def VMVNv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 1, 1, (outs QPR:$Vd),
5191                          (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5192                          "vmvn", "i32", "$Vd, $SIMM", "",
5193                          [(set QPR:$Vd, (v4i32 (NEONvmvnImm timm:$SIMM)))]> {
5194   let Inst{11-8} = SIMM{11-8};
5195 }
5196 }
5197
5198 //   VMVN     : Vector Bitwise NOT
5199 def  VMVNd    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0,
5200                      (outs DPR:$Vd), (ins DPR:$Vm), IIC_VSUBiD,
5201                      "vmvn", "$Vd, $Vm", "",
5202                      [(set DPR:$Vd, (v2i32 (vnotd DPR:$Vm)))]>;
5203 def  VMVNq    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0,
5204                      (outs QPR:$Vd), (ins QPR:$Vm), IIC_VSUBiD,
5205                      "vmvn", "$Vd, $Vm", "",
5206                      [(set QPR:$Vd, (v4i32 (vnotq QPR:$Vm)))]>;
5207 def : Pat<(v2i32 (vnotd DPR:$src)), (VMVNd DPR:$src)>;
5208 def : Pat<(v4i32 (vnotq QPR:$src)), (VMVNq QPR:$src)>;
5209
5210 //   VBSL     : Vector Bitwise Select
5211 def  VBSLd    : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
5212                      (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
5213                      N3RegFrm, IIC_VCNTiD,
5214                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5215                      [(set DPR:$Vd,
5216                            (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, DPR:$Vm)))]>;
5217 def : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 DPR:$src1),
5218                                    (v8i8 DPR:$Vn), (v8i8 DPR:$Vm))),
5219           (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
5220         Requires<[HasNEON]>;
5221 def : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 DPR:$src1),
5222                                     (v4i16 DPR:$Vn), (v4i16 DPR:$Vm))),
5223           (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
5224         Requires<[HasNEON]>;
5225 def : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 DPR:$src1),
5226                                     (v2i32 DPR:$Vn), (v2i32 DPR:$Vm))),
5227           (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
5228         Requires<[HasNEON]>;
5229 def : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 DPR:$src1),
5230                                     (v2f32 DPR:$Vn), (v2f32 DPR:$Vm))),
5231           (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
5232         Requires<[HasNEON]>;
5233 def : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 DPR:$src1),
5234                                     (v1i64 DPR:$Vn), (v1i64 DPR:$Vm))),
5235           (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
5236         Requires<[HasNEON]>;
5237
5238 def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),
5239                      (and DPR:$Vm, (vnotd DPR:$Vd)))),
5240           (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>,
5241         Requires<[HasNEON]>;
5242
5243 def : Pat<(v1i64 (or (and DPR:$Vn, DPR:$Vd),
5244                      (and DPR:$Vm, (vnotd DPR:$Vd)))),
5245           (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>,
5246         Requires<[HasNEON]>;
5247
5248 def  VBSLq    : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
5249                      (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
5250                      N3RegFrm, IIC_VCNTiQ,
5251                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5252                      [(set QPR:$Vd,
5253                            (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, QPR:$Vm)))]>;
5254
5255 def : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 QPR:$src1),
5256                                    (v16i8 QPR:$Vn), (v16i8 QPR:$Vm))),
5257           (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
5258         Requires<[HasNEON]>;
5259 def : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 QPR:$src1),
5260                                     (v8i16 QPR:$Vn), (v8i16 QPR:$Vm))),
5261           (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
5262         Requires<[HasNEON]>;
5263 def : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 QPR:$src1),
5264                                     (v4i32 QPR:$Vn), (v4i32 QPR:$Vm))),
5265           (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
5266         Requires<[HasNEON]>;
5267 def : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 QPR:$src1),
5268                                     (v4f32 QPR:$Vn), (v4f32 QPR:$Vm))),
5269           (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
5270         Requires<[HasNEON]>;
5271 def : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 QPR:$src1),
5272                                     (v2i64 QPR:$Vn), (v2i64 QPR:$Vm))),
5273           (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
5274         Requires<[HasNEON]>;
5275
5276 def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),
5277                      (and QPR:$Vm, (vnotq QPR:$Vd)))),
5278           (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>,
5279         Requires<[HasNEON]>;
5280 def : Pat<(v2i64 (or (and QPR:$Vn, QPR:$Vd),
5281                      (and QPR:$Vm, (vnotq QPR:$Vd)))),
5282           (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>,
5283         Requires<[HasNEON]>;
5284
5285 //   VBIF     : Vector Bitwise Insert if False
5286 //              like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
5287 // FIXME: This instruction's encoding MAY NOT BE correct.
5288 def  VBIFd    : N3VX<1, 0, 0b11, 0b0001, 0, 1,
5289                      (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
5290                      N3RegFrm, IIC_VBINiD,
5291                      "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5292                      []>;
5293 def  VBIFq    : N3VX<1, 0, 0b11, 0b0001, 1, 1,
5294                      (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
5295                      N3RegFrm, IIC_VBINiQ,
5296                      "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5297                      []>;
5298
5299 //   VBIT     : Vector Bitwise Insert if True
5300 //              like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst",
5301 // FIXME: This instruction's encoding MAY NOT BE correct.
5302 def  VBITd    : N3VX<1, 0, 0b10, 0b0001, 0, 1,
5303                      (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
5304                      N3RegFrm, IIC_VBINiD,
5305                      "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5306                      []>;
5307 def  VBITq    : N3VX<1, 0, 0b10, 0b0001, 1, 1,
5308                      (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
5309                      N3RegFrm, IIC_VBINiQ,
5310                      "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",
5311                      []>;
5312
5313 // VBIT/VBIF are not yet implemented.  The TwoAddress pass will not go looking
5314 // for equivalent operations with different register constraints; it just
5315 // inserts copies.
5316
5317 // Vector Absolute Differences.
5318
5319 //   VABD     : Vector Absolute Difference
5320 defm VABDs    : N3VInt_QHS<0, 0, 0b0111, 0, N3RegFrm,
5321                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5322                            "vabd", "s", int_arm_neon_vabds, 1>;
5323 defm VABDu    : N3VInt_QHS<1, 0, 0b0111, 0, N3RegFrm,
5324                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5325                            "vabd", "u", int_arm_neon_vabdu, 1>;
5326 def  VABDfd   : N3VDInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBIND,
5327                         "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 1>;
5328 def  VABDfq   : N3VQInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBINQ,
5329                         "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 1>;
5330 def  VABDhd   : N3VDInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBIND,
5331                         "vabd", "f16", v4f16, v4f16, int_arm_neon_vabds, 1>,
5332                 Requires<[HasNEON, HasFullFP16]>;
5333 def  VABDhq   : N3VQInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBINQ,
5334                         "vabd", "f16", v8f16, v8f16, int_arm_neon_vabds, 1>,
5335                 Requires<[HasNEON, HasFullFP16]>;
5336
5337 //   VABDL    : Vector Absolute Difference Long (Q = | D - D |)
5338 defm VABDLs   : N3VLIntExt_QHS<0,1,0b0111,0, IIC_VSUBi4Q,
5339                                "vabdl", "s", int_arm_neon_vabds, zext, 1>;
5340 defm VABDLu   : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q,
5341                                "vabdl", "u", int_arm_neon_vabdu, zext, 1>;
5342
5343 def abd_shr :
5344     PatFrag<(ops node:$in1, node:$in2, node:$shift),
5345             (NEONvshrs (sub (zext node:$in1),
5346                             (zext node:$in2)), (i32 $shift))>;
5347
5348 def : Pat<(xor (v4i32 (bitconvert (v8i16 (abd_shr (v8i8 DPR:$opA), (v8i8 DPR:$opB), 15)))),
5349                (v4i32 (bitconvert (v8i16 (add (sub (zext (v8i8 DPR:$opA)),
5350                                                    (zext (v8i8 DPR:$opB))),
5351                                               (v8i16 (abd_shr (v8i8 DPR:$opA), (v8i8 DPR:$opB), 15))))))),
5352           (VABDLuv8i16 DPR:$opA, DPR:$opB)>;
5353
5354 def : Pat<(xor (v4i32 (abd_shr (v4i16 DPR:$opA), (v4i16 DPR:$opB), 31)),
5355                (v4i32 (add (sub (zext (v4i16 DPR:$opA)),
5356                                 (zext (v4i16 DPR:$opB))),
5357                            (abd_shr (v4i16 DPR:$opA), (v4i16 DPR:$opB), 31)))),
5358           (VABDLuv4i32 DPR:$opA, DPR:$opB)>;
5359
5360 def : Pat<(xor (v4i32 (bitconvert (v2i64 (abd_shr (v2i32 DPR:$opA), (v2i32 DPR:$opB), 63)))),
5361                (v4i32 (bitconvert (v2i64 (add (sub (zext (v2i32 DPR:$opA)),
5362                                                    (zext (v2i32 DPR:$opB))),
5363                                          (abd_shr (v2i32 DPR:$opA), (v2i32 DPR:$opB), 63)))))),
5364           (VABDLuv2i64 DPR:$opA, DPR:$opB)>;
5365
5366 //   VABA     : Vector Absolute Difference and Accumulate
5367 defm VABAs    : N3VIntOp_QHS<0,0,0b0111,1, IIC_VABAD, IIC_VABAQ,
5368                              "vaba", "s", int_arm_neon_vabds, add>;
5369 defm VABAu    : N3VIntOp_QHS<1,0,0b0111,1, IIC_VABAD, IIC_VABAQ,
5370                              "vaba", "u", int_arm_neon_vabdu, add>;
5371
5372 //   VABAL    : Vector Absolute Difference and Accumulate Long (Q += | D - D |)
5373 defm VABALs   : N3VLIntExtOp_QHS<0,1,0b0101,0, IIC_VABAD,
5374                                  "vabal", "s", int_arm_neon_vabds, zext, add>;
5375 defm VABALu   : N3VLIntExtOp_QHS<1,1,0b0101,0, IIC_VABAD,
5376                                  "vabal", "u", int_arm_neon_vabdu, zext, add>;
5377
5378 // Vector Maximum and Minimum.
5379
5380 //   VMAX     : Vector Maximum
5381 defm VMAXs    : N3VInt_QHS<0, 0, 0b0110, 0, N3RegFrm,
5382                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5383                            "vmax", "s", smax, 1>;
5384 defm VMAXu    : N3VInt_QHS<1, 0, 0b0110, 0, N3RegFrm,
5385                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5386                            "vmax", "u", umax, 1>;
5387 def  VMAXfd   : N3VDInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBIND,
5388                         "vmax", "f32",
5389                         v2f32, v2f32, fmaxnan, 1>;
5390 def  VMAXfq   : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ,
5391                         "vmax", "f32",
5392                         v4f32, v4f32, fmaxnan, 1>;
5393 def  VMAXhd   : N3VDInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBIND,
5394                         "vmax", "f16",
5395                         v4f16, v4f16, fmaxnan, 1>,
5396                 Requires<[HasNEON, HasFullFP16]>;
5397 def  VMAXhq   : N3VQInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBINQ,
5398                         "vmax", "f16",
5399                         v8f16, v8f16, fmaxnan, 1>,
5400                 Requires<[HasNEON, HasFullFP16]>;
5401
5402 // VMAXNM
5403 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
5404   def VMAXNMNDf  : N3VDIntnp<0b00110, 0b00, 0b1111, 0, 1,
5405                             N3RegFrm, NoItinerary, "vmaxnm", "f32",
5406                             v2f32, v2f32, fmaxnum, 1>,
5407                             Requires<[HasV8, HasNEON]>;
5408   def VMAXNMNQf  : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1,
5409                             N3RegFrm, NoItinerary, "vmaxnm", "f32",
5410                             v4f32, v4f32, fmaxnum, 1>,
5411                             Requires<[HasV8, HasNEON]>;
5412   def VMAXNMNDh  : N3VDIntnp<0b00110, 0b01, 0b1111, 0, 1,
5413                             N3RegFrm, NoItinerary, "vmaxnm", "f16",
5414                             v4f16, v4f16, fmaxnum, 1>,
5415                             Requires<[HasV8, HasNEON, HasFullFP16]>;
5416   def VMAXNMNQh  : N3VQIntnp<0b00110, 0b01, 0b1111, 1, 1,
5417                             N3RegFrm, NoItinerary, "vmaxnm", "f16",
5418                             v8f16, v8f16, fmaxnum, 1>,
5419                             Requires<[HasV8, HasNEON, HasFullFP16]>;
5420 }
5421
5422 //   VMIN     : Vector Minimum
5423 defm VMINs    : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm,
5424                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5425                            "vmin", "s", smin, 1>;
5426 defm VMINu    : N3VInt_QHS<1, 0, 0b0110, 1, N3RegFrm,
5427                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
5428                            "vmin", "u", umin, 1>;
5429 def  VMINfd   : N3VDInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBIND,
5430                         "vmin", "f32",
5431                         v2f32, v2f32, fminnan, 1>;
5432 def  VMINfq   : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ,
5433                         "vmin", "f32",
5434                         v4f32, v4f32, fminnan, 1>;
5435 def  VMINhd   : N3VDInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBIND,
5436                         "vmin", "f16",
5437                         v4f16, v4f16, fminnan, 1>,
5438                 Requires<[HasNEON, HasFullFP16]>;
5439 def  VMINhq   : N3VQInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBINQ,
5440                         "vmin", "f16",
5441                         v8f16, v8f16, fminnan, 1>,
5442                 Requires<[HasNEON, HasFullFP16]>;
5443
5444 // VMINNM
5445 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
5446   def VMINNMNDf  : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1,
5447                             N3RegFrm, NoItinerary, "vminnm", "f32",
5448                             v2f32, v2f32, fminnum, 1>,
5449                             Requires<[HasV8, HasNEON]>;
5450   def VMINNMNQf  : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1,
5451                             N3RegFrm, NoItinerary, "vminnm", "f32",
5452                             v4f32, v4f32, fminnum, 1>,
5453                             Requires<[HasV8, HasNEON]>;
5454   def VMINNMNDh  : N3VDIntnp<0b00110, 0b11, 0b1111, 0, 1,
5455                             N3RegFrm, NoItinerary, "vminnm", "f16",
5456                             v4f16, v4f16, fminnum, 1>,
5457                             Requires<[HasV8, HasNEON, HasFullFP16]>;
5458   def VMINNMNQh  : N3VQIntnp<0b00110, 0b11, 0b1111, 1, 1,
5459                             N3RegFrm, NoItinerary, "vminnm", "f16",
5460                             v8f16, v8f16, fminnum, 1>,
5461                             Requires<[HasV8, HasNEON, HasFullFP16]>;
5462 }
5463
5464 // Vector Pairwise Operations.
5465
5466 //   VPADD    : Vector Pairwise Add
5467 def  VPADDi8  : N3VDInt<0, 0, 0b00, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
5468                         "vpadd", "i8",
5469                         v8i8, v8i8, int_arm_neon_vpadd, 0>;
5470 def  VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
5471                         "vpadd", "i16",
5472                         v4i16, v4i16, int_arm_neon_vpadd, 0>;
5473 def  VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
5474                         "vpadd", "i32",
5475                         v2i32, v2i32, int_arm_neon_vpadd, 0>;
5476 def  VPADDf   : N3VDInt<1, 0, 0b00, 0b1101, 0, N3RegFrm,
5477                         IIC_VPBIND, "vpadd", "f32",
5478                         v2f32, v2f32, int_arm_neon_vpadd, 0>;
5479 def  VPADDh   : N3VDInt<1, 0, 0b01, 0b1101, 0, N3RegFrm,
5480                         IIC_VPBIND, "vpadd", "f16",
5481                         v4f16, v4f16, int_arm_neon_vpadd, 0>,
5482                 Requires<[HasNEON, HasFullFP16]>;
5483
5484 //   VPADDL   : Vector Pairwise Add Long
5485 defm VPADDLs  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s",
5486                              int_arm_neon_vpaddls>;
5487 defm VPADDLu  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u",
5488                              int_arm_neon_vpaddlu>;
5489
5490 //   VPADAL   : Vector Pairwise Add and Accumulate Long
5491 defm VPADALs  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s",
5492                               int_arm_neon_vpadals>;
5493 defm VPADALu  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u",
5494                               int_arm_neon_vpadalu>;
5495
5496 //   VPMAX    : Vector Pairwise Maximum
5497 def  VPMAXs8  : N3VDInt<0, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5498                         "s8", v8i8, v8i8, int_arm_neon_vpmaxs, 0>;
5499 def  VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5500                         "s16", v4i16, v4i16, int_arm_neon_vpmaxs, 0>;
5501 def  VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5502                         "s32", v2i32, v2i32, int_arm_neon_vpmaxs, 0>;
5503 def  VPMAXu8  : N3VDInt<1, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5504                         "u8", v8i8, v8i8, int_arm_neon_vpmaxu, 0>;
5505 def  VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5506                         "u16", v4i16, v4i16, int_arm_neon_vpmaxu, 0>;
5507 def  VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
5508                         "u32", v2i32, v2i32, int_arm_neon_vpmaxu, 0>;
5509 def  VPMAXf   : N3VDInt<1, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax",
5510                         "f32", v2f32, v2f32, int_arm_neon_vpmaxs, 0>;
5511 def  VPMAXh   : N3VDInt<1, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax",
5512                         "f16", v4f16, v4f16, int_arm_neon_vpmaxs, 0>,
5513                 Requires<[HasNEON, HasFullFP16]>;
5514
5515 //   VPMIN    : Vector Pairwise Minimum
5516 def  VPMINs8  : N3VDInt<0, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5517                         "s8", v8i8, v8i8, int_arm_neon_vpmins, 0>;
5518 def  VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5519                         "s16", v4i16, v4i16, int_arm_neon_vpmins, 0>;
5520 def  VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5521                         "s32", v2i32, v2i32, int_arm_neon_vpmins, 0>;
5522 def  VPMINu8  : N3VDInt<1, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5523                         "u8", v8i8, v8i8, int_arm_neon_vpminu, 0>;
5524 def  VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5525                         "u16", v4i16, v4i16, int_arm_neon_vpminu, 0>;
5526 def  VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
5527                         "u32", v2i32, v2i32, int_arm_neon_vpminu, 0>;
5528 def  VPMINf   : N3VDInt<1, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin",
5529                         "f32", v2f32, v2f32, int_arm_neon_vpmins, 0>;
5530 def  VPMINh   : N3VDInt<1, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin",
5531                         "f16", v4f16, v4f16, int_arm_neon_vpmins, 0>,
5532                 Requires<[HasNEON, HasFullFP16]>;
5533
5534 // Vector Reciprocal and Reciprocal Square Root Estimate and Step.
5535
5536 //   VRECPE   : Vector Reciprocal Estimate
5537 def  VRECPEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,
5538                         IIC_VUNAD, "vrecpe", "u32",
5539                         v2i32, v2i32, int_arm_neon_vrecpe>;
5540 def  VRECPEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,
5541                         IIC_VUNAQ, "vrecpe", "u32",
5542                         v4i32, v4i32, int_arm_neon_vrecpe>;
5543 def  VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
5544                         IIC_VUNAD, "vrecpe", "f32",
5545                         v2f32, v2f32, int_arm_neon_vrecpe>;
5546 def  VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
5547                         IIC_VUNAQ, "vrecpe", "f32",
5548                         v4f32, v4f32, int_arm_neon_vrecpe>;
5549 def  VRECPEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0,
5550                         IIC_VUNAD, "vrecpe", "f16",
5551                         v4f16, v4f16, int_arm_neon_vrecpe>,
5552                 Requires<[HasNEON, HasFullFP16]>;
5553 def  VRECPEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0,
5554                         IIC_VUNAQ, "vrecpe", "f16",
5555                         v8f16, v8f16, int_arm_neon_vrecpe>,
5556                 Requires<[HasNEON, HasFullFP16]>;
5557
5558 //   VRECPS   : Vector Reciprocal Step
5559 def  VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,
5560                         IIC_VRECSD, "vrecps", "f32",
5561                         v2f32, v2f32, int_arm_neon_vrecps, 1>;
5562 def  VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,
5563                         IIC_VRECSQ, "vrecps", "f32",
5564                         v4f32, v4f32, int_arm_neon_vrecps, 1>;
5565 def  VRECPShd : N3VDInt<0, 0, 0b01, 0b1111, 1, N3RegFrm,
5566                         IIC_VRECSD, "vrecps", "f16",
5567                         v4f16, v4f16, int_arm_neon_vrecps, 1>,
5568                 Requires<[HasNEON, HasFullFP16]>;
5569 def  VRECPShq : N3VQInt<0, 0, 0b01, 0b1111, 1, N3RegFrm,
5570                         IIC_VRECSQ, "vrecps", "f16",
5571                         v8f16, v8f16, int_arm_neon_vrecps, 1>,
5572                 Requires<[HasNEON, HasFullFP16]>;
5573
5574 //   VRSQRTE  : Vector Reciprocal Square Root Estimate
5575 def  VRSQRTEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
5576                          IIC_VUNAD, "vrsqrte", "u32",
5577                          v2i32, v2i32, int_arm_neon_vrsqrte>;
5578 def  VRSQRTEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
5579                          IIC_VUNAQ, "vrsqrte", "u32",
5580                          v4i32, v4i32, int_arm_neon_vrsqrte>;
5581 def  VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,
5582                          IIC_VUNAD, "vrsqrte", "f32",
5583                          v2f32, v2f32, int_arm_neon_vrsqrte>;
5584 def  VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,
5585                          IIC_VUNAQ, "vrsqrte", "f32",
5586                          v4f32, v4f32, int_arm_neon_vrsqrte>;
5587 def  VRSQRTEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0,
5588                          IIC_VUNAD, "vrsqrte", "f16",
5589                          v4f16, v4f16, int_arm_neon_vrsqrte>,
5590                 Requires<[HasNEON, HasFullFP16]>;
5591 def  VRSQRTEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0,
5592                          IIC_VUNAQ, "vrsqrte", "f16",
5593                          v8f16, v8f16, int_arm_neon_vrsqrte>,
5594                 Requires<[HasNEON, HasFullFP16]>;
5595
5596 //   VRSQRTS  : Vector Reciprocal Square Root Step
5597 def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,
5598                         IIC_VRECSD, "vrsqrts", "f32",
5599                         v2f32, v2f32, int_arm_neon_vrsqrts, 1>;
5600 def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,
5601                         IIC_VRECSQ, "vrsqrts", "f32",
5602                         v4f32, v4f32, int_arm_neon_vrsqrts, 1>;
5603 def VRSQRTShd : N3VDInt<0, 0, 0b11, 0b1111, 1, N3RegFrm,
5604                         IIC_VRECSD, "vrsqrts", "f16",
5605                         v4f16, v4f16, int_arm_neon_vrsqrts, 1>,
5606                 Requires<[HasNEON, HasFullFP16]>;
5607 def VRSQRTShq : N3VQInt<0, 0, 0b11, 0b1111, 1, N3RegFrm,
5608                         IIC_VRECSQ, "vrsqrts", "f16",
5609                         v8f16, v8f16, int_arm_neon_vrsqrts, 1>,
5610                 Requires<[HasNEON, HasFullFP16]>;
5611
5612 // Vector Shifts.
5613
5614 //   VSHL     : Vector Shift
5615 defm VSHLs    : N3VInt_QHSDSh<0, 0, 0b0100, 0, N3RegVShFrm,
5616                             IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,
5617                             "vshl", "s", int_arm_neon_vshifts>;
5618 defm VSHLu    : N3VInt_QHSDSh<1, 0, 0b0100, 0, N3RegVShFrm,
5619                             IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,
5620                             "vshl", "u", int_arm_neon_vshiftu>;
5621
5622 //   VSHL     : Vector Shift Left (Immediate)
5623 defm VSHLi    : N2VShL_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>;
5624
5625 //   VSHR     : Vector Shift Right (Immediate)
5626 defm VSHRs    : N2VShR_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", "VSHRs",
5627                             NEONvshrs>;
5628 defm VSHRu    : N2VShR_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", "VSHRu",
5629                             NEONvshru>;
5630
5631 //   VSHLL    : Vector Shift Left Long
5632 defm VSHLLs   : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s",
5633   PatFrag<(ops node:$LHS, node:$RHS), (NEONvshl (sext node:$LHS), node:$RHS)>>;
5634 defm VSHLLu   : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u",
5635   PatFrag<(ops node:$LHS, node:$RHS), (NEONvshl (zext node:$LHS), node:$RHS)>>;
5636
5637 //   VSHLL    : Vector Shift Left Long (with maximum shift count)
5638 class N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
5639                 bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy,
5640                 ValueType OpTy, Operand ImmTy>
5641   : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,
5642            ResTy, OpTy, ImmTy, null_frag> {
5643   let Inst{21-16} = op21_16;
5644   let DecoderMethod = "DecodeVSHLMaxInstruction";
5645 }
5646 def  VSHLLi8  : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",
5647                           v8i16, v8i8, imm8>;
5648 def  VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16",
5649                           v4i32, v4i16, imm16>;
5650 def  VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32",
5651                           v2i64, v2i32, imm32>;
5652
5653 def : Pat<(v8i16 (NEONvshl (zext (v8i8 DPR:$Rn)), (i32 8))),
5654           (VSHLLi8 DPR:$Rn, 8)>;
5655 def : Pat<(v4i32 (NEONvshl (zext (v4i16 DPR:$Rn)), (i32 16))),
5656           (VSHLLi16 DPR:$Rn, 16)>;
5657 def : Pat<(v2i64 (NEONvshl (zext (v2i32 DPR:$Rn)), (i32 32))),
5658           (VSHLLi32 DPR:$Rn, 32)>;
5659 def : Pat<(v8i16 (NEONvshl (sext (v8i8 DPR:$Rn)), (i32 8))),
5660           (VSHLLi8 DPR:$Rn, 8)>;
5661 def : Pat<(v4i32 (NEONvshl (sext (v4i16 DPR:$Rn)), (i32 16))),
5662           (VSHLLi16 DPR:$Rn, 16)>;
5663 def : Pat<(v2i64 (NEONvshl (sext (v2i32 DPR:$Rn)), (i32 32))),
5664           (VSHLLi32 DPR:$Rn, 32)>;
5665 def : Pat<(v8i16 (NEONvshl (anyext (v8i8 DPR:$Rn)), (i32 8))),
5666           (VSHLLi8 DPR:$Rn, 8)>;
5667 def : Pat<(v4i32 (NEONvshl (anyext (v4i16 DPR:$Rn)), (i32 16))),
5668           (VSHLLi16 DPR:$Rn, 16)>;
5669 def : Pat<(v2i64 (NEONvshl (anyext (v2i32 DPR:$Rn)), (i32 32))),
5670           (VSHLLi32 DPR:$Rn, 32)>;
5671
5672 //   VSHRN    : Vector Shift Right and Narrow
5673 defm VSHRN    : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i",
5674                            PatFrag<(ops node:$Rn, node:$amt),
5675                                    (trunc (NEONvshrs node:$Rn, node:$amt))>>;
5676
5677 def : Pat<(v8i8 (trunc (NEONvshru (v8i16 QPR:$Vn), shr_imm8:$amt))),
5678           (VSHRNv8i8 QPR:$Vn, shr_imm8:$amt)>;
5679 def : Pat<(v4i16 (trunc (NEONvshru (v4i32 QPR:$Vn), shr_imm16:$amt))),
5680           (VSHRNv4i16 QPR:$Vn, shr_imm16:$amt)>;
5681 def : Pat<(v2i32 (trunc (NEONvshru (v2i64 QPR:$Vn), shr_imm32:$amt))),
5682           (VSHRNv2i32 QPR:$Vn, shr_imm32:$amt)>;
5683
5684 //   VRSHL    : Vector Rounding Shift
5685 defm VRSHLs   : N3VInt_QHSDSh<0, 0, 0b0101, 0, N3RegVShFrm,
5686                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5687                             "vrshl", "s", int_arm_neon_vrshifts>;
5688 defm VRSHLu   : N3VInt_QHSDSh<1, 0, 0b0101, 0, N3RegVShFrm,
5689                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5690                             "vrshl", "u", int_arm_neon_vrshiftu>;
5691 //   VRSHR    : Vector Rounding Shift Right
5692 defm VRSHRs   : N2VShR_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", "VRSHRs",
5693                             NEONvrshrs>;
5694 defm VRSHRu   : N2VShR_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", "VRSHRu",
5695                             NEONvrshru>;
5696
5697 //   VRSHRN   : Vector Rounding Shift Right and Narrow
5698 defm VRSHRN   : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",
5699                            NEONvrshrn>;
5700
5701 //   VQSHL    : Vector Saturating Shift
5702 defm VQSHLs   : N3VInt_QHSDSh<0, 0, 0b0100, 1, N3RegVShFrm,
5703                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5704                             "vqshl", "s", int_arm_neon_vqshifts>;
5705 defm VQSHLu   : N3VInt_QHSDSh<1, 0, 0b0100, 1, N3RegVShFrm,
5706                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5707                             "vqshl", "u", int_arm_neon_vqshiftu>;
5708 //   VQSHL    : Vector Saturating Shift Left (Immediate)
5709 defm VQSHLsi  : N2VShL_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s",NEONvqshls>;
5710 defm VQSHLui  : N2VShL_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u",NEONvqshlu>;
5711
5712 //   VQSHLU   : Vector Saturating Shift Left (Immediate, Unsigned)
5713 defm VQSHLsu  : N2VShL_QHSD<1,1,0b0110,1, IIC_VSHLi4D,"vqshlu","s",NEONvqshlsu>;
5714
5715 //   VQSHRN   : Vector Saturating Shift Right and Narrow
5716 defm VQSHRNs  : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",
5717                            NEONvqshrns>;
5718 defm VQSHRNu  : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u",
5719                            NEONvqshrnu>;
5720
5721 //   VQSHRUN  : Vector Saturating Shift Right and Narrow (Unsigned)
5722 defm VQSHRUN  : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s",
5723                            NEONvqshrnsu>;
5724
5725 //   VQRSHL   : Vector Saturating Rounding Shift
5726 defm VQRSHLs  : N3VInt_QHSDSh<0, 0, 0b0101, 1, N3RegVShFrm,
5727                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5728                             "vqrshl", "s", int_arm_neon_vqrshifts>;
5729 defm VQRSHLu  : N3VInt_QHSDSh<1, 0, 0b0101, 1, N3RegVShFrm,
5730                             IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5731                             "vqrshl", "u", int_arm_neon_vqrshiftu>;
5732
5733 //   VQRSHRN  : Vector Saturating Rounding Shift Right and Narrow
5734 defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s",
5735                            NEONvqrshrns>;
5736 defm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u",
5737                            NEONvqrshrnu>;
5738
5739 //   VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned)
5740 defm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s",
5741                            NEONvqrshrnsu>;
5742
5743 //   VSRA     : Vector Shift Right and Accumulate
5744 defm VSRAs    : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", NEONvshrs>;
5745 defm VSRAu    : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", NEONvshru>;
5746 //   VRSRA    : Vector Rounding Shift Right and Accumulate
5747 defm VRSRAs   : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrs>;
5748 defm VRSRAu   : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshru>;
5749
5750 //   VSLI     : Vector Shift Left and Insert
5751 defm VSLI     : N2VShInsL_QHSD<1, 1, 0b0101, 1, "vsli">;
5752
5753 //   VSRI     : Vector Shift Right and Insert
5754 defm VSRI     : N2VShInsR_QHSD<1, 1, 0b0100, 1, "vsri">;
5755
5756 // Vector Absolute and Saturating Absolute.
5757
5758 //   VABS     : Vector Absolute Value
5759 defm VABS     : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0,
5760                            IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", abs>;
5761 def  VABSfd   : N2VD<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
5762                      "vabs", "f32",
5763                      v2f32, v2f32, fabs>;
5764 def  VABSfq   : N2VQ<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
5765                      "vabs", "f32",
5766                       v4f32, v4f32, fabs>;
5767 def  VABShd   : N2VD<0b11, 0b11, 0b01, 0b01, 0b01110, 0,
5768                      "vabs", "f16",
5769                      v4f16, v4f16, fabs>,
5770                 Requires<[HasNEON, HasFullFP16]>;
5771 def  VABShq   : N2VQ<0b11, 0b11, 0b01, 0b01, 0b01110, 0,
5772                      "vabs", "f16",
5773                       v8f16, v8f16, fabs>,
5774                 Requires<[HasNEON, HasFullFP16]>;
5775
5776 //   VQABS    : Vector Saturating Absolute Value
5777 defm VQABS    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0,
5778                            IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s",
5779                            int_arm_neon_vqabs>;
5780
5781 // Vector Negate.
5782
5783 def vnegd  : PatFrag<(ops node:$in),
5784                      (sub (bitconvert (v2i32 NEONimmAllZerosV)), node:$in)>;
5785 def vnegq  : PatFrag<(ops node:$in),
5786                      (sub (bitconvert (v4i32 NEONimmAllZerosV)), node:$in)>;
5787
5788 class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
5789   : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm),
5790         IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
5791         [(set DPR:$Vd, (Ty (vnegd DPR:$Vm)))]>;
5792 class VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
5793   : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$Vd), (ins QPR:$Vm),
5794         IIC_VSHLiQ, OpcodeStr, Dt, "$Vd, $Vm", "",
5795         [(set QPR:$Vd, (Ty (vnegq QPR:$Vm)))]>;
5796
5797 //   VNEG     : Vector Negate (integer)
5798 def  VNEGs8d  : VNEGD<0b00, "vneg", "s8", v8i8>;
5799 def  VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>;
5800 def  VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>;
5801 def  VNEGs8q  : VNEGQ<0b00, "vneg", "s8", v16i8>;
5802 def  VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>;
5803 def  VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>;
5804
5805 //   VNEG     : Vector Negate (floating-point)
5806 def  VNEGfd   : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
5807                     (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD,
5808                     "vneg", "f32", "$Vd, $Vm", "",
5809                     [(set DPR:$Vd, (v2f32 (fneg DPR:$Vm)))]>;
5810 def  VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0,
5811                     (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ,
5812                     "vneg", "f32", "$Vd, $Vm", "",
5813                     [(set QPR:$Vd, (v4f32 (fneg QPR:$Vm)))]>;
5814 def  VNEGhd   : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 0, 0,
5815                     (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD,
5816                     "vneg", "f16", "$Vd, $Vm", "",
5817                     [(set DPR:$Vd, (v4f16 (fneg DPR:$Vm)))]>,
5818                 Requires<[HasNEON, HasFullFP16]>;
5819 def  VNEGhq   : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 1, 0,
5820                     (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ,
5821                     "vneg", "f16", "$Vd, $Vm", "",
5822                     [(set QPR:$Vd, (v8f16 (fneg QPR:$Vm)))]>,
5823                 Requires<[HasNEON, HasFullFP16]>;
5824
5825 def : Pat<(v8i8  (vnegd  DPR:$src)), (VNEGs8d DPR:$src)>;
5826 def : Pat<(v4i16 (vnegd  DPR:$src)), (VNEGs16d DPR:$src)>;
5827 def : Pat<(v2i32 (vnegd  DPR:$src)), (VNEGs32d DPR:$src)>;
5828 def : Pat<(v16i8 (vnegq QPR:$src)), (VNEGs8q QPR:$src)>;
5829 def : Pat<(v8i16 (vnegq QPR:$src)), (VNEGs16q QPR:$src)>;
5830 def : Pat<(v4i32 (vnegq QPR:$src)), (VNEGs32q QPR:$src)>;
5831
5832 //   VQNEG    : Vector Saturating Negate
5833 defm VQNEG    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0,
5834                            IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s",
5835                            int_arm_neon_vqneg>;
5836
5837 // Vector Bit Counting Operations.
5838
5839 //   VCLS     : Vector Count Leading Sign Bits
5840 defm VCLS     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0,
5841                            IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s",
5842                            int_arm_neon_vcls>;
5843 //   VCLZ     : Vector Count Leading Zeros
5844 defm VCLZ     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0,
5845                            IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i",
5846                            ctlz>;
5847 //   VCNT     : Vector Count One Bits
5848 def  VCNTd    : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
5849                         IIC_VCNTiD, "vcnt", "8",
5850                         v8i8, v8i8, ctpop>;
5851 def  VCNTq    : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
5852                         IIC_VCNTiQ, "vcnt", "8",
5853                         v16i8, v16i8, ctpop>;
5854
5855 // Vector Swap
5856 def  VSWPd    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
5857                      (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2),
5858                      NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
5859                      []>;
5860 def  VSWPq    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
5861                      (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2),
5862                      NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
5863                      []>;
5864
5865 // Vector Move Operations.
5866
5867 //   VMOV     : Vector Move (Register)
5868 def : NEONInstAlias<"vmov${p} $Vd, $Vm",
5869                     (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;
5870 def : NEONInstAlias<"vmov${p} $Vd, $Vm",
5871                     (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;
5872
5873 //   VMOV     : Vector Move (Immediate)
5874
5875 // Although VMOVs are not strictly speaking cheap, they are as expensive
5876 // as their copies counterpart (VORR), so we should prefer rematerialization
5877 // over splitting when it applies.
5878 let isReMaterializable = 1, isAsCheapAsAMove=1 in {
5879 def VMOVv8i8  : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$Vd),
5880                          (ins nImmSplatI8:$SIMM), IIC_VMOVImm,
5881                          "vmov", "i8", "$Vd, $SIMM", "",
5882                          [(set DPR:$Vd, (v8i8 (NEONvmovImm timm:$SIMM)))]>;
5883 def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd),
5884                          (ins nImmSplatI8:$SIMM), IIC_VMOVImm,
5885                          "vmov", "i8", "$Vd, $SIMM", "",
5886                          [(set QPR:$Vd, (v16i8 (NEONvmovImm timm:$SIMM)))]>;
5887
5888 def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd),
5889                          (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5890                          "vmov", "i16", "$Vd, $SIMM", "",
5891                          [(set DPR:$Vd, (v4i16 (NEONvmovImm timm:$SIMM)))]> {
5892   let Inst{9} = SIMM{9};
5893 }
5894
5895 def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd),
5896                          (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5897                          "vmov", "i16", "$Vd, $SIMM", "",
5898                          [(set QPR:$Vd, (v8i16 (NEONvmovImm timm:$SIMM)))]> {
5899  let Inst{9} = SIMM{9};
5900 }
5901
5902 def VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 0, 1, (outs DPR:$Vd),
5903                          (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5904                          "vmov", "i32", "$Vd, $SIMM", "",
5905                          [(set DPR:$Vd, (v2i32 (NEONvmovImm timm:$SIMM)))]> {
5906   let Inst{11-8} = SIMM{11-8};
5907 }
5908
5909 def VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 0, 1, (outs QPR:$Vd),
5910                          (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5911                          "vmov", "i32", "$Vd, $SIMM", "",
5912                          [(set QPR:$Vd, (v4i32 (NEONvmovImm timm:$SIMM)))]> {
5913   let Inst{11-8} = SIMM{11-8};
5914 }
5915
5916 def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$Vd),
5917                          (ins nImmSplatI64:$SIMM), IIC_VMOVImm,
5918                          "vmov", "i64", "$Vd, $SIMM", "",
5919                          [(set DPR:$Vd, (v1i64 (NEONvmovImm timm:$SIMM)))]>;
5920 def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$Vd),
5921                          (ins nImmSplatI64:$SIMM), IIC_VMOVImm,
5922                          "vmov", "i64", "$Vd, $SIMM", "",
5923                          [(set QPR:$Vd, (v2i64 (NEONvmovImm timm:$SIMM)))]>;
5924
5925 def VMOVv2f32 : N1ModImm<1, 0b000, 0b1111, 0, 0, 0, 1, (outs DPR:$Vd),
5926                          (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,
5927                          "vmov", "f32", "$Vd, $SIMM", "",
5928                          [(set DPR:$Vd, (v2f32 (NEONvmovFPImm timm:$SIMM)))]>;
5929 def VMOVv4f32 : N1ModImm<1, 0b000, 0b1111, 0, 1, 0, 1, (outs QPR:$Vd),
5930                          (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,
5931                          "vmov", "f32", "$Vd, $SIMM", "",
5932                          [(set QPR:$Vd, (v4f32 (NEONvmovFPImm timm:$SIMM)))]>;
5933 } // isReMaterializable, isAsCheapAsAMove
5934
5935 // Add support for bytes replication feature, so it could be GAS compatible.
5936 // E.g. instructions below:
5937 // "vmov.i32 d0, 0xffffffff"
5938 // "vmov.i32 d0, 0xabababab"
5939 // "vmov.i16 d0, 0xabab"
5940 // are incorrect, but we could deal with such cases.
5941 // For last two instructions, for example, it should emit:
5942 // "vmov.i8 d0, 0xab"
5943 def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",
5944                     (VMOVv8i8 DPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;
5945 def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",
5946                     (VMOVv8i8 DPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;
5947 def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",
5948                     (VMOVv16i8 QPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;
5949 def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",
5950                     (VMOVv16i8 QPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;
5951
5952 // Also add same support for VMVN instructions. So instruction:
5953 // "vmvn.i32 d0, 0xabababab"
5954 // actually means:
5955 // "vmov.i8 d0, 0x54"
5956 def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",
5957                     (VMOVv8i8 DPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;
5958 def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",
5959                     (VMOVv8i8 DPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;
5960 def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",
5961                     (VMOVv16i8 QPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;
5962 def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",
5963                     (VMOVv16i8 QPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;
5964
5965 // On some CPUs the two instructions "vmov.i32 dD, #0" and "vmov.i32 qD, #0"
5966 // require zero cycles to execute so they should be used wherever possible for
5967 // setting a register to zero.
5968
5969 // Even without these pseudo-insts we would probably end up with the correct
5970 // instruction, but we could not mark the general ones with "isAsCheapAsAMove"
5971 // since they are sometimes rather expensive (in general).
5972
5973 let AddedComplexity = 50, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
5974   def VMOVD0 : ARMPseudoExpand<(outs DPR:$Vd), (ins), 4, IIC_VMOVImm,
5975                                [(set DPR:$Vd, (v2i32 NEONimmAllZerosV))],
5976                                (VMOVv2i32 DPR:$Vd, 0, (ops 14, zero_reg))>,
5977                Requires<[HasZCZ]>;
5978   def VMOVQ0 : ARMPseudoExpand<(outs QPR:$Vd), (ins), 4, IIC_VMOVImm,
5979                                [(set QPR:$Vd, (v4i32 NEONimmAllZerosV))],
5980                                (VMOVv4i32 QPR:$Vd, 0, (ops 14, zero_reg))>,
5981                Requires<[HasZCZ]>;
5982 }
5983
5984 //   VMOV     : Vector Get Lane (move scalar to ARM core register)
5985
5986 def VGETLNs8  : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?},
5987                           (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),
5988                           IIC_VMOVSI, "vmov", "s8", "$R, $V$lane",
5989                           [(set GPR:$R, (NEONvgetlanes (v8i8 DPR:$V),
5990                                            imm:$lane))]> {
5991   let Inst{21}  = lane{2};
5992   let Inst{6-5} = lane{1-0};
5993 }
5994 def VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1},
5995                           (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),
5996                           IIC_VMOVSI, "vmov", "s16", "$R, $V$lane",
5997                           [(set GPR:$R, (NEONvgetlanes (v4i16 DPR:$V),
5998                                            imm:$lane))]> {
5999   let Inst{21} = lane{1};
6000   let Inst{6}  = lane{0};
6001 }
6002 def VGETLNu8  : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?},
6003                           (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),
6004                           IIC_VMOVSI, "vmov", "u8", "$R, $V$lane",
6005                           [(set GPR:$R, (NEONvgetlaneu (v8i8 DPR:$V),
6006                                            imm:$lane))]> {
6007   let Inst{21}  = lane{2};
6008   let Inst{6-5} = lane{1-0};
6009 }
6010 def VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1},
6011                           (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),
6012                           IIC_VMOVSI, "vmov", "u16", "$R, $V$lane",
6013                           [(set GPR:$R, (NEONvgetlaneu (v4i16 DPR:$V),
6014                                            imm:$lane))]> {
6015   let Inst{21} = lane{1};
6016   let Inst{6}  = lane{0};
6017 }
6018 def VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00,
6019                           (outs GPR:$R), (ins DPR:$V, VectorIndex32:$lane),
6020                           IIC_VMOVSI, "vmov", "32", "$R, $V$lane",
6021                           [(set GPR:$R, (extractelt (v2i32 DPR:$V),
6022                                            imm:$lane))]>,
6023                 Requires<[HasVFP2, HasFastVGETLNi32]> {
6024   let Inst{21} = lane{0};
6025 }
6026 // def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td
6027 def : Pat<(NEONvgetlanes (v16i8 QPR:$src), imm:$lane),
6028           (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src,
6029                            (DSubReg_i8_reg imm:$lane))),
6030                      (SubReg_i8_lane imm:$lane))>;
6031 def : Pat<(NEONvgetlanes (v8i16 QPR:$src), imm:$lane),
6032           (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src,
6033                              (DSubReg_i16_reg imm:$lane))),
6034                      (SubReg_i16_lane imm:$lane))>;
6035 def : Pat<(NEONvgetlaneu (v16i8 QPR:$src), imm:$lane),
6036           (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src,
6037                            (DSubReg_i8_reg imm:$lane))),
6038                      (SubReg_i8_lane imm:$lane))>;
6039 def : Pat<(NEONvgetlaneu (v8i16 QPR:$src), imm:$lane),
6040           (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src,
6041                              (DSubReg_i16_reg imm:$lane))),
6042                      (SubReg_i16_lane imm:$lane))>;
6043 def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
6044           (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src,
6045                              (DSubReg_i32_reg imm:$lane))),
6046                      (SubReg_i32_lane imm:$lane))>,
6047       Requires<[HasNEON, HasFastVGETLNi32]>;
6048 def : Pat<(extractelt (v2i32 DPR:$src), imm:$lane),
6049           (COPY_TO_REGCLASS
6050             (i32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,
6051       Requires<[HasNEON, HasSlowVGETLNi32]>;
6052 def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
6053           (COPY_TO_REGCLASS
6054             (i32 (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,
6055       Requires<[HasNEON, HasSlowVGETLNi32]>;
6056 def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2),
6057           (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)),
6058                           (SSubReg_f32_reg imm:$src2))>;
6059 def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2),
6060           (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)),
6061                           (SSubReg_f32_reg imm:$src2))>;
6062 //def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2),
6063 //          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
6064 def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2),
6065           (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
6066
6067
6068 //   VMOV     : Vector Set Lane (move ARM core register to scalar)
6069
6070 let Constraints = "$src1 = $V" in {
6071 def VSETLNi8  : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$V),
6072                           (ins DPR:$src1, GPR:$R, VectorIndex8:$lane),
6073                           IIC_VMOVISL, "vmov", "8", "$V$lane, $R",
6074                           [(set DPR:$V, (vector_insert (v8i8 DPR:$src1),
6075                                            GPR:$R, imm:$lane))]> {
6076   let Inst{21}  = lane{2};
6077   let Inst{6-5} = lane{1-0};
6078 }
6079 def VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$V),
6080                           (ins DPR:$src1, GPR:$R, VectorIndex16:$lane),
6081                           IIC_VMOVISL, "vmov", "16", "$V$lane, $R",
6082                           [(set DPR:$V, (vector_insert (v4i16 DPR:$src1),
6083                                            GPR:$R, imm:$lane))]> {
6084   let Inst{21} = lane{1};
6085   let Inst{6}  = lane{0};
6086 }
6087 def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V),
6088                           (ins DPR:$src1, GPR:$R, VectorIndex32:$lane),
6089                           IIC_VMOVISL, "vmov", "32", "$V$lane, $R",
6090                           [(set DPR:$V, (insertelt (v2i32 DPR:$src1),
6091                                            GPR:$R, imm:$lane))]>,
6092                 Requires<[HasVFP2]> {
6093   let Inst{21} = lane{0};
6094   // This instruction is equivalent as
6095   // $V = INSERT_SUBREG $src1, $R, translateImmToSubIdx($imm)
6096   let isInsertSubreg = 1;
6097 }
6098 }
6099 def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane),
6100           (v16i8 (INSERT_SUBREG QPR:$src1,
6101                   (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,
6102                                    (DSubReg_i8_reg imm:$lane))),
6103                             GPR:$src2, (SubReg_i8_lane imm:$lane))),
6104                   (DSubReg_i8_reg imm:$lane)))>;
6105 def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane),
6106           (v8i16 (INSERT_SUBREG QPR:$src1,
6107                   (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,
6108                                      (DSubReg_i16_reg imm:$lane))),
6109                              GPR:$src2, (SubReg_i16_lane imm:$lane))),
6110                   (DSubReg_i16_reg imm:$lane)))>;
6111 def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane),
6112           (v4i32 (INSERT_SUBREG QPR:$src1,
6113                   (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,
6114                                      (DSubReg_i32_reg imm:$lane))),
6115                              GPR:$src2, (SubReg_i32_lane imm:$lane))),
6116                   (DSubReg_i32_reg imm:$lane)))>;
6117
6118 def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)),
6119           (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)),
6120                                 SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
6121 def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)),
6122           (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)),
6123                                 SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
6124
6125 //def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
6126 //          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
6127 def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
6128           (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
6129
6130 def : Pat<(v2f32 (scalar_to_vector SPR:$src)),
6131           (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
6132 def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))),
6133           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
6134 def : Pat<(v4f32 (scalar_to_vector SPR:$src)),
6135           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
6136
6137 def : Pat<(v8i8 (scalar_to_vector GPR:$src)),
6138           (VSETLNi8  (v8i8  (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
6139 def : Pat<(v4i16 (scalar_to_vector GPR:$src)),
6140           (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
6141 def : Pat<(v2i32 (scalar_to_vector GPR:$src)),
6142           (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
6143
6144 def : Pat<(v16i8 (scalar_to_vector GPR:$src)),
6145           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
6146                          (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
6147                          dsub_0)>;
6148 def : Pat<(v8i16 (scalar_to_vector GPR:$src)),
6149           (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)),
6150                          (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
6151                          dsub_0)>;
6152 def : Pat<(v4i32 (scalar_to_vector GPR:$src)),
6153           (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
6154                          (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
6155                          dsub_0)>;
6156
6157 //   VDUP     : Vector Duplicate (from ARM core register to all elements)
6158
6159 class VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
6160   : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$V), (ins GPR:$R),
6161           IIC_VMOVIS, "vdup", Dt, "$V, $R",
6162           [(set DPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>;
6163 class VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
6164   : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$V), (ins GPR:$R),
6165           IIC_VMOVIS, "vdup", Dt, "$V, $R",
6166           [(set QPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>;
6167
6168 def  VDUP8d   : VDUPD<0b11101100, 0b00, "8", v8i8>;
6169 def  VDUP16d  : VDUPD<0b11101000, 0b01, "16", v4i16>;
6170 def  VDUP32d  : VDUPD<0b11101000, 0b00, "32", v2i32>,
6171                 Requires<[HasNEON, HasFastVDUP32]>;
6172 def  VDUP8q   : VDUPQ<0b11101110, 0b00, "8", v16i8>;
6173 def  VDUP16q  : VDUPQ<0b11101010, 0b01, "16", v8i16>;
6174 def  VDUP32q  : VDUPQ<0b11101010, 0b00, "32", v4i32>;
6175
6176 // NEONvdup patterns for uarchs with fast VDUP.32.
6177 def : Pat<(v2f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32d GPR:$R)>,
6178       Requires<[HasNEON,HasFastVDUP32]>;
6179 def : Pat<(v4f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>;
6180
6181 // NEONvdup patterns for uarchs with slow VDUP.32 - use VMOVDRR instead.
6182 def : Pat<(v2i32 (NEONvdup (i32 GPR:$R))), (VMOVDRR GPR:$R, GPR:$R)>,
6183       Requires<[HasNEON,HasSlowVDUP32]>;
6184 def : Pat<(v2f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VMOVDRR GPR:$R, GPR:$R)>,
6185       Requires<[HasNEON,HasSlowVDUP32]>;
6186
6187 //   VDUP     : Vector Duplicate Lane (from scalar to all elements)
6188
6189 class VDUPLND<bits<4> op19_16, string OpcodeStr, string Dt,
6190               ValueType Ty, Operand IdxTy>
6191   : NVDupLane<op19_16, 0, (outs DPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),
6192               IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane",
6193               [(set DPR:$Vd, (Ty (NEONvduplane (Ty DPR:$Vm), imm:$lane)))]>;
6194
6195 class VDUPLNQ<bits<4> op19_16, string OpcodeStr, string Dt,
6196               ValueType ResTy, ValueType OpTy, Operand IdxTy>
6197   : NVDupLane<op19_16, 1, (outs QPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),
6198               IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane",
6199               [(set QPR:$Vd, (ResTy (NEONvduplane (OpTy DPR:$Vm),
6200                                       VectorIndex32:$lane)))]>;
6201
6202 // Inst{19-16} is partially specified depending on the element size.
6203
6204 def VDUPLN8d  : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> {
6205   bits<3> lane;
6206   let Inst{19-17} = lane{2-0};
6207 }
6208 def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> {
6209   bits<2> lane;
6210   let Inst{19-18} = lane{1-0};
6211 }
6212 def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> {
6213   bits<1> lane;
6214   let Inst{19} = lane{0};
6215 }
6216 def VDUPLN8q  : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> {
6217   bits<3> lane;
6218   let Inst{19-17} = lane{2-0};
6219 }
6220 def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> {
6221   bits<2> lane;
6222   let Inst{19-18} = lane{1-0};
6223 }
6224 def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> {
6225   bits<1> lane;
6226   let Inst{19} = lane{0};
6227 }
6228
6229 def : Pat<(v2f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)),
6230           (VDUPLN32d DPR:$Vm, imm:$lane)>;
6231
6232 def : Pat<(v4f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)),
6233           (VDUPLN32q DPR:$Vm, imm:$lane)>;
6234
6235 def : Pat<(v16i8 (NEONvduplane (v16i8 QPR:$src), imm:$lane)),
6236           (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src,
6237                                   (DSubReg_i8_reg imm:$lane))),
6238                            (SubReg_i8_lane imm:$lane)))>;
6239 def : Pat<(v8i16 (NEONvduplane (v8i16 QPR:$src), imm:$lane)),
6240           (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src,
6241                                     (DSubReg_i16_reg imm:$lane))),
6242                             (SubReg_i16_lane imm:$lane)))>;
6243 def : Pat<(v4i32 (NEONvduplane (v4i32 QPR:$src), imm:$lane)),
6244           (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src,
6245                                     (DSubReg_i32_reg imm:$lane))),
6246                             (SubReg_i32_lane imm:$lane)))>;
6247 def : Pat<(v4f32 (NEONvduplane (v4f32 QPR:$src), imm:$lane)),
6248           (v4f32 (VDUPLN32q (v2f32 (EXTRACT_SUBREG QPR:$src,
6249                                    (DSubReg_i32_reg imm:$lane))),
6250                            (SubReg_i32_lane imm:$lane)))>;
6251
6252 def : Pat<(v2f32 (NEONvdup (f32 SPR:$src))),
6253           (v2f32 (VDUPLN32d (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
6254                              SPR:$src, ssub_0), (i32 0)))>;
6255 def : Pat<(v4f32 (NEONvdup (f32 SPR:$src))),
6256           (v4f32 (VDUPLN32q (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
6257                              SPR:$src, ssub_0), (i32 0)))>;
6258
6259 //   VMOVN    : Vector Narrowing Move
6260 defm VMOVN    : N2VN_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVN,
6261                          "vmovn", "i", trunc>;
6262 //   VQMOVN   : Vector Saturating Narrowing Move
6263 defm VQMOVNs  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD,
6264                             "vqmovn", "s", int_arm_neon_vqmovns>;
6265 defm VQMOVNu  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD,
6266                             "vqmovn", "u", int_arm_neon_vqmovnu>;
6267 defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD,
6268                             "vqmovun", "s", int_arm_neon_vqmovnsu>;
6269 //   VMOVL    : Vector Lengthening Move
6270 defm VMOVLs   : N2VL_QHS<0b01,0b10100,0,1, "vmovl", "s", sext>;
6271 defm VMOVLu   : N2VL_QHS<0b11,0b10100,0,1, "vmovl", "u", zext>;
6272 def : Pat<(v8i16 (anyext (v8i8 DPR:$Vm))), (VMOVLuv8i16 DPR:$Vm)>;
6273 def : Pat<(v4i32 (anyext (v4i16 DPR:$Vm))), (VMOVLuv4i32 DPR:$Vm)>;
6274 def : Pat<(v2i64 (anyext (v2i32 DPR:$Vm))), (VMOVLuv2i64 DPR:$Vm)>;
6275
6276 // Vector Conversions.
6277
6278 //   VCVT     : Vector Convert Between Floating-Point and Integers
6279 def  VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
6280                      v2i32, v2f32, fp_to_sint>;
6281 def  VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
6282                      v2i32, v2f32, fp_to_uint>;
6283 def  VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
6284                      v2f32, v2i32, sint_to_fp>;
6285 def  VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
6286                      v2f32, v2i32, uint_to_fp>;
6287
6288 def  VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
6289                      v4i32, v4f32, fp_to_sint>;
6290 def  VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
6291                      v4i32, v4f32, fp_to_uint>;
6292 def  VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
6293                      v4f32, v4i32, sint_to_fp>;
6294 def  VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
6295                      v4f32, v4i32, uint_to_fp>;
6296
6297 def  VCVTh2sd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16",
6298                      v4i16, v4f16, fp_to_sint>,
6299                 Requires<[HasNEON, HasFullFP16]>;
6300 def  VCVTh2ud : N2VD<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16",
6301                      v4i16, v4f16, fp_to_uint>,
6302                 Requires<[HasNEON, HasFullFP16]>;
6303 def  VCVTs2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16",
6304                      v4f16, v4i16, sint_to_fp>,
6305                 Requires<[HasNEON, HasFullFP16]>;
6306 def  VCVTu2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16",
6307                      v4f16, v4i16, uint_to_fp>,
6308                 Requires<[HasNEON, HasFullFP16]>;
6309
6310 def  VCVTh2sq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16",
6311                      v8i16, v8f16, fp_to_sint>,
6312                 Requires<[HasNEON, HasFullFP16]>;
6313 def  VCVTh2uq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16",
6314                      v8i16, v8f16, fp_to_uint>,
6315                 Requires<[HasNEON, HasFullFP16]>;
6316 def  VCVTs2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16",
6317                      v8f16, v8i16, sint_to_fp>,
6318                 Requires<[HasNEON, HasFullFP16]>;
6319 def  VCVTu2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16",
6320                      v8f16, v8i16, uint_to_fp>,
6321                 Requires<[HasNEON, HasFullFP16]>;
6322
6323 // VCVT{A, N, P, M}
6324 multiclass VCVT_FPI<string op, bits<3> op10_8, SDPatternOperator IntS,
6325                     SDPatternOperator IntU> {
6326   let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
6327     def SDf : N2VDIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
6328                        "s32.f32", v2i32, v2f32, IntS>, Requires<[HasV8, HasNEON]>;
6329     def SQf : N2VQIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
6330                        "s32.f32", v4i32, v4f32, IntS>, Requires<[HasV8, HasNEON]>;
6331     def UDf : N2VDIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
6332                        "u32.f32", v2i32, v2f32, IntU>, Requires<[HasV8, HasNEON]>;
6333     def UQf : N2VQIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
6334                        "u32.f32", v4i32, v4f32, IntU>, Requires<[HasV8, HasNEON]>;
6335     def SDh : N2VDIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
6336                        "s16.f16", v4i16, v4f16, IntS>,
6337               Requires<[HasV8, HasNEON, HasFullFP16]>;
6338     def SQh : N2VQIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
6339                        "s16.f16", v8i16, v8f16, IntS>,
6340               Requires<[HasV8, HasNEON, HasFullFP16]>;
6341     def UDh : N2VDIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
6342                        "u16.f16", v4i16, v4f16, IntU>,
6343               Requires<[HasV8, HasNEON, HasFullFP16]>;
6344     def UQh : N2VQIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
6345                        "u16.f16", v8i16, v8f16, IntU>,
6346               Requires<[HasV8, HasNEON, HasFullFP16]>;
6347   }
6348 }
6349
6350 defm VCVTAN : VCVT_FPI<"a", 0b000, int_arm_neon_vcvtas, int_arm_neon_vcvtau>;
6351 defm VCVTNN : VCVT_FPI<"n", 0b001, int_arm_neon_vcvtns, int_arm_neon_vcvtnu>;
6352 defm VCVTPN : VCVT_FPI<"p", 0b010, int_arm_neon_vcvtps, int_arm_neon_vcvtpu>;
6353 defm VCVTMN : VCVT_FPI<"m", 0b011, int_arm_neon_vcvtms, int_arm_neon_vcvtmu>;
6354
6355 //   VCVT     : Vector Convert Between Floating-Point and Fixed-Point.
6356 let DecoderMethod = "DecodeVCVTD" in {
6357 def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
6358                         v2i32, v2f32, int_arm_neon_vcvtfp2fxs>;
6359 def VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
6360                         v2i32, v2f32, int_arm_neon_vcvtfp2fxu>;
6361 def VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
6362                         v2f32, v2i32, int_arm_neon_vcvtfxs2fp>;
6363 def VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
6364                         v2f32, v2i32, int_arm_neon_vcvtfxu2fp>;
6365 let Predicates = [HasNEON, HasFullFP16] in {
6366 def VCVTh2xsd : N2VCvtD<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16",
6367                         v4i16, v4f16, int_arm_neon_vcvtfp2fxs>;
6368 def VCVTh2xud : N2VCvtD<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16",
6369                         v4i16, v4f16, int_arm_neon_vcvtfp2fxu>;
6370 def VCVTxs2hd : N2VCvtD<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16",
6371                         v4f16, v4i16, int_arm_neon_vcvtfxs2fp>;
6372 def VCVTxu2hd : N2VCvtD<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16",
6373                         v4f16, v4i16, int_arm_neon_vcvtfxu2fp>;
6374 } // Predicates = [HasNEON, HasFullFP16]
6375 }
6376
6377 let DecoderMethod = "DecodeVCVTQ" in {
6378 def VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
6379                         v4i32, v4f32, int_arm_neon_vcvtfp2fxs>;
6380 def VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
6381                         v4i32, v4f32, int_arm_neon_vcvtfp2fxu>;
6382 def VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
6383                         v4f32, v4i32, int_arm_neon_vcvtfxs2fp>;
6384 def VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
6385                         v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;
6386 let Predicates = [HasNEON, HasFullFP16] in {
6387 def VCVTh2xsq : N2VCvtQ<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16",
6388                         v8i16, v8f16, int_arm_neon_vcvtfp2fxs>;
6389 def VCVTh2xuq : N2VCvtQ<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16",
6390                         v8i16, v8f16, int_arm_neon_vcvtfp2fxu>;
6391 def VCVTxs2hq : N2VCvtQ<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16",
6392                         v8f16, v8i16, int_arm_neon_vcvtfxs2fp>;
6393 def VCVTxu2hq : N2VCvtQ<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16",
6394                         v8f16, v8i16, int_arm_neon_vcvtfxu2fp>;
6395 } // Predicates = [HasNEON, HasFullFP16]
6396 }
6397
6398 def : NEONInstAlias<"vcvt${p}.s32.f32 $Dd, $Dm, #0",
6399                     (VCVTf2sd DPR:$Dd, DPR:$Dm, pred:$p)>;
6400 def : NEONInstAlias<"vcvt${p}.u32.f32 $Dd, $Dm, #0",
6401                     (VCVTf2ud DPR:$Dd, DPR:$Dm, pred:$p)>;
6402 def : NEONInstAlias<"vcvt${p}.f32.s32 $Dd, $Dm, #0",
6403                     (VCVTs2fd DPR:$Dd, DPR:$Dm, pred:$p)>;
6404 def : NEONInstAlias<"vcvt${p}.f32.u32 $Dd, $Dm, #0",
6405                     (VCVTu2fd DPR:$Dd, DPR:$Dm, pred:$p)>;
6406
6407 def : NEONInstAlias<"vcvt${p}.s32.f32 $Qd, $Qm, #0",
6408                     (VCVTf2sq QPR:$Qd, QPR:$Qm, pred:$p)>;
6409 def : NEONInstAlias<"vcvt${p}.u32.f32 $Qd, $Qm, #0",
6410                     (VCVTf2uq QPR:$Qd, QPR:$Qm, pred:$p)>;
6411 def : NEONInstAlias<"vcvt${p}.f32.s32 $Qd, $Qm, #0",
6412                     (VCVTs2fq QPR:$Qd, QPR:$Qm, pred:$p)>;
6413 def : NEONInstAlias<"vcvt${p}.f32.u32 $Qd, $Qm, #0",
6414                     (VCVTu2fq QPR:$Qd, QPR:$Qm, pred:$p)>;
6415
6416 def : NEONInstAlias<"vcvt${p}.s16.f16 $Dd, $Dm, #0",
6417                     (VCVTh2sd DPR:$Dd, DPR:$Dm, pred:$p)>;
6418 def : NEONInstAlias<"vcvt${p}.u16.f16 $Dd, $Dm, #0",
6419                     (VCVTh2ud DPR:$Dd, DPR:$Dm, pred:$p)>;
6420 def : NEONInstAlias<"vcvt${p}.f16.s16 $Dd, $Dm, #0",
6421                     (VCVTs2hd DPR:$Dd, DPR:$Dm, pred:$p)>;
6422 def : NEONInstAlias<"vcvt${p}.f16.u16 $Dd, $Dm, #0",
6423                     (VCVTu2hd DPR:$Dd, DPR:$Dm, pred:$p)>;
6424
6425 def : NEONInstAlias<"vcvt${p}.s16.f16 $Qd, $Qm, #0",
6426                     (VCVTh2sq QPR:$Qd, QPR:$Qm, pred:$p)>;
6427 def : NEONInstAlias<"vcvt${p}.u16.f16 $Qd, $Qm, #0",
6428                     (VCVTh2uq QPR:$Qd, QPR:$Qm, pred:$p)>;
6429 def : NEONInstAlias<"vcvt${p}.f16.s16 $Qd, $Qm, #0",
6430                     (VCVTs2hq QPR:$Qd, QPR:$Qm, pred:$p)>;
6431 def : NEONInstAlias<"vcvt${p}.f16.u16 $Qd, $Qm, #0",
6432                     (VCVTu2hq QPR:$Qd, QPR:$Qm, pred:$p)>;
6433
6434
6435 //   VCVT     : Vector Convert Between Half-Precision and Single-Precision.
6436 def  VCVTf2h  : N2VNInt<0b11, 0b11, 0b01, 0b10, 0b01100, 0, 0,
6437                         IIC_VUNAQ, "vcvt", "f16.f32",
6438                         v4i16, v4f32, int_arm_neon_vcvtfp2hf>,
6439                 Requires<[HasNEON, HasFP16]>;
6440 def  VCVTh2f  : N2VLInt<0b11, 0b11, 0b01, 0b10, 0b01110, 0, 0,
6441                         IIC_VUNAQ, "vcvt", "f32.f16",
6442                         v4f32, v4i16, int_arm_neon_vcvthf2fp>,
6443                 Requires<[HasNEON, HasFP16]>;
6444
6445 // Vector Reverse.
6446
6447 //   VREV64   : Vector Reverse elements within 64-bit doublewords
6448
6449 class VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6450   : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$Vd),
6451         (ins DPR:$Vm), IIC_VMOVD,
6452         OpcodeStr, Dt, "$Vd, $Vm", "",
6453         [(set DPR:$Vd, (Ty (NEONvrev64 (Ty DPR:$Vm))))]>;
6454 class VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6455   : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$Vd),
6456         (ins QPR:$Vm), IIC_VMOVQ,
6457         OpcodeStr, Dt, "$Vd, $Vm", "",
6458         [(set QPR:$Vd, (Ty (NEONvrev64 (Ty QPR:$Vm))))]>;
6459
6460 def VREV64d8  : VREV64D<0b00, "vrev64", "8", v8i8>;
6461 def VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>;
6462 def VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>;
6463 def : Pat<(v2f32 (NEONvrev64 (v2f32 DPR:$Vm))), (VREV64d32 DPR:$Vm)>;
6464
6465 def VREV64q8  : VREV64Q<0b00, "vrev64", "8", v16i8>;
6466 def VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>;
6467 def VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>;
6468 def : Pat<(v4f32 (NEONvrev64 (v4f32 QPR:$Vm))), (VREV64q32 QPR:$Vm)>;
6469
6470 //   VREV32   : Vector Reverse elements within 32-bit words
6471
6472 class VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6473   : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$Vd),
6474         (ins DPR:$Vm), IIC_VMOVD,
6475         OpcodeStr, Dt, "$Vd, $Vm", "",
6476         [(set DPR:$Vd, (Ty (NEONvrev32 (Ty DPR:$Vm))))]>;
6477 class VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6478   : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$Vd),
6479         (ins QPR:$Vm), IIC_VMOVQ,
6480         OpcodeStr, Dt, "$Vd, $Vm", "",
6481         [(set QPR:$Vd, (Ty (NEONvrev32 (Ty QPR:$Vm))))]>;
6482
6483 def VREV32d8  : VREV32D<0b00, "vrev32", "8", v8i8>;
6484 def VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>;
6485
6486 def VREV32q8  : VREV32Q<0b00, "vrev32", "8", v16i8>;
6487 def VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>;
6488
6489 //   VREV16   : Vector Reverse elements within 16-bit halfwords
6490
6491 class VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6492   : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$Vd),
6493         (ins DPR:$Vm), IIC_VMOVD,
6494         OpcodeStr, Dt, "$Vd, $Vm", "",
6495         [(set DPR:$Vd, (Ty (NEONvrev16 (Ty DPR:$Vm))))]>;
6496 class VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
6497   : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$Vd),
6498         (ins QPR:$Vm), IIC_VMOVQ,
6499         OpcodeStr, Dt, "$Vd, $Vm", "",
6500         [(set QPR:$Vd, (Ty (NEONvrev16 (Ty QPR:$Vm))))]>;
6501
6502 def VREV16d8  : VREV16D<0b00, "vrev16", "8", v8i8>;
6503 def VREV16q8  : VREV16Q<0b00, "vrev16", "8", v16i8>;
6504
6505 // Other Vector Shuffles.
6506
6507 //  Aligned extractions: really just dropping registers
6508
6509 class AlignedVEXTq<ValueType DestTy, ValueType SrcTy, SDNodeXForm LaneCVT>
6510       : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))),
6511              (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>;
6512
6513 def : AlignedVEXTq<v8i8, v16i8, DSubReg_i8_reg>;
6514
6515 def : AlignedVEXTq<v4i16, v8i16, DSubReg_i16_reg>;
6516
6517 def : AlignedVEXTq<v2i32, v4i32, DSubReg_i32_reg>;
6518
6519 def : AlignedVEXTq<v1i64, v2i64, DSubReg_f64_reg>;
6520
6521 def : AlignedVEXTq<v2f32, v4f32, DSubReg_i32_reg>;
6522
6523
6524 //   VEXT     : Vector Extract
6525
6526
6527 // All of these have a two-operand InstAlias.
6528 let TwoOperandAliasConstraint = "$Vn = $Vd" in {
6529 class VEXTd<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>
6530   : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd),
6531         (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm,
6532         IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",
6533         [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn),
6534                                      (Ty DPR:$Vm), imm:$index)))]> {
6535   bits<3> index;
6536   let Inst{11} = 0b0;
6537   let Inst{10-8} = index{2-0};
6538 }
6539
6540 class VEXTq<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>
6541   : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd),
6542         (ins QPR:$Vn, QPR:$Vm, imm0_15:$index), NVExtFrm,
6543         IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",
6544         [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn),
6545                                      (Ty QPR:$Vm), imm:$index)))]> {
6546   bits<4> index;
6547   let Inst{11-8} = index{3-0};
6548 }
6549 }
6550
6551 def VEXTd8  : VEXTd<"vext", "8",  v8i8, imm0_7> {
6552   let Inst{10-8} = index{2-0};
6553 }
6554 def VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> {
6555   let Inst{10-9} = index{1-0};
6556   let Inst{8}    = 0b0;
6557 }
6558 def VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> {
6559   let Inst{10}     = index{0};
6560   let Inst{9-8}    = 0b00;
6561 }
6562 def : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn),
6563                            (v2f32 DPR:$Vm),
6564                            (i32 imm:$index))),
6565           (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>;
6566
6567 def VEXTq8  : VEXTq<"vext", "8",  v16i8, imm0_15> {
6568   let Inst{11-8} = index{3-0};
6569 }
6570 def VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> {
6571   let Inst{11-9} = index{2-0};
6572   let Inst{8}    = 0b0;
6573 }
6574 def VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> {
6575   let Inst{11-10} = index{1-0};
6576   let Inst{9-8}    = 0b00;
6577 }
6578 def VEXTq64 : VEXTq<"vext", "64", v2i64, imm0_1> {
6579   let Inst{11} = index{0};
6580   let Inst{10-8}    = 0b000;
6581 }
6582 def : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn),
6583                            (v4f32 QPR:$Vm),
6584                            (i32 imm:$index))),
6585           (VEXTq32 QPR:$Vn, QPR:$Vm, imm:$index)>;
6586
6587 //   VTRN     : Vector Transpose
6588
6589 def  VTRNd8   : N2VDShuffle<0b00, 0b00001, "vtrn", "8">;
6590 def  VTRNd16  : N2VDShuffle<0b01, 0b00001, "vtrn", "16">;
6591 def  VTRNd32  : N2VDShuffle<0b10, 0b00001, "vtrn", "32">;
6592
6593 def  VTRNq8   : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">;
6594 def  VTRNq16  : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">;
6595 def  VTRNq32  : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">;
6596
6597 //   VUZP     : Vector Unzip (Deinterleave)
6598
6599 def  VUZPd8   : N2VDShuffle<0b00, 0b00010, "vuzp", "8">;
6600 def  VUZPd16  : N2VDShuffle<0b01, 0b00010, "vuzp", "16">;
6601 // vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
6602 def : NEONInstAlias<"vuzp${p}.32 $Dd, $Dm",
6603                     (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;
6604
6605 def  VUZPq8   : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">;
6606 def  VUZPq16  : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">;
6607 def  VUZPq32  : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">;
6608
6609 //   VZIP     : Vector Zip (Interleave)
6610
6611 def  VZIPd8   : N2VDShuffle<0b00, 0b00011, "vzip", "8">;
6612 def  VZIPd16  : N2VDShuffle<0b01, 0b00011, "vzip", "16">;
6613 // vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
6614 def : NEONInstAlias<"vzip${p}.32 $Dd, $Dm",
6615                     (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;
6616
6617 def  VZIPq8   : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">;
6618 def  VZIPq16  : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">;
6619 def  VZIPq32  : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">;
6620
6621 // Vector Table Lookup and Table Extension.
6622
6623 //   VTBL     : Vector Table Lookup
6624 let DecoderMethod = "DecodeTBLInstruction" in {
6625 def  VTBL1
6626   : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd),
6627         (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,
6628         "vtbl", "8", "$Vd, $Vn, $Vm", "",
6629         [(set DPR:$Vd, (v8i8 (NEONvtbl1 VecListOneD:$Vn, DPR:$Vm)))]>;
6630
6631 let hasExtraSrcRegAllocReq = 1 in {
6632 def  VTBL2
6633   : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd),
6634         (ins VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB2,
6635         "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
6636 def  VTBL3
6637   : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$Vd),
6638         (ins VecListThreeD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB3,
6639         "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
6640 def  VTBL4
6641   : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$Vd),
6642         (ins VecListFourD:$Vn, DPR:$Vm),
6643         NVTBLFrm, IIC_VTB4,
6644         "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
6645 } // hasExtraSrcRegAllocReq = 1
6646
6647 def  VTBL3Pseudo
6648   : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB3, "", []>;
6649 def  VTBL4Pseudo
6650   : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB4, "", []>;
6651
6652 //   VTBX     : Vector Table Extension
6653 def  VTBX1
6654   : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$Vd),
6655         (ins DPR:$orig, VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX1,
6656         "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd",
6657         [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbx1
6658                                DPR:$orig, VecListOneD:$Vn, DPR:$Vm)))]>;
6659 let hasExtraSrcRegAllocReq = 1 in {
6660 def  VTBX2
6661   : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$Vd),
6662         (ins DPR:$orig, VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX2,
6663         "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", []>;
6664 def  VTBX3
6665   : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$Vd),
6666         (ins DPR:$orig, VecListThreeD:$Vn, DPR:$Vm),
6667         NVTBLFrm, IIC_VTBX3,
6668         "vtbx", "8", "$Vd, $Vn, $Vm",
6669         "$orig = $Vd", []>;
6670 def  VTBX4
6671   : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$Vd),
6672         (ins DPR:$orig, VecListFourD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX4,
6673         "vtbx", "8", "$Vd, $Vn, $Vm",
6674         "$orig = $Vd", []>;
6675 } // hasExtraSrcRegAllocReq = 1
6676
6677 def  VTBX3Pseudo
6678   : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),
6679                 IIC_VTBX3, "$orig = $dst", []>;
6680 def  VTBX4Pseudo
6681   : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),
6682                 IIC_VTBX4, "$orig = $dst", []>;
6683 } // DecoderMethod = "DecodeTBLInstruction"
6684
6685 def : Pat<(v8i8 (NEONvtbl2 v8i8:$Vn0, v8i8:$Vn1, v8i8:$Vm)),
6686           (v8i8 (VTBL2 (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0,
6687                                             v8i8:$Vn1, dsub_1),
6688                        v8i8:$Vm))>;
6689 def : Pat<(v8i8 (int_arm_neon_vtbx2 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,
6690                                     v8i8:$Vm)),
6691           (v8i8 (VTBX2 v8i8:$orig,
6692                        (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0,
6693                                             v8i8:$Vn1, dsub_1),
6694                        v8i8:$Vm))>;
6695
6696 def : Pat<(v8i8 (int_arm_neon_vtbl3 v8i8:$Vn0, v8i8:$Vn1,
6697                                     v8i8:$Vn2, v8i8:$Vm)),
6698           (v8i8 (VTBL3Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,
6699                                                  v8i8:$Vn1, dsub_1,
6700                                                  v8i8:$Vn2, dsub_2,
6701                                                  (v8i8 (IMPLICIT_DEF)), dsub_3),
6702                              v8i8:$Vm))>;
6703 def : Pat<(v8i8 (int_arm_neon_vtbx3 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,
6704                                     v8i8:$Vn2, v8i8:$Vm)),
6705           (v8i8 (VTBX3Pseudo v8i8:$orig,
6706                              (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,
6707                                                  v8i8:$Vn1, dsub_1,
6708                                                  v8i8:$Vn2, dsub_2,
6709                                                  (v8i8 (IMPLICIT_DEF)), dsub_3),
6710                              v8i8:$Vm))>;
6711
6712 def : Pat<(v8i8 (int_arm_neon_vtbl4 v8i8:$Vn0, v8i8:$Vn1,
6713                                     v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)),
6714           (v8i8 (VTBL4Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,
6715                                                  v8i8:$Vn1, dsub_1,
6716                                                  v8i8:$Vn2, dsub_2,
6717                                                  v8i8:$Vn3, dsub_3),
6718                              v8i8:$Vm))>;
6719 def : Pat<(v8i8 (int_arm_neon_vtbx4 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1,
6720                                     v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)),
6721           (v8i8 (VTBX4Pseudo v8i8:$orig,
6722                              (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0,
6723                                                  v8i8:$Vn1, dsub_1,
6724                                                  v8i8:$Vn2, dsub_2,
6725                                                  v8i8:$Vn3, dsub_3),
6726                              v8i8:$Vm))>;
6727
6728 // VRINT      : Vector Rounding
6729 multiclass VRINT_FPI<string op, bits<3> op9_7, SDPatternOperator Int> {
6730   let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
6731     def Df : N2VDIntnp<0b10, 0b10, 0b100, 0, NoItinerary,
6732                       !strconcat("vrint", op), "f32",
6733                       v2f32, v2f32, Int>, Requires<[HasV8, HasNEON]> {
6734       let Inst{9-7} = op9_7;
6735     }
6736     def Qf : N2VQIntnp<0b10, 0b10, 0b100, 0, NoItinerary,
6737                       !strconcat("vrint", op), "f32",
6738                       v4f32, v4f32, Int>, Requires<[HasV8, HasNEON]> {
6739       let Inst{9-7} = op9_7;
6740     }
6741     def Dh : N2VDIntnp<0b01, 0b10, 0b100, 0, NoItinerary,
6742                       !strconcat("vrint", op), "f16",
6743                       v4f16, v4f16, Int>,
6744              Requires<[HasV8, HasNEON, HasFullFP16]> {
6745       let Inst{9-7} = op9_7;
6746     }
6747     def Qh : N2VQIntnp<0b01, 0b10, 0b100, 0, NoItinerary,
6748                       !strconcat("vrint", op), "f16",
6749                       v8f16, v8f16, Int>,
6750              Requires<[HasV8, HasNEON, HasFullFP16]> {
6751       let Inst{9-7} = op9_7;
6752     }
6753   }
6754
6755   def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Dd, $Dm"),
6756                   (!cast<Instruction>(NAME#"Df") DPR:$Dd, DPR:$Dm)>;
6757   def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Qd, $Qm"),
6758                   (!cast<Instruction>(NAME#"Qf") QPR:$Qd, QPR:$Qm)>;
6759   let Predicates = [HasNEON, HasFullFP16] in {
6760   def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Dd, $Dm"),
6761                   (!cast<Instruction>(NAME#"Dh") DPR:$Dd, DPR:$Dm)>;
6762   def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Qd, $Qm"),
6763                   (!cast<Instruction>(NAME#"Qh") QPR:$Qd, QPR:$Qm)>;
6764   }
6765 }
6766
6767 defm VRINTNN : VRINT_FPI<"n", 0b000, int_arm_neon_vrintn>;
6768 defm VRINTXN : VRINT_FPI<"x", 0b001, int_arm_neon_vrintx>;
6769 defm VRINTAN : VRINT_FPI<"a", 0b010, int_arm_neon_vrinta>;
6770 defm VRINTZN : VRINT_FPI<"z", 0b011, int_arm_neon_vrintz>;
6771 defm VRINTMN : VRINT_FPI<"m", 0b101, int_arm_neon_vrintm>;
6772 defm VRINTPN : VRINT_FPI<"p", 0b111, int_arm_neon_vrintp>;
6773
6774 // Cryptography instructions
6775 let PostEncoderMethod = "NEONThumb2DataIPostEncoder",
6776     DecoderNamespace = "v8Crypto", hasSideEffects = 0 in {
6777   class AES<string op, bit op7, bit op6, SDPatternOperator Int>
6778     : N2VQIntXnp<0b00, 0b00, 0b011, op6, op7, NoItinerary,
6779                  !strconcat("aes", op), "8", v16i8, v16i8, Int>,
6780       Requires<[HasV8, HasCrypto]>;
6781   class AES2Op<string op, bit op7, bit op6, SDPatternOperator Int>
6782     : N2VQIntX2np<0b00, 0b00, 0b011, op6, op7, NoItinerary,
6783                  !strconcat("aes", op), "8", v16i8, v16i8, Int>,
6784       Requires<[HasV8, HasCrypto]>;
6785   class N2SHA<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
6786               SDPatternOperator Int>
6787     : N2VQIntXnp<0b10, op17_16, op10_8, op6, op7, NoItinerary,
6788                  !strconcat("sha", op), "32", v4i32, v4i32, Int>,
6789       Requires<[HasV8, HasCrypto]>;
6790   class N2SHA2Op<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
6791               SDPatternOperator Int>
6792     : N2VQIntX2np<0b10, op17_16, op10_8, op6, op7, NoItinerary,
6793                  !strconcat("sha", op), "32", v4i32, v4i32, Int>,
6794       Requires<[HasV8, HasCrypto]>;
6795   class N3SHA3Op<string op, bits<5> op27_23, bits<2> op21_20, SDPatternOperator Int>
6796     : N3VQInt3np<op27_23, op21_20, 0b1100, 1, 0, N3RegFrm, NoItinerary,
6797                 !strconcat("sha", op), "32", v4i32, v4i32, Int, 0>,
6798       Requires<[HasV8, HasCrypto]>;
6799 }
6800
6801 def AESD : AES2Op<"d", 0, 1, int_arm_neon_aesd>;
6802 def AESE : AES2Op<"e", 0, 0, int_arm_neon_aese>;
6803 def AESIMC : AES<"imc", 1, 1, int_arm_neon_aesimc>;
6804 def AESMC : AES<"mc", 1, 0, int_arm_neon_aesmc>;
6805
6806 def SHA1H : N2SHA<"1h", 0b01, 0b010, 1, 1, null_frag>;
6807 def SHA1SU1 : N2SHA2Op<"1su1", 0b10, 0b011, 1, 0, int_arm_neon_sha1su1>;
6808 def SHA256SU0 : N2SHA2Op<"256su0", 0b10, 0b011, 1, 1, int_arm_neon_sha256su0>;
6809 def SHA1C : N3SHA3Op<"1c", 0b00100, 0b00, null_frag>;
6810 def SHA1M : N3SHA3Op<"1m", 0b00100, 0b10, null_frag>;
6811 def SHA1P : N3SHA3Op<"1p", 0b00100, 0b01, null_frag>;
6812 def SHA1SU0 : N3SHA3Op<"1su0", 0b00100, 0b11, int_arm_neon_sha1su0>;
6813 def SHA256H : N3SHA3Op<"256h", 0b00110, 0b00, int_arm_neon_sha256h>;
6814 def SHA256H2 : N3SHA3Op<"256h2", 0b00110, 0b01, int_arm_neon_sha256h2>;
6815 def SHA256SU1 : N3SHA3Op<"256su1", 0b00110, 0b10, int_arm_neon_sha256su1>;
6816
6817 def : Pat<(i32 (int_arm_neon_sha1h i32:$Rn)),
6818           (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG
6819               (SHA1H (SUBREG_TO_REG (i64 0),
6820                                     (f32 (COPY_TO_REGCLASS i32:$Rn, SPR)),
6821                                     ssub_0)),
6822               ssub_0)), GPR)>;
6823
6824 def : Pat<(v4i32 (int_arm_neon_sha1c v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),
6825           (SHA1C v4i32:$hash_abcd,
6826                  (SUBREG_TO_REG (i64 0),
6827                                 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),
6828                                 ssub_0),
6829                  v4i32:$wk)>;
6830
6831 def : Pat<(v4i32 (int_arm_neon_sha1m v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),
6832           (SHA1M v4i32:$hash_abcd,
6833                  (SUBREG_TO_REG (i64 0),
6834                                 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),
6835                                 ssub_0),
6836                  v4i32:$wk)>;
6837
6838 def : Pat<(v4i32 (int_arm_neon_sha1p v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)),
6839           (SHA1P v4i32:$hash_abcd,
6840                  (SUBREG_TO_REG (i64 0),
6841                                 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)),
6842                                 ssub_0),
6843                  v4i32:$wk)>;
6844
6845 //===----------------------------------------------------------------------===//
6846 // NEON instructions for single-precision FP math
6847 //===----------------------------------------------------------------------===//
6848
6849 class N2VSPat<SDNode OpNode, NeonI Inst>
6850   : NEONFPPat<(f32 (OpNode SPR:$a)),
6851               (EXTRACT_SUBREG
6852                (v2f32 (COPY_TO_REGCLASS (Inst
6853                 (INSERT_SUBREG
6854                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6855                  SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>;
6856
6857 class N3VSPat<SDNode OpNode, NeonI Inst>
6858   : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
6859               (EXTRACT_SUBREG
6860                (v2f32 (COPY_TO_REGCLASS (Inst
6861                 (INSERT_SUBREG
6862                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6863                  SPR:$a, ssub_0),
6864                 (INSERT_SUBREG
6865                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6866                  SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;
6867
6868 class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>
6869   : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),
6870               (EXTRACT_SUBREG
6871                (v2f32 (COPY_TO_REGCLASS (Inst
6872                 (INSERT_SUBREG
6873                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6874                  SPR:$acc, ssub_0),
6875                 (INSERT_SUBREG
6876                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6877                  SPR:$a, ssub_0),
6878                 (INSERT_SUBREG
6879                  (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
6880                  SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;
6881
6882 class NVCVTIFPat<SDNode OpNode, NeonI Inst>
6883   : NEONFPPat<(f32 (OpNode GPR:$a)),
6884               (f32 (EXTRACT_SUBREG
6885                      (v2f32 (Inst
6886                        (INSERT_SUBREG
6887                          (v2f32 (IMPLICIT_DEF)),
6888                          (i32 (COPY_TO_REGCLASS GPR:$a, SPR)), ssub_0))),
6889                      ssub_0))>;
6890 class NVCVTFIPat<SDNode OpNode, NeonI Inst>
6891   : NEONFPPat<(i32 (OpNode SPR:$a)),
6892               (i32 (EXTRACT_SUBREG
6893                      (v2f32 (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
6894                                                  SPR:$a, ssub_0))),
6895                      ssub_0))>;
6896
6897 def : N3VSPat<fadd, VADDfd>;
6898 def : N3VSPat<fsub, VSUBfd>;
6899 def : N3VSPat<fmul, VMULfd>;
6900 def : N3VSMulOpPat<fmul, fadd, VMLAfd>,
6901       Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>;
6902 def : N3VSMulOpPat<fmul, fsub, VMLSfd>,
6903       Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>;
6904 def : N3VSMulOpPat<fmul, fadd, VFMAfd>,
6905       Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;
6906 def : N3VSMulOpPat<fmul, fsub, VFMSfd>,
6907       Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;
6908 def : N2VSPat<fabs, VABSfd>;
6909 def : N2VSPat<fneg, VNEGfd>;
6910 def : N3VSPat<fmaxnan, VMAXfd>, Requires<[HasNEON]>;
6911 def : N3VSPat<fminnan, VMINfd>, Requires<[HasNEON]>;
6912 def : NVCVTFIPat<fp_to_sint, VCVTf2sd>;
6913 def : NVCVTFIPat<fp_to_uint, VCVTf2ud>;
6914 def : NVCVTIFPat<sint_to_fp, VCVTs2fd>;
6915 def : NVCVTIFPat<uint_to_fp, VCVTu2fd>;
6916
6917 // NEON doesn't have any f64 conversions, so provide patterns to make
6918 // sure the VFP conversions match when extracting from a vector.
6919 def : VFPPat<(f64 (sint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))),
6920              (VSITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;
6921 def : VFPPat<(f64 (sint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))),
6922              (VSITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>;
6923 def : VFPPat<(f64 (uint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))),
6924              (VUITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;
6925 def : VFPPat<(f64 (uint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))),
6926              (VUITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>;
6927
6928
6929 // Prefer VMOVDRR for i32 -> f32 bitcasts, it can write all DPR registers.
6930 def : Pat<(f32 (bitconvert GPR:$a)),
6931           (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>,
6932         Requires<[HasNEON, DontUseVMOVSR]>;
6933
6934 //===----------------------------------------------------------------------===//
6935 // Non-Instruction Patterns
6936 //===----------------------------------------------------------------------===//
6937
6938 // bit_convert
6939 let Predicates = [IsLE] in {
6940   def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>;
6941   def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>;
6942   def : Pat<(v1i64 (bitconvert (v8i8  DPR:$src))), (v1i64 DPR:$src)>;
6943 }
6944 def : Pat<(v1i64 (bitconvert (f64   DPR:$src))), (v1i64 DPR:$src)>;
6945 let Predicates = [IsLE] in {
6946   def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>;
6947   def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>;
6948   def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>;
6949   def : Pat<(v2i32 (bitconvert (v8i8  DPR:$src))), (v2i32 DPR:$src)>;
6950   def : Pat<(v2i32 (bitconvert (f64   DPR:$src))), (v2i32 DPR:$src)>;
6951 }
6952 def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>;
6953 let Predicates = [IsLE] in {
6954   def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>;
6955   def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>;
6956   def : Pat<(v4i16 (bitconvert (v8i8  DPR:$src))), (v4i16 DPR:$src)>;
6957   def : Pat<(v4i16 (bitconvert (f64   DPR:$src))), (v4i16 DPR:$src)>;
6958   def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>;
6959   def : Pat<(v8i8  (bitconvert (v1i64 DPR:$src))), (v8i8  DPR:$src)>;
6960   def : Pat<(v8i8  (bitconvert (v2i32 DPR:$src))), (v8i8  DPR:$src)>;
6961   def : Pat<(v8i8  (bitconvert (v4i16 DPR:$src))), (v8i8  DPR:$src)>;
6962   def : Pat<(v8i8  (bitconvert (f64   DPR:$src))), (v8i8  DPR:$src)>;
6963   def : Pat<(v8i8  (bitconvert (v2f32 DPR:$src))), (v8i8  DPR:$src)>;
6964 }
6965 def : Pat<(f64   (bitconvert (v1i64 DPR:$src))), (f64   DPR:$src)>;
6966 let Predicates = [IsLE] in {
6967   def : Pat<(f64   (bitconvert (v2i32 DPR:$src))), (f64   DPR:$src)>;
6968   def : Pat<(f64   (bitconvert (v4i16 DPR:$src))), (f64   DPR:$src)>;
6969   def : Pat<(f64   (bitconvert (v8i8  DPR:$src))), (f64   DPR:$src)>;
6970   def : Pat<(f64   (bitconvert (v2f32 DPR:$src))), (f64   DPR:$src)>;
6971   def : Pat<(v2f32 (bitconvert (f64   DPR:$src))), (v2f32 DPR:$src)>;
6972   def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>;
6973 }
6974 def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>;
6975 let Predicates = [IsLE] in {
6976   def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>;
6977   def : Pat<(v2f32 (bitconvert (v8i8  DPR:$src))), (v2f32 DPR:$src)>;
6978 }
6979
6980 let Predicates = [IsLE] in {
6981   def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>;
6982   def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>;
6983   def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>;
6984 }
6985 def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>;
6986 let Predicates = [IsLE] in {
6987   def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>;
6988   def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>;
6989   def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>;
6990   def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>;
6991   def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>;
6992 }
6993 def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>;
6994 let Predicates = [IsLE] in {
6995   def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>;
6996   def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>;
6997   def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>;
6998   def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>;
6999   def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>;
7000   def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>;
7001   def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>;
7002   def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>;
7003   def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>;
7004   def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>;
7005   def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>;
7006 }
7007 def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>;
7008 let Predicates = [IsLE] in {
7009   def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>;
7010   def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>;
7011   def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>;
7012 }
7013 def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>;
7014 let Predicates = [IsLE] in {
7015   def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>;
7016   def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>;
7017   def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>;
7018   def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>;
7019 }
7020
7021 let Predicates = [IsBE] in {
7022   // 64 bit conversions
7023   def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>;
7024   def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>;
7025   def : Pat<(v1i64 (bitconvert (v8i8  DPR:$src))), (VREV64d8  DPR:$src)>;
7026   def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>;
7027   def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>;
7028   def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>;
7029   def : Pat<(v2i32 (bitconvert (v8i8  DPR:$src))), (VREV32d8  DPR:$src)>;
7030   def : Pat<(v2i32 (bitconvert (f64   DPR:$src))), (VREV64d32 DPR:$src)>;
7031   def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>;
7032   def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>;
7033   def : Pat<(v4i16 (bitconvert (v8i8  DPR:$src))), (VREV16d8  DPR:$src)>;
7034   def : Pat<(v4i16 (bitconvert (f64   DPR:$src))), (VREV64d16 DPR:$src)>;
7035   def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>;
7036   def : Pat<(v8i8  (bitconvert (v1i64 DPR:$src))), (VREV64d8  DPR:$src)>;
7037   def : Pat<(v8i8  (bitconvert (v2i32 DPR:$src))), (VREV32d8  DPR:$src)>;
7038   def : Pat<(v8i8  (bitconvert (v4i16 DPR:$src))), (VREV16d8  DPR:$src)>;
7039   def : Pat<(v8i8  (bitconvert (f64   DPR:$src))), (VREV64d8  DPR:$src)>;
7040   def : Pat<(v8i8  (bitconvert (v2f32 DPR:$src))), (VREV32d8  DPR:$src)>;
7041   def : Pat<(f64   (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>;
7042   def : Pat<(f64   (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>;
7043   def : Pat<(f64   (bitconvert (v8i8  DPR:$src))), (VREV64d8  DPR:$src)>;
7044   def : Pat<(f64   (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>;
7045   def : Pat<(v2f32 (bitconvert (f64   DPR:$src))), (VREV64d32 DPR:$src)>;
7046   def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>;
7047   def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>;
7048   def : Pat<(v2f32 (bitconvert (v8i8  DPR:$src))), (VREV32d8  DPR:$src)>;
7049
7050   // 128 bit conversions
7051   def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>;
7052   def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>;
7053   def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (VREV64q8  QPR:$src)>;
7054   def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>;
7055   def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>;
7056   def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>;
7057   def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (VREV32q8  QPR:$src)>;
7058   def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>;
7059   def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>;
7060   def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>;
7061   def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (VREV16q8  QPR:$src)>;
7062   def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>;
7063   def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>;
7064   def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (VREV64q8  QPR:$src)>;
7065   def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (VREV32q8  QPR:$src)>;
7066   def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (VREV16q8  QPR:$src)>;
7067   def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (VREV64q8  QPR:$src)>;
7068   def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (VREV32q8  QPR:$src)>;
7069   def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>;
7070   def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>;
7071   def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (VREV32q8  QPR:$src)>;
7072   def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>;
7073   def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>;
7074   def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>;
7075   def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (VREV64q8  QPR:$src)>;
7076   def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>;
7077 }
7078
7079 // Use VLD1/VST1 + VREV for non-word-aligned v2f64 load/store on Big Endian
7080 def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)),
7081           (VREV64q8 (VLD1q8 addrmode6:$addr))>, Requires<[IsBE]>;
7082 def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
7083           (VST1q8 addrmode6:$addr, (VREV64q8 QPR:$value))>, Requires<[IsBE]>;
7084 def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)),
7085           (VREV64q16 (VLD1q16 addrmode6:$addr))>, Requires<[IsBE]>;
7086 def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
7087           (VST1q16 addrmode6:$addr, (VREV64q16 QPR:$value))>, Requires<[IsBE]>;
7088
7089 // Fold extracting an element out of a v2i32 into a vfp register.
7090 def : Pat<(f32 (bitconvert (i32 (extractelt (v2i32 DPR:$src), imm:$lane)))),
7091           (f32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;
7092
7093 // Vector lengthening move with load, matching extending loads.
7094
7095 // extload, zextload and sextload for a standard lengthening load. Example:
7096 // Lengthen_Single<"8", "i16", "8"> =
7097 //     Pat<(v8i16 (extloadvi8 addrmode6:$addr))
7098 //         (VMOVLuv8i16 (VLD1d8 addrmode6:$addr,
7099 //                              (f64 (IMPLICIT_DEF)), (i32 0)))>;
7100 multiclass Lengthen_Single<string DestLanes, string DestTy, string SrcTy> {
7101   let AddedComplexity = 10 in {
7102   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7103                     (!cast<PatFrag>("extloadvi" # SrcTy) addrmode6:$addr)),
7104                   (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)
7105                     (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
7106
7107   def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7108                   (!cast<PatFrag>("zextloadvi" # SrcTy) addrmode6:$addr)),
7109                 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)
7110                     (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
7111
7112   def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7113                   (!cast<PatFrag>("sextloadvi" # SrcTy) addrmode6:$addr)),
7114                 (!cast<Instruction>("VMOVLsv" # DestLanes # DestTy)
7115                     (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
7116   }
7117 }
7118
7119 // extload, zextload and sextload for a lengthening load which only uses
7120 // half the lanes available. Example:
7121 // Lengthen_HalfSingle<"4", "i16", "8", "i16", "i8"> =
7122 //     Pat<(v4i16 (extloadvi8 addrmode6oneL32:$addr)),
7123 //         (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr,
7124 //                                      (f64 (IMPLICIT_DEF)), (i32 0))),
7125 //                         dsub_0)>;
7126 multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy,
7127                                string InsnLanes, string InsnTy> {
7128   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7129                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
7130        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
7131          (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7132          dsub_0)>;
7133   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7134                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
7135        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
7136          (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7137          dsub_0)>;
7138   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7139                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
7140        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy)
7141          (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7142          dsub_0)>;
7143 }
7144
7145 // The following class definition is basically a copy of the
7146 // Lengthen_HalfSingle definition above, however with an additional parameter
7147 // "RevLanes" to select the correct VREV32dXX instruction. This is to convert
7148 // data loaded by VLD1LN into proper vector format in big endian mode.
7149 multiclass Lengthen_HalfSingle_Big_Endian<string DestLanes, string DestTy, string SrcTy,
7150                                string InsnLanes, string InsnTy, string RevLanes> {
7151   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7152                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
7153        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
7154          (!cast<Instruction>("VREV32d" # RevLanes)
7155            (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7156          dsub_0)>;
7157   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7158                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
7159        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
7160          (!cast<Instruction>("VREV32d" # RevLanes)
7161            (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7162          dsub_0)>;
7163   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7164                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
7165        (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy)
7166          (!cast<Instruction>("VREV32d" # RevLanes)
7167            (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7168          dsub_0)>;
7169 }
7170
7171 // extload, zextload and sextload for a lengthening load followed by another
7172 // lengthening load, to quadruple the initial length.
7173 //
7174 // Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32"> =
7175 //     Pat<(v4i32 (extloadvi8 addrmode6oneL32:$addr))
7176 //         (EXTRACT_SUBREG (VMOVLuv4i32
7177 //           (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr,
7178 //                                                   (f64 (IMPLICIT_DEF)),
7179 //                                                   (i32 0))),
7180 //                           dsub_0)),
7181 //           dsub_0)>;
7182 multiclass Lengthen_Double<string DestLanes, string DestTy, string SrcTy,
7183                            string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
7184                            string Insn2Ty> {
7185   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7186                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
7187          (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7188            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7189              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7190              dsub_0))>;
7191   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7192                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
7193          (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7194            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7195              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7196              dsub_0))>;
7197   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7198                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
7199          (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
7200            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
7201              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7202              dsub_0))>;
7203 }
7204
7205 // The following class definition is basically a copy of the
7206 // Lengthen_Double definition above, however with an additional parameter
7207 // "RevLanes" to select the correct VREV32dXX instruction. This is to convert
7208 // data loaded by VLD1LN into proper vector format in big endian mode.
7209 multiclass Lengthen_Double_Big_Endian<string DestLanes, string DestTy, string SrcTy,
7210                            string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
7211                            string Insn2Ty, string RevLanes> {
7212   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7213                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
7214          (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7215            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7216             (!cast<Instruction>("VREV32d" # RevLanes)
7217              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7218              dsub_0))>;
7219   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7220                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
7221          (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7222            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7223             (!cast<Instruction>("VREV32d" # RevLanes)
7224              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7225              dsub_0))>;
7226   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7227                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
7228          (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
7229            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
7230             (!cast<Instruction>("VREV32d" # RevLanes)
7231              (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7232              dsub_0))>;
7233 }
7234
7235 // extload, zextload and sextload for a lengthening load followed by another
7236 // lengthening load, to quadruple the initial length, but which ends up only
7237 // requiring half the available lanes (a 64-bit outcome instead of a 128-bit).
7238 //
7239 // Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> =
7240 // Pat<(v2i32 (extloadvi8 addrmode6:$addr))
7241 //     (EXTRACT_SUBREG (VMOVLuv4i32
7242 //       (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd16 addrmode6:$addr,
7243 //                                               (f64 (IMPLICIT_DEF)), (i32 0))),
7244 //                       dsub_0)),
7245 //       dsub_0)>;
7246 multiclass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy,
7247                            string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
7248                            string Insn2Ty> {
7249   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7250                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)),
7251          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7252            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7253              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7254              dsub_0)),
7255           dsub_0)>;
7256   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7257                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)),
7258          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7259            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7260              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7261              dsub_0)),
7262           dsub_0)>;
7263   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7264                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)),
7265          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
7266            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
7267              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
7268              dsub_0)),
7269           dsub_0)>;
7270 }
7271
7272 // The following class definition is basically a copy of the
7273 // Lengthen_HalfDouble definition above, however with an additional VREV16d8
7274 // instruction to convert data loaded by VLD1LN into proper vector format
7275 // in big endian mode.
7276 multiclass Lengthen_HalfDouble_Big_Endian<string DestLanes, string DestTy, string SrcTy,
7277                            string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
7278                            string Insn2Ty> {
7279   def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7280                    (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)),
7281          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7282            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7283             (!cast<Instruction>("VREV16d8")
7284              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7285              dsub_0)),
7286           dsub_0)>;
7287   def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7288                    (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)),
7289          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
7290            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
7291             (!cast<Instruction>("VREV16d8")
7292              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7293              dsub_0)),
7294           dsub_0)>;
7295   def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
7296                    (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)),
7297          (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
7298            (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
7299             (!cast<Instruction>("VREV16d8")
7300              (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))),
7301              dsub_0)),
7302           dsub_0)>;
7303 }
7304
7305 defm : Lengthen_Single<"8", "i16", "8">; // v8i8 -> v8i16
7306 defm : Lengthen_Single<"4", "i32", "16">; // v4i16 -> v4i32
7307 defm : Lengthen_Single<"2", "i64", "32">; // v2i32 -> v2i64
7308
7309 let Predicates = [IsLE] in {
7310   defm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i16
7311   defm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i32
7312
7313   // Double lengthening - v4i8 -> v4i16 -> v4i32
7314   defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">;
7315   // v2i8 -> v2i16 -> v2i32
7316   defm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">;
7317   // v2i16 -> v2i32 -> v2i64
7318   defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">;
7319 }
7320
7321 let Predicates = [IsBE] in {
7322   defm : Lengthen_HalfSingle_Big_Endian<"4", "i16", "i8", "8", "i16", "8">; // v4i8 -> v4i16
7323   defm : Lengthen_HalfSingle_Big_Endian<"2", "i32", "i16", "4", "i32", "16">; // v2i16 -> v2i32
7324
7325   // Double lengthening - v4i8 -> v4i16 -> v4i32
7326   defm : Lengthen_Double_Big_Endian<"4", "i32", "i8", "8", "i16", "4", "i32", "8">;
7327   // v2i8 -> v2i16 -> v2i32
7328   defm : Lengthen_HalfDouble_Big_Endian<"2", "i32", "i8", "8", "i16", "4", "i32">;
7329   // v2i16 -> v2i32 -> v2i64
7330   defm : Lengthen_Double_Big_Endian<"2", "i64", "i16", "4", "i32", "2", "i64", "16">;
7331 }
7332
7333 // Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i64
7334 let Predicates = [IsLE] in {
7335   def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)),
7336         (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
7337            (VLD1LNd16 addrmode6:$addr,
7338                       (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
7339   def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)),
7340         (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
7341            (VLD1LNd16 addrmode6:$addr,
7342                       (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
7343   def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)),
7344         (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16
7345            (VLD1LNd16 addrmode6:$addr,
7346                       (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
7347 }
7348 // The following patterns are basically a copy of the patterns above, 
7349 // however with an additional VREV16d instruction to convert data
7350 // loaded by VLD1LN into proper vector format in big endian mode.
7351 let Predicates = [IsBE] in {
7352   def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)),
7353         (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
7354            (!cast<Instruction>("VREV16d8")
7355              (VLD1LNd16 addrmode6:$addr,
7356                         (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;
7357   def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)),
7358         (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
7359            (!cast<Instruction>("VREV16d8")
7360              (VLD1LNd16 addrmode6:$addr,
7361                         (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;
7362   def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)),
7363         (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16
7364            (!cast<Instruction>("VREV16d8")
7365              (VLD1LNd16 addrmode6:$addr,
7366                         (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>;
7367 }
7368
7369 def : Pat<(v2i64 (concat_vectors DPR:$Dn, DPR:$Dm)),
7370           (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;
7371 def : Pat<(v4i32 (concat_vectors DPR:$Dn, DPR:$Dm)),
7372           (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;
7373 def : Pat<(v8i16 (concat_vectors DPR:$Dn, DPR:$Dm)),
7374           (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;
7375 def : Pat<(v16i8 (concat_vectors DPR:$Dn, DPR:$Dm)),
7376           (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;
7377 def : Pat<(v4f32 (concat_vectors DPR:$Dn, DPR:$Dm)),
7378           (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>;
7379
7380 //===----------------------------------------------------------------------===//
7381 // Assembler aliases
7382 //
7383
7384 def : VFP2InstAlias<"fmdhr${p} $Dd, $Rn",
7385                     (VSETLNi32 DPR:$Dd, GPR:$Rn, 1, pred:$p)>;
7386 def : VFP2InstAlias<"fmdlr${p} $Dd, $Rn",
7387                     (VSETLNi32 DPR:$Dd, GPR:$Rn, 0, pred:$p)>;
7388
7389 // VAND/VBIC/VEOR/VORR accept but do not require a type suffix.
7390 defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",
7391                          (VANDd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7392 defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",
7393                          (VANDq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7394 defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",
7395                          (VBICd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7396 defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",
7397                          (VBICq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7398 defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",
7399                          (VEORd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7400 defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",
7401                          (VEORq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7402 defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",
7403                          (VORRd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7404 defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",
7405                          (VORRq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7406 // ... two-operand aliases
7407 defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",
7408                          (VANDd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
7409 defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",
7410                          (VANDq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
7411 defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",
7412                          (VEORd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
7413 defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",
7414                          (VEORq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
7415 defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",
7416                          (VORRd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
7417 defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",
7418                          (VORRq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
7419 // ... immediates
7420 def : NEONInstAlias<"vand${p}.i16 $Vd, $imm",
7421                     (VBICiv4i16 DPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>;
7422 def : NEONInstAlias<"vand${p}.i32 $Vd, $imm",
7423                     (VBICiv2i32 DPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>;
7424 def : NEONInstAlias<"vand${p}.i16 $Vd, $imm",
7425                     (VBICiv8i16 QPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>;
7426 def : NEONInstAlias<"vand${p}.i32 $Vd, $imm",
7427                     (VBICiv4i32 QPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>;
7428
7429
7430 // VLD1 single-lane pseudo-instructions. These need special handling for
7431 // the lane index that an InstAlias can't handle, so we use these instead.
7432 def VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr",
7433                  (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7434                       pred:$p)>;
7435 def VLD1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr",
7436                  (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7437                       pred:$p)>;
7438 def VLD1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr",
7439                  (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7440                       pred:$p)>;
7441
7442 def VLD1LNdWB_fixed_Asm_8 :
7443         NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr!",
7444                  (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7445                       pred:$p)>;
7446 def VLD1LNdWB_fixed_Asm_16 :
7447         NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr!",
7448                  (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7449                       pred:$p)>;
7450 def VLD1LNdWB_fixed_Asm_32 :
7451         NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr!",
7452                  (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7453                       pred:$p)>;
7454 def VLD1LNdWB_register_Asm_8 :
7455         NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr, $Rm",
7456                   (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7457                        rGPR:$Rm, pred:$p)>;
7458 def VLD1LNdWB_register_Asm_16 :
7459         NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr, $Rm",
7460                   (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7461                        rGPR:$Rm, pred:$p)>;
7462 def VLD1LNdWB_register_Asm_32 :
7463         NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr, $Rm",
7464                   (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7465                        rGPR:$Rm, pred:$p)>;
7466
7467
7468 // VST1 single-lane pseudo-instructions. These need special handling for
7469 // the lane index that an InstAlias can't handle, so we use these instead.
7470 def VST1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr",
7471                  (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7472                       pred:$p)>;
7473 def VST1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr",
7474                  (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7475                       pred:$p)>;
7476 def VST1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr",
7477                  (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7478                       pred:$p)>;
7479
7480 def VST1LNdWB_fixed_Asm_8 :
7481         NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr!",
7482                  (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7483                       pred:$p)>;
7484 def VST1LNdWB_fixed_Asm_16 :
7485         NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr!",
7486                  (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7487                       pred:$p)>;
7488 def VST1LNdWB_fixed_Asm_32 :
7489         NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr!",
7490                  (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7491                       pred:$p)>;
7492 def VST1LNdWB_register_Asm_8 :
7493         NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr, $Rm",
7494                   (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr,
7495                        rGPR:$Rm, pred:$p)>;
7496 def VST1LNdWB_register_Asm_16 :
7497         NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr, $Rm",
7498                   (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr,
7499                        rGPR:$Rm, pred:$p)>;
7500 def VST1LNdWB_register_Asm_32 :
7501         NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr, $Rm",
7502                   (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr,
7503                        rGPR:$Rm, pred:$p)>;
7504
7505 // VLD2 single-lane pseudo-instructions. These need special handling for
7506 // the lane index that an InstAlias can't handle, so we use these instead.
7507 def VLD2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr",
7508                  (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7509                   pred:$p)>;
7510 def VLD2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",
7511                  (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7512                       pred:$p)>;
7513 def VLD2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",
7514                  (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, pred:$p)>;
7515 def VLD2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",
7516                  (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7517                       pred:$p)>;
7518 def VLD2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",
7519                  (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7520                       pred:$p)>;
7521
7522 def VLD2LNdWB_fixed_Asm_8 :
7523         NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr!",
7524                  (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7525                       pred:$p)>;
7526 def VLD2LNdWB_fixed_Asm_16 :
7527         NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",
7528                  (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7529                       pred:$p)>;
7530 def VLD2LNdWB_fixed_Asm_32 :
7531         NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",
7532                  (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,
7533                       pred:$p)>;
7534 def VLD2LNqWB_fixed_Asm_16 :
7535         NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",
7536                  (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7537                       pred:$p)>;
7538 def VLD2LNqWB_fixed_Asm_32 :
7539         NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",
7540                  (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7541                       pred:$p)>;
7542 def VLD2LNdWB_register_Asm_8 :
7543         NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr, $Rm",
7544                   (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7545                        rGPR:$Rm, pred:$p)>;
7546 def VLD2LNdWB_register_Asm_16 :
7547         NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",
7548                   (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7549                        rGPR:$Rm, pred:$p)>;
7550 def VLD2LNdWB_register_Asm_32 :
7551         NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",
7552                   (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,
7553                        rGPR:$Rm, pred:$p)>;
7554 def VLD2LNqWB_register_Asm_16 :
7555         NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",
7556                   (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7557                        rGPR:$Rm, pred:$p)>;
7558 def VLD2LNqWB_register_Asm_32 :
7559         NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",
7560                   (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7561                        rGPR:$Rm, pred:$p)>;
7562
7563
7564 // VST2 single-lane pseudo-instructions. These need special handling for
7565 // the lane index that an InstAlias can't handle, so we use these instead.
7566 def VST2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr",
7567                  (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7568                       pred:$p)>;
7569 def VST2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",
7570                  (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7571                       pred:$p)>;
7572 def VST2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",
7573                  (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,
7574                       pred:$p)>;
7575 def VST2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",
7576                  (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7577                       pred:$p)>;
7578 def VST2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",
7579                  (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7580                       pred:$p)>;
7581
7582 def VST2LNdWB_fixed_Asm_8 :
7583         NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr!",
7584                  (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7585                       pred:$p)>;
7586 def VST2LNdWB_fixed_Asm_16 :
7587         NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",
7588                  (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7589                       pred:$p)>;
7590 def VST2LNdWB_fixed_Asm_32 :
7591         NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",
7592                  (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,
7593                       pred:$p)>;
7594 def VST2LNqWB_fixed_Asm_16 :
7595         NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",
7596                  (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7597                       pred:$p)>;
7598 def VST2LNqWB_fixed_Asm_32 :
7599         NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",
7600                  (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7601                       pred:$p)>;
7602 def VST2LNdWB_register_Asm_8 :
7603         NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr, $Rm",
7604                   (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr,
7605                        rGPR:$Rm, pred:$p)>;
7606 def VST2LNdWB_register_Asm_16 :
7607         NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",
7608                   (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr,
7609                        rGPR:$Rm, pred:$p)>;
7610 def VST2LNdWB_register_Asm_32 :
7611         NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",
7612                   (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr,
7613                        rGPR:$Rm, pred:$p)>;
7614 def VST2LNqWB_register_Asm_16 :
7615         NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",
7616                   (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr,
7617                        rGPR:$Rm, pred:$p)>;
7618 def VST2LNqWB_register_Asm_32 :
7619         NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",
7620                   (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr,
7621                        rGPR:$Rm, pred:$p)>;
7622
7623 // VLD3 all-lanes pseudo-instructions. These need special handling for
7624 // the lane index that an InstAlias can't handle, so we use these instead.
7625 def VLD3DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
7626                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7627                     pred:$p)>;
7628 def VLD3DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7629                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7630                     pred:$p)>;
7631 def VLD3DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7632                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7633                     pred:$p)>;
7634 def VLD3DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
7635                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7636                     pred:$p)>;
7637 def VLD3DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7638                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7639                     pred:$p)>;
7640 def VLD3DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7641                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7642                     pred:$p)>;
7643
7644 def VLD3DUPdWB_fixed_Asm_8 :
7645         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
7646                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7647                     pred:$p)>;
7648 def VLD3DUPdWB_fixed_Asm_16 :
7649         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7650                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7651                     pred:$p)>;
7652 def VLD3DUPdWB_fixed_Asm_32 :
7653         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7654                (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7655                     pred:$p)>;
7656 def VLD3DUPqWB_fixed_Asm_8 :
7657         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
7658                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7659                     pred:$p)>;
7660 def VLD3DUPqWB_fixed_Asm_16 :
7661         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7662                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7663                     pred:$p)>;
7664 def VLD3DUPqWB_fixed_Asm_32 :
7665         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7666                (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7667                     pred:$p)>;
7668 def VLD3DUPdWB_register_Asm_8 :
7669         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
7670                   (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7671                        rGPR:$Rm, pred:$p)>;
7672 def VLD3DUPdWB_register_Asm_16 :
7673         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7674                   (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7675                        rGPR:$Rm, pred:$p)>;
7676 def VLD3DUPdWB_register_Asm_32 :
7677         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7678                   (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr,
7679                        rGPR:$Rm, pred:$p)>;
7680 def VLD3DUPqWB_register_Asm_8 :
7681         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
7682                   (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7683                        rGPR:$Rm, pred:$p)>;
7684 def VLD3DUPqWB_register_Asm_16 :
7685         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7686                   (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7687                        rGPR:$Rm, pred:$p)>;
7688 def VLD3DUPqWB_register_Asm_32 :
7689         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7690                   (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr,
7691                        rGPR:$Rm, pred:$p)>;
7692
7693
7694 // VLD3 single-lane pseudo-instructions. These need special handling for
7695 // the lane index that an InstAlias can't handle, so we use these instead.
7696 def VLD3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
7697                (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7698                     pred:$p)>;
7699 def VLD3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7700                (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,
7701                     pred:$p)>;
7702 def VLD3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7703                (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7704                     pred:$p)>;
7705 def VLD3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7706                (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,
7707                     pred:$p)>;
7708 def VLD3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7709                (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7710                     pred:$p)>;
7711
7712 def VLD3LNdWB_fixed_Asm_8 :
7713         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
7714                (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7715                     pred:$p)>;
7716 def VLD3LNdWB_fixed_Asm_16 :
7717         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7718                (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,
7719                     pred:$p)>;
7720 def VLD3LNdWB_fixed_Asm_32 :
7721         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7722                (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7723                     pred:$p)>;
7724 def VLD3LNqWB_fixed_Asm_16 :
7725         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7726                (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,
7727                     pred:$p)>;
7728 def VLD3LNqWB_fixed_Asm_32 :
7729         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7730                (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7731                     pred:$p)>;
7732 def VLD3LNdWB_register_Asm_8 :
7733         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
7734                   (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7735                        rGPR:$Rm, pred:$p)>;
7736 def VLD3LNdWB_register_Asm_16 :
7737         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7738                   (ins VecListThreeDHWordIndexed:$list,
7739                        addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;
7740 def VLD3LNdWB_register_Asm_32 :
7741         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7742                   (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7743                        rGPR:$Rm, pred:$p)>;
7744 def VLD3LNqWB_register_Asm_16 :
7745         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7746                   (ins VecListThreeQHWordIndexed:$list,
7747                        addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;
7748 def VLD3LNqWB_register_Asm_32 :
7749         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7750                   (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7751                        rGPR:$Rm, pred:$p)>;
7752
7753 // VLD3 multiple structure pseudo-instructions. These need special handling for
7754 // the vector operands that the normal instructions don't yet model.
7755 // FIXME: Remove these when the register classes and instructions are updated.
7756 def VLD3dAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
7757                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7758 def VLD3dAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7759                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7760 def VLD3dAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7761                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7762 def VLD3qAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
7763                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7764 def VLD3qAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
7765                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7766 def VLD3qAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
7767                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7768
7769 def VLD3dWB_fixed_Asm_8 :
7770         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
7771                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7772 def VLD3dWB_fixed_Asm_16 :
7773         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7774                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7775 def VLD3dWB_fixed_Asm_32 :
7776         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7777                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7778 def VLD3qWB_fixed_Asm_8 :
7779         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
7780                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7781 def VLD3qWB_fixed_Asm_16 :
7782         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
7783                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7784 def VLD3qWB_fixed_Asm_32 :
7785         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
7786                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7787 def VLD3dWB_register_Asm_8 :
7788         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
7789                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7790                        rGPR:$Rm, pred:$p)>;
7791 def VLD3dWB_register_Asm_16 :
7792         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7793                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7794                        rGPR:$Rm, pred:$p)>;
7795 def VLD3dWB_register_Asm_32 :
7796         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7797                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7798                        rGPR:$Rm, pred:$p)>;
7799 def VLD3qWB_register_Asm_8 :
7800         NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
7801                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7802                        rGPR:$Rm, pred:$p)>;
7803 def VLD3qWB_register_Asm_16 :
7804         NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
7805                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7806                        rGPR:$Rm, pred:$p)>;
7807 def VLD3qWB_register_Asm_32 :
7808         NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
7809                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7810                        rGPR:$Rm, pred:$p)>;
7811
7812 // VST3 single-lane pseudo-instructions. These need special handling for
7813 // the lane index that an InstAlias can't handle, so we use these instead.
7814 def VST3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
7815                (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7816                     pred:$p)>;
7817 def VST3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
7818                (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,
7819                     pred:$p)>;
7820 def VST3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
7821                (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7822                     pred:$p)>;
7823 def VST3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
7824                (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,
7825                     pred:$p)>;
7826 def VST3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
7827                (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7828                     pred:$p)>;
7829
7830 def VST3LNdWB_fixed_Asm_8 :
7831         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
7832                (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7833                     pred:$p)>;
7834 def VST3LNdWB_fixed_Asm_16 :
7835         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
7836                (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr,
7837                     pred:$p)>;
7838 def VST3LNdWB_fixed_Asm_32 :
7839         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
7840                (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7841                     pred:$p)>;
7842 def VST3LNqWB_fixed_Asm_16 :
7843         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
7844                (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr,
7845                     pred:$p)>;
7846 def VST3LNqWB_fixed_Asm_32 :
7847         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
7848                (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7849                     pred:$p)>;
7850 def VST3LNdWB_register_Asm_8 :
7851         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
7852                   (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr,
7853                        rGPR:$Rm, pred:$p)>;
7854 def VST3LNdWB_register_Asm_16 :
7855         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
7856                   (ins VecListThreeDHWordIndexed:$list,
7857                        addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;
7858 def VST3LNdWB_register_Asm_32 :
7859         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
7860                   (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr,
7861                        rGPR:$Rm, pred:$p)>;
7862 def VST3LNqWB_register_Asm_16 :
7863         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
7864                   (ins VecListThreeQHWordIndexed:$list,
7865                        addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>;
7866 def VST3LNqWB_register_Asm_32 :
7867         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
7868                   (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr,
7869                        rGPR:$Rm, pred:$p)>;
7870
7871
7872 // VST3 multiple structure pseudo-instructions. These need special handling for
7873 // the vector operands that the normal instructions don't yet model.
7874 // FIXME: Remove these when the register classes and instructions are updated.
7875 def VST3dAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
7876                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7877 def VST3dAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
7878                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7879 def VST3dAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
7880                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7881 def VST3qAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
7882                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7883 def VST3qAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
7884                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7885 def VST3qAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
7886                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7887
7888 def VST3dWB_fixed_Asm_8 :
7889         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
7890                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7891 def VST3dWB_fixed_Asm_16 :
7892         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
7893                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7894 def VST3dWB_fixed_Asm_32 :
7895         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
7896                (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>;
7897 def VST3qWB_fixed_Asm_8 :
7898         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
7899                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7900 def VST3qWB_fixed_Asm_16 :
7901         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
7902                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7903 def VST3qWB_fixed_Asm_32 :
7904         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
7905                (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>;
7906 def VST3dWB_register_Asm_8 :
7907         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
7908                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7909                        rGPR:$Rm, pred:$p)>;
7910 def VST3dWB_register_Asm_16 :
7911         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
7912                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7913                        rGPR:$Rm, pred:$p)>;
7914 def VST3dWB_register_Asm_32 :
7915         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
7916                   (ins VecListThreeD:$list, addrmode6align64:$addr,
7917                        rGPR:$Rm, pred:$p)>;
7918 def VST3qWB_register_Asm_8 :
7919         NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
7920                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7921                        rGPR:$Rm, pred:$p)>;
7922 def VST3qWB_register_Asm_16 :
7923         NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
7924                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7925                        rGPR:$Rm, pred:$p)>;
7926 def VST3qWB_register_Asm_32 :
7927         NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
7928                   (ins VecListThreeQ:$list, addrmode6align64:$addr,
7929                        rGPR:$Rm, pred:$p)>;
7930
7931 // VLD4 all-lanes pseudo-instructions. These need special handling for
7932 // the lane index that an InstAlias can't handle, so we use these instead.
7933 def VLD4DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
7934                (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,
7935                     pred:$p)>;
7936 def VLD4DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
7937                (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,
7938                     pred:$p)>;
7939 def VLD4DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
7940                (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr,
7941                     pred:$p)>;
7942 def VLD4DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
7943                (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,
7944                     pred:$p)>;
7945 def VLD4DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
7946                (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,
7947                     pred:$p)>;
7948 def VLD4DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
7949                (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr,
7950                     pred:$p)>;
7951
7952 def VLD4DUPdWB_fixed_Asm_8 :
7953         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
7954                (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,
7955                     pred:$p)>;
7956 def VLD4DUPdWB_fixed_Asm_16 :
7957         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
7958                (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,
7959                     pred:$p)>;
7960 def VLD4DUPdWB_fixed_Asm_32 :
7961         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
7962                (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr,
7963                     pred:$p)>;
7964 def VLD4DUPqWB_fixed_Asm_8 :
7965         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
7966                (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,
7967                     pred:$p)>;
7968 def VLD4DUPqWB_fixed_Asm_16 :
7969         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
7970                (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,
7971                     pred:$p)>;
7972 def VLD4DUPqWB_fixed_Asm_32 :
7973         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
7974                (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr,
7975                     pred:$p)>;
7976 def VLD4DUPdWB_register_Asm_8 :
7977         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
7978                   (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr,
7979                        rGPR:$Rm, pred:$p)>;
7980 def VLD4DUPdWB_register_Asm_16 :
7981         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
7982                   (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr,
7983                        rGPR:$Rm, pred:$p)>;
7984 def VLD4DUPdWB_register_Asm_32 :
7985         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
7986                   (ins VecListFourDAllLanes:$list,
7987                        addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>;
7988 def VLD4DUPqWB_register_Asm_8 :
7989         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
7990                   (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr,
7991                        rGPR:$Rm, pred:$p)>;
7992 def VLD4DUPqWB_register_Asm_16 :
7993         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
7994                   (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr,
7995                        rGPR:$Rm, pred:$p)>;
7996 def VLD4DUPqWB_register_Asm_32 :
7997         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
7998                   (ins VecListFourQAllLanes:$list,
7999                        addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>;
8000
8001
8002 // VLD4 single-lane pseudo-instructions. These need special handling for
8003 // the lane index that an InstAlias can't handle, so we use these instead.
8004 def VLD4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
8005                (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8006                     pred:$p)>;
8007 def VLD4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
8008                (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8009                     pred:$p)>;
8010 def VLD4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
8011                (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,
8012                     pred:$p)>;
8013 def VLD4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
8014                (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8015                     pred:$p)>;
8016 def VLD4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
8017                (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,
8018                     pred:$p)>;
8019
8020 def VLD4LNdWB_fixed_Asm_8 :
8021         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
8022                (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8023                     pred:$p)>;
8024 def VLD4LNdWB_fixed_Asm_16 :
8025         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
8026                (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8027                     pred:$p)>;
8028 def VLD4LNdWB_fixed_Asm_32 :
8029         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
8030                (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,
8031                     pred:$p)>;
8032 def VLD4LNqWB_fixed_Asm_16 :
8033         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
8034                (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8035                     pred:$p)>;
8036 def VLD4LNqWB_fixed_Asm_32 :
8037         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
8038                (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,
8039                     pred:$p)>;
8040 def VLD4LNdWB_register_Asm_8 :
8041         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
8042                   (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8043                        rGPR:$Rm, pred:$p)>;
8044 def VLD4LNdWB_register_Asm_16 :
8045         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
8046                   (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8047                        rGPR:$Rm, pred:$p)>;
8048 def VLD4LNdWB_register_Asm_32 :
8049         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
8050                   (ins VecListFourDWordIndexed:$list,
8051                        addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;
8052 def VLD4LNqWB_register_Asm_16 :
8053         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
8054                   (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8055                        rGPR:$Rm, pred:$p)>;
8056 def VLD4LNqWB_register_Asm_32 :
8057         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
8058                   (ins VecListFourQWordIndexed:$list,
8059                        addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;
8060
8061
8062
8063 // VLD4 multiple structure pseudo-instructions. These need special handling for
8064 // the vector operands that the normal instructions don't yet model.
8065 // FIXME: Remove these when the register classes and instructions are updated.
8066 def VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
8067                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8068                 pred:$p)>;
8069 def VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
8070                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8071                 pred:$p)>;
8072 def VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
8073                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8074                 pred:$p)>;
8075 def VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
8076                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8077                 pred:$p)>;
8078 def VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
8079                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8080                 pred:$p)>;
8081 def VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
8082                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8083                 pred:$p)>;
8084
8085 def VLD4dWB_fixed_Asm_8 :
8086         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
8087                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8088                 pred:$p)>;
8089 def VLD4dWB_fixed_Asm_16 :
8090         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
8091                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8092                 pred:$p)>;
8093 def VLD4dWB_fixed_Asm_32 :
8094         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
8095                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8096                 pred:$p)>;
8097 def VLD4qWB_fixed_Asm_8 :
8098         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
8099                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8100                 pred:$p)>;
8101 def VLD4qWB_fixed_Asm_16 :
8102         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
8103                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8104                 pred:$p)>;
8105 def VLD4qWB_fixed_Asm_32 :
8106         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
8107                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8108                 pred:$p)>;
8109 def VLD4dWB_register_Asm_8 :
8110         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
8111                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8112                        rGPR:$Rm, pred:$p)>;
8113 def VLD4dWB_register_Asm_16 :
8114         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
8115                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8116                        rGPR:$Rm, pred:$p)>;
8117 def VLD4dWB_register_Asm_32 :
8118         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
8119                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8120                        rGPR:$Rm, pred:$p)>;
8121 def VLD4qWB_register_Asm_8 :
8122         NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
8123                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8124                        rGPR:$Rm, pred:$p)>;
8125 def VLD4qWB_register_Asm_16 :
8126         NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
8127                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8128                        rGPR:$Rm, pred:$p)>;
8129 def VLD4qWB_register_Asm_32 :
8130         NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
8131                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8132                        rGPR:$Rm, pred:$p)>;
8133
8134 // VST4 single-lane pseudo-instructions. These need special handling for
8135 // the lane index that an InstAlias can't handle, so we use these instead.
8136 def VST4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
8137                (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8138                     pred:$p)>;
8139 def VST4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
8140                (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8141                     pred:$p)>;
8142 def VST4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
8143                (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,
8144                     pred:$p)>;
8145 def VST4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
8146                (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8147                     pred:$p)>;
8148 def VST4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
8149                (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,
8150                     pred:$p)>;
8151
8152 def VST4LNdWB_fixed_Asm_8 :
8153         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
8154                (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8155                     pred:$p)>;
8156 def VST4LNdWB_fixed_Asm_16 :
8157         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
8158                (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8159                     pred:$p)>;
8160 def VST4LNdWB_fixed_Asm_32 :
8161         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
8162                (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr,
8163                     pred:$p)>;
8164 def VST4LNqWB_fixed_Asm_16 :
8165         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
8166                (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8167                     pred:$p)>;
8168 def VST4LNqWB_fixed_Asm_32 :
8169         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
8170                (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr,
8171                     pred:$p)>;
8172 def VST4LNdWB_register_Asm_8 :
8173         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
8174                   (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr,
8175                        rGPR:$Rm, pred:$p)>;
8176 def VST4LNdWB_register_Asm_16 :
8177         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
8178                   (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr,
8179                        rGPR:$Rm, pred:$p)>;
8180 def VST4LNdWB_register_Asm_32 :
8181         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
8182                   (ins VecListFourDWordIndexed:$list,
8183                        addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;
8184 def VST4LNqWB_register_Asm_16 :
8185         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
8186                   (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr,
8187                        rGPR:$Rm, pred:$p)>;
8188 def VST4LNqWB_register_Asm_32 :
8189         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
8190                   (ins VecListFourQWordIndexed:$list,
8191                        addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>;
8192
8193
8194 // VST4 multiple structure pseudo-instructions. These need special handling for
8195 // the vector operands that the normal instructions don't yet model.
8196 // FIXME: Remove these when the register classes and instructions are updated.
8197 def VST4dAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
8198                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8199                     pred:$p)>;
8200 def VST4dAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
8201                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8202                     pred:$p)>;
8203 def VST4dAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
8204                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8205                     pred:$p)>;
8206 def VST4qAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
8207                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8208                     pred:$p)>;
8209 def VST4qAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
8210                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8211                     pred:$p)>;
8212 def VST4qAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
8213                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8214                     pred:$p)>;
8215
8216 def VST4dWB_fixed_Asm_8 :
8217         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
8218                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8219                     pred:$p)>;
8220 def VST4dWB_fixed_Asm_16 :
8221         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
8222                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8223                     pred:$p)>;
8224 def VST4dWB_fixed_Asm_32 :
8225         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
8226                (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8227                     pred:$p)>;
8228 def VST4qWB_fixed_Asm_8 :
8229         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
8230                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8231                     pred:$p)>;
8232 def VST4qWB_fixed_Asm_16 :
8233         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
8234                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8235                     pred:$p)>;
8236 def VST4qWB_fixed_Asm_32 :
8237         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
8238                (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8239                     pred:$p)>;
8240 def VST4dWB_register_Asm_8 :
8241         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
8242                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8243                        rGPR:$Rm, pred:$p)>;
8244 def VST4dWB_register_Asm_16 :
8245         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
8246                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8247                        rGPR:$Rm, pred:$p)>;
8248 def VST4dWB_register_Asm_32 :
8249         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
8250                   (ins VecListFourD:$list, addrmode6align64or128or256:$addr,
8251                        rGPR:$Rm, pred:$p)>;
8252 def VST4qWB_register_Asm_8 :
8253         NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
8254                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8255                        rGPR:$Rm, pred:$p)>;
8256 def VST4qWB_register_Asm_16 :
8257         NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
8258                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8259                        rGPR:$Rm, pred:$p)>;
8260 def VST4qWB_register_Asm_32 :
8261         NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
8262                   (ins VecListFourQ:$list, addrmode6align64or128or256:$addr,
8263                        rGPR:$Rm, pred:$p)>;
8264
8265 // VMOV/VMVN takes an optional datatype suffix
8266 defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",
8267                          (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;
8268 defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",
8269                          (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;
8270
8271 defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",
8272                          (VMVNd DPR:$Vd, DPR:$Vm, pred:$p)>;
8273 defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",
8274                          (VMVNq QPR:$Vd, QPR:$Vm, pred:$p)>;
8275
8276 // VCLT (register) is an assembler alias for VCGT w/ the operands reversed.
8277 // D-register versions.
8278 def : NEONInstAlias<"vcle${p}.s8 $Dd, $Dn, $Dm",
8279                     (VCGEsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8280 def : NEONInstAlias<"vcle${p}.s16 $Dd, $Dn, $Dm",
8281                     (VCGEsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8282 def : NEONInstAlias<"vcle${p}.s32 $Dd, $Dn, $Dm",
8283                     (VCGEsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8284 def : NEONInstAlias<"vcle${p}.u8 $Dd, $Dn, $Dm",
8285                     (VCGEuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8286 def : NEONInstAlias<"vcle${p}.u16 $Dd, $Dn, $Dm",
8287                     (VCGEuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8288 def : NEONInstAlias<"vcle${p}.u32 $Dd, $Dn, $Dm",
8289                     (VCGEuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8290 def : NEONInstAlias<"vcle${p}.f32 $Dd, $Dn, $Dm",
8291                     (VCGEfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8292 let Predicates = [HasNEON, HasFullFP16] in
8293 def : NEONInstAlias<"vcle${p}.f16 $Dd, $Dn, $Dm",
8294                     (VCGEhd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8295 // Q-register versions.
8296 def : NEONInstAlias<"vcle${p}.s8 $Qd, $Qn, $Qm",
8297                     (VCGEsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8298 def : NEONInstAlias<"vcle${p}.s16 $Qd, $Qn, $Qm",
8299                     (VCGEsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8300 def : NEONInstAlias<"vcle${p}.s32 $Qd, $Qn, $Qm",
8301                     (VCGEsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8302 def : NEONInstAlias<"vcle${p}.u8 $Qd, $Qn, $Qm",
8303                     (VCGEuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8304 def : NEONInstAlias<"vcle${p}.u16 $Qd, $Qn, $Qm",
8305                     (VCGEuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8306 def : NEONInstAlias<"vcle${p}.u32 $Qd, $Qn, $Qm",
8307                     (VCGEuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8308 def : NEONInstAlias<"vcle${p}.f32 $Qd, $Qn, $Qm",
8309                     (VCGEfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8310 let Predicates = [HasNEON, HasFullFP16] in
8311 def : NEONInstAlias<"vcle${p}.f16 $Qd, $Qn, $Qm",
8312                     (VCGEhq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8313
8314 // VCLT (register) is an assembler alias for VCGT w/ the operands reversed.
8315 // D-register versions.
8316 def : NEONInstAlias<"vclt${p}.s8 $Dd, $Dn, $Dm",
8317                     (VCGTsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8318 def : NEONInstAlias<"vclt${p}.s16 $Dd, $Dn, $Dm",
8319                     (VCGTsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8320 def : NEONInstAlias<"vclt${p}.s32 $Dd, $Dn, $Dm",
8321                     (VCGTsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8322 def : NEONInstAlias<"vclt${p}.u8 $Dd, $Dn, $Dm",
8323                     (VCGTuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8324 def : NEONInstAlias<"vclt${p}.u16 $Dd, $Dn, $Dm",
8325                     (VCGTuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8326 def : NEONInstAlias<"vclt${p}.u32 $Dd, $Dn, $Dm",
8327                     (VCGTuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8328 def : NEONInstAlias<"vclt${p}.f32 $Dd, $Dn, $Dm",
8329                     (VCGTfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8330 let Predicates = [HasNEON, HasFullFP16] in
8331 def : NEONInstAlias<"vclt${p}.f16 $Dd, $Dn, $Dm",
8332                     (VCGThd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
8333 // Q-register versions.
8334 def : NEONInstAlias<"vclt${p}.s8 $Qd, $Qn, $Qm",
8335                     (VCGTsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8336 def : NEONInstAlias<"vclt${p}.s16 $Qd, $Qn, $Qm",
8337                     (VCGTsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8338 def : NEONInstAlias<"vclt${p}.s32 $Qd, $Qn, $Qm",
8339                     (VCGTsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8340 def : NEONInstAlias<"vclt${p}.u8 $Qd, $Qn, $Qm",
8341                     (VCGTuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8342 def : NEONInstAlias<"vclt${p}.u16 $Qd, $Qn, $Qm",
8343                     (VCGTuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8344 def : NEONInstAlias<"vclt${p}.u32 $Qd, $Qn, $Qm",
8345                     (VCGTuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8346 def : NEONInstAlias<"vclt${p}.f32 $Qd, $Qn, $Qm",
8347                     (VCGTfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8348 let Predicates = [HasNEON, HasFullFP16] in
8349 def : NEONInstAlias<"vclt${p}.f16 $Qd, $Qn, $Qm",
8350                     (VCGThq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
8351
8352 // VSWP allows, but does not require, a type suffix.
8353 defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",
8354                          (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>;
8355 defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",
8356                          (VSWPq QPR:$Vd, QPR:$Vm, pred:$p)>;
8357
8358 // VBIF, VBIT, and VBSL allow, but do not require, a type suffix.
8359 defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",
8360                          (VBIFd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
8361 defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",
8362                          (VBITd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
8363 defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",
8364                          (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
8365 defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",
8366                          (VBIFq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
8367 defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",
8368                          (VBITq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
8369 defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",
8370                          (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
8371
8372 // "vmov Rd, #-imm" can be handled via "vmvn".
8373 def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",
8374                     (VMVNv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
8375 def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",
8376                     (VMVNv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
8377 def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",
8378                     (VMOVv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
8379 def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",
8380                     (VMOVv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
8381
8382 // 'gas' compatibility aliases for quad-word instructions. Strictly speaking,
8383 // these should restrict to just the Q register variants, but the register
8384 // classes are enough to match correctly regardless, so we keep it simple
8385 // and just use MnemonicAlias.
8386 def : NEONMnemonicAlias<"vbicq", "vbic">;
8387 def : NEONMnemonicAlias<"vandq", "vand">;
8388 def : NEONMnemonicAlias<"veorq", "veor">;
8389 def : NEONMnemonicAlias<"vorrq", "vorr">;
8390
8391 def : NEONMnemonicAlias<"vmovq", "vmov">;
8392 def : NEONMnemonicAlias<"vmvnq", "vmvn">;
8393 // Explicit versions for floating point so that the FPImm variants get
8394 // handled early. The parser gets confused otherwise.
8395 def : NEONMnemonicAlias<"vmovq.f32", "vmov.f32">;
8396 def : NEONMnemonicAlias<"vmovq.f64", "vmov.f64">;
8397
8398 def : NEONMnemonicAlias<"vaddq", "vadd">;
8399 def : NEONMnemonicAlias<"vsubq", "vsub">;
8400
8401 def : NEONMnemonicAlias<"vminq", "vmin">;
8402 def : NEONMnemonicAlias<"vmaxq", "vmax">;
8403
8404 def : NEONMnemonicAlias<"vmulq", "vmul">;
8405
8406 def : NEONMnemonicAlias<"vabsq", "vabs">;
8407
8408 def : NEONMnemonicAlias<"vshlq", "vshl">;
8409 def : NEONMnemonicAlias<"vshrq", "vshr">;
8410
8411 def : NEONMnemonicAlias<"vcvtq", "vcvt">;
8412
8413 def : NEONMnemonicAlias<"vcleq", "vcle">;
8414 def : NEONMnemonicAlias<"vceqq", "vceq">;
8415
8416 def : NEONMnemonicAlias<"vzipq", "vzip">;
8417 def : NEONMnemonicAlias<"vswpq", "vswp">;
8418
8419 def : NEONMnemonicAlias<"vrecpeq.f32", "vrecpe.f32">;
8420 def : NEONMnemonicAlias<"vrecpeq.u32", "vrecpe.u32">;
8421
8422
8423 // Alias for loading floating point immediates that aren't representable
8424 // using the vmov.f32 encoding but the bitpattern is representable using
8425 // the .i32 encoding.
8426 def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",
8427                      (VMOVv4i32 QPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;
8428 def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",
8429                      (VMOVv2i32 DPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;