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