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