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