1234353Sdim//===-- ARMInstrNEON.td - NEON support for ARM -------------*- tablegen -*-===//
2194710Sed//
3194710Sed//                     The LLVM Compiler Infrastructure
4194710Sed//
5194710Sed// This file is distributed under the University of Illinois Open Source
6194710Sed// License. See LICENSE.TXT for details.
7194710Sed//
8194710Sed//===----------------------------------------------------------------------===//
9194710Sed//
10194710Sed// This file describes the ARM NEON instruction set.
11194710Sed//
12194710Sed//===----------------------------------------------------------------------===//
13194710Sed
14226633Sdim
15194710Sed//===----------------------------------------------------------------------===//
16226633Sdim// NEON-specific Operands.
17226633Sdim//===----------------------------------------------------------------------===//
18234353Sdimdef nModImm : Operand<i32> {
19234353Sdim  let PrintMethod = "printNEONModImmOperand";
20234353Sdim}
21234353Sdim
22234353Sdimdef nImmSplatI8AsmOperand : AsmOperandClass { let Name = "NEONi8splat"; }
23234353Sdimdef nImmSplatI8 : Operand<i32> {
24234353Sdim  let PrintMethod = "printNEONModImmOperand";
25234353Sdim  let ParserMatchClass = nImmSplatI8AsmOperand;
26234353Sdim}
27234353Sdimdef nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; }
28234353Sdimdef nImmSplatI16 : Operand<i32> {
29234353Sdim  let PrintMethod = "printNEONModImmOperand";
30234353Sdim  let ParserMatchClass = nImmSplatI16AsmOperand;
31234353Sdim}
32234353Sdimdef nImmSplatI32AsmOperand : AsmOperandClass { let Name = "NEONi32splat"; }
33234353Sdimdef nImmSplatI32 : Operand<i32> {
34234353Sdim  let PrintMethod = "printNEONModImmOperand";
35234353Sdim  let ParserMatchClass = nImmSplatI32AsmOperand;
36234353Sdim}
37234353Sdimdef nImmVMOVI32AsmOperand : AsmOperandClass { let Name = "NEONi32vmov"; }
38234353Sdimdef nImmVMOVI32 : Operand<i32> {
39234353Sdim  let PrintMethod = "printNEONModImmOperand";
40234353Sdim  let ParserMatchClass = nImmVMOVI32AsmOperand;
41234353Sdim}
42234353Sdimdef nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; }
43234353Sdimdef nImmVMOVI32Neg : Operand<i32> {
44234353Sdim  let PrintMethod = "printNEONModImmOperand";
45234353Sdim  let ParserMatchClass = nImmVMOVI32NegAsmOperand;
46234353Sdim}
47234353Sdimdef nImmVMOVF32 : Operand<i32> {
48234353Sdim  let PrintMethod = "printFPImmOperand";
49234353Sdim  let ParserMatchClass = FPImmOperand;
50234353Sdim}
51234353Sdimdef nImmSplatI64AsmOperand : AsmOperandClass { let Name = "NEONi64splat"; }
52234353Sdimdef nImmSplatI64 : Operand<i32> {
53234353Sdim  let PrintMethod = "printNEONModImmOperand";
54234353Sdim  let ParserMatchClass = nImmSplatI64AsmOperand;
55234353Sdim}
56234353Sdim
57226633Sdimdef VectorIndex8Operand  : AsmOperandClass { let Name = "VectorIndex8"; }
58226633Sdimdef VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; }
59226633Sdimdef VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; }
60226633Sdimdef VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{
61226633Sdim  return ((uint64_t)Imm) < 8;
62226633Sdim}]> {
63226633Sdim  let ParserMatchClass = VectorIndex8Operand;
64226633Sdim  let PrintMethod = "printVectorIndex";
65226633Sdim  let MIOperandInfo = (ops i32imm);
66226633Sdim}
67226633Sdimdef VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{
68226633Sdim  return ((uint64_t)Imm) < 4;
69226633Sdim}]> {
70226633Sdim  let ParserMatchClass = VectorIndex16Operand;
71226633Sdim  let PrintMethod = "printVectorIndex";
72226633Sdim  let MIOperandInfo = (ops i32imm);
73226633Sdim}
74226633Sdimdef VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{
75226633Sdim  return ((uint64_t)Imm) < 2;
76226633Sdim}]> {
77226633Sdim  let ParserMatchClass = VectorIndex32Operand;
78226633Sdim  let PrintMethod = "printVectorIndex";
79226633Sdim  let MIOperandInfo = (ops i32imm);
80226633Sdim}
81226633Sdim
82234353Sdim// Register list of one D register.
83234353Sdimdef VecListOneDAsmOperand : AsmOperandClass {
84234353Sdim  let Name = "VecListOneD";
85234353Sdim  let ParserMethod = "parseVectorList";
86234353Sdim  let RenderMethod = "addVecListOperands";
87234353Sdim}
88234353Sdimdef VecListOneD : RegisterOperand<DPR, "printVectorListOne"> {
89234353Sdim  let ParserMatchClass = VecListOneDAsmOperand;
90234353Sdim}
91234353Sdim// Register list of two sequential D registers.
92234353Sdimdef VecListDPairAsmOperand : AsmOperandClass {
93234353Sdim  let Name = "VecListDPair";
94234353Sdim  let ParserMethod = "parseVectorList";
95234353Sdim  let RenderMethod = "addVecListOperands";
96234353Sdim}
97234353Sdimdef VecListDPair : RegisterOperand<DPair, "printVectorListTwo"> {
98234353Sdim  let ParserMatchClass = VecListDPairAsmOperand;
99234353Sdim}
100234353Sdim// Register list of three sequential D registers.
101234353Sdimdef VecListThreeDAsmOperand : AsmOperandClass {
102234353Sdim  let Name = "VecListThreeD";
103234353Sdim  let ParserMethod = "parseVectorList";
104234353Sdim  let RenderMethod = "addVecListOperands";
105234353Sdim}
106234353Sdimdef VecListThreeD : RegisterOperand<DPR, "printVectorListThree"> {
107234353Sdim  let ParserMatchClass = VecListThreeDAsmOperand;
108234353Sdim}
109234353Sdim// Register list of four sequential D registers.
110234353Sdimdef VecListFourDAsmOperand : AsmOperandClass {
111234353Sdim  let Name = "VecListFourD";
112234353Sdim  let ParserMethod = "parseVectorList";
113234353Sdim  let RenderMethod = "addVecListOperands";
114234353Sdim}
115234353Sdimdef VecListFourD : RegisterOperand<DPR, "printVectorListFour"> {
116234353Sdim  let ParserMatchClass = VecListFourDAsmOperand;
117234353Sdim}
118234353Sdim// Register list of two D registers spaced by 2 (two sequential Q registers).
119234353Sdimdef VecListDPairSpacedAsmOperand : AsmOperandClass {
120234353Sdim  let Name = "VecListDPairSpaced";
121234353Sdim  let ParserMethod = "parseVectorList";
122234353Sdim  let RenderMethod = "addVecListOperands";
123234353Sdim}
124234353Sdimdef VecListDPairSpaced : RegisterOperand<DPair, "printVectorListTwoSpaced"> {
125234353Sdim  let ParserMatchClass = VecListDPairSpacedAsmOperand;
126234353Sdim}
127234353Sdim// Register list of three D registers spaced by 2 (three Q registers).
128234353Sdimdef VecListThreeQAsmOperand : AsmOperandClass {
129234353Sdim  let Name = "VecListThreeQ";
130234353Sdim  let ParserMethod = "parseVectorList";
131234353Sdim  let RenderMethod = "addVecListOperands";
132234353Sdim}
133234353Sdimdef VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> {
134234353Sdim  let ParserMatchClass = VecListThreeQAsmOperand;
135234353Sdim}
136234353Sdim// Register list of three D registers spaced by 2 (three Q registers).
137234353Sdimdef VecListFourQAsmOperand : AsmOperandClass {
138234353Sdim  let Name = "VecListFourQ";
139234353Sdim  let ParserMethod = "parseVectorList";
140234353Sdim  let RenderMethod = "addVecListOperands";
141234353Sdim}
142234353Sdimdef VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> {
143234353Sdim  let ParserMatchClass = VecListFourQAsmOperand;
144234353Sdim}
145234353Sdim
146234353Sdim// Register list of one D register, with "all lanes" subscripting.
147234353Sdimdef VecListOneDAllLanesAsmOperand : AsmOperandClass {
148234353Sdim  let Name = "VecListOneDAllLanes";
149234353Sdim  let ParserMethod = "parseVectorList";
150234353Sdim  let RenderMethod = "addVecListOperands";
151234353Sdim}
152234353Sdimdef VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> {
153234353Sdim  let ParserMatchClass = VecListOneDAllLanesAsmOperand;
154234353Sdim}
155234353Sdim// Register list of two D registers, with "all lanes" subscripting.
156234353Sdimdef VecListDPairAllLanesAsmOperand : AsmOperandClass {
157234353Sdim  let Name = "VecListDPairAllLanes";
158234353Sdim  let ParserMethod = "parseVectorList";
159234353Sdim  let RenderMethod = "addVecListOperands";
160234353Sdim}
161234353Sdimdef VecListDPairAllLanes : RegisterOperand<DPair,
162234353Sdim                                           "printVectorListTwoAllLanes"> {
163234353Sdim  let ParserMatchClass = VecListDPairAllLanesAsmOperand;
164234353Sdim}
165234353Sdim// Register list of two D registers spaced by 2 (two sequential Q registers).
166234353Sdimdef VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass {
167234353Sdim  let Name = "VecListDPairSpacedAllLanes";
168234353Sdim  let ParserMethod = "parseVectorList";
169234353Sdim  let RenderMethod = "addVecListOperands";
170234353Sdim}
171234353Sdimdef VecListDPairSpacedAllLanes : RegisterOperand<DPair,
172234353Sdim                                         "printVectorListTwoSpacedAllLanes"> {
173234353Sdim  let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand;
174234353Sdim}
175234353Sdim// Register list of three D registers, with "all lanes" subscripting.
176234353Sdimdef VecListThreeDAllLanesAsmOperand : AsmOperandClass {
177234353Sdim  let Name = "VecListThreeDAllLanes";
178234353Sdim  let ParserMethod = "parseVectorList";
179234353Sdim  let RenderMethod = "addVecListOperands";
180234353Sdim}
181234353Sdimdef VecListThreeDAllLanes : RegisterOperand<DPR,
182234353Sdim                                            "printVectorListThreeAllLanes"> {
183234353Sdim  let ParserMatchClass = VecListThreeDAllLanesAsmOperand;
184234353Sdim}
185234353Sdim// Register list of three D registers spaced by 2 (three sequential Q regs).
186234353Sdimdef VecListThreeQAllLanesAsmOperand : AsmOperandClass {
187234353Sdim  let Name = "VecListThreeQAllLanes";
188234353Sdim  let ParserMethod = "parseVectorList";
189234353Sdim  let RenderMethod = "addVecListOperands";
190234353Sdim}
191234353Sdimdef VecListThreeQAllLanes : RegisterOperand<DPR,
192234353Sdim                                         "printVectorListThreeSpacedAllLanes"> {
193234353Sdim  let ParserMatchClass = VecListThreeQAllLanesAsmOperand;
194234353Sdim}
195234353Sdim// Register list of four D registers, with "all lanes" subscripting.
196234353Sdimdef VecListFourDAllLanesAsmOperand : AsmOperandClass {
197234353Sdim  let Name = "VecListFourDAllLanes";
198234353Sdim  let ParserMethod = "parseVectorList";
199234353Sdim  let RenderMethod = "addVecListOperands";
200234353Sdim}
201234353Sdimdef VecListFourDAllLanes : RegisterOperand<DPR, "printVectorListFourAllLanes"> {
202234353Sdim  let ParserMatchClass = VecListFourDAllLanesAsmOperand;
203234353Sdim}
204234353Sdim// Register list of four D registers spaced by 2 (four sequential Q regs).
205234353Sdimdef VecListFourQAllLanesAsmOperand : AsmOperandClass {
206234353Sdim  let Name = "VecListFourQAllLanes";
207234353Sdim  let ParserMethod = "parseVectorList";
208234353Sdim  let RenderMethod = "addVecListOperands";
209234353Sdim}
210234353Sdimdef VecListFourQAllLanes : RegisterOperand<DPR,
211234353Sdim                                         "printVectorListFourSpacedAllLanes"> {
212234353Sdim  let ParserMatchClass = VecListFourQAllLanesAsmOperand;
213234353Sdim}
214234353Sdim
215234353Sdim
216234353Sdim// Register list of one D register, with byte lane subscripting.
217234353Sdimdef VecListOneDByteIndexAsmOperand : AsmOperandClass {
218234353Sdim  let Name = "VecListOneDByteIndexed";
219234353Sdim  let ParserMethod = "parseVectorList";
220234353Sdim  let RenderMethod = "addVecListIndexedOperands";
221234353Sdim}
222234353Sdimdef VecListOneDByteIndexed : Operand<i32> {
223234353Sdim  let ParserMatchClass = VecListOneDByteIndexAsmOperand;
224234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
225234353Sdim}
226234353Sdim// ...with half-word lane subscripting.
227234353Sdimdef VecListOneDHWordIndexAsmOperand : AsmOperandClass {
228234353Sdim  let Name = "VecListOneDHWordIndexed";
229234353Sdim  let ParserMethod = "parseVectorList";
230234353Sdim  let RenderMethod = "addVecListIndexedOperands";
231234353Sdim}
232234353Sdimdef VecListOneDHWordIndexed : Operand<i32> {
233234353Sdim  let ParserMatchClass = VecListOneDHWordIndexAsmOperand;
234234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
235234353Sdim}
236234353Sdim// ...with word lane subscripting.
237234353Sdimdef VecListOneDWordIndexAsmOperand : AsmOperandClass {
238234353Sdim  let Name = "VecListOneDWordIndexed";
239234353Sdim  let ParserMethod = "parseVectorList";
240234353Sdim  let RenderMethod = "addVecListIndexedOperands";
241234353Sdim}
242234353Sdimdef VecListOneDWordIndexed : Operand<i32> {
243234353Sdim  let ParserMatchClass = VecListOneDWordIndexAsmOperand;
244234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
245234353Sdim}
246234353Sdim
247234353Sdim// Register list of two D registers with byte lane subscripting.
248234353Sdimdef VecListTwoDByteIndexAsmOperand : AsmOperandClass {
249234353Sdim  let Name = "VecListTwoDByteIndexed";
250234353Sdim  let ParserMethod = "parseVectorList";
251234353Sdim  let RenderMethod = "addVecListIndexedOperands";
252234353Sdim}
253234353Sdimdef VecListTwoDByteIndexed : Operand<i32> {
254234353Sdim  let ParserMatchClass = VecListTwoDByteIndexAsmOperand;
255234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
256234353Sdim}
257234353Sdim// ...with half-word lane subscripting.
258234353Sdimdef VecListTwoDHWordIndexAsmOperand : AsmOperandClass {
259234353Sdim  let Name = "VecListTwoDHWordIndexed";
260234353Sdim  let ParserMethod = "parseVectorList";
261234353Sdim  let RenderMethod = "addVecListIndexedOperands";
262234353Sdim}
263234353Sdimdef VecListTwoDHWordIndexed : Operand<i32> {
264234353Sdim  let ParserMatchClass = VecListTwoDHWordIndexAsmOperand;
265234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
266234353Sdim}
267234353Sdim// ...with word lane subscripting.
268234353Sdimdef VecListTwoDWordIndexAsmOperand : AsmOperandClass {
269234353Sdim  let Name = "VecListTwoDWordIndexed";
270234353Sdim  let ParserMethod = "parseVectorList";
271234353Sdim  let RenderMethod = "addVecListIndexedOperands";
272234353Sdim}
273234353Sdimdef VecListTwoDWordIndexed : Operand<i32> {
274234353Sdim  let ParserMatchClass = VecListTwoDWordIndexAsmOperand;
275234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
276234353Sdim}
277234353Sdim// Register list of two Q registers with half-word lane subscripting.
278234353Sdimdef VecListTwoQHWordIndexAsmOperand : AsmOperandClass {
279234353Sdim  let Name = "VecListTwoQHWordIndexed";
280234353Sdim  let ParserMethod = "parseVectorList";
281234353Sdim  let RenderMethod = "addVecListIndexedOperands";
282234353Sdim}
283234353Sdimdef VecListTwoQHWordIndexed : Operand<i32> {
284234353Sdim  let ParserMatchClass = VecListTwoQHWordIndexAsmOperand;
285234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
286234353Sdim}
287234353Sdim// ...with word lane subscripting.
288234353Sdimdef VecListTwoQWordIndexAsmOperand : AsmOperandClass {
289234353Sdim  let Name = "VecListTwoQWordIndexed";
290234353Sdim  let ParserMethod = "parseVectorList";
291234353Sdim  let RenderMethod = "addVecListIndexedOperands";
292234353Sdim}
293234353Sdimdef VecListTwoQWordIndexed : Operand<i32> {
294234353Sdim  let ParserMatchClass = VecListTwoQWordIndexAsmOperand;
295234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
296234353Sdim}
297234353Sdim
298234353Sdim
299234353Sdim// Register list of three D registers with byte lane subscripting.
300234353Sdimdef VecListThreeDByteIndexAsmOperand : AsmOperandClass {
301234353Sdim  let Name = "VecListThreeDByteIndexed";
302234353Sdim  let ParserMethod = "parseVectorList";
303234353Sdim  let RenderMethod = "addVecListIndexedOperands";
304234353Sdim}
305234353Sdimdef VecListThreeDByteIndexed : Operand<i32> {
306234353Sdim  let ParserMatchClass = VecListThreeDByteIndexAsmOperand;
307234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
308234353Sdim}
309234353Sdim// ...with half-word lane subscripting.
310234353Sdimdef VecListThreeDHWordIndexAsmOperand : AsmOperandClass {
311234353Sdim  let Name = "VecListThreeDHWordIndexed";
312234353Sdim  let ParserMethod = "parseVectorList";
313234353Sdim  let RenderMethod = "addVecListIndexedOperands";
314234353Sdim}
315234353Sdimdef VecListThreeDHWordIndexed : Operand<i32> {
316234353Sdim  let ParserMatchClass = VecListThreeDHWordIndexAsmOperand;
317234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
318234353Sdim}
319234353Sdim// ...with word lane subscripting.
320234353Sdimdef VecListThreeDWordIndexAsmOperand : AsmOperandClass {
321234353Sdim  let Name = "VecListThreeDWordIndexed";
322234353Sdim  let ParserMethod = "parseVectorList";
323234353Sdim  let RenderMethod = "addVecListIndexedOperands";
324234353Sdim}
325234353Sdimdef VecListThreeDWordIndexed : Operand<i32> {
326234353Sdim  let ParserMatchClass = VecListThreeDWordIndexAsmOperand;
327234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
328234353Sdim}
329234353Sdim// Register list of three Q registers with half-word lane subscripting.
330234353Sdimdef VecListThreeQHWordIndexAsmOperand : AsmOperandClass {
331234353Sdim  let Name = "VecListThreeQHWordIndexed";
332234353Sdim  let ParserMethod = "parseVectorList";
333234353Sdim  let RenderMethod = "addVecListIndexedOperands";
334234353Sdim}
335234353Sdimdef VecListThreeQHWordIndexed : Operand<i32> {
336234353Sdim  let ParserMatchClass = VecListThreeQHWordIndexAsmOperand;
337234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
338234353Sdim}
339234353Sdim// ...with word lane subscripting.
340234353Sdimdef VecListThreeQWordIndexAsmOperand : AsmOperandClass {
341234353Sdim  let Name = "VecListThreeQWordIndexed";
342234353Sdim  let ParserMethod = "parseVectorList";
343234353Sdim  let RenderMethod = "addVecListIndexedOperands";
344234353Sdim}
345234353Sdimdef VecListThreeQWordIndexed : Operand<i32> {
346234353Sdim  let ParserMatchClass = VecListThreeQWordIndexAsmOperand;
347234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
348234353Sdim}
349234353Sdim
350234353Sdim// Register list of four D registers with byte lane subscripting.
351234353Sdimdef VecListFourDByteIndexAsmOperand : AsmOperandClass {
352234353Sdim  let Name = "VecListFourDByteIndexed";
353234353Sdim  let ParserMethod = "parseVectorList";
354234353Sdim  let RenderMethod = "addVecListIndexedOperands";
355234353Sdim}
356234353Sdimdef VecListFourDByteIndexed : Operand<i32> {
357234353Sdim  let ParserMatchClass = VecListFourDByteIndexAsmOperand;
358234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
359234353Sdim}
360234353Sdim// ...with half-word lane subscripting.
361234353Sdimdef VecListFourDHWordIndexAsmOperand : AsmOperandClass {
362234353Sdim  let Name = "VecListFourDHWordIndexed";
363234353Sdim  let ParserMethod = "parseVectorList";
364234353Sdim  let RenderMethod = "addVecListIndexedOperands";
365234353Sdim}
366234353Sdimdef VecListFourDHWordIndexed : Operand<i32> {
367234353Sdim  let ParserMatchClass = VecListFourDHWordIndexAsmOperand;
368234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
369234353Sdim}
370234353Sdim// ...with word lane subscripting.
371234353Sdimdef VecListFourDWordIndexAsmOperand : AsmOperandClass {
372234353Sdim  let Name = "VecListFourDWordIndexed";
373234353Sdim  let ParserMethod = "parseVectorList";
374234353Sdim  let RenderMethod = "addVecListIndexedOperands";
375234353Sdim}
376234353Sdimdef VecListFourDWordIndexed : Operand<i32> {
377234353Sdim  let ParserMatchClass = VecListFourDWordIndexAsmOperand;
378234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
379234353Sdim}
380234353Sdim// Register list of four Q registers with half-word lane subscripting.
381234353Sdimdef VecListFourQHWordIndexAsmOperand : AsmOperandClass {
382234353Sdim  let Name = "VecListFourQHWordIndexed";
383234353Sdim  let ParserMethod = "parseVectorList";
384234353Sdim  let RenderMethod = "addVecListIndexedOperands";
385234353Sdim}
386234353Sdimdef VecListFourQHWordIndexed : Operand<i32> {
387234353Sdim  let ParserMatchClass = VecListFourQHWordIndexAsmOperand;
388234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
389234353Sdim}
390234353Sdim// ...with word lane subscripting.
391234353Sdimdef VecListFourQWordIndexAsmOperand : AsmOperandClass {
392234353Sdim  let Name = "VecListFourQWordIndexed";
393234353Sdim  let ParserMethod = "parseVectorList";
394234353Sdim  let RenderMethod = "addVecListIndexedOperands";
395234353Sdim}
396234353Sdimdef VecListFourQWordIndexed : Operand<i32> {
397234353Sdim  let ParserMatchClass = VecListFourQWordIndexAsmOperand;
398234353Sdim  let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx);
399234353Sdim}
400234353Sdim
401243830Sdimdef dword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
402243830Sdim  return cast<LoadSDNode>(N)->getAlignment() >= 8;
403243830Sdim}]>;
404243830Sdimdef dword_alignedstore : PatFrag<(ops node:$val, node:$ptr),
405243830Sdim                                 (store node:$val, node:$ptr), [{
406243830Sdim  return cast<StoreSDNode>(N)->getAlignment() >= 8;
407243830Sdim}]>;
408243830Sdimdef word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
409243830Sdim  return cast<LoadSDNode>(N)->getAlignment() == 4;
410243830Sdim}]>;
411243830Sdimdef word_alignedstore : PatFrag<(ops node:$val, node:$ptr),
412243830Sdim                                 (store node:$val, node:$ptr), [{
413243830Sdim  return cast<StoreSDNode>(N)->getAlignment() == 4;
414243830Sdim}]>;
415239462Sdimdef hword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
416239462Sdim  return cast<LoadSDNode>(N)->getAlignment() == 2;
417239462Sdim}]>;
418239462Sdimdef hword_alignedstore : PatFrag<(ops node:$val, node:$ptr),
419239462Sdim                                 (store node:$val, node:$ptr), [{
420239462Sdim  return cast<StoreSDNode>(N)->getAlignment() == 2;
421239462Sdim}]>;
422239462Sdimdef byte_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
423239462Sdim  return cast<LoadSDNode>(N)->getAlignment() == 1;
424239462Sdim}]>;
425239462Sdimdef byte_alignedstore : PatFrag<(ops node:$val, node:$ptr),
426239462Sdim                             (store node:$val, node:$ptr), [{
427239462Sdim  return cast<StoreSDNode>(N)->getAlignment() == 1;
428239462Sdim}]>;
429239462Sdimdef non_word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
430239462Sdim  return cast<LoadSDNode>(N)->getAlignment() < 4;
431239462Sdim}]>;
432239462Sdimdef non_word_alignedstore : PatFrag<(ops node:$val, node:$ptr),
433239462Sdim                                    (store node:$val, node:$ptr), [{
434239462Sdim  return cast<StoreSDNode>(N)->getAlignment() < 4;
435239462Sdim}]>;
436234353Sdim
437226633Sdim//===----------------------------------------------------------------------===//
438194710Sed// NEON-specific DAG Nodes.
439194710Sed//===----------------------------------------------------------------------===//
440194710Sed
441194710Seddef SDTARMVCMP    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>;
442218893Sdimdef SDTARMVCMPZ   : SDTypeProfile<1, 1, []>;
443194710Sed
444194710Seddef NEONvceq      : SDNode<"ARMISD::VCEQ", SDTARMVCMP>;
445218893Sdimdef NEONvceqz     : SDNode<"ARMISD::VCEQZ", SDTARMVCMPZ>;
446194710Seddef NEONvcge      : SDNode<"ARMISD::VCGE", SDTARMVCMP>;
447218893Sdimdef NEONvcgez     : SDNode<"ARMISD::VCGEZ", SDTARMVCMPZ>;
448218893Sdimdef NEONvclez     : SDNode<"ARMISD::VCLEZ", SDTARMVCMPZ>;
449194710Seddef NEONvcgeu     : SDNode<"ARMISD::VCGEU", SDTARMVCMP>;
450194710Seddef NEONvcgt      : SDNode<"ARMISD::VCGT", SDTARMVCMP>;
451218893Sdimdef NEONvcgtz     : SDNode<"ARMISD::VCGTZ", SDTARMVCMPZ>;
452218893Sdimdef NEONvcltz     : SDNode<"ARMISD::VCLTZ", SDTARMVCMPZ>;
453194710Seddef NEONvcgtu     : SDNode<"ARMISD::VCGTU", SDTARMVCMP>;
454194710Seddef NEONvtst      : SDNode<"ARMISD::VTST", SDTARMVCMP>;
455194710Sed
456194710Sed// Types for vector shift by immediates.  The "SHX" version is for long and
457194710Sed// narrow operations where the source and destination vectors have different
458194710Sed// types.  The "SHINS" version is for shift and insert operations.
459194710Seddef SDTARMVSH     : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
460194710Sed                                         SDTCisVT<2, i32>]>;
461194710Seddef SDTARMVSHX    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
462194710Sed                                         SDTCisVT<2, i32>]>;
463194710Seddef SDTARMVSHINS  : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
464194710Sed                                         SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
465194710Sed
466194710Seddef NEONvshl      : SDNode<"ARMISD::VSHL", SDTARMVSH>;
467194710Seddef NEONvshrs     : SDNode<"ARMISD::VSHRs", SDTARMVSH>;
468194710Seddef NEONvshru     : SDNode<"ARMISD::VSHRu", SDTARMVSH>;
469194710Seddef NEONvshlls    : SDNode<"ARMISD::VSHLLs", SDTARMVSHX>;
470194710Seddef NEONvshllu    : SDNode<"ARMISD::VSHLLu", SDTARMVSHX>;
471194710Seddef NEONvshlli    : SDNode<"ARMISD::VSHLLi", SDTARMVSHX>;
472194710Seddef NEONvshrn     : SDNode<"ARMISD::VSHRN", SDTARMVSHX>;
473194710Sed
474194710Seddef NEONvrshrs    : SDNode<"ARMISD::VRSHRs", SDTARMVSH>;
475194710Seddef NEONvrshru    : SDNode<"ARMISD::VRSHRu", SDTARMVSH>;
476194710Seddef NEONvrshrn    : SDNode<"ARMISD::VRSHRN", SDTARMVSHX>;
477194710Sed
478194710Seddef NEONvqshls    : SDNode<"ARMISD::VQSHLs", SDTARMVSH>;
479194710Seddef NEONvqshlu    : SDNode<"ARMISD::VQSHLu", SDTARMVSH>;
480194710Seddef NEONvqshlsu   : SDNode<"ARMISD::VQSHLsu", SDTARMVSH>;
481194710Seddef NEONvqshrns   : SDNode<"ARMISD::VQSHRNs", SDTARMVSHX>;
482194710Seddef NEONvqshrnu   : SDNode<"ARMISD::VQSHRNu", SDTARMVSHX>;
483194710Seddef NEONvqshrnsu  : SDNode<"ARMISD::VQSHRNsu", SDTARMVSHX>;
484194710Sed
485194710Seddef NEONvqrshrns  : SDNode<"ARMISD::VQRSHRNs", SDTARMVSHX>;
486194710Seddef NEONvqrshrnu  : SDNode<"ARMISD::VQRSHRNu", SDTARMVSHX>;
487194710Seddef NEONvqrshrnsu : SDNode<"ARMISD::VQRSHRNsu", SDTARMVSHX>;
488194710Sed
489194710Seddef NEONvsli      : SDNode<"ARMISD::VSLI", SDTARMVSHINS>;
490194710Seddef NEONvsri      : SDNode<"ARMISD::VSRI", SDTARMVSHINS>;
491194710Sed
492194710Seddef SDTARMVGETLN  : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>,
493194710Sed                                         SDTCisVT<2, i32>]>;
494194710Seddef NEONvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>;
495194710Seddef NEONvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>;
496194710Sed
497210299Seddef SDTARMVMOVIMM : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
498210299Seddef NEONvmovImm   : SDNode<"ARMISD::VMOVIMM", SDTARMVMOVIMM>;
499210299Seddef NEONvmvnImm   : SDNode<"ARMISD::VMVNIMM", SDTARMVMOVIMM>;
500234353Sdimdef NEONvmovFPImm : SDNode<"ARMISD::VMOVFPIMM", SDTARMVMOVIMM>;
501210299Sed
502218893Sdimdef SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
503218893Sdim                                           SDTCisVT<2, i32>]>;
504218893Sdimdef NEONvorrImm   : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>;
505218893Sdimdef NEONvbicImm   : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>;
506218893Sdim
507221345Sdimdef NEONvbsl      : SDNode<"ARMISD::VBSL",
508221345Sdim                           SDTypeProfile<1, 3, [SDTCisVec<0>,
509221345Sdim                                                SDTCisSameAs<0, 1>,
510221345Sdim                                                SDTCisSameAs<0, 2>,
511221345Sdim                                                SDTCisSameAs<0, 3>]>>;
512221345Sdim
513198090Srdivackydef NEONvdup      : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
514194710Sed
515198090Srdivacky// VDUPLANE can produce a quad-register result from a double-register source,
516198090Srdivacky// so the result is not constrained to match the source.
517198090Srdivackydef NEONvduplane  : SDNode<"ARMISD::VDUPLANE",
518198090Srdivacky                           SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
519198090Srdivacky                                                SDTCisVT<2, i32>]>>;
520198090Srdivacky
521198090Srdivackydef SDTARMVEXT    : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
522198090Srdivacky                                         SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
523198090Srdivackydef NEONvext      : SDNode<"ARMISD::VEXT", SDTARMVEXT>;
524198090Srdivacky
525198090Srdivackydef SDTARMVSHUF   : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
526198090Srdivackydef NEONvrev64    : SDNode<"ARMISD::VREV64", SDTARMVSHUF>;
527198090Srdivackydef NEONvrev32    : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
528198090Srdivackydef NEONvrev16    : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
529198090Srdivacky
530198090Srdivackydef SDTARMVSHUF2  : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
531204642Srdivacky                                         SDTCisSameAs<0, 2>,
532204642Srdivacky                                         SDTCisSameAs<0, 3>]>;
533198090Srdivackydef NEONzip       : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>;
534198090Srdivackydef NEONuzp       : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>;
535198090Srdivackydef NEONtrn       : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>;
536198090Srdivacky
537212904Sdimdef SDTARMVMULL   : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
538212904Sdim                                         SDTCisSameAs<1, 2>]>;
539212904Sdimdef NEONvmulls    : SDNode<"ARMISD::VMULLs", SDTARMVMULL>;
540212904Sdimdef NEONvmullu    : SDNode<"ARMISD::VMULLu", SDTARMVMULL>;
541212904Sdim
542204642Srdivackydef SDTARMFMAX    : SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisSameAs<0, 1>,
543204642Srdivacky                                         SDTCisSameAs<0, 2>]>;
544204642Srdivackydef NEONfmax      : SDNode<"ARMISD::FMAX", SDTARMFMAX>;
545204642Srdivackydef NEONfmin      : SDNode<"ARMISD::FMIN", SDTARMFMAX>;
546204642Srdivacky
547210299Seddef NEONimmAllZerosV: PatLeaf<(NEONvmovImm (i32 timm)), [{
548210299Sed  ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
549212904Sdim  unsigned EltBits = 0;
550210299Sed  uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits);
551210299Sed  return (EltBits == 32 && EltVal == 0);
552210299Sed}]>;
553210299Sed
554210299Seddef NEONimmAllOnesV: PatLeaf<(NEONvmovImm (i32 timm)), [{
555210299Sed  ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
556212904Sdim  unsigned EltBits = 0;
557210299Sed  uint64_t EltVal = ARM_AM::decodeNEONModImm(ConstVal->getZExtValue(), EltBits);
558210299Sed  return (EltBits == 8 && EltVal == 0xff);
559210299Sed}]>;
560210299Sed
561194710Sed//===----------------------------------------------------------------------===//
562194710Sed// NEON load / store instructions
563194710Sed//===----------------------------------------------------------------------===//
564194710Sed
565218893Sdim// Use VLDM to load a Q register as a D register pair.
566218893Sdim// This is a pseudo instruction that is expanded to VLDMD after reg alloc.
567218893Sdimdef VLDMQIA
568234353Sdim  : PseudoVFPLdStM<(outs DPair:$dst), (ins GPR:$Rn),
569218893Sdim                    IIC_fpLoad_m, "",
570234353Sdim                   [(set DPair:$dst, (v2f64 (load GPR:$Rn)))]>;
571194710Sed
572218893Sdim// Use VSTM to store a Q register as a D register pair.
573218893Sdim// This is a pseudo instruction that is expanded to VSTMD after reg alloc.
574218893Sdimdef VSTMQIA
575234353Sdim  : PseudoVFPLdStM<(outs), (ins DPair:$src, GPR:$Rn),
576218893Sdim                    IIC_fpStore_m, "",
577234353Sdim                   [(store (v2f64 DPair:$src), GPR:$Rn)]>;
578206083Srdivacky
579212904Sdim// Classes for VLD* pseudo-instructions with multi-register operands.
580212904Sdim// These are expanded to real instructions after register allocation.
581218893Sdimclass VLDQPseudo<InstrItinClass itin>
582218893Sdim  : PseudoNLdSt<(outs QPR:$dst), (ins addrmode6:$addr), itin, "">;
583218893Sdimclass VLDQWBPseudo<InstrItinClass itin>
584212904Sdim  : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
585218893Sdim                (ins addrmode6:$addr, am6offset:$offset), itin,
586212904Sdim                "$addr.addr = $wb">;
587234353Sdimclass VLDQWBfixedPseudo<InstrItinClass itin>
588234353Sdim  : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
589234353Sdim                (ins addrmode6:$addr), itin,
590234353Sdim                "$addr.addr = $wb">;
591234353Sdimclass VLDQWBregisterPseudo<InstrItinClass itin>
592234353Sdim  : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
593234353Sdim                (ins addrmode6:$addr, rGPR:$offset), itin,
594234353Sdim                "$addr.addr = $wb">;
595234353Sdim
596218893Sdimclass VLDQQPseudo<InstrItinClass itin>
597218893Sdim  : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">;
598218893Sdimclass VLDQQWBPseudo<InstrItinClass itin>
599212904Sdim  : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
600218893Sdim                (ins addrmode6:$addr, am6offset:$offset), itin,
601212904Sdim                "$addr.addr = $wb">;
602234353Sdimclass VLDQQWBfixedPseudo<InstrItinClass itin>
603234353Sdim  : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
604234353Sdim                (ins addrmode6:$addr), itin,
605234353Sdim                "$addr.addr = $wb">;
606234353Sdimclass VLDQQWBregisterPseudo<InstrItinClass itin>
607234353Sdim  : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
608234353Sdim                (ins addrmode6:$addr, rGPR:$offset), itin,
609234353Sdim                "$addr.addr = $wb">;
610234353Sdim
611234353Sdim
612218893Sdimclass VLDQQQQPseudo<InstrItinClass itin>
613226633Sdim  : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin,
614226633Sdim                "$src = $dst">;
615218893Sdimclass VLDQQQQWBPseudo<InstrItinClass itin>
616212904Sdim  : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),
617218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,
618212904Sdim                "$addr.addr = $wb, $src = $dst">;
619212904Sdim
620218893Sdimlet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
621218893Sdim
622198090Srdivacky//   VLD1     : Vector Load (multiple single elements)
623206083Srdivackyclass VLD1D<bits<4> op7_4, string Dt>
624234353Sdim  : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd),
625218893Sdim          (ins addrmode6:$Rn), IIC_VLD1,
626234353Sdim          "vld1", Dt, "$Vd, $Rn", "", []> {
627218893Sdim  let Rm = 0b1111;
628218893Sdim  let Inst{4} = Rn{4};
629263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
630218893Sdim}
631206083Srdivackyclass VLD1Q<bits<4> op7_4, string Dt>
632234353Sdim  : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd),
633218893Sdim          (ins addrmode6:$Rn), IIC_VLD1x2,
634234353Sdim          "vld1", Dt, "$Vd, $Rn", "", []> {
635218893Sdim  let Rm = 0b1111;
636218893Sdim  let Inst{5-4} = Rn{5-4};
637263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
638218893Sdim}
639194710Sed
640218893Sdimdef  VLD1d8   : VLD1D<{0,0,0,?}, "8">;
641218893Sdimdef  VLD1d16  : VLD1D<{0,1,0,?}, "16">;
642218893Sdimdef  VLD1d32  : VLD1D<{1,0,0,?}, "32">;
643218893Sdimdef  VLD1d64  : VLD1D<{1,1,0,?}, "64">;
644198090Srdivacky
645218893Sdimdef  VLD1q8   : VLD1Q<{0,0,?,?}, "8">;
646218893Sdimdef  VLD1q16  : VLD1Q<{0,1,?,?}, "16">;
647218893Sdimdef  VLD1q32  : VLD1Q<{1,0,?,?}, "32">;
648218893Sdimdef  VLD1q64  : VLD1Q<{1,1,?,?}, "64">;
649198090Srdivacky
650205407Srdivacky// ...with address register writeback:
651234353Sdimmulticlass VLD1DWB<bits<4> op7_4, string Dt> {
652234353Sdim  def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
653234353Sdim                     (ins addrmode6:$Rn), IIC_VLD1u,
654234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
655234353Sdim                     "$Rn.addr = $wb", []> {
656234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
657234353Sdim    let Inst{4} = Rn{4};
658263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
659234353Sdim  }
660234353Sdim  def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
661234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1u,
662234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
663234353Sdim                        "$Rn.addr = $wb", []> {
664234353Sdim    let Inst{4} = Rn{4};
665263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
666234353Sdim  }
667218893Sdim}
668234353Sdimmulticlass VLD1QWB<bits<4> op7_4, string Dt> {
669234353Sdim  def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),
670234353Sdim                    (ins addrmode6:$Rn), IIC_VLD1x2u,
671234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
672234353Sdim                     "$Rn.addr = $wb", []> {
673234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
674234353Sdim    let Inst{5-4} = Rn{5-4};
675263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
676234353Sdim  }
677234353Sdim  def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb),
678234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u,
679234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
680234353Sdim                        "$Rn.addr = $wb", []> {
681234353Sdim    let Inst{5-4} = Rn{5-4};
682263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
683234353Sdim  }
684218893Sdim}
685205407Srdivacky
686234353Sdimdefm VLD1d8wb  : VLD1DWB<{0,0,0,?}, "8">;
687234353Sdimdefm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16">;
688234353Sdimdefm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32">;
689234353Sdimdefm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64">;
690234353Sdimdefm VLD1q8wb  : VLD1QWB<{0,0,?,?}, "8">;
691234353Sdimdefm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16">;
692234353Sdimdefm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32">;
693234353Sdimdefm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64">;
694205407Srdivacky
695234353Sdim// ...with 3 registers
696205407Srdivackyclass VLD1D3<bits<4> op7_4, string Dt>
697234353Sdim  : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd),
698218893Sdim          (ins addrmode6:$Rn), IIC_VLD1x3, "vld1", Dt,
699234353Sdim          "$Vd, $Rn", "", []> {
700218893Sdim  let Rm = 0b1111;
701218893Sdim  let Inst{4} = Rn{4};
702263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
703218893Sdim}
704234353Sdimmulticlass VLD1D3WB<bits<4> op7_4, string Dt> {
705234353Sdim  def _fixed : NLdSt<0,0b10,0b0110, op7_4, (outs VecListThreeD:$Vd, GPR:$wb),
706234353Sdim                    (ins addrmode6:$Rn), IIC_VLD1x2u,
707234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
708234353Sdim                     "$Rn.addr = $wb", []> {
709234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
710234353Sdim    let Inst{4} = Rn{4};
711263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
712234353Sdim  }
713234353Sdim  def _register : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd, GPR:$wb),
714234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u,
715234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
716234353Sdim                        "$Rn.addr = $wb", []> {
717234353Sdim    let Inst{4} = Rn{4};
718263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
719234353Sdim  }
720218893Sdim}
721206083Srdivacky
722218893Sdimdef VLD1d8T      : VLD1D3<{0,0,0,?}, "8">;
723218893Sdimdef VLD1d16T     : VLD1D3<{0,1,0,?}, "16">;
724218893Sdimdef VLD1d32T     : VLD1D3<{1,0,0,?}, "32">;
725218893Sdimdef VLD1d64T     : VLD1D3<{1,1,0,?}, "64">;
726206083Srdivacky
727234353Sdimdefm VLD1d8Twb  : VLD1D3WB<{0,0,0,?}, "8">;
728234353Sdimdefm VLD1d16Twb : VLD1D3WB<{0,1,0,?}, "16">;
729234353Sdimdefm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32">;
730234353Sdimdefm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64">;
731206083Srdivacky
732234353Sdimdef VLD1d64TPseudo : VLDQQPseudo<IIC_VLD1x3>;
733266715Sdimdef VLD1d64TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>;
734266715Sdimdef VLD1d64TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>;
735212904Sdim
736234353Sdim// ...with 4 registers
737205407Srdivackyclass VLD1D4<bits<4> op7_4, string Dt>
738234353Sdim  : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd),
739218893Sdim          (ins addrmode6:$Rn), IIC_VLD1x4, "vld1", Dt,
740234353Sdim          "$Vd, $Rn", "", []> {
741218893Sdim  let Rm = 0b1111;
742218893Sdim  let Inst{5-4} = Rn{5-4};
743263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
744218893Sdim}
745234353Sdimmulticlass VLD1D4WB<bits<4> op7_4, string Dt> {
746234353Sdim  def _fixed : NLdSt<0,0b10,0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb),
747234353Sdim                    (ins addrmode6:$Rn), IIC_VLD1x2u,
748234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
749234353Sdim                     "$Rn.addr = $wb", []> {
750234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
751234353Sdim    let Inst{5-4} = Rn{5-4};
752263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
753234353Sdim  }
754234353Sdim  def _register : NLdSt<0,0b10,0b0010,op7_4, (outs VecListFourD:$Vd, GPR:$wb),
755234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u,
756234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
757234353Sdim                        "$Rn.addr = $wb", []> {
758234353Sdim    let Inst{5-4} = Rn{5-4};
759263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
760234353Sdim  }
761218893Sdim}
762204642Srdivacky
763218893Sdimdef VLD1d8Q      : VLD1D4<{0,0,?,?}, "8">;
764218893Sdimdef VLD1d16Q     : VLD1D4<{0,1,?,?}, "16">;
765218893Sdimdef VLD1d32Q     : VLD1D4<{1,0,?,?}, "32">;
766218893Sdimdef VLD1d64Q     : VLD1D4<{1,1,?,?}, "64">;
767198090Srdivacky
768234353Sdimdefm VLD1d8Qwb   : VLD1D4WB<{0,0,?,?}, "8">;
769234353Sdimdefm VLD1d16Qwb  : VLD1D4WB<{0,1,?,?}, "16">;
770234353Sdimdefm VLD1d32Qwb  : VLD1D4WB<{1,0,?,?}, "32">;
771234353Sdimdefm VLD1d64Qwb  : VLD1D4WB<{1,1,?,?}, "64">;
772205407Srdivacky
773234353Sdimdef VLD1d64QPseudo : VLDQQPseudo<IIC_VLD1x4>;
774266715Sdimdef VLD1d64QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>;
775266715Sdimdef VLD1d64QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>;
776212904Sdim
777198090Srdivacky//   VLD2     : Vector Load (multiple 2-element structures)
778234353Sdimclass VLD2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,
779234353Sdim           InstrItinClass itin>
780234353Sdim  : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd),
781234353Sdim          (ins addrmode6:$Rn), itin,
782234353Sdim          "vld2", Dt, "$Vd, $Rn", "", []> {
783218893Sdim  let Rm = 0b1111;
784218893Sdim  let Inst{5-4} = Rn{5-4};
785263508Sdim  let DecoderMethod = "DecodeVLDST2Instruction";
786218893Sdim}
787198090Srdivacky
788234353Sdimdef  VLD2d8   : VLD2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2>;
789234353Sdimdef  VLD2d16  : VLD2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2>;
790234353Sdimdef  VLD2d32  : VLD2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2>;
791198090Srdivacky
792234353Sdimdef  VLD2q8   : VLD2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2>;
793234353Sdimdef  VLD2q16  : VLD2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2>;
794234353Sdimdef  VLD2q32  : VLD2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2>;
795198090Srdivacky
796218893Sdimdef  VLD2q8Pseudo  : VLDQQPseudo<IIC_VLD2x2>;
797218893Sdimdef  VLD2q16Pseudo : VLDQQPseudo<IIC_VLD2x2>;
798218893Sdimdef  VLD2q32Pseudo : VLDQQPseudo<IIC_VLD2x2>;
799212904Sdim
800205407Srdivacky// ...with address register writeback:
801234353Sdimmulticlass VLD2WB<bits<4> op11_8, bits<4> op7_4, string Dt,
802234353Sdim                  RegisterOperand VdTy, InstrItinClass itin> {
803234353Sdim  def _fixed : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),
804234353Sdim                     (ins addrmode6:$Rn), itin,
805234353Sdim                     "vld2", Dt, "$Vd, $Rn!",
806234353Sdim                     "$Rn.addr = $wb", []> {
807234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
808234353Sdim    let Inst{5-4} = Rn{5-4};
809263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
810234353Sdim  }
811234353Sdim  def _register : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb),
812234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm), itin,
813234353Sdim                        "vld2", Dt, "$Vd, $Rn, $Rm",
814234353Sdim                        "$Rn.addr = $wb", []> {
815234353Sdim    let Inst{5-4} = Rn{5-4};
816263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
817234353Sdim  }
818218893Sdim}
819204642Srdivacky
820234353Sdimdefm VLD2d8wb  : VLD2WB<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2u>;
821234353Sdimdefm VLD2d16wb : VLD2WB<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2u>;
822234353Sdimdefm VLD2d32wb : VLD2WB<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2u>;
823204642Srdivacky
824234353Sdimdefm VLD2q8wb  : VLD2WB<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2u>;
825234353Sdimdefm VLD2q16wb : VLD2WB<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2u>;
826234353Sdimdefm VLD2q32wb : VLD2WB<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2u>;
827205407Srdivacky
828234353Sdimdef VLD2q8PseudoWB_fixed     : VLDQQWBfixedPseudo<IIC_VLD2x2u>;
829234353Sdimdef VLD2q16PseudoWB_fixed    : VLDQQWBfixedPseudo<IIC_VLD2x2u>;
830234353Sdimdef VLD2q32PseudoWB_fixed    : VLDQQWBfixedPseudo<IIC_VLD2x2u>;
831234353Sdimdef VLD2q8PseudoWB_register  : VLDQQWBregisterPseudo<IIC_VLD2x2u>;
832234353Sdimdef VLD2q16PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>;
833234353Sdimdef VLD2q32PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>;
834212904Sdim
835234353Sdim// ...with double-spaced registers
836234353Sdimdef  VLD2b8    : VLD2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2>;
837234353Sdimdef  VLD2b16   : VLD2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2>;
838234353Sdimdef  VLD2b32   : VLD2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2>;
839234353Sdimdefm VLD2b8wb  : VLD2WB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2u>;
840234353Sdimdefm VLD2b16wb : VLD2WB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2u>;
841234353Sdimdefm VLD2b32wb : VLD2WB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2u>;
842212904Sdim
843198090Srdivacky//   VLD3     : Vector Load (multiple 3-element structures)
844205407Srdivackyclass VLD3D<bits<4> op11_8, bits<4> op7_4, string Dt>
845218893Sdim  : NLdSt<0, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
846218893Sdim          (ins addrmode6:$Rn), IIC_VLD3,
847218893Sdim          "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> {
848218893Sdim  let Rm = 0b1111;
849218893Sdim  let Inst{4} = Rn{4};
850263508Sdim  let DecoderMethod = "DecodeVLDST3Instruction";
851218893Sdim}
852198090Srdivacky
853218893Sdimdef  VLD3d8   : VLD3D<0b0100, {0,0,0,?}, "8">;
854218893Sdimdef  VLD3d16  : VLD3D<0b0100, {0,1,0,?}, "16">;
855218893Sdimdef  VLD3d32  : VLD3D<0b0100, {1,0,0,?}, "32">;
856198090Srdivacky
857218893Sdimdef  VLD3d8Pseudo  : VLDQQPseudo<IIC_VLD3>;
858218893Sdimdef  VLD3d16Pseudo : VLDQQPseudo<IIC_VLD3>;
859218893Sdimdef  VLD3d32Pseudo : VLDQQPseudo<IIC_VLD3>;
860212904Sdim
861205407Srdivacky// ...with address register writeback:
862205407Srdivackyclass VLD3DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
863205407Srdivacky  : NLdSt<0, 0b10, op11_8, op7_4,
864218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
865218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD3u,
866218893Sdim          "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm",
867218893Sdim          "$Rn.addr = $wb", []> {
868218893Sdim  let Inst{4} = Rn{4};
869263508Sdim  let DecoderMethod = "DecodeVLDST3Instruction";
870218893Sdim}
871198090Srdivacky
872218893Sdimdef VLD3d8_UPD  : VLD3DWB<0b0100, {0,0,0,?}, "8">;
873218893Sdimdef VLD3d16_UPD : VLD3DWB<0b0100, {0,1,0,?}, "16">;
874218893Sdimdef VLD3d32_UPD : VLD3DWB<0b0100, {1,0,0,?}, "32">;
875198090Srdivacky
876218893Sdimdef VLD3d8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD3u>;
877218893Sdimdef VLD3d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>;
878218893Sdimdef VLD3d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>;
879212904Sdim
880218893Sdim// ...with double-spaced registers:
881218893Sdimdef VLD3q8      : VLD3D<0b0101, {0,0,0,?}, "8">;
882218893Sdimdef VLD3q16     : VLD3D<0b0101, {0,1,0,?}, "16">;
883218893Sdimdef VLD3q32     : VLD3D<0b0101, {1,0,0,?}, "32">;
884218893Sdimdef VLD3q8_UPD  : VLD3DWB<0b0101, {0,0,0,?}, "8">;
885218893Sdimdef VLD3q16_UPD : VLD3DWB<0b0101, {0,1,0,?}, "16">;
886218893Sdimdef VLD3q32_UPD : VLD3DWB<0b0101, {1,0,0,?}, "32">;
887205407Srdivacky
888218893Sdimdef VLD3q8Pseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD3u>;
889218893Sdimdef VLD3q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>;
890218893Sdimdef VLD3q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>;
891212904Sdim
892205407Srdivacky// ...alternate versions to be allocated odd register numbers:
893218893Sdimdef VLD3q8oddPseudo   : VLDQQQQPseudo<IIC_VLD3>;
894218893Sdimdef VLD3q16oddPseudo  : VLDQQQQPseudo<IIC_VLD3>;
895218893Sdimdef VLD3q32oddPseudo  : VLDQQQQPseudo<IIC_VLD3>;
896205407Srdivacky
897218893Sdimdef VLD3q8oddPseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD3u>;
898218893Sdimdef VLD3q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>;
899218893Sdimdef VLD3q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>;
900218893Sdim
901198090Srdivacky//   VLD4     : Vector Load (multiple 4-element structures)
902205407Srdivackyclass VLD4D<bits<4> op11_8, bits<4> op7_4, string Dt>
903205407Srdivacky  : NLdSt<0, 0b10, op11_8, op7_4,
904218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
905218893Sdim          (ins addrmode6:$Rn), IIC_VLD4,
906218893Sdim          "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> {
907218893Sdim  let Rm = 0b1111;
908218893Sdim  let Inst{5-4} = Rn{5-4};
909263508Sdim  let DecoderMethod = "DecodeVLDST4Instruction";
910218893Sdim}
911198090Srdivacky
912218893Sdimdef  VLD4d8   : VLD4D<0b0000, {0,0,?,?}, "8">;
913218893Sdimdef  VLD4d16  : VLD4D<0b0000, {0,1,?,?}, "16">;
914218893Sdimdef  VLD4d32  : VLD4D<0b0000, {1,0,?,?}, "32">;
915198090Srdivacky
916218893Sdimdef  VLD4d8Pseudo  : VLDQQPseudo<IIC_VLD4>;
917218893Sdimdef  VLD4d16Pseudo : VLDQQPseudo<IIC_VLD4>;
918218893Sdimdef  VLD4d32Pseudo : VLDQQPseudo<IIC_VLD4>;
919212904Sdim
920205407Srdivacky// ...with address register writeback:
921205407Srdivackyclass VLD4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
922205407Srdivacky  : NLdSt<0, 0b10, op11_8, op7_4,
923218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
924218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD4u,
925218893Sdim          "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm",
926218893Sdim          "$Rn.addr = $wb", []> {
927218893Sdim  let Inst{5-4} = Rn{5-4};
928263508Sdim  let DecoderMethod = "DecodeVLDST4Instruction";
929218893Sdim}
930198090Srdivacky
931218893Sdimdef VLD4d8_UPD  : VLD4DWB<0b0000, {0,0,?,?}, "8">;
932218893Sdimdef VLD4d16_UPD : VLD4DWB<0b0000, {0,1,?,?}, "16">;
933218893Sdimdef VLD4d32_UPD : VLD4DWB<0b0000, {1,0,?,?}, "32">;
934198090Srdivacky
935218893Sdimdef VLD4d8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD4u>;
936218893Sdimdef VLD4d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>;
937218893Sdimdef VLD4d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>;
938212904Sdim
939218893Sdim// ...with double-spaced registers:
940218893Sdimdef VLD4q8      : VLD4D<0b0001, {0,0,?,?}, "8">;
941218893Sdimdef VLD4q16     : VLD4D<0b0001, {0,1,?,?}, "16">;
942218893Sdimdef VLD4q32     : VLD4D<0b0001, {1,0,?,?}, "32">;
943218893Sdimdef VLD4q8_UPD  : VLD4DWB<0b0001, {0,0,?,?}, "8">;
944218893Sdimdef VLD4q16_UPD : VLD4DWB<0b0001, {0,1,?,?}, "16">;
945218893Sdimdef VLD4q32_UPD : VLD4DWB<0b0001, {1,0,?,?}, "32">;
946205407Srdivacky
947218893Sdimdef VLD4q8Pseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD4u>;
948218893Sdimdef VLD4q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>;
949218893Sdimdef VLD4q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>;
950212904Sdim
951205407Srdivacky// ...alternate versions to be allocated odd register numbers:
952218893Sdimdef VLD4q8oddPseudo   : VLDQQQQPseudo<IIC_VLD4>;
953218893Sdimdef VLD4q16oddPseudo  : VLDQQQQPseudo<IIC_VLD4>;
954218893Sdimdef VLD4q32oddPseudo  : VLDQQQQPseudo<IIC_VLD4>;
955205407Srdivacky
956218893Sdimdef VLD4q8oddPseudo_UPD  : VLDQQQQWBPseudo<IIC_VLD4u>;
957218893Sdimdef VLD4q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>;
958218893Sdimdef VLD4q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>;
959218893Sdim
960218893Sdim} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
961218893Sdim
962218893Sdim// Classes for VLD*LN pseudo-instructions with multi-register operands.
963218893Sdim// These are expanded to real instructions after register allocation.
964218893Sdimclass VLDQLNPseudo<InstrItinClass itin>
965218893Sdim  : PseudoNLdSt<(outs QPR:$dst),
966218893Sdim                (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),
967218893Sdim                itin, "$src = $dst">;
968218893Sdimclass VLDQLNWBPseudo<InstrItinClass itin>
969218893Sdim  : PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
970218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QPR:$src,
971218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
972218893Sdimclass VLDQQLNPseudo<InstrItinClass itin>
973218893Sdim  : PseudoNLdSt<(outs QQPR:$dst),
974218893Sdim                (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),
975218893Sdim                itin, "$src = $dst">;
976218893Sdimclass VLDQQLNWBPseudo<InstrItinClass itin>
977218893Sdim  : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb),
978218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,
979218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
980218893Sdimclass VLDQQQQLNPseudo<InstrItinClass itin>
981218893Sdim  : PseudoNLdSt<(outs QQQQPR:$dst),
982218893Sdim                (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),
983218893Sdim                itin, "$src = $dst">;
984218893Sdimclass VLDQQQQLNWBPseudo<InstrItinClass itin>
985218893Sdim  : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb),
986218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,
987218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">;
988218893Sdim
989198090Srdivacky//   VLD1LN   : Vector Load (single element to one lane)
990218893Sdimclass VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
991218893Sdim             PatFrag LoadOp>
992218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),
993218893Sdim          (ins addrmode6:$Rn, DPR:$src, nohash_imm:$lane),
994218893Sdim          IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",
995218893Sdim          "$src = $Vd",
996218893Sdim          [(set DPR:$Vd, (vector_insert (Ty DPR:$src),
997218893Sdim                                         (i32 (LoadOp addrmode6:$Rn)),
998218893Sdim                                         imm:$lane))]> {
999218893Sdim  let Rm = 0b1111;
1000226633Sdim  let DecoderMethod = "DecodeVLD1LN";
1001218893Sdim}
1002223017Sdimclass VLD1LN32<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
1003223017Sdim             PatFrag LoadOp>
1004223017Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd),
1005223017Sdim          (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane),
1006223017Sdim          IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn",
1007223017Sdim          "$src = $Vd",
1008223017Sdim          [(set DPR:$Vd, (vector_insert (Ty DPR:$src),
1009223017Sdim                                         (i32 (LoadOp addrmode6oneL32:$Rn)),
1010223017Sdim                                         imm:$lane))]> {
1011223017Sdim  let Rm = 0b1111;
1012226633Sdim  let DecoderMethod = "DecodeVLD1LN";
1013223017Sdim}
1014218893Sdimclass VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln> {
1015218893Sdim  let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src),
1016218893Sdim                                               (i32 (LoadOp addrmode6:$addr)),
1017218893Sdim                                               imm:$lane))];
1018218893Sdim}
1019198090Srdivacky
1020218893Sdimdef VLD1LNd8  : VLD1LN<0b0000, {?,?,?,0}, "8", v8i8, extloadi8> {
1021218893Sdim  let Inst{7-5} = lane{2-0};
1022218893Sdim}
1023218893Sdimdef VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> {
1024218893Sdim  let Inst{7-6} = lane{1-0};
1025234353Sdim  let Inst{5-4} = Rn{5-4};
1026218893Sdim}
1027223017Sdimdef VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> {
1028218893Sdim  let Inst{7} = lane{0};
1029234353Sdim  let Inst{5-4} = Rn{5-4};
1030218893Sdim}
1031218893Sdim
1032218893Sdimdef VLD1LNq8Pseudo  : VLD1QLNPseudo<v16i8, extloadi8>;
1033218893Sdimdef VLD1LNq16Pseudo : VLD1QLNPseudo<v8i16, extloadi16>;
1034218893Sdimdef VLD1LNq32Pseudo : VLD1QLNPseudo<v4i32, load>;
1035218893Sdim
1036218893Sdimdef : Pat<(vector_insert (v2f32 DPR:$src),
1037218893Sdim                         (f32 (load addrmode6:$addr)), imm:$lane),
1038218893Sdim          (VLD1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;
1039218893Sdimdef : Pat<(vector_insert (v4f32 QPR:$src),
1040218893Sdim                         (f32 (load addrmode6:$addr)), imm:$lane),
1041218893Sdim          (VLD1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;
1042218893Sdim
1043218893Sdimlet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1044218893Sdim
1045218893Sdim// ...with address register writeback:
1046218893Sdimclass VLD1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1047218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, GPR:$wb),
1048218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1049218893Sdim           DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt,
1050218893Sdim          "\\{$Vd[$lane]\\}, $Rn$Rm",
1051226633Sdim          "$src = $Vd, $Rn.addr = $wb", []> {
1052226633Sdim  let DecoderMethod = "DecodeVLD1LN";
1053226633Sdim}
1054218893Sdim
1055218893Sdimdef VLD1LNd8_UPD  : VLD1LNWB<0b0000, {?,?,?,0}, "8"> {
1056218893Sdim  let Inst{7-5} = lane{2-0};
1057218893Sdim}
1058218893Sdimdef VLD1LNd16_UPD : VLD1LNWB<0b0100, {?,?,0,?}, "16"> {
1059218893Sdim  let Inst{7-6} = lane{1-0};
1060218893Sdim  let Inst{4}   = Rn{4};
1061218893Sdim}
1062218893Sdimdef VLD1LNd32_UPD : VLD1LNWB<0b1000, {?,0,?,?}, "32"> {
1063218893Sdim  let Inst{7} = lane{0};
1064218893Sdim  let Inst{5} = Rn{4};
1065218893Sdim  let Inst{4} = Rn{4};
1066218893Sdim}
1067218893Sdim
1068218893Sdimdef VLD1LNq8Pseudo_UPD  : VLDQLNWBPseudo<IIC_VLD1lnu>;
1069218893Sdimdef VLD1LNq16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>;
1070218893Sdimdef VLD1LNq32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>;
1071218893Sdim
1072198090Srdivacky//   VLD2LN   : Vector Load (single 2-element structure to one lane)
1073206083Srdivackyclass VLD2LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1074218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2),
1075218893Sdim          (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, nohash_imm:$lane),
1076218893Sdim          IIC_VLD2ln, "vld2", Dt, "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn",
1077218893Sdim          "$src1 = $Vd, $src2 = $dst2", []> {
1078218893Sdim  let Rm = 0b1111;
1079218893Sdim  let Inst{4}   = Rn{4};
1080226633Sdim  let DecoderMethod = "DecodeVLD2LN";
1081218893Sdim}
1082198090Srdivacky
1083218893Sdimdef VLD2LNd8  : VLD2LN<0b0001, {?,?,?,?}, "8"> {
1084218893Sdim  let Inst{7-5} = lane{2-0};
1085218893Sdim}
1086218893Sdimdef VLD2LNd16 : VLD2LN<0b0101, {?,?,0,?}, "16"> {
1087218893Sdim  let Inst{7-6} = lane{1-0};
1088218893Sdim}
1089218893Sdimdef VLD2LNd32 : VLD2LN<0b1001, {?,0,0,?}, "32"> {
1090218893Sdim  let Inst{7} = lane{0};
1091218893Sdim}
1092198090Srdivacky
1093218893Sdimdef VLD2LNd8Pseudo  : VLDQLNPseudo<IIC_VLD2ln>;
1094218893Sdimdef VLD2LNd16Pseudo : VLDQLNPseudo<IIC_VLD2ln>;
1095218893Sdimdef VLD2LNd32Pseudo : VLDQLNPseudo<IIC_VLD2ln>;
1096218893Sdim
1097205407Srdivacky// ...with double-spaced registers:
1098218893Sdimdef VLD2LNq16 : VLD2LN<0b0101, {?,?,1,?}, "16"> {
1099218893Sdim  let Inst{7-6} = lane{1-0};
1100218893Sdim}
1101218893Sdimdef VLD2LNq32 : VLD2LN<0b1001, {?,1,0,?}, "32"> {
1102218893Sdim  let Inst{7} = lane{0};
1103218893Sdim}
1104198090Srdivacky
1105218893Sdimdef VLD2LNq16Pseudo : VLDQQLNPseudo<IIC_VLD2ln>;
1106218893Sdimdef VLD2LNq32Pseudo : VLDQQLNPseudo<IIC_VLD2ln>;
1107198090Srdivacky
1108205407Srdivacky// ...with address register writeback:
1109206083Srdivackyclass VLD2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1110218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb),
1111218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1112218893Sdim           DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2lnu, "vld2", Dt,
1113218893Sdim          "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm",
1114218893Sdim          "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> {
1115218893Sdim  let Inst{4}   = Rn{4};
1116226633Sdim  let DecoderMethod = "DecodeVLD2LN";
1117218893Sdim}
1118205407Srdivacky
1119218893Sdimdef VLD2LNd8_UPD  : VLD2LNWB<0b0001, {?,?,?,?}, "8"> {
1120218893Sdim  let Inst{7-5} = lane{2-0};
1121218893Sdim}
1122218893Sdimdef VLD2LNd16_UPD : VLD2LNWB<0b0101, {?,?,0,?}, "16"> {
1123218893Sdim  let Inst{7-6} = lane{1-0};
1124218893Sdim}
1125218893Sdimdef VLD2LNd32_UPD : VLD2LNWB<0b1001, {?,0,0,?}, "32"> {
1126218893Sdim  let Inst{7} = lane{0};
1127218893Sdim}
1128205407Srdivacky
1129218893Sdimdef VLD2LNd8Pseudo_UPD  : VLDQLNWBPseudo<IIC_VLD2lnu>;
1130218893Sdimdef VLD2LNd16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>;
1131218893Sdimdef VLD2LNd32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>;
1132205407Srdivacky
1133218893Sdimdef VLD2LNq16_UPD : VLD2LNWB<0b0101, {?,?,1,?}, "16"> {
1134218893Sdim  let Inst{7-6} = lane{1-0};
1135218893Sdim}
1136218893Sdimdef VLD2LNq32_UPD : VLD2LNWB<0b1001, {?,1,0,?}, "32"> {
1137218893Sdim  let Inst{7} = lane{0};
1138218893Sdim}
1139218893Sdim
1140218893Sdimdef VLD2LNq16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>;
1141218893Sdimdef VLD2LNq32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>;
1142218893Sdim
1143198090Srdivacky//   VLD3LN   : Vector Load (single 3-element structure to one lane)
1144206083Srdivackyclass VLD3LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1145218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
1146218893Sdim          (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3,
1147218893Sdim          nohash_imm:$lane), IIC_VLD3ln, "vld3", Dt,
1148218893Sdim          "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn",
1149218893Sdim          "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []> {
1150218893Sdim  let Rm = 0b1111;
1151226633Sdim  let DecoderMethod = "DecodeVLD3LN";
1152218893Sdim}
1153198090Srdivacky
1154218893Sdimdef VLD3LNd8  : VLD3LN<0b0010, {?,?,?,0}, "8"> {
1155218893Sdim  let Inst{7-5} = lane{2-0};
1156218893Sdim}
1157218893Sdimdef VLD3LNd16 : VLD3LN<0b0110, {?,?,0,0}, "16"> {
1158218893Sdim  let Inst{7-6} = lane{1-0};
1159218893Sdim}
1160218893Sdimdef VLD3LNd32 : VLD3LN<0b1010, {?,0,0,0}, "32"> {
1161218893Sdim  let Inst{7}   = lane{0};
1162218893Sdim}
1163198090Srdivacky
1164218893Sdimdef VLD3LNd8Pseudo  : VLDQQLNPseudo<IIC_VLD3ln>;
1165218893Sdimdef VLD3LNd16Pseudo : VLDQQLNPseudo<IIC_VLD3ln>;
1166218893Sdimdef VLD3LNd32Pseudo : VLDQQLNPseudo<IIC_VLD3ln>;
1167218893Sdim
1168205407Srdivacky// ...with double-spaced registers:
1169218893Sdimdef VLD3LNq16 : VLD3LN<0b0110, {?,?,1,0}, "16"> {
1170218893Sdim  let Inst{7-6} = lane{1-0};
1171218893Sdim}
1172218893Sdimdef VLD3LNq32 : VLD3LN<0b1010, {?,1,0,0}, "32"> {
1173218893Sdim  let Inst{7}   = lane{0};
1174218893Sdim}
1175198090Srdivacky
1176218893Sdimdef VLD3LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>;
1177218893Sdimdef VLD3LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>;
1178198090Srdivacky
1179205407Srdivacky// ...with address register writeback:
1180206083Srdivackyclass VLD3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1181218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4,
1182218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
1183218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1184205407Srdivacky           DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane),
1185218893Sdim          IIC_VLD3lnu, "vld3", Dt,
1186218893Sdim          "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm",
1187218893Sdim          "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb",
1188226633Sdim          []> {
1189226633Sdim  let DecoderMethod = "DecodeVLD3LN";
1190226633Sdim}
1191205407Srdivacky
1192218893Sdimdef VLD3LNd8_UPD  : VLD3LNWB<0b0010, {?,?,?,0}, "8"> {
1193218893Sdim  let Inst{7-5} = lane{2-0};
1194218893Sdim}
1195218893Sdimdef VLD3LNd16_UPD : VLD3LNWB<0b0110, {?,?,0,0}, "16"> {
1196218893Sdim  let Inst{7-6} = lane{1-0};
1197218893Sdim}
1198218893Sdimdef VLD3LNd32_UPD : VLD3LNWB<0b1010, {?,0,0,0}, "32"> {
1199234353Sdim  let Inst{7} = lane{0};
1200218893Sdim}
1201205407Srdivacky
1202218893Sdimdef VLD3LNd8Pseudo_UPD  : VLDQQLNWBPseudo<IIC_VLD3lnu>;
1203218893Sdimdef VLD3LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>;
1204218893Sdimdef VLD3LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>;
1205205407Srdivacky
1206218893Sdimdef VLD3LNq16_UPD : VLD3LNWB<0b0110, {?,?,1,0}, "16"> {
1207218893Sdim  let Inst{7-6} = lane{1-0};
1208218893Sdim}
1209218893Sdimdef VLD3LNq32_UPD : VLD3LNWB<0b1010, {?,1,0,0}, "32"> {
1210234353Sdim  let Inst{7} = lane{0};
1211218893Sdim}
1212218893Sdim
1213218893Sdimdef VLD3LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>;
1214218893Sdimdef VLD3LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>;
1215218893Sdim
1216198090Srdivacky//   VLD4LN   : Vector Load (single 4-element structure to one lane)
1217206083Srdivackyclass VLD4LN<bits<4> op11_8, bits<4> op7_4, string Dt>
1218218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4,
1219218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
1220218893Sdim          (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
1221218893Sdim          nohash_imm:$lane), IIC_VLD4ln, "vld4", Dt,
1222218893Sdim          "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn",
1223218893Sdim          "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []> {
1224218893Sdim  let Rm = 0b1111;
1225234353Sdim  let Inst{4} = Rn{4};
1226226633Sdim  let DecoderMethod = "DecodeVLD4LN";
1227218893Sdim}
1228198090Srdivacky
1229218893Sdimdef VLD4LNd8  : VLD4LN<0b0011, {?,?,?,?}, "8"> {
1230218893Sdim  let Inst{7-5} = lane{2-0};
1231218893Sdim}
1232218893Sdimdef VLD4LNd16 : VLD4LN<0b0111, {?,?,0,?}, "16"> {
1233218893Sdim  let Inst{7-6} = lane{1-0};
1234218893Sdim}
1235218893Sdimdef VLD4LNd32 : VLD4LN<0b1011, {?,0,?,?}, "32"> {
1236234353Sdim  let Inst{7} = lane{0};
1237218893Sdim  let Inst{5} = Rn{5};
1238218893Sdim}
1239198090Srdivacky
1240218893Sdimdef VLD4LNd8Pseudo  : VLDQQLNPseudo<IIC_VLD4ln>;
1241218893Sdimdef VLD4LNd16Pseudo : VLDQQLNPseudo<IIC_VLD4ln>;
1242218893Sdimdef VLD4LNd32Pseudo : VLDQQLNPseudo<IIC_VLD4ln>;
1243218893Sdim
1244205407Srdivacky// ...with double-spaced registers:
1245218893Sdimdef VLD4LNq16 : VLD4LN<0b0111, {?,?,1,?}, "16"> {
1246218893Sdim  let Inst{7-6} = lane{1-0};
1247218893Sdim}
1248218893Sdimdef VLD4LNq32 : VLD4LN<0b1011, {?,1,?,?}, "32"> {
1249234353Sdim  let Inst{7} = lane{0};
1250218893Sdim  let Inst{5} = Rn{5};
1251218893Sdim}
1252198090Srdivacky
1253218893Sdimdef VLD4LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>;
1254218893Sdimdef VLD4LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>;
1255198090Srdivacky
1256205407Srdivacky// ...with address register writeback:
1257206083Srdivackyclass VLD4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1258218893Sdim  : NLdStLn<1, 0b10, op11_8, op7_4,
1259218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
1260218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1261205407Srdivacky           DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),
1262218893Sdim          IIC_VLD4lnu, "vld4", Dt,
1263218893Sdim"\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn$Rm",
1264218893Sdim"$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb",
1265218893Sdim          []> {
1266218893Sdim  let Inst{4}   = Rn{4};
1267226633Sdim  let DecoderMethod = "DecodeVLD4LN"  ;
1268218893Sdim}
1269205407Srdivacky
1270218893Sdimdef VLD4LNd8_UPD  : VLD4LNWB<0b0011, {?,?,?,?}, "8"> {
1271218893Sdim  let Inst{7-5} = lane{2-0};
1272218893Sdim}
1273218893Sdimdef VLD4LNd16_UPD : VLD4LNWB<0b0111, {?,?,0,?}, "16"> {
1274218893Sdim  let Inst{7-6} = lane{1-0};
1275218893Sdim}
1276218893Sdimdef VLD4LNd32_UPD : VLD4LNWB<0b1011, {?,0,?,?}, "32"> {
1277234353Sdim  let Inst{7} = lane{0};
1278218893Sdim  let Inst{5} = Rn{5};
1279218893Sdim}
1280205407Srdivacky
1281218893Sdimdef VLD4LNd8Pseudo_UPD  : VLDQQLNWBPseudo<IIC_VLD4lnu>;
1282218893Sdimdef VLD4LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>;
1283218893Sdimdef VLD4LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>;
1284205407Srdivacky
1285218893Sdimdef VLD4LNq16_UPD : VLD4LNWB<0b0111, {?,?,1,?}, "16"> {
1286218893Sdim  let Inst{7-6} = lane{1-0};
1287218893Sdim}
1288218893Sdimdef VLD4LNq32_UPD : VLD4LNWB<0b1011, {?,1,?,?}, "32"> {
1289234353Sdim  let Inst{7} = lane{0};
1290218893Sdim  let Inst{5} = Rn{5};
1291218893Sdim}
1292218893Sdim
1293218893Sdimdef VLD4LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>;
1294218893Sdimdef VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>;
1295218893Sdim
1296218893Sdim} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1297218893Sdim
1298198090Srdivacky//   VLD1DUP  : Vector Load (single element to all lanes)
1299218893Sdimclass VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp>
1300234353Sdim  : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd),
1301234353Sdim          (ins addrmode6dup:$Rn),
1302234353Sdim          IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "",
1303234353Sdim          [(set VecListOneDAllLanes:$Vd,
1304234353Sdim                (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> {
1305218893Sdim  let Rm = 0b1111;
1306218893Sdim  let Inst{4} = Rn{4};
1307226633Sdim  let DecoderMethod = "DecodeVLD1DupInstruction";
1308218893Sdim}
1309218893Sdimdef VLD1DUPd8  : VLD1DUP<{0,0,0,?}, "8", v8i8, extloadi8>;
1310218893Sdimdef VLD1DUPd16 : VLD1DUP<{0,1,0,?}, "16", v4i16, extloadi16>;
1311218893Sdimdef VLD1DUPd32 : VLD1DUP<{1,0,0,?}, "32", v2i32, load>;
1312218893Sdim
1313218893Sdimdef : Pat<(v2f32 (NEONvdup (f32 (load addrmode6dup:$addr)))),
1314218893Sdim          (VLD1DUPd32 addrmode6:$addr)>;
1315218893Sdim
1316234353Sdimclass VLD1QDUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp>
1317234353Sdim  : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListDPairAllLanes:$Vd),
1318218893Sdim          (ins addrmode6dup:$Rn), IIC_VLD1dup,
1319234353Sdim          "vld1", Dt, "$Vd, $Rn", "",
1320234353Sdim          [(set VecListDPairAllLanes:$Vd,
1321234353Sdim                (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> {
1322218893Sdim  let Rm = 0b1111;
1323218893Sdim  let Inst{4} = Rn{4};
1324226633Sdim  let DecoderMethod = "DecodeVLD1DupInstruction";
1325218893Sdim}
1326218893Sdim
1327234353Sdimdef VLD1DUPq8  : VLD1QDUP<{0,0,1,0}, "8", v16i8, extloadi8>;
1328234353Sdimdef VLD1DUPq16 : VLD1QDUP<{0,1,1,?}, "16", v8i16, extloadi16>;
1329234353Sdimdef VLD1DUPq32 : VLD1QDUP<{1,0,1,?}, "32", v4i32, load>;
1330218893Sdim
1331234353Sdimdef : Pat<(v4f32 (NEONvdup (f32 (load addrmode6dup:$addr)))),
1332234353Sdim          (VLD1DUPq32 addrmode6:$addr)>;
1333234353Sdim
1334234353Sdimlet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1335218893Sdim// ...with address register writeback:
1336234353Sdimmulticlass VLD1DUPWB<bits<4> op7_4, string Dt> {
1337234353Sdim  def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,
1338234353Sdim                     (outs VecListOneDAllLanes:$Vd, GPR:$wb),
1339234353Sdim                     (ins addrmode6dup:$Rn), IIC_VLD1dupu,
1340234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
1341234353Sdim                     "$Rn.addr = $wb", []> {
1342234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1343234353Sdim    let Inst{4} = Rn{4};
1344234353Sdim    let DecoderMethod = "DecodeVLD1DupInstruction";
1345234353Sdim  }
1346234353Sdim  def _register : NLdSt<1, 0b10, 0b1100, op7_4,
1347234353Sdim                        (outs VecListOneDAllLanes:$Vd, GPR:$wb),
1348234353Sdim                        (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD1dupu,
1349234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
1350234353Sdim                        "$Rn.addr = $wb", []> {
1351234353Sdim    let Inst{4} = Rn{4};
1352234353Sdim    let DecoderMethod = "DecodeVLD1DupInstruction";
1353234353Sdim  }
1354218893Sdim}
1355234353Sdimmulticlass VLD1QDUPWB<bits<4> op7_4, string Dt> {
1356234353Sdim  def _fixed : NLdSt<1, 0b10, 0b1100, op7_4,
1357234353Sdim                     (outs VecListDPairAllLanes:$Vd, GPR:$wb),
1358234353Sdim                     (ins addrmode6dup:$Rn), IIC_VLD1dupu,
1359234353Sdim                     "vld1", Dt, "$Vd, $Rn!",
1360234353Sdim                     "$Rn.addr = $wb", []> {
1361234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1362234353Sdim    let Inst{4} = Rn{4};
1363234353Sdim    let DecoderMethod = "DecodeVLD1DupInstruction";
1364234353Sdim  }
1365234353Sdim  def _register : NLdSt<1, 0b10, 0b1100, op7_4,
1366234353Sdim                        (outs VecListDPairAllLanes:$Vd, GPR:$wb),
1367234353Sdim                        (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD1dupu,
1368234353Sdim                        "vld1", Dt, "$Vd, $Rn, $Rm",
1369234353Sdim                        "$Rn.addr = $wb", []> {
1370234353Sdim    let Inst{4} = Rn{4};
1371234353Sdim    let DecoderMethod = "DecodeVLD1DupInstruction";
1372234353Sdim  }
1373218893Sdim}
1374218893Sdim
1375234353Sdimdefm VLD1DUPd8wb  : VLD1DUPWB<{0,0,0,0}, "8">;
1376234353Sdimdefm VLD1DUPd16wb : VLD1DUPWB<{0,1,0,?}, "16">;
1377234353Sdimdefm VLD1DUPd32wb : VLD1DUPWB<{1,0,0,?}, "32">;
1378218893Sdim
1379234353Sdimdefm VLD1DUPq8wb  : VLD1QDUPWB<{0,0,1,0}, "8">;
1380234353Sdimdefm VLD1DUPq16wb : VLD1QDUPWB<{0,1,1,?}, "16">;
1381234353Sdimdefm VLD1DUPq32wb : VLD1QDUPWB<{1,0,1,?}, "32">;
1382218893Sdim
1383198090Srdivacky//   VLD2DUP  : Vector Load (single 2-element structure to all lanes)
1384234353Sdimclass VLD2DUP<bits<4> op7_4, string Dt, RegisterOperand VdTy>
1385234353Sdim  : NLdSt<1, 0b10, 0b1101, op7_4, (outs VdTy:$Vd),
1386218893Sdim          (ins addrmode6dup:$Rn), IIC_VLD2dup,
1387234353Sdim          "vld2", Dt, "$Vd, $Rn", "", []> {
1388218893Sdim  let Rm = 0b1111;
1389218893Sdim  let Inst{4} = Rn{4};
1390226633Sdim  let DecoderMethod = "DecodeVLD2DupInstruction";
1391218893Sdim}
1392218893Sdim
1393234353Sdimdef VLD2DUPd8  : VLD2DUP<{0,0,0,?}, "8",  VecListDPairAllLanes>;
1394234353Sdimdef VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes>;
1395234353Sdimdef VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes>;
1396218893Sdim
1397234353Sdim// ...with double-spaced registers
1398234353Sdimdef VLD2DUPd8x2  : VLD2DUP<{0,0,1,?}, "8",  VecListDPairSpacedAllLanes>;
1399234353Sdimdef VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
1400234353Sdimdef VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
1401218893Sdim
1402218893Sdim// ...with address register writeback:
1403234353Sdimmulticlass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy> {
1404234353Sdim  def _fixed : NLdSt<1, 0b10, 0b1101, op7_4,
1405234353Sdim                     (outs VdTy:$Vd, GPR:$wb),
1406234353Sdim                     (ins addrmode6dup:$Rn), IIC_VLD2dupu,
1407234353Sdim                     "vld2", Dt, "$Vd, $Rn!",
1408234353Sdim                     "$Rn.addr = $wb", []> {
1409234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1410234353Sdim    let Inst{4} = Rn{4};
1411234353Sdim    let DecoderMethod = "DecodeVLD2DupInstruction";
1412234353Sdim  }
1413234353Sdim  def _register : NLdSt<1, 0b10, 0b1101, op7_4,
1414234353Sdim                        (outs VdTy:$Vd, GPR:$wb),
1415234353Sdim                        (ins addrmode6dup:$Rn, rGPR:$Rm), IIC_VLD2dupu,
1416234353Sdim                        "vld2", Dt, "$Vd, $Rn, $Rm",
1417234353Sdim                        "$Rn.addr = $wb", []> {
1418234353Sdim    let Inst{4} = Rn{4};
1419234353Sdim    let DecoderMethod = "DecodeVLD2DupInstruction";
1420234353Sdim  }
1421218893Sdim}
1422218893Sdim
1423234353Sdimdefm VLD2DUPd8wb    : VLD2DUPWB<{0,0,0,0}, "8",  VecListDPairAllLanes>;
1424234353Sdimdefm VLD2DUPd16wb   : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes>;
1425234353Sdimdefm VLD2DUPd32wb   : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes>;
1426218893Sdim
1427234353Sdimdefm VLD2DUPd8x2wb  : VLD2DUPWB<{0,0,1,0}, "8",  VecListDPairSpacedAllLanes>;
1428234353Sdimdefm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
1429234353Sdimdefm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
1430218893Sdim
1431198090Srdivacky//   VLD3DUP  : Vector Load (single 3-element structure to all lanes)
1432218893Sdimclass VLD3DUP<bits<4> op7_4, string Dt>
1433218893Sdim  : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3),
1434218893Sdim          (ins addrmode6dup:$Rn), IIC_VLD3dup,
1435218893Sdim          "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []> {
1436218893Sdim  let Rm = 0b1111;
1437226633Sdim  let Inst{4} = 0;
1438226633Sdim  let DecoderMethod = "DecodeVLD3DupInstruction";
1439218893Sdim}
1440218893Sdim
1441218893Sdimdef VLD3DUPd8  : VLD3DUP<{0,0,0,?}, "8">;
1442218893Sdimdef VLD3DUPd16 : VLD3DUP<{0,1,0,?}, "16">;
1443218893Sdimdef VLD3DUPd32 : VLD3DUP<{1,0,0,?}, "32">;
1444218893Sdim
1445218893Sdimdef VLD3DUPd8Pseudo  : VLDQQPseudo<IIC_VLD3dup>;
1446218893Sdimdef VLD3DUPd16Pseudo : VLDQQPseudo<IIC_VLD3dup>;
1447218893Sdimdef VLD3DUPd32Pseudo : VLDQQPseudo<IIC_VLD3dup>;
1448218893Sdim
1449218893Sdim// ...with double-spaced registers (not used for codegen):
1450234353Sdimdef VLD3DUPq8  : VLD3DUP<{0,0,1,?}, "8">;
1451234353Sdimdef VLD3DUPq16 : VLD3DUP<{0,1,1,?}, "16">;
1452234353Sdimdef VLD3DUPq32 : VLD3DUP<{1,0,1,?}, "32">;
1453218893Sdim
1454218893Sdim// ...with address register writeback:
1455218893Sdimclass VLD3DUPWB<bits<4> op7_4, string Dt>
1456218893Sdim  : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
1457218893Sdim          (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD3dupu,
1458218893Sdim          "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm",
1459218893Sdim          "$Rn.addr = $wb", []> {
1460226633Sdim  let Inst{4} = 0;
1461226633Sdim  let DecoderMethod = "DecodeVLD3DupInstruction";
1462218893Sdim}
1463218893Sdim
1464218893Sdimdef VLD3DUPd8_UPD  : VLD3DUPWB<{0,0,0,0}, "8">;
1465218893Sdimdef VLD3DUPd16_UPD : VLD3DUPWB<{0,1,0,?}, "16">;
1466218893Sdimdef VLD3DUPd32_UPD : VLD3DUPWB<{1,0,0,?}, "32">;
1467218893Sdim
1468234353Sdimdef VLD3DUPq8_UPD  : VLD3DUPWB<{0,0,1,0}, "8">;
1469234353Sdimdef VLD3DUPq16_UPD : VLD3DUPWB<{0,1,1,?}, "16">;
1470234353Sdimdef VLD3DUPq32_UPD : VLD3DUPWB<{1,0,1,?}, "32">;
1471218893Sdim
1472218893Sdimdef VLD3DUPd8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD3dupu>;
1473218893Sdimdef VLD3DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>;
1474218893Sdimdef VLD3DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>;
1475218893Sdim
1476198090Srdivacky//   VLD4DUP  : Vector Load (single 4-element structure to all lanes)
1477218893Sdimclass VLD4DUP<bits<4> op7_4, string Dt>
1478218893Sdim  : NLdSt<1, 0b10, 0b1111, op7_4,
1479218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4),
1480218893Sdim          (ins addrmode6dup:$Rn), IIC_VLD4dup,
1481218893Sdim          "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> {
1482218893Sdim  let Rm = 0b1111;
1483218893Sdim  let Inst{4} = Rn{4};
1484226633Sdim  let DecoderMethod = "DecodeVLD4DupInstruction";
1485218893Sdim}
1486218893Sdim
1487218893Sdimdef VLD4DUPd8  : VLD4DUP<{0,0,0,?}, "8">;
1488218893Sdimdef VLD4DUPd16 : VLD4DUP<{0,1,0,?}, "16">;
1489218893Sdimdef VLD4DUPd32 : VLD4DUP<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }
1490218893Sdim
1491218893Sdimdef VLD4DUPd8Pseudo  : VLDQQPseudo<IIC_VLD4dup>;
1492218893Sdimdef VLD4DUPd16Pseudo : VLDQQPseudo<IIC_VLD4dup>;
1493218893Sdimdef VLD4DUPd32Pseudo : VLDQQPseudo<IIC_VLD4dup>;
1494218893Sdim
1495218893Sdim// ...with double-spaced registers (not used for codegen):
1496234353Sdimdef VLD4DUPq8  : VLD4DUP<{0,0,1,?}, "8">;
1497234353Sdimdef VLD4DUPq16 : VLD4DUP<{0,1,1,?}, "16">;
1498234353Sdimdef VLD4DUPq32 : VLD4DUP<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }
1499218893Sdim
1500218893Sdim// ...with address register writeback:
1501218893Sdimclass VLD4DUPWB<bits<4> op7_4, string Dt>
1502218893Sdim  : NLdSt<1, 0b10, 0b1111, op7_4,
1503218893Sdim          (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
1504218893Sdim          (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD4dupu,
1505218893Sdim          "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm",
1506218893Sdim          "$Rn.addr = $wb", []> {
1507218893Sdim  let Inst{4} = Rn{4};
1508226633Sdim  let DecoderMethod = "DecodeVLD4DupInstruction";
1509218893Sdim}
1510218893Sdim
1511218893Sdimdef VLD4DUPd8_UPD  : VLD4DUPWB<{0,0,0,0}, "8">;
1512218893Sdimdef VLD4DUPd16_UPD : VLD4DUPWB<{0,1,0,?}, "16">;
1513218893Sdimdef VLD4DUPd32_UPD : VLD4DUPWB<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; }
1514218893Sdim
1515234353Sdimdef VLD4DUPq8_UPD  : VLD4DUPWB<{0,0,1,0}, "8">;
1516234353Sdimdef VLD4DUPq16_UPD : VLD4DUPWB<{0,1,1,?}, "16">;
1517234353Sdimdef VLD4DUPq32_UPD : VLD4DUPWB<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; }
1518218893Sdim
1519218893Sdimdef VLD4DUPd8Pseudo_UPD  : VLDQQWBPseudo<IIC_VLD4dupu>;
1520218893Sdimdef VLD4DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>;
1521218893Sdimdef VLD4DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>;
1522218893Sdim
1523208599Srdivacky} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1524198090Srdivacky
1525208599Srdivackylet mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1526206083Srdivacky
1527212904Sdim// Classes for VST* pseudo-instructions with multi-register operands.
1528212904Sdim// These are expanded to real instructions after register allocation.
1529218893Sdimclass VSTQPseudo<InstrItinClass itin>
1530218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src), itin, "">;
1531218893Sdimclass VSTQWBPseudo<InstrItinClass itin>
1532212904Sdim  : PseudoNLdSt<(outs GPR:$wb),
1533218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin,
1534212904Sdim                "$addr.addr = $wb">;
1535234353Sdimclass VSTQWBfixedPseudo<InstrItinClass itin>
1536234353Sdim  : PseudoNLdSt<(outs GPR:$wb),
1537234353Sdim                (ins addrmode6:$addr, QPR:$src), itin,
1538234353Sdim                "$addr.addr = $wb">;
1539234353Sdimclass VSTQWBregisterPseudo<InstrItinClass itin>
1540234353Sdim  : PseudoNLdSt<(outs GPR:$wb),
1541234353Sdim                (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin,
1542234353Sdim                "$addr.addr = $wb">;
1543218893Sdimclass VSTQQPseudo<InstrItinClass itin>
1544218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">;
1545218893Sdimclass VSTQQWBPseudo<InstrItinClass itin>
1546212904Sdim  : PseudoNLdSt<(outs GPR:$wb),
1547218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQPR:$src), itin,
1548212904Sdim                "$addr.addr = $wb">;
1549234353Sdimclass VSTQQWBfixedPseudo<InstrItinClass itin>
1550234353Sdim  : PseudoNLdSt<(outs GPR:$wb),
1551234353Sdim                (ins addrmode6:$addr, QQPR:$src), itin,
1552234353Sdim                "$addr.addr = $wb">;
1553234353Sdimclass VSTQQWBregisterPseudo<InstrItinClass itin>
1554234353Sdim  : PseudoNLdSt<(outs GPR:$wb),
1555234353Sdim                (ins addrmode6:$addr, rGPR:$offset, QQPR:$src), itin,
1556234353Sdim                "$addr.addr = $wb">;
1557234353Sdim
1558218893Sdimclass VSTQQQQPseudo<InstrItinClass itin>
1559218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src), itin, "">;
1560218893Sdimclass VSTQQQQWBPseudo<InstrItinClass itin>
1561212904Sdim  : PseudoNLdSt<(outs GPR:$wb),
1562218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin,
1563212904Sdim                "$addr.addr = $wb">;
1564212904Sdim
1565198090Srdivacky//   VST1     : Vector Store (multiple single elements)
1566206083Srdivackyclass VST1D<bits<4> op7_4, string Dt>
1567234353Sdim  : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins addrmode6:$Rn, VecListOneD:$Vd),
1568234353Sdim          IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []> {
1569218893Sdim  let Rm = 0b1111;
1570218893Sdim  let Inst{4} = Rn{4};
1571263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
1572218893Sdim}
1573206083Srdivackyclass VST1Q<bits<4> op7_4, string Dt>
1574234353Sdim  : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins addrmode6:$Rn, VecListDPair:$Vd),
1575234353Sdim          IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []> {
1576218893Sdim  let Rm = 0b1111;
1577218893Sdim  let Inst{5-4} = Rn{5-4};
1578263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
1579218893Sdim}
1580198090Srdivacky
1581218893Sdimdef  VST1d8   : VST1D<{0,0,0,?}, "8">;
1582218893Sdimdef  VST1d16  : VST1D<{0,1,0,?}, "16">;
1583218893Sdimdef  VST1d32  : VST1D<{1,0,0,?}, "32">;
1584218893Sdimdef  VST1d64  : VST1D<{1,1,0,?}, "64">;
1585198090Srdivacky
1586218893Sdimdef  VST1q8   : VST1Q<{0,0,?,?}, "8">;
1587218893Sdimdef  VST1q16  : VST1Q<{0,1,?,?}, "16">;
1588218893Sdimdef  VST1q32  : VST1Q<{1,0,?,?}, "32">;
1589218893Sdimdef  VST1q64  : VST1Q<{1,1,?,?}, "64">;
1590198090Srdivacky
1591205407Srdivacky// ...with address register writeback:
1592234353Sdimmulticlass VST1DWB<bits<4> op7_4, string Dt> {
1593234353Sdim  def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb),
1594234353Sdim                     (ins addrmode6:$Rn, VecListOneD:$Vd), IIC_VLD1u,
1595234353Sdim                     "vst1", Dt, "$Vd, $Rn!",
1596234353Sdim                     "$Rn.addr = $wb", []> {
1597234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1598234353Sdim    let Inst{4} = Rn{4};
1599263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1600234353Sdim  }
1601234353Sdim  def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb),
1602234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VecListOneD:$Vd),
1603234353Sdim                        IIC_VLD1u,
1604234353Sdim                        "vst1", Dt, "$Vd, $Rn, $Rm",
1605234353Sdim                        "$Rn.addr = $wb", []> {
1606234353Sdim    let Inst{4} = Rn{4};
1607263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1608234353Sdim  }
1609218893Sdim}
1610234353Sdimmulticlass VST1QWB<bits<4> op7_4, string Dt> {
1611234353Sdim  def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),
1612234353Sdim                    (ins addrmode6:$Rn, VecListDPair:$Vd), IIC_VLD1x2u,
1613234353Sdim                     "vst1", Dt, "$Vd, $Rn!",
1614234353Sdim                     "$Rn.addr = $wb", []> {
1615234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1616234353Sdim    let Inst{5-4} = Rn{5-4};
1617263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1618234353Sdim  }
1619234353Sdim  def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb),
1620234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VecListDPair:$Vd),
1621234353Sdim                        IIC_VLD1x2u,
1622234353Sdim                        "vst1", Dt, "$Vd, $Rn, $Rm",
1623234353Sdim                        "$Rn.addr = $wb", []> {
1624234353Sdim    let Inst{5-4} = Rn{5-4};
1625263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1626234353Sdim  }
1627218893Sdim}
1628205407Srdivacky
1629234353Sdimdefm VST1d8wb  : VST1DWB<{0,0,0,?}, "8">;
1630234353Sdimdefm VST1d16wb : VST1DWB<{0,1,0,?}, "16">;
1631234353Sdimdefm VST1d32wb : VST1DWB<{1,0,0,?}, "32">;
1632234353Sdimdefm VST1d64wb : VST1DWB<{1,1,0,?}, "64">;
1633205407Srdivacky
1634234353Sdimdefm VST1q8wb  : VST1QWB<{0,0,?,?}, "8">;
1635234353Sdimdefm VST1q16wb : VST1QWB<{0,1,?,?}, "16">;
1636234353Sdimdefm VST1q32wb : VST1QWB<{1,0,?,?}, "32">;
1637234353Sdimdefm VST1q64wb : VST1QWB<{1,1,?,?}, "64">;
1638205407Srdivacky
1639234353Sdim// ...with 3 registers
1640205407Srdivackyclass VST1D3<bits<4> op7_4, string Dt>
1641204642Srdivacky  : NLdSt<0, 0b00, 0b0110, op7_4, (outs),
1642234353Sdim          (ins addrmode6:$Rn, VecListThreeD:$Vd),
1643234353Sdim          IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []> {
1644218893Sdim  let Rm = 0b1111;
1645218893Sdim  let Inst{4} = Rn{4};
1646263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
1647218893Sdim}
1648234353Sdimmulticlass VST1D3WB<bits<4> op7_4, string Dt> {
1649234353Sdim  def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),
1650234353Sdim                    (ins addrmode6:$Rn, VecListThreeD:$Vd), IIC_VLD1x3u,
1651234353Sdim                     "vst1", Dt, "$Vd, $Rn!",
1652234353Sdim                     "$Rn.addr = $wb", []> {
1653234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1654234353Sdim    let Inst{5-4} = Rn{5-4};
1655263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1656234353Sdim  }
1657234353Sdim  def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb),
1658234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VecListThreeD:$Vd),
1659234353Sdim                        IIC_VLD1x3u,
1660234353Sdim                        "vst1", Dt, "$Vd, $Rn, $Rm",
1661234353Sdim                        "$Rn.addr = $wb", []> {
1662234353Sdim    let Inst{5-4} = Rn{5-4};
1663263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1664234353Sdim  }
1665218893Sdim}
1666206083Srdivacky
1667234353Sdimdef VST1d8T     : VST1D3<{0,0,0,?}, "8">;
1668234353Sdimdef VST1d16T    : VST1D3<{0,1,0,?}, "16">;
1669234353Sdimdef VST1d32T    : VST1D3<{1,0,0,?}, "32">;
1670234353Sdimdef VST1d64T    : VST1D3<{1,1,0,?}, "64">;
1671206083Srdivacky
1672234353Sdimdefm VST1d8Twb  : VST1D3WB<{0,0,0,?}, "8">;
1673234353Sdimdefm VST1d16Twb : VST1D3WB<{0,1,0,?}, "16">;
1674234353Sdimdefm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32">;
1675234353Sdimdefm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64">;
1676206083Srdivacky
1677234353Sdimdef VST1d64TPseudo            : VSTQQPseudo<IIC_VST1x3>;
1678266715Sdimdef VST1d64TPseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST1x3u>;
1679234353Sdimdef VST1d64TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>;
1680212904Sdim
1681234353Sdim// ...with 4 registers
1682206083Srdivackyclass VST1D4<bits<4> op7_4, string Dt>
1683206083Srdivacky  : NLdSt<0, 0b00, 0b0010, op7_4, (outs),
1684234353Sdim          (ins addrmode6:$Rn, VecListFourD:$Vd),
1685234353Sdim          IIC_VST1x4, "vst1", Dt, "$Vd, $Rn", "",
1686218893Sdim          []> {
1687218893Sdim  let Rm = 0b1111;
1688218893Sdim  let Inst{5-4} = Rn{5-4};
1689263508Sdim  let DecoderMethod = "DecodeVLDST1Instruction";
1690218893Sdim}
1691234353Sdimmulticlass VST1D4WB<bits<4> op7_4, string Dt> {
1692234353Sdim  def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),
1693234353Sdim                    (ins addrmode6:$Rn, VecListFourD:$Vd), IIC_VLD1x4u,
1694234353Sdim                     "vst1", Dt, "$Vd, $Rn!",
1695234353Sdim                     "$Rn.addr = $wb", []> {
1696234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1697234353Sdim    let Inst{5-4} = Rn{5-4};
1698263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1699234353Sdim  }
1700234353Sdim  def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb),
1701234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VecListFourD:$Vd),
1702234353Sdim                        IIC_VLD1x4u,
1703234353Sdim                        "vst1", Dt, "$Vd, $Rn, $Rm",
1704234353Sdim                        "$Rn.addr = $wb", []> {
1705234353Sdim    let Inst{5-4} = Rn{5-4};
1706263508Sdim    let DecoderMethod = "DecodeVLDST1Instruction";
1707234353Sdim  }
1708218893Sdim}
1709204642Srdivacky
1710234353Sdimdef VST1d8Q     : VST1D4<{0,0,?,?}, "8">;
1711234353Sdimdef VST1d16Q    : VST1D4<{0,1,?,?}, "16">;
1712234353Sdimdef VST1d32Q    : VST1D4<{1,0,?,?}, "32">;
1713234353Sdimdef VST1d64Q    : VST1D4<{1,1,?,?}, "64">;
1714198090Srdivacky
1715234353Sdimdefm VST1d8Qwb  : VST1D4WB<{0,0,?,?}, "8">;
1716234353Sdimdefm VST1d16Qwb : VST1D4WB<{0,1,?,?}, "16">;
1717234353Sdimdefm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32">;
1718234353Sdimdefm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64">;
1719205407Srdivacky
1720234353Sdimdef VST1d64QPseudo            : VSTQQPseudo<IIC_VST1x4>;
1721266715Sdimdef VST1d64QPseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST1x4u>;
1722234353Sdimdef VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>;
1723212904Sdim
1724198090Srdivacky//   VST2     : Vector Store (multiple 2-element structures)
1725234353Sdimclass VST2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy,
1726234353Sdim            InstrItinClass itin>
1727234353Sdim  : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd),
1728234353Sdim          itin, "vst2", Dt, "$Vd, $Rn", "", []> {
1729218893Sdim  let Rm = 0b1111;
1730218893Sdim  let Inst{5-4} = Rn{5-4};
1731263508Sdim  let DecoderMethod = "DecodeVLDST2Instruction";
1732218893Sdim}
1733198090Srdivacky
1734234353Sdimdef  VST2d8   : VST2<0b1000, {0,0,?,?}, "8",  VecListDPair, IIC_VST2>;
1735234353Sdimdef  VST2d16  : VST2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VST2>;
1736234353Sdimdef  VST2d32  : VST2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VST2>;
1737198090Srdivacky
1738234353Sdimdef  VST2q8   : VST2<0b0011, {0,0,?,?}, "8",  VecListFourD, IIC_VST2x2>;
1739234353Sdimdef  VST2q16  : VST2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VST2x2>;
1740234353Sdimdef  VST2q32  : VST2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VST2x2>;
1741198090Srdivacky
1742218893Sdimdef  VST2q8Pseudo  : VSTQQPseudo<IIC_VST2x2>;
1743218893Sdimdef  VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>;
1744218893Sdimdef  VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>;
1745212904Sdim
1746205407Srdivacky// ...with address register writeback:
1747234353Sdimmulticlass VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt,
1748234353Sdim                   RegisterOperand VdTy> {
1749234353Sdim  def _fixed : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1750234353Sdim                     (ins addrmode6:$Rn, VdTy:$Vd), IIC_VLD1u,
1751234353Sdim                     "vst2", Dt, "$Vd, $Rn!",
1752234353Sdim                     "$Rn.addr = $wb", []> {
1753234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1754234353Sdim    let Inst{5-4} = Rn{5-4};
1755263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
1756234353Sdim  }
1757234353Sdim  def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1758234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VdTy:$Vd), IIC_VLD1u,
1759234353Sdim                        "vst2", Dt, "$Vd, $Rn, $Rm",
1760234353Sdim                        "$Rn.addr = $wb", []> {
1761234353Sdim    let Inst{5-4} = Rn{5-4};
1762263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
1763234353Sdim  }
1764218893Sdim}
1765234353Sdimmulticlass VST2QWB<bits<4> op7_4, string Dt> {
1766234353Sdim  def _fixed : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
1767234353Sdim                     (ins addrmode6:$Rn, VecListFourD:$Vd), IIC_VLD1u,
1768234353Sdim                     "vst2", Dt, "$Vd, $Rn!",
1769234353Sdim                     "$Rn.addr = $wb", []> {
1770234353Sdim    let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
1771234353Sdim    let Inst{5-4} = Rn{5-4};
1772263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
1773234353Sdim  }
1774234353Sdim  def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
1775234353Sdim                        (ins addrmode6:$Rn, rGPR:$Rm, VecListFourD:$Vd),
1776234353Sdim                        IIC_VLD1u,
1777234353Sdim                        "vst2", Dt, "$Vd, $Rn, $Rm",
1778234353Sdim                        "$Rn.addr = $wb", []> {
1779234353Sdim    let Inst{5-4} = Rn{5-4};
1780263508Sdim    let DecoderMethod = "DecodeVLDST2Instruction";
1781234353Sdim  }
1782218893Sdim}
1783204642Srdivacky
1784234353Sdimdefm VST2d8wb    : VST2DWB<0b1000, {0,0,?,?}, "8",  VecListDPair>;
1785234353Sdimdefm VST2d16wb   : VST2DWB<0b1000, {0,1,?,?}, "16", VecListDPair>;
1786234353Sdimdefm VST2d32wb   : VST2DWB<0b1000, {1,0,?,?}, "32", VecListDPair>;
1787204642Srdivacky
1788234353Sdimdefm VST2q8wb    : VST2QWB<{0,0,?,?}, "8">;
1789234353Sdimdefm VST2q16wb   : VST2QWB<{0,1,?,?}, "16">;
1790234353Sdimdefm VST2q32wb   : VST2QWB<{1,0,?,?}, "32">;
1791205407Srdivacky
1792234353Sdimdef VST2q8PseudoWB_fixed     : VSTQQWBfixedPseudo<IIC_VST2x2u>;
1793234353Sdimdef VST2q16PseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST2x2u>;
1794234353Sdimdef VST2q32PseudoWB_fixed    : VSTQQWBfixedPseudo<IIC_VST2x2u>;
1795234353Sdimdef VST2q8PseudoWB_register  : VSTQQWBregisterPseudo<IIC_VST2x2u>;
1796234353Sdimdef VST2q16PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>;
1797234353Sdimdef VST2q32PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>;
1798212904Sdim
1799234353Sdim// ...with double-spaced registers
1800234353Sdimdef VST2b8      : VST2<0b1001, {0,0,?,?}, "8",  VecListDPairSpaced, IIC_VST2>;
1801234353Sdimdef VST2b16     : VST2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VST2>;
1802234353Sdimdef VST2b32     : VST2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VST2>;
1803234353Sdimdefm VST2b8wb   : VST2DWB<0b1001, {0,0,?,?}, "8",  VecListDPairSpaced>;
1804234353Sdimdefm VST2b16wb  : VST2DWB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced>;
1805234353Sdimdefm VST2b32wb  : VST2DWB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced>;
1806212904Sdim
1807198090Srdivacky//   VST3     : Vector Store (multiple 3-element structures)
1808205407Srdivackyclass VST3D<bits<4> op11_8, bits<4> op7_4, string Dt>
1809205407Srdivacky  : NLdSt<0, 0b00, op11_8, op7_4, (outs),
1810218893Sdim          (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3,
1811218893Sdim          "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> {
1812218893Sdim  let Rm = 0b1111;
1813218893Sdim  let Inst{4} = Rn{4};
1814263508Sdim  let DecoderMethod = "DecodeVLDST3Instruction";
1815218893Sdim}
1816198090Srdivacky
1817218893Sdimdef  VST3d8   : VST3D<0b0100, {0,0,0,?}, "8">;
1818218893Sdimdef  VST3d16  : VST3D<0b0100, {0,1,0,?}, "16">;
1819218893Sdimdef  VST3d32  : VST3D<0b0100, {1,0,0,?}, "32">;
1820198090Srdivacky
1821218893Sdimdef  VST3d8Pseudo  : VSTQQPseudo<IIC_VST3>;
1822218893Sdimdef  VST3d16Pseudo : VSTQQPseudo<IIC_VST3>;
1823218893Sdimdef  VST3d32Pseudo : VSTQQPseudo<IIC_VST3>;
1824212904Sdim
1825205407Srdivacky// ...with address register writeback:
1826205407Srdivackyclass VST3DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1827205407Srdivacky  : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1828218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1829218893Sdim           DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3u,
1830218893Sdim          "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm",
1831218893Sdim          "$Rn.addr = $wb", []> {
1832218893Sdim  let Inst{4} = Rn{4};
1833263508Sdim  let DecoderMethod = "DecodeVLDST3Instruction";
1834218893Sdim}
1835198090Srdivacky
1836218893Sdimdef VST3d8_UPD  : VST3DWB<0b0100, {0,0,0,?}, "8">;
1837218893Sdimdef VST3d16_UPD : VST3DWB<0b0100, {0,1,0,?}, "16">;
1838218893Sdimdef VST3d32_UPD : VST3DWB<0b0100, {1,0,0,?}, "32">;
1839198090Srdivacky
1840218893Sdimdef VST3d8Pseudo_UPD  : VSTQQWBPseudo<IIC_VST3u>;
1841218893Sdimdef VST3d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>;
1842218893Sdimdef VST3d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>;
1843212904Sdim
1844218893Sdim// ...with double-spaced registers:
1845218893Sdimdef VST3q8      : VST3D<0b0101, {0,0,0,?}, "8">;
1846218893Sdimdef VST3q16     : VST3D<0b0101, {0,1,0,?}, "16">;
1847218893Sdimdef VST3q32     : VST3D<0b0101, {1,0,0,?}, "32">;
1848218893Sdimdef VST3q8_UPD  : VST3DWB<0b0101, {0,0,0,?}, "8">;
1849218893Sdimdef VST3q16_UPD : VST3DWB<0b0101, {0,1,0,?}, "16">;
1850218893Sdimdef VST3q32_UPD : VST3DWB<0b0101, {1,0,0,?}, "32">;
1851205407Srdivacky
1852218893Sdimdef VST3q8Pseudo_UPD  : VSTQQQQWBPseudo<IIC_VST3u>;
1853218893Sdimdef VST3q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>;
1854218893Sdimdef VST3q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>;
1855212904Sdim
1856205407Srdivacky// ...alternate versions to be allocated odd register numbers:
1857218893Sdimdef VST3q8oddPseudo   : VSTQQQQPseudo<IIC_VST3>;
1858218893Sdimdef VST3q16oddPseudo  : VSTQQQQPseudo<IIC_VST3>;
1859218893Sdimdef VST3q32oddPseudo  : VSTQQQQPseudo<IIC_VST3>;
1860205407Srdivacky
1861218893Sdimdef VST3q8oddPseudo_UPD  : VSTQQQQWBPseudo<IIC_VST3u>;
1862218893Sdimdef VST3q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>;
1863218893Sdimdef VST3q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>;
1864218893Sdim
1865198090Srdivacky//   VST4     : Vector Store (multiple 4-element structures)
1866205407Srdivackyclass VST4D<bits<4> op11_8, bits<4> op7_4, string Dt>
1867205407Srdivacky  : NLdSt<0, 0b00, op11_8, op7_4, (outs),
1868218893Sdim          (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4),
1869218893Sdim          IIC_VST4, "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn",
1870218893Sdim          "", []> {
1871218893Sdim  let Rm = 0b1111;
1872218893Sdim  let Inst{5-4} = Rn{5-4};
1873263508Sdim  let DecoderMethod = "DecodeVLDST4Instruction";
1874218893Sdim}
1875198090Srdivacky
1876218893Sdimdef  VST4d8   : VST4D<0b0000, {0,0,?,?}, "8">;
1877218893Sdimdef  VST4d16  : VST4D<0b0000, {0,1,?,?}, "16">;
1878218893Sdimdef  VST4d32  : VST4D<0b0000, {1,0,?,?}, "32">;
1879198090Srdivacky
1880218893Sdimdef  VST4d8Pseudo  : VSTQQPseudo<IIC_VST4>;
1881218893Sdimdef  VST4d16Pseudo : VSTQQPseudo<IIC_VST4>;
1882218893Sdimdef  VST4d32Pseudo : VSTQQPseudo<IIC_VST4>;
1883212904Sdim
1884205407Srdivacky// ...with address register writeback:
1885205407Srdivackyclass VST4DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
1886205407Srdivacky  : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
1887218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
1888218893Sdim           DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST4u,
1889218893Sdim           "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
1890218893Sdim          "$Rn.addr = $wb", []> {
1891218893Sdim  let Inst{5-4} = Rn{5-4};
1892263508Sdim  let DecoderMethod = "DecodeVLDST4Instruction";
1893218893Sdim}
1894198090Srdivacky
1895218893Sdimdef VST4d8_UPD  : VST4DWB<0b0000, {0,0,?,?}, "8">;
1896218893Sdimdef VST4d16_UPD : VST4DWB<0b0000, {0,1,?,?}, "16">;
1897218893Sdimdef VST4d32_UPD : VST4DWB<0b0000, {1,0,?,?}, "32">;
1898198090Srdivacky
1899218893Sdimdef VST4d8Pseudo_UPD  : VSTQQWBPseudo<IIC_VST4u>;
1900218893Sdimdef VST4d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>;
1901218893Sdimdef VST4d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>;
1902212904Sdim
1903218893Sdim// ...with double-spaced registers:
1904218893Sdimdef VST4q8      : VST4D<0b0001, {0,0,?,?}, "8">;
1905218893Sdimdef VST4q16     : VST4D<0b0001, {0,1,?,?}, "16">;
1906218893Sdimdef VST4q32     : VST4D<0b0001, {1,0,?,?}, "32">;
1907218893Sdimdef VST4q8_UPD  : VST4DWB<0b0001, {0,0,?,?}, "8">;
1908218893Sdimdef VST4q16_UPD : VST4DWB<0b0001, {0,1,?,?}, "16">;
1909218893Sdimdef VST4q32_UPD : VST4DWB<0b0001, {1,0,?,?}, "32">;
1910205407Srdivacky
1911218893Sdimdef VST4q8Pseudo_UPD  : VSTQQQQWBPseudo<IIC_VST4u>;
1912218893Sdimdef VST4q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>;
1913218893Sdimdef VST4q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>;
1914212904Sdim
1915205407Srdivacky// ...alternate versions to be allocated odd register numbers:
1916218893Sdimdef VST4q8oddPseudo   : VSTQQQQPseudo<IIC_VST4>;
1917218893Sdimdef VST4q16oddPseudo  : VSTQQQQPseudo<IIC_VST4>;
1918218893Sdimdef VST4q32oddPseudo  : VSTQQQQPseudo<IIC_VST4>;
1919205407Srdivacky
1920218893Sdimdef VST4q8oddPseudo_UPD  : VSTQQQQWBPseudo<IIC_VST4u>;
1921218893Sdimdef VST4q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>;
1922218893Sdimdef VST4q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>;
1923218893Sdim
1924218893Sdim} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
1925218893Sdim
1926218893Sdim// Classes for VST*LN pseudo-instructions with multi-register operands.
1927218893Sdim// These are expanded to real instructions after register allocation.
1928218893Sdimclass VSTQLNPseudo<InstrItinClass itin>
1929218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane),
1930218893Sdim                itin, "">;
1931218893Sdimclass VSTQLNWBPseudo<InstrItinClass itin>
1932218893Sdim  : PseudoNLdSt<(outs GPR:$wb),
1933218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QPR:$src,
1934218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb">;
1935218893Sdimclass VSTQQLNPseudo<InstrItinClass itin>
1936218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane),
1937218893Sdim                itin, "">;
1938218893Sdimclass VSTQQLNWBPseudo<InstrItinClass itin>
1939218893Sdim  : PseudoNLdSt<(outs GPR:$wb),
1940218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQPR:$src,
1941218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb">;
1942218893Sdimclass VSTQQQQLNPseudo<InstrItinClass itin>
1943218893Sdim  : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane),
1944218893Sdim                itin, "">;
1945218893Sdimclass VSTQQQQLNWBPseudo<InstrItinClass itin>
1946218893Sdim  : PseudoNLdSt<(outs GPR:$wb),
1947218893Sdim                (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src,
1948218893Sdim                 nohash_imm:$lane), itin, "$addr.addr = $wb">;
1949218893Sdim
1950198090Srdivacky//   VST1LN   : Vector Store (single element from one lane)
1951218893Sdimclass VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
1952234353Sdim             PatFrag StoreOp, SDNode ExtractOp, Operand AddrMode>
1953218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
1954234353Sdim          (ins AddrMode:$Rn, DPR:$Vd, nohash_imm:$lane),
1955218893Sdim          IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "",
1956234353Sdim          [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), AddrMode:$Rn)]> {
1957218893Sdim  let Rm = 0b1111;
1958226633Sdim  let DecoderMethod = "DecodeVST1LN";
1959218893Sdim}
1960218893Sdimclass VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>
1961218893Sdim  : VSTQLNPseudo<IIC_VST1ln> {
1962218893Sdim  let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),
1963218893Sdim                          addrmode6:$addr)];
1964218893Sdim}
1965198090Srdivacky
1966218893Sdimdef VST1LNd8  : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8,
1967234353Sdim                       NEONvgetlaneu, addrmode6> {
1968218893Sdim  let Inst{7-5} = lane{2-0};
1969218893Sdim}
1970218893Sdimdef VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16,
1971234353Sdim                       NEONvgetlaneu, addrmode6> {
1972218893Sdim  let Inst{7-6} = lane{1-0};
1973243830Sdim  let Inst{4}   = Rn{4};
1974218893Sdim}
1975223017Sdim
1976239462Sdimdef VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt,
1977234353Sdim                       addrmode6oneL32> {
1978218893Sdim  let Inst{7}   = lane{0};
1979218893Sdim  let Inst{5-4} = Rn{5-4};
1980218893Sdim}
1981218893Sdim
1982218893Sdimdef VST1LNq8Pseudo  : VST1QLNPseudo<v16i8, truncstorei8, NEONvgetlaneu>;
1983218893Sdimdef VST1LNq16Pseudo : VST1QLNPseudo<v8i16, truncstorei16, NEONvgetlaneu>;
1984218893Sdimdef VST1LNq32Pseudo : VST1QLNPseudo<v4i32, store, extractelt>;
1985218893Sdim
1986218893Sdimdef : Pat<(store (extractelt (v2f32 DPR:$src), imm:$lane), addrmode6:$addr),
1987218893Sdim          (VST1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>;
1988218893Sdimdef : Pat<(store (extractelt (v4f32 QPR:$src), imm:$lane), addrmode6:$addr),
1989218893Sdim          (VST1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>;
1990218893Sdim
1991218893Sdim// ...with address register writeback:
1992219077Sdimclass VST1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
1993234353Sdim               PatFrag StoreOp, SDNode ExtractOp, Operand AdrMode>
1994218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
1995234353Sdim          (ins AdrMode:$Rn, am6offset:$Rm,
1996218893Sdim           DPR:$Vd, nohash_imm:$lane), IIC_VST1lnu, "vst1", Dt,
1997218893Sdim          "\\{$Vd[$lane]\\}, $Rn$Rm",
1998219077Sdim          "$Rn.addr = $wb",
1999219077Sdim          [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane),
2000234353Sdim                                  AdrMode:$Rn, am6offset:$Rm))]> {
2001226633Sdim  let DecoderMethod = "DecodeVST1LN";
2002226633Sdim}
2003219077Sdimclass VST1QLNWBPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>
2004219077Sdim  : VSTQLNWBPseudo<IIC_VST1lnu> {
2005219077Sdim  let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane),
2006219077Sdim                                        addrmode6:$addr, am6offset:$offset))];
2007219077Sdim}
2008218893Sdim
2009219077Sdimdef VST1LNd8_UPD  : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8,
2010234353Sdim                             NEONvgetlaneu, addrmode6> {
2011218893Sdim  let Inst{7-5} = lane{2-0};
2012218893Sdim}
2013219077Sdimdef VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16,
2014234353Sdim                             NEONvgetlaneu, addrmode6> {
2015218893Sdim  let Inst{7-6} = lane{1-0};
2016243830Sdim  let Inst{4}   = Rn{4};
2017218893Sdim}
2018219077Sdimdef VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store,
2019234353Sdim                             extractelt, addrmode6oneL32> {
2020218893Sdim  let Inst{7}   = lane{0};
2021218893Sdim  let Inst{5-4} = Rn{5-4};
2022218893Sdim}
2023218893Sdim
2024219077Sdimdef VST1LNq8Pseudo_UPD  : VST1QLNWBPseudo<v16i8, post_truncsti8, NEONvgetlaneu>;
2025219077Sdimdef VST1LNq16Pseudo_UPD : VST1QLNWBPseudo<v8i16, post_truncsti16,NEONvgetlaneu>;
2026219077Sdimdef VST1LNq32Pseudo_UPD : VST1QLNWBPseudo<v4i32, post_store, extractelt>;
2027218893Sdim
2028219077Sdimlet mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
2029219077Sdim
2030198090Srdivacky//   VST2LN   : Vector Store (single 2-element structure from one lane)
2031206083Srdivackyclass VST2LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2032218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2033218893Sdim          (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, nohash_imm:$lane),
2034218893Sdim          IIC_VST2ln, "vst2", Dt, "\\{$Vd[$lane], $src2[$lane]\\}, $Rn",
2035218893Sdim          "", []> {
2036218893Sdim  let Rm = 0b1111;
2037218893Sdim  let Inst{4}   = Rn{4};
2038226633Sdim  let DecoderMethod = "DecodeVST2LN";
2039218893Sdim}
2040198090Srdivacky
2041218893Sdimdef VST2LNd8  : VST2LN<0b0001, {?,?,?,?}, "8"> {
2042218893Sdim  let Inst{7-5} = lane{2-0};
2043218893Sdim}
2044218893Sdimdef VST2LNd16 : VST2LN<0b0101, {?,?,0,?}, "16"> {
2045218893Sdim  let Inst{7-6} = lane{1-0};
2046218893Sdim}
2047218893Sdimdef VST2LNd32 : VST2LN<0b1001, {?,0,0,?}, "32"> {
2048218893Sdim  let Inst{7}   = lane{0};
2049218893Sdim}
2050198090Srdivacky
2051218893Sdimdef VST2LNd8Pseudo  : VSTQLNPseudo<IIC_VST2ln>;
2052218893Sdimdef VST2LNd16Pseudo : VSTQLNPseudo<IIC_VST2ln>;
2053218893Sdimdef VST2LNd32Pseudo : VSTQLNPseudo<IIC_VST2ln>;
2054218893Sdim
2055205407Srdivacky// ...with double-spaced registers:
2056218893Sdimdef VST2LNq16 : VST2LN<0b0101, {?,?,1,?}, "16"> {
2057218893Sdim  let Inst{7-6} = lane{1-0};
2058218893Sdim  let Inst{4}   = Rn{4};
2059218893Sdim}
2060218893Sdimdef VST2LNq32 : VST2LN<0b1001, {?,1,0,?}, "32"> {
2061218893Sdim  let Inst{7}   = lane{0};
2062218893Sdim  let Inst{4}   = Rn{4};
2063218893Sdim}
2064198090Srdivacky
2065218893Sdimdef VST2LNq16Pseudo : VSTQQLNPseudo<IIC_VST2ln>;
2066218893Sdimdef VST2LNq32Pseudo : VSTQQLNPseudo<IIC_VST2ln>;
2067198090Srdivacky
2068205407Srdivacky// ...with address register writeback:
2069206083Srdivackyclass VST2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2070218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2071234353Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
2072234353Sdim           DPR:$Vd, DPR:$src2, nohash_imm:$lane), IIC_VST2lnu, "vst2", Dt,
2073234353Sdim          "\\{$Vd[$lane], $src2[$lane]\\}, $Rn$Rm",
2074234353Sdim          "$Rn.addr = $wb", []> {
2075218893Sdim  let Inst{4}   = Rn{4};
2076226633Sdim  let DecoderMethod = "DecodeVST2LN";
2077218893Sdim}
2078205407Srdivacky
2079218893Sdimdef VST2LNd8_UPD  : VST2LNWB<0b0001, {?,?,?,?}, "8"> {
2080218893Sdim  let Inst{7-5} = lane{2-0};
2081218893Sdim}
2082218893Sdimdef VST2LNd16_UPD : VST2LNWB<0b0101, {?,?,0,?}, "16"> {
2083218893Sdim  let Inst{7-6} = lane{1-0};
2084218893Sdim}
2085218893Sdimdef VST2LNd32_UPD : VST2LNWB<0b1001, {?,0,0,?}, "32"> {
2086218893Sdim  let Inst{7}   = lane{0};
2087218893Sdim}
2088205407Srdivacky
2089218893Sdimdef VST2LNd8Pseudo_UPD  : VSTQLNWBPseudo<IIC_VST2lnu>;
2090218893Sdimdef VST2LNd16Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>;
2091218893Sdimdef VST2LNd32Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>;
2092205407Srdivacky
2093218893Sdimdef VST2LNq16_UPD : VST2LNWB<0b0101, {?,?,1,?}, "16"> {
2094218893Sdim  let Inst{7-6} = lane{1-0};
2095218893Sdim}
2096218893Sdimdef VST2LNq32_UPD : VST2LNWB<0b1001, {?,1,0,?}, "32"> {
2097218893Sdim  let Inst{7}   = lane{0};
2098218893Sdim}
2099218893Sdim
2100218893Sdimdef VST2LNq16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>;
2101218893Sdimdef VST2LNq32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>;
2102218893Sdim
2103198090Srdivacky//   VST3LN   : Vector Store (single 3-element structure from one lane)
2104206083Srdivackyclass VST3LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2105218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2106218893Sdim          (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3,
2107218893Sdim           nohash_imm:$lane), IIC_VST3ln, "vst3", Dt,
2108218893Sdim          "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []> {
2109218893Sdim  let Rm = 0b1111;
2110226633Sdim  let DecoderMethod = "DecodeVST3LN";
2111218893Sdim}
2112198090Srdivacky
2113218893Sdimdef VST3LNd8  : VST3LN<0b0010, {?,?,?,0}, "8"> {
2114218893Sdim  let Inst{7-5} = lane{2-0};
2115218893Sdim}
2116218893Sdimdef VST3LNd16 : VST3LN<0b0110, {?,?,0,0}, "16"> {
2117218893Sdim  let Inst{7-6} = lane{1-0};
2118218893Sdim}
2119218893Sdimdef VST3LNd32 : VST3LN<0b1010, {?,0,0,0}, "32"> {
2120218893Sdim  let Inst{7}   = lane{0};
2121218893Sdim}
2122198090Srdivacky
2123218893Sdimdef VST3LNd8Pseudo  : VSTQQLNPseudo<IIC_VST3ln>;
2124218893Sdimdef VST3LNd16Pseudo : VSTQQLNPseudo<IIC_VST3ln>;
2125218893Sdimdef VST3LNd32Pseudo : VSTQQLNPseudo<IIC_VST3ln>;
2126218893Sdim
2127205407Srdivacky// ...with double-spaced registers:
2128218893Sdimdef VST3LNq16 : VST3LN<0b0110, {?,?,1,0}, "16"> {
2129218893Sdim  let Inst{7-6} = lane{1-0};
2130218893Sdim}
2131218893Sdimdef VST3LNq32 : VST3LN<0b1010, {?,1,0,0}, "32"> {
2132218893Sdim  let Inst{7}   = lane{0};
2133218893Sdim}
2134198090Srdivacky
2135218893Sdimdef VST3LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;
2136218893Sdimdef VST3LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>;
2137198090Srdivacky
2138205407Srdivacky// ...with address register writeback:
2139206083Srdivackyclass VST3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2140218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2141218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
2142218893Sdim           DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane),
2143218893Sdim          IIC_VST3lnu, "vst3", Dt,
2144218893Sdim          "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm",
2145226633Sdim          "$Rn.addr = $wb", []> {
2146226633Sdim  let DecoderMethod = "DecodeVST3LN";
2147226633Sdim}
2148205407Srdivacky
2149218893Sdimdef VST3LNd8_UPD  : VST3LNWB<0b0010, {?,?,?,0}, "8"> {
2150218893Sdim  let Inst{7-5} = lane{2-0};
2151218893Sdim}
2152218893Sdimdef VST3LNd16_UPD : VST3LNWB<0b0110, {?,?,0,0}, "16"> {
2153218893Sdim  let Inst{7-6} = lane{1-0};
2154218893Sdim}
2155218893Sdimdef VST3LNd32_UPD : VST3LNWB<0b1010, {?,0,0,0}, "32"> {
2156218893Sdim  let Inst{7}   = lane{0};
2157218893Sdim}
2158205407Srdivacky
2159218893Sdimdef VST3LNd8Pseudo_UPD  : VSTQQLNWBPseudo<IIC_VST3lnu>;
2160218893Sdimdef VST3LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>;
2161218893Sdimdef VST3LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>;
2162205407Srdivacky
2163218893Sdimdef VST3LNq16_UPD : VST3LNWB<0b0110, {?,?,1,0}, "16"> {
2164218893Sdim  let Inst{7-6} = lane{1-0};
2165218893Sdim}
2166218893Sdimdef VST3LNq32_UPD : VST3LNWB<0b1010, {?,1,0,0}, "32"> {
2167218893Sdim  let Inst{7}   = lane{0};
2168218893Sdim}
2169218893Sdim
2170218893Sdimdef VST3LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>;
2171218893Sdimdef VST3LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>;
2172218893Sdim
2173198090Srdivacky//   VST4LN   : Vector Store (single 4-element structure from one lane)
2174206083Srdivackyclass VST4LN<bits<4> op11_8, bits<4> op7_4, string Dt>
2175218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs),
2176218893Sdim          (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4,
2177218893Sdim           nohash_imm:$lane), IIC_VST4ln, "vst4", Dt,
2178218893Sdim          "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn",
2179218893Sdim          "", []> {
2180218893Sdim  let Rm = 0b1111;
2181218893Sdim  let Inst{4} = Rn{4};
2182226633Sdim  let DecoderMethod = "DecodeVST4LN";
2183218893Sdim}
2184198090Srdivacky
2185218893Sdimdef VST4LNd8  : VST4LN<0b0011, {?,?,?,?}, "8"> {
2186218893Sdim  let Inst{7-5} = lane{2-0};
2187218893Sdim}
2188218893Sdimdef VST4LNd16 : VST4LN<0b0111, {?,?,0,?}, "16"> {
2189218893Sdim  let Inst{7-6} = lane{1-0};
2190218893Sdim}
2191218893Sdimdef VST4LNd32 : VST4LN<0b1011, {?,0,?,?}, "32"> {
2192218893Sdim  let Inst{7}   = lane{0};
2193218893Sdim  let Inst{5} = Rn{5};
2194218893Sdim}
2195198090Srdivacky
2196218893Sdimdef VST4LNd8Pseudo  : VSTQQLNPseudo<IIC_VST4ln>;
2197218893Sdimdef VST4LNd16Pseudo : VSTQQLNPseudo<IIC_VST4ln>;
2198218893Sdimdef VST4LNd32Pseudo : VSTQQLNPseudo<IIC_VST4ln>;
2199218893Sdim
2200205407Srdivacky// ...with double-spaced registers:
2201218893Sdimdef VST4LNq16 : VST4LN<0b0111, {?,?,1,?}, "16"> {
2202218893Sdim  let Inst{7-6} = lane{1-0};
2203218893Sdim}
2204218893Sdimdef VST4LNq32 : VST4LN<0b1011, {?,1,?,?}, "32"> {
2205218893Sdim  let Inst{7}   = lane{0};
2206218893Sdim  let Inst{5} = Rn{5};
2207218893Sdim}
2208198090Srdivacky
2209218893Sdimdef VST4LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>;
2210218893Sdimdef VST4LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>;
2211198090Srdivacky
2212205407Srdivacky// ...with address register writeback:
2213206083Srdivackyclass VST4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt>
2214218893Sdim  : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb),
2215218893Sdim          (ins addrmode6:$Rn, am6offset:$Rm,
2216218893Sdim           DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane),
2217218893Sdim          IIC_VST4lnu, "vst4", Dt,
2218218893Sdim  "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm",
2219218893Sdim          "$Rn.addr = $wb", []> {
2220218893Sdim  let Inst{4} = Rn{4};
2221226633Sdim  let DecoderMethod = "DecodeVST4LN";
2222218893Sdim}
2223205407Srdivacky
2224218893Sdimdef VST4LNd8_UPD  : VST4LNWB<0b0011, {?,?,?,?}, "8"> {
2225218893Sdim  let Inst{7-5} = lane{2-0};
2226218893Sdim}
2227218893Sdimdef VST4LNd16_UPD : VST4LNWB<0b0111, {?,?,0,?}, "16"> {
2228218893Sdim  let Inst{7-6} = lane{1-0};
2229218893Sdim}
2230218893Sdimdef VST4LNd32_UPD : VST4LNWB<0b1011, {?,0,?,?}, "32"> {
2231218893Sdim  let Inst{7}   = lane{0};
2232218893Sdim  let Inst{5} = Rn{5};
2233218893Sdim}
2234205407Srdivacky
2235218893Sdimdef VST4LNd8Pseudo_UPD  : VSTQQLNWBPseudo<IIC_VST4lnu>;
2236218893Sdimdef VST4LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>;
2237218893Sdimdef VST4LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>;
2238205407Srdivacky
2239218893Sdimdef VST4LNq16_UPD : VST4LNWB<0b0111, {?,?,1,?}, "16"> {
2240218893Sdim  let Inst{7-6} = lane{1-0};
2241218893Sdim}
2242218893Sdimdef VST4LNq32_UPD : VST4LNWB<0b1011, {?,1,?,?}, "32"> {
2243218893Sdim  let Inst{7}   = lane{0};
2244218893Sdim  let Inst{5} = Rn{5};
2245218893Sdim}
2246218893Sdim
2247218893Sdimdef VST4LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>;
2248218893Sdimdef VST4LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>;
2249218893Sdim
2250208599Srdivacky} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
2251198090Srdivacky
2252239462Sdim// Use vld1/vst1 for unaligned f64 load / store
2253239462Sdimdef : Pat<(f64 (hword_alignedload addrmode6:$addr)),
2254239462Sdim          (VLD1d16 addrmode6:$addr)>, Requires<[IsLE]>;
2255239462Sdimdef : Pat<(hword_alignedstore (f64 DPR:$value), addrmode6:$addr),
2256239462Sdim          (VST1d16 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>;
2257239462Sdimdef : Pat<(f64 (byte_alignedload addrmode6:$addr)),
2258239462Sdim          (VLD1d8 addrmode6:$addr)>, Requires<[IsLE]>;
2259239462Sdimdef : Pat<(byte_alignedstore (f64 DPR:$value), addrmode6:$addr),
2260239462Sdim          (VST1d8 addrmode6:$addr, DPR:$value)>, Requires<[IsLE]>;
2261239462Sdimdef : Pat<(f64 (non_word_alignedload addrmode6:$addr)),
2262239462Sdim          (VLD1d64 addrmode6:$addr)>, Requires<[IsBE]>;
2263239462Sdimdef : Pat<(non_word_alignedstore (f64 DPR:$value), addrmode6:$addr),
2264239462Sdim          (VST1d64 addrmode6:$addr, DPR:$value)>, Requires<[IsBE]>;
2265198090Srdivacky
2266243830Sdim// Use vld1/vst1 for Q and QQ. Also use them for unaligned v2f64
2267243830Sdim// load / store if it's legal.
2268243830Sdimdef : Pat<(v2f64 (dword_alignedload addrmode6:$addr)),
2269243830Sdim          (VLD1q64 addrmode6:$addr)>;
2270243830Sdimdef : Pat<(dword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2271243830Sdim          (VST1q64 addrmode6:$addr, QPR:$value)>;
2272243830Sdimdef : Pat<(v2f64 (word_alignedload addrmode6:$addr)),
2273243830Sdim          (VLD1q32 addrmode6:$addr)>;
2274243830Sdimdef : Pat<(word_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2275243830Sdim          (VST1q32 addrmode6:$addr, QPR:$value)>;
2276243830Sdimdef : Pat<(v2f64 (hword_alignedload addrmode6:$addr)),
2277243830Sdim          (VLD1q16 addrmode6:$addr)>, Requires<[IsLE]>;
2278243830Sdimdef : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2279243830Sdim          (VST1q16 addrmode6:$addr, QPR:$value)>, Requires<[IsLE]>;
2280243830Sdimdef : Pat<(v2f64 (byte_alignedload addrmode6:$addr)),
2281243830Sdim          (VLD1q8 addrmode6:$addr)>, Requires<[IsLE]>;
2282243830Sdimdef : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr),
2283243830Sdim          (VST1q8 addrmode6:$addr, QPR:$value)>, Requires<[IsLE]>;
2284243830Sdim
2285194710Sed//===----------------------------------------------------------------------===//
2286194710Sed// NEON pattern fragments
2287194710Sed//===----------------------------------------------------------------------===//
2288194710Sed
2289194710Sed// Extract D sub-registers of Q registers.
2290198090Srdivackydef DSubReg_i8_reg  : SDNodeXForm<imm, [{
2291208599Srdivacky  assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2292208599Srdivacky  return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, MVT::i32);
2293194710Sed}]>;
2294198090Srdivackydef DSubReg_i16_reg : SDNodeXForm<imm, [{
2295208599Srdivacky  assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2296208599Srdivacky  return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, MVT::i32);
2297194710Sed}]>;
2298198090Srdivackydef DSubReg_i32_reg : SDNodeXForm<imm, [{
2299208599Srdivacky  assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2300208599Srdivacky  return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, MVT::i32);
2301194710Sed}]>;
2302198090Srdivackydef DSubReg_f64_reg : SDNodeXForm<imm, [{
2303208599Srdivacky  assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
2304208599Srdivacky  return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), MVT::i32);
2305194710Sed}]>;
2306194710Sed
2307198090Srdivacky// Extract S sub-registers of Q/D registers.
2308198090Srdivackydef SSubReg_f32_reg : SDNodeXForm<imm, [{
2309208599Srdivacky  assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering");
2310208599Srdivacky  return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), MVT::i32);
2311198090Srdivacky}]>;
2312198090Srdivacky
2313194710Sed// Translate lane numbers from Q registers to D subregs.
2314194710Seddef SubReg_i8_lane  : SDNodeXForm<imm, [{
2315194710Sed  return CurDAG->getTargetConstant(N->getZExtValue() & 7, MVT::i32);
2316194710Sed}]>;
2317194710Seddef SubReg_i16_lane : SDNodeXForm<imm, [{
2318194710Sed  return CurDAG->getTargetConstant(N->getZExtValue() & 3, MVT::i32);
2319194710Sed}]>;
2320194710Seddef SubReg_i32_lane : SDNodeXForm<imm, [{
2321194710Sed  return CurDAG->getTargetConstant(N->getZExtValue() & 1, MVT::i32);
2322194710Sed}]>;
2323194710Sed
2324194710Sed//===----------------------------------------------------------------------===//
2325194710Sed// Instruction Classes
2326194710Sed//===----------------------------------------------------------------------===//
2327194710Sed
2328218893Sdim// Basic 2-register operations: double- and quad-register.
2329194710Sedclass N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2330204642Srdivacky           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
2331204642Srdivacky           string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
2332218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
2333218893Sdim        (ins DPR:$Vm), IIC_VUNAD, OpcodeStr, Dt,"$Vd, $Vm", "",
2334218893Sdim        [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm))))]>;
2335194710Sedclass N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2336204642Srdivacky           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
2337204642Srdivacky           string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
2338218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
2339218893Sdim        (ins QPR:$Vm), IIC_VUNAQ, OpcodeStr, Dt,"$Vd, $Vm", "",
2340218893Sdim        [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm))))]>;
2341194710Sed
2342194710Sed// Basic 2-register intrinsics, both double- and quad-register.
2343194710Sedclass N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2344206083Srdivacky              bits<2> op17_16, bits<5> op11_7, bit op4,
2345199989Srdivacky              InstrItinClass itin, string OpcodeStr, string Dt,
2346239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2347218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
2348218893Sdim        (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2349218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
2350194710Sedclass N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2351198090Srdivacky              bits<2> op17_16, bits<5> op11_7, bit op4,
2352199989Srdivacky              InstrItinClass itin, string OpcodeStr, string Dt,
2353239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2354218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
2355218893Sdim        (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2356218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2357194710Sed
2358263508Sdim// Same as above, but not predicated.
2359263508Sdimclass N2VDIntnp<bits<2> op17_16, bits<3> op10_8, bit op7,
2360263508Sdim              InstrItinClass itin, string OpcodeStr, string Dt,
2361263508Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2362263508Sdim  : N2Vnp<0b10, op17_16, op10_8, op7, 0,  (outs DPR:$Vd), (ins DPR:$Vm),
2363263508Sdim          itin, OpcodeStr, Dt, ResTy, OpTy,
2364263508Sdim          [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
2365263508Sdim
2366263508Sdimclass N2VQIntnp<bits<2> op17_16, bits<3> op10_8, bit op7,
2367263508Sdim              InstrItinClass itin, string OpcodeStr, string Dt,
2368263508Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2369263508Sdim  : N2Vnp<0b10, op17_16, op10_8, op7, 1,  (outs QPR:$Vd), (ins QPR:$Vm),
2370263508Sdim          itin, OpcodeStr, Dt, ResTy, OpTy,
2371263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2372263508Sdim
2373263508Sdim// Similar to NV2VQIntnp with some more encoding bits exposed (crypto).
2374263508Sdimclass N2VQIntXnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,
2375263508Sdim              bit op7, InstrItinClass itin, string OpcodeStr, string Dt,
2376263508Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2377263508Sdim  : N2Vnp<op19_18, op17_16, op10_8, op7, op6,  (outs QPR:$Vd), (ins QPR:$Vm),
2378263508Sdim          itin, OpcodeStr, Dt, ResTy, OpTy,
2379263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2380263508Sdim
2381263508Sdim// Same as N2VQIntXnp but with Vd as a src register.
2382263508Sdimclass N2VQIntX2np<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6,
2383263508Sdim              bit op7, InstrItinClass itin, string OpcodeStr, string Dt,
2384263508Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2385263508Sdim  : N2Vnp<op19_18, op17_16, op10_8, op7, op6,
2386263508Sdim          (outs QPR:$Vd), (ins QPR:$src, QPR:$Vm),
2387263508Sdim          itin, OpcodeStr, Dt, ResTy, OpTy,
2388263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vm))))]> {
2389263508Sdim  let Constraints = "$src = $Vd";
2390263508Sdim}
2391263508Sdim
2392212904Sdim// Narrow 2-register operations.
2393212904Sdimclass N2VN<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2394212904Sdim           bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2395212904Sdim           InstrItinClass itin, string OpcodeStr, string Dt,
2396212904Sdim           ValueType TyD, ValueType TyQ, SDNode OpNode>
2397218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),
2398218893Sdim        (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2399218893Sdim        [(set DPR:$Vd, (TyD (OpNode (TyQ QPR:$Vm))))]>;
2400212904Sdim
2401194710Sed// Narrow 2-register intrinsics.
2402194710Sedclass N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2403194710Sed              bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2404199989Srdivacky              InstrItinClass itin, string OpcodeStr, string Dt,
2405239462Sdim              ValueType TyD, ValueType TyQ, SDPatternOperator IntOp>
2406218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd),
2407218893Sdim        (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2408218893Sdim        [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vm))))]>;
2409194710Sed
2410212904Sdim// Long 2-register operations (currently only used for VMOVL).
2411212904Sdimclass N2VL<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2412212904Sdim           bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2413212904Sdim           InstrItinClass itin, string OpcodeStr, string Dt,
2414212904Sdim           ValueType TyQ, ValueType TyD, SDNode OpNode>
2415218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),
2416218893Sdim        (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2417218893Sdim        [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vm))))]>;
2418194710Sed
2419218893Sdim// Long 2-register intrinsics.
2420218893Sdimclass N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2421218893Sdim              bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
2422218893Sdim              InstrItinClass itin, string OpcodeStr, string Dt,
2423239462Sdim              ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>
2424218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd),
2425218893Sdim        (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "",
2426218893Sdim        [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vm))))]>;
2427218893Sdim
2428198090Srdivacky// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register.
2429199989Srdivackyclass N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>
2430218893Sdim  : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$Vd, DPR:$Vm),
2431218893Sdim        (ins DPR:$src1, DPR:$src2), IIC_VPERMD,
2432218893Sdim        OpcodeStr, Dt, "$Vd, $Vm",
2433218893Sdim        "$src1 = $Vd, $src2 = $Vm", []>;
2434198090Srdivackyclass N2VQShuffle<bits<2> op19_18, bits<5> op11_7,
2435199989Srdivacky                  InstrItinClass itin, string OpcodeStr, string Dt>
2436218893Sdim  : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$Vd, QPR:$Vm),
2437218893Sdim        (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm",
2438218893Sdim        "$src1 = $Vd, $src2 = $Vm", []>;
2439198090Srdivacky
2440218893Sdim// Basic 3-register operations: double- and quad-register.
2441194710Sedclass N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2442199989Srdivacky           InstrItinClass itin, string OpcodeStr, string Dt,
2443204642Srdivacky           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2444194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2445218893Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2446218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2447218893Sdim        [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {
2448239462Sdim  // All of these have a two-operand InstAlias.
2449239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2450194710Sed  let isCommutable = Commutable;
2451194710Sed}
2452199989Srdivacky// Same as N3VD but no data type.
2453199989Srdivackyclass N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2454199989Srdivacky           InstrItinClass itin, string OpcodeStr,
2455199989Srdivacky           ValueType ResTy, ValueType OpTy,
2456199989Srdivacky           SDNode OpNode, bit Commutable>
2457199989Srdivacky  : N3VX<op24, op23, op21_20, op11_8, 0, op4,
2458218893Sdim         (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2459218893Sdim         OpcodeStr, "$Vd, $Vn, $Vm", "",
2460218893Sdim         [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>{
2461239462Sdim  // All of these have a two-operand InstAlias.
2462239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2463199989Srdivacky  let isCommutable = Commutable;
2464199989Srdivacky}
2465206083Srdivacky
2466218893Sdimclass N3VDSL<bits<2> op21_20, bits<4> op11_8,
2467199989Srdivacky             InstrItinClass itin, string OpcodeStr, string Dt,
2468199989Srdivacky             ValueType Ty, SDNode ShOp>
2469221345Sdim  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2470234353Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2471234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2472218893Sdim        [(set (Ty DPR:$Vd),
2473218893Sdim              (Ty (ShOp (Ty DPR:$Vn),
2474218893Sdim                        (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),imm:$lane)))))]> {
2475239462Sdim  // All of these have a two-operand InstAlias.
2476239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2477198090Srdivacky  let isCommutable = 0;
2478198090Srdivacky}
2479218893Sdimclass N3VDSL16<bits<2> op21_20, bits<4> op11_8,
2480199989Srdivacky               string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
2481221345Sdim  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2482234353Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2483234353Sdim        NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane","",
2484218893Sdim        [(set (Ty DPR:$Vd),
2485218893Sdim              (Ty (ShOp (Ty DPR:$Vn),
2486218893Sdim                        (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {
2487239462Sdim  // All of these have a two-operand InstAlias.
2488239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2489198090Srdivacky  let isCommutable = 0;
2490198090Srdivacky}
2491198090Srdivacky
2492194710Sedclass N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2493199989Srdivacky           InstrItinClass itin, string OpcodeStr, string Dt,
2494204642Srdivacky           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2495194710Sed  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2496218893Sdim        (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2497218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2498218893Sdim        [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {
2499239462Sdim  // All of these have a two-operand InstAlias.
2500239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2501194710Sed  let isCommutable = Commutable;
2502194710Sed}
2503199989Srdivackyclass N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2504199989Srdivacky           InstrItinClass itin, string OpcodeStr,
2505204642Srdivacky           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
2506199989Srdivacky  : N3VX<op24, op23, op21_20, op11_8, 1, op4,
2507218893Sdim         (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2508218893Sdim         OpcodeStr, "$Vd, $Vn, $Vm", "",
2509218893Sdim         [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>{
2510239462Sdim  // All of these have a two-operand InstAlias.
2511239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2512199989Srdivacky  let isCommutable = Commutable;
2513199989Srdivacky}
2514218893Sdimclass N3VQSL<bits<2> op21_20, bits<4> op11_8,
2515199989Srdivacky             InstrItinClass itin, string OpcodeStr, string Dt,
2516198090Srdivacky             ValueType ResTy, ValueType OpTy, SDNode ShOp>
2517221345Sdim  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2518234353Sdim        (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2519234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2520218893Sdim        [(set (ResTy QPR:$Vd),
2521218893Sdim              (ResTy (ShOp (ResTy QPR:$Vn),
2522218893Sdim                           (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2523198090Srdivacky                                                imm:$lane)))))]> {
2524239462Sdim  // All of these have a two-operand InstAlias.
2525239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2526198090Srdivacky  let isCommutable = 0;
2527198090Srdivacky}
2528204642Srdivackyclass N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
2529199989Srdivacky               ValueType ResTy, ValueType OpTy, SDNode ShOp>
2530221345Sdim  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2531234353Sdim        (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2532234353Sdim        NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane", "",
2533218893Sdim        [(set (ResTy QPR:$Vd),
2534218893Sdim              (ResTy (ShOp (ResTy QPR:$Vn),
2535218893Sdim                           (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2536198090Srdivacky                                                imm:$lane)))))]> {
2537239462Sdim  // All of these have a two-operand InstAlias.
2538239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2539198090Srdivacky  let isCommutable = 0;
2540198090Srdivacky}
2541194710Sed
2542194710Sed// Basic 3-register intrinsics, both double- and quad-register.
2543194710Sedclass N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2544206083Srdivacky              Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2545239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>
2546194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2547218893Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin,
2548218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2549218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> {
2550239462Sdim  // All of these have a two-operand InstAlias.
2551239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2552194710Sed  let isCommutable = Commutable;
2553194710Sed}
2554263508Sdim
2555263508Sdimclass N3VDIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2556263508Sdim                bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2557263508Sdim                string Dt, ValueType ResTy, ValueType OpTy,
2558263508Sdim                SDPatternOperator IntOp, bit Commutable>
2559263508Sdim  : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2560263508Sdim          (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt,
2561263508Sdim          ResTy, OpTy, IntOp, Commutable,
2562263508Sdim          [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2563263508Sdim
2564218893Sdimclass N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2565239462Sdim                string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
2566221345Sdim  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2567234353Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2568234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2569218893Sdim        [(set (Ty DPR:$Vd),
2570218893Sdim              (Ty (IntOp (Ty DPR:$Vn),
2571218893Sdim                         (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),
2572198090Srdivacky                                           imm:$lane)))))]> {
2573198090Srdivacky  let isCommutable = 0;
2574198090Srdivacky}
2575263508Sdim
2576198090Srdivackyclass N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2577239462Sdim                  string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
2578221345Sdim  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2579234353Sdim        (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2580234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2581218893Sdim        [(set (Ty DPR:$Vd),
2582218893Sdim              (Ty (IntOp (Ty DPR:$Vn),
2583218893Sdim                         (Ty (NEONvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> {
2584198090Srdivacky  let isCommutable = 0;
2585198090Srdivacky}
2586218893Sdimclass N3VDIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2587218893Sdim              Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2588239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2589218893Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2590218893Sdim        (outs DPR:$Vd), (ins DPR:$Vm, DPR:$Vn), f, itin,
2591218893Sdim        OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",
2592218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (OpTy DPR:$Vn))))]> {
2593239462Sdim  let TwoOperandAliasConstraint = "$Vm = $Vd";
2594218893Sdim  let isCommutable = 0;
2595218893Sdim}
2596198090Srdivacky
2597194710Sedclass N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2598206083Srdivacky              Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2599239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable>
2600194710Sed  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2601218893Sdim        (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin,
2602218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2603218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> {
2604239462Sdim  // All of these have a two-operand InstAlias.
2605239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2606194710Sed  let isCommutable = Commutable;
2607194710Sed}
2608263508Sdim
2609263508Sdimclass N3VQIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2610263508Sdim                bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2611263508Sdim                string Dt, ValueType ResTy, ValueType OpTy,
2612263508Sdim                SDPatternOperator IntOp, bit Commutable>
2613263508Sdim  : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2614263508Sdim          (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt,
2615263508Sdim          ResTy, OpTy, IntOp, Commutable,
2616263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
2617263508Sdim
2618263508Sdim// Same as N3VQIntnp but with Vd as a src register.
2619263508Sdimclass N3VQInt3np<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2620263508Sdim                bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2621263508Sdim                string Dt, ValueType ResTy, ValueType OpTy,
2622263508Sdim                SDPatternOperator IntOp, bit Commutable>
2623263508Sdim  : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2624263508Sdim          (outs QPR:$Vd), (ins QPR:$src, QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr,
2625263508Sdim          Dt, ResTy, OpTy, IntOp, Commutable,
2626263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vn),
2627263508Sdim                                       (OpTy QPR:$Vm))))]> {
2628263508Sdim  let Constraints = "$src = $Vd";
2629263508Sdim}
2630263508Sdim
2631218893Sdimclass N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2632199989Srdivacky                string OpcodeStr, string Dt,
2633239462Sdim                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2634221345Sdim  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2635234353Sdim        (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2636234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2637218893Sdim        [(set (ResTy QPR:$Vd),
2638218893Sdim              (ResTy (IntOp (ResTy QPR:$Vn),
2639218893Sdim                            (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2640198090Srdivacky                                                 imm:$lane)))))]> {
2641198090Srdivacky  let isCommutable = 0;
2642198090Srdivacky}
2643198090Srdivackyclass N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2644199989Srdivacky                  string OpcodeStr, string Dt,
2645239462Sdim                  ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2646221345Sdim  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2647234353Sdim        (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2648234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2649218893Sdim        [(set (ResTy QPR:$Vd),
2650218893Sdim              (ResTy (IntOp (ResTy QPR:$Vn),
2651218893Sdim                            (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2652198090Srdivacky                                                 imm:$lane)))))]> {
2653198090Srdivacky  let isCommutable = 0;
2654198090Srdivacky}
2655218893Sdimclass N3VQIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2656218893Sdim              Format f, InstrItinClass itin, string OpcodeStr, string Dt,
2657239462Sdim              ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2658218893Sdim  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2659218893Sdim        (outs QPR:$Vd), (ins QPR:$Vm, QPR:$Vn), f, itin,
2660218893Sdim        OpcodeStr, Dt, "$Vd, $Vm, $Vn", "",
2661218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (OpTy QPR:$Vn))))]> {
2662239462Sdim  let TwoOperandAliasConstraint = "$Vm = $Vd";
2663218893Sdim  let isCommutable = 0;
2664218893Sdim}
2665194710Sed
2666218893Sdim// Multiply-Add/Sub operations: double- and quad-register.
2667218893Sdimclass N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2668204642Srdivacky                InstrItinClass itin, string OpcodeStr, string Dt,
2669218893Sdim                ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode>
2670204642Srdivacky  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2671218893Sdim        (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2672218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2673218893Sdim        [(set DPR:$Vd, (Ty (OpNode DPR:$src1,
2674218893Sdim                             (Ty (MulOp DPR:$Vn, DPR:$Vm)))))]>;
2675204642Srdivacky
2676198090Srdivackyclass N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2677199989Srdivacky                  string OpcodeStr, string Dt,
2678218893Sdim                  ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
2679221345Sdim  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
2680218893Sdim        (outs DPR:$Vd),
2681234353Sdim        (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2682206083Srdivacky        NVMulSLFrm, itin,
2683234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2684218893Sdim        [(set (Ty DPR:$Vd),
2685198090Srdivacky              (Ty (ShOp (Ty DPR:$src1),
2686218893Sdim                        (Ty (MulOp DPR:$Vn,
2687218893Sdim                                   (Ty (NEONvduplane (Ty DPR_VFP2:$Vm),
2688198090Srdivacky                                                     imm:$lane)))))))]>;
2689198090Srdivackyclass N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2690199989Srdivacky                    string OpcodeStr, string Dt,
2691199989Srdivacky                    ValueType Ty, SDNode MulOp, SDNode ShOp>
2692221345Sdim  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
2693218893Sdim        (outs DPR:$Vd),
2694234353Sdim        (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2695206083Srdivacky        NVMulSLFrm, itin,
2696234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2697218893Sdim        [(set (Ty DPR:$Vd),
2698198090Srdivacky              (Ty (ShOp (Ty DPR:$src1),
2699218893Sdim                        (Ty (MulOp DPR:$Vn,
2700218893Sdim                                   (Ty (NEONvduplane (Ty DPR_8:$Vm),
2701198090Srdivacky                                                     imm:$lane)))))))]>;
2702198090Srdivacky
2703194710Sedclass N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2704199989Srdivacky                InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,
2705218893Sdim                SDPatternOperator MulOp, SDPatternOperator OpNode>
2706194710Sed  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2707218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2708218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2709218893Sdim        [(set QPR:$Vd, (Ty (OpNode QPR:$src1,
2710218893Sdim                             (Ty (MulOp QPR:$Vn, QPR:$Vm)))))]>;
2711198090Srdivackyclass N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2712199989Srdivacky                  string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
2713218893Sdim                  SDPatternOperator MulOp, SDPatternOperator ShOp>
2714221345Sdim  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
2715218893Sdim        (outs QPR:$Vd),
2716234353Sdim        (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2717206083Srdivacky        NVMulSLFrm, itin,
2718234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2719218893Sdim        [(set (ResTy QPR:$Vd),
2720198090Srdivacky              (ResTy (ShOp (ResTy QPR:$src1),
2721218893Sdim                           (ResTy (MulOp QPR:$Vn,
2722218893Sdim                                   (ResTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2723204642Srdivacky                                                        imm:$lane)))))))]>;
2724198090Srdivackyclass N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2725199989Srdivacky                    string OpcodeStr, string Dt,
2726199989Srdivacky                    ValueType ResTy, ValueType OpTy,
2727198090Srdivacky                    SDNode MulOp, SDNode ShOp>
2728221345Sdim  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
2729218893Sdim        (outs QPR:$Vd),
2730234353Sdim        (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2731206083Srdivacky        NVMulSLFrm, itin,
2732234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2733218893Sdim        [(set (ResTy QPR:$Vd),
2734198090Srdivacky              (ResTy (ShOp (ResTy QPR:$src1),
2735218893Sdim                           (ResTy (MulOp QPR:$Vn,
2736218893Sdim                                   (ResTy (NEONvduplane (OpTy DPR_8:$Vm),
2737204642Srdivacky                                                        imm:$lane)))))))]>;
2738194710Sed
2739212904Sdim// Neon Intrinsic-Op instructions (VABA): double- and quad-register.
2740212904Sdimclass N3VDIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2741212904Sdim                InstrItinClass itin, string OpcodeStr, string Dt,
2742239462Sdim                ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>
2743212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2744218893Sdim        (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2745218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2746218893Sdim        [(set DPR:$Vd, (Ty (OpNode DPR:$src1,
2747218893Sdim                             (Ty (IntOp (Ty DPR:$Vn), (Ty DPR:$Vm))))))]>;
2748212904Sdimclass N3VQIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2749212904Sdim                InstrItinClass itin, string OpcodeStr, string Dt,
2750239462Sdim                ValueType Ty, SDPatternOperator IntOp, SDNode OpNode>
2751212904Sdim  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2752218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2753218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2754218893Sdim        [(set QPR:$Vd, (Ty (OpNode QPR:$src1,
2755218893Sdim                             (Ty (IntOp (Ty QPR:$Vn), (Ty QPR:$Vm))))))]>;
2756212904Sdim
2757194710Sed// Neon 3-argument intrinsics, both double- and quad-register.
2758194710Sed// The destination register is also used as the first source operand register.
2759194710Sedclass N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2760199989Srdivacky               InstrItinClass itin, string OpcodeStr, string Dt,
2761239462Sdim               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2762194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2763218893Sdim        (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2764218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2765218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$src1),
2766218893Sdim                                      (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2767194710Sedclass N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2768199989Srdivacky               InstrItinClass itin, string OpcodeStr, string Dt,
2769239462Sdim               ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2770194710Sed  : N3V<op24, op23, op21_20, op11_8, 1, op4,
2771218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin,
2772218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2773218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src1),
2774218893Sdim                                      (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
2775194710Sed
2776212904Sdim// Long Multiply-Add/Sub operations.
2777212904Sdimclass N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2778212904Sdim                InstrItinClass itin, string OpcodeStr, string Dt,
2779212904Sdim                ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2780212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2781218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2782218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2783218893Sdim        [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),
2784218893Sdim                                (TyQ (MulOp (TyD DPR:$Vn),
2785218893Sdim                                            (TyD DPR:$Vm)))))]>;
2786212904Sdimclass N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
2787212904Sdim                  InstrItinClass itin, string OpcodeStr, string Dt,
2788212904Sdim                  ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2789221345Sdim  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
2790234353Sdim        (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2791212904Sdim        NVMulSLFrm, itin,
2792234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2793218893Sdim        [(set QPR:$Vd,
2794212904Sdim          (OpNode (TyQ QPR:$src1),
2795218893Sdim                  (TyQ (MulOp (TyD DPR:$Vn),
2796218893Sdim                              (TyD (NEONvduplane (TyD DPR_VFP2:$Vm),
2797212904Sdim                                                 imm:$lane))))))]>;
2798212904Sdimclass N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2799212904Sdim                    InstrItinClass itin, string OpcodeStr, string Dt,
2800212904Sdim                    ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
2801221345Sdim  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
2802234353Sdim        (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2803212904Sdim        NVMulSLFrm, itin,
2804234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2805218893Sdim        [(set QPR:$Vd,
2806212904Sdim          (OpNode (TyQ QPR:$src1),
2807218893Sdim                  (TyQ (MulOp (TyD DPR:$Vn),
2808218893Sdim                              (TyD (NEONvduplane (TyD DPR_8:$Vm),
2809212904Sdim                                                 imm:$lane))))))]>;
2810212904Sdim
2811212904Sdim// Long Intrinsic-Op vector operations with explicit extend (VABAL).
2812212904Sdimclass N3VLIntExtOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2813212904Sdim                   InstrItinClass itin, string OpcodeStr, string Dt,
2814239462Sdim                   ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,
2815212904Sdim                   SDNode OpNode>
2816212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2817218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2818218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2819218893Sdim        [(set QPR:$Vd, (OpNode (TyQ QPR:$src1),
2820218893Sdim                                (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),
2821218893Sdim                                                        (TyD DPR:$Vm)))))))]>;
2822212904Sdim
2823194710Sed// Neon Long 3-argument intrinsic.  The destination register is
2824194710Sed// a quad-register and is also used as the first source operand register.
2825194710Sedclass N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2826199989Srdivacky               InstrItinClass itin, string OpcodeStr, string Dt,
2827239462Sdim               ValueType TyQ, ValueType TyD, SDPatternOperator IntOp>
2828194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2829218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2830218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd",
2831218893Sdim        [(set QPR:$Vd,
2832218893Sdim          (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$Vn), (TyD DPR:$Vm))))]>;
2833198090Srdivackyclass N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2834199989Srdivacky                 string OpcodeStr, string Dt,
2835239462Sdim                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2836221345Sdim  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
2837218893Sdim        (outs QPR:$Vd),
2838234353Sdim        (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2839206083Srdivacky        NVMulSLFrm, itin,
2840234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2841218893Sdim        [(set (ResTy QPR:$Vd),
2842198090Srdivacky              (ResTy (IntOp (ResTy QPR:$src1),
2843218893Sdim                            (OpTy DPR:$Vn),
2844218893Sdim                            (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2845198090Srdivacky                                                imm:$lane)))))]>;
2846204642Srdivackyclass N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2847204642Srdivacky                   InstrItinClass itin, string OpcodeStr, string Dt,
2848239462Sdim                   ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2849221345Sdim  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
2850218893Sdim        (outs QPR:$Vd),
2851234353Sdim        (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2852206083Srdivacky        NVMulSLFrm, itin,
2853234353Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd",
2854218893Sdim        [(set (ResTy QPR:$Vd),
2855198090Srdivacky              (ResTy (IntOp (ResTy QPR:$src1),
2856218893Sdim                            (OpTy DPR:$Vn),
2857218893Sdim                            (OpTy (NEONvduplane (OpTy DPR_8:$Vm),
2858198090Srdivacky                                                imm:$lane)))))]>;
2859194710Sed
2860194710Sed// Narrowing 3-register intrinsics.
2861194710Sedclass N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2862199989Srdivacky              string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ,
2863239462Sdim              SDPatternOperator IntOp, bit Commutable>
2864194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2865218893Sdim        (outs DPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINi4D,
2866218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2867218893Sdim        [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vn), (TyQ QPR:$Vm))))]> {
2868194710Sed  let isCommutable = Commutable;
2869194710Sed}
2870194710Sed
2871212904Sdim// Long 3-register operations.
2872212904Sdimclass N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2873212904Sdim           InstrItinClass itin, string OpcodeStr, string Dt,
2874212904Sdim           ValueType TyQ, ValueType TyD, SDNode OpNode, bit Commutable>
2875212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2876218893Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2877218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2878218893Sdim        [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {
2879212904Sdim  let isCommutable = Commutable;
2880212904Sdim}
2881263508Sdim
2882212904Sdimclass N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
2883212904Sdim             InstrItinClass itin, string OpcodeStr, string Dt,
2884212904Sdim             ValueType TyQ, ValueType TyD, SDNode OpNode>
2885221345Sdim  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
2886234353Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2887234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2888218893Sdim        [(set QPR:$Vd,
2889218893Sdim          (TyQ (OpNode (TyD DPR:$Vn),
2890218893Sdim                       (TyD (NEONvduplane (TyD DPR_VFP2:$Vm),imm:$lane)))))]>;
2891212904Sdimclass N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2892212904Sdim               InstrItinClass itin, string OpcodeStr, string Dt,
2893212904Sdim               ValueType TyQ, ValueType TyD, SDNode OpNode>
2894221345Sdim  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
2895234353Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2896234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2897218893Sdim        [(set QPR:$Vd,
2898218893Sdim          (TyQ (OpNode (TyD DPR:$Vn),
2899218893Sdim                       (TyD (NEONvduplane (TyD DPR_8:$Vm), imm:$lane)))))]>;
2900212904Sdim
2901212904Sdim// Long 3-register operations with explicitly extended operands.
2902212904Sdimclass N3VLExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2903212904Sdim              InstrItinClass itin, string OpcodeStr, string Dt,
2904212904Sdim              ValueType TyQ, ValueType TyD, SDNode OpNode, SDNode ExtOp,
2905212904Sdim              bit Commutable>
2906212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2907218893Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2908218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2909218893Sdim        [(set QPR:$Vd, (OpNode (TyQ (ExtOp (TyD DPR:$Vn))),
2910218893Sdim                                (TyQ (ExtOp (TyD DPR:$Vm)))))]> {
2911212904Sdim  let isCommutable = Commutable;
2912212904Sdim}
2913212904Sdim
2914212904Sdim// Long 3-register intrinsics with explicit extend (VABDL).
2915212904Sdimclass N3VLIntExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2916212904Sdim                 InstrItinClass itin, string OpcodeStr, string Dt,
2917239462Sdim                 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp,
2918212904Sdim                 bit Commutable>
2919212904Sdim  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2920218893Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2921218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2922218893Sdim        [(set QPR:$Vd, (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn),
2923218893Sdim                                                (TyD DPR:$Vm))))))]> {
2924212904Sdim  let isCommutable = Commutable;
2925212904Sdim}
2926212904Sdim
2927194710Sed// Long 3-register intrinsics.
2928194710Sedclass N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2929199989Srdivacky              InstrItinClass itin, string OpcodeStr, string Dt,
2930239462Sdim              ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, bit Commutable>
2931194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2932218893Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin,
2933218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2934218893Sdim        [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vn), (TyD DPR:$Vm))))]> {
2935194710Sed  let isCommutable = Commutable;
2936194710Sed}
2937263508Sdim
2938263508Sdim// Same as above, but not predicated.
2939263508Sdimclass N3VLIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2940263508Sdim                bit op4, InstrItinClass itin, string OpcodeStr,
2941263508Sdim                string Dt, ValueType ResTy, ValueType OpTy,
2942263508Sdim                SDPatternOperator IntOp, bit Commutable>
2943263508Sdim  : N3Vnp<op27_23, op21_20, op11_8, op6, op4,
2944263508Sdim          (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt,
2945263508Sdim          ResTy, OpTy, IntOp, Commutable,
2946263508Sdim          [(set QPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2947263508Sdim
2948198090Srdivackyclass N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
2949199989Srdivacky                string OpcodeStr, string Dt,
2950239462Sdim                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2951221345Sdim  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
2952234353Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane),
2953234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2954218893Sdim        [(set (ResTy QPR:$Vd),
2955218893Sdim              (ResTy (IntOp (OpTy DPR:$Vn),
2956218893Sdim                            (OpTy (NEONvduplane (OpTy DPR_VFP2:$Vm),
2957198090Srdivacky                                                imm:$lane)))))]>;
2958204642Srdivackyclass N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
2959204642Srdivacky                  InstrItinClass itin, string OpcodeStr, string Dt,
2960239462Sdim                  ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2961221345Sdim  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
2962234353Sdim        (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
2963234353Sdim        NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "",
2964218893Sdim        [(set (ResTy QPR:$Vd),
2965218893Sdim              (ResTy (IntOp (OpTy DPR:$Vn),
2966218893Sdim                            (OpTy (NEONvduplane (OpTy DPR_8:$Vm),
2967198090Srdivacky                                                imm:$lane)))))]>;
2968194710Sed
2969212904Sdim// Wide 3-register operations.
2970212904Sdimclass N3VW<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
2971212904Sdim           string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD,
2972212904Sdim           SDNode OpNode, SDNode ExtOp, bit Commutable>
2973194710Sed  : N3V<op24, op23, op21_20, op11_8, 0, op4,
2974218893Sdim        (outs QPR:$Vd), (ins QPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VSUBiD,
2975218893Sdim        OpcodeStr, Dt, "$Vd, $Vn, $Vm", "",
2976218893Sdim        [(set QPR:$Vd, (OpNode (TyQ QPR:$Vn),
2977218893Sdim                                (TyQ (ExtOp (TyD DPR:$Vm)))))]> {
2978239462Sdim  // All of these have a two-operand InstAlias.
2979239462Sdim  let TwoOperandAliasConstraint = "$Vn = $Vd";
2980194710Sed  let isCommutable = Commutable;
2981194710Sed}
2982194710Sed
2983194710Sed// Pairwise long 2-register intrinsics, both double- and quad-register.
2984194710Sedclass N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2985199989Srdivacky                bits<2> op17_16, bits<5> op11_7, bit op4,
2986199989Srdivacky                string OpcodeStr, string Dt,
2987239462Sdim                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2988218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd),
2989218893Sdim        (ins DPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
2990218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>;
2991194710Sedclass N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
2992199989Srdivacky                bits<2> op17_16, bits<5> op11_7, bit op4,
2993199989Srdivacky                string OpcodeStr, string Dt,
2994239462Sdim                ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
2995218893Sdim  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd),
2996218893Sdim        (ins QPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
2997218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>;
2998194710Sed
2999194710Sed// Pairwise long 2-register accumulate intrinsics,
3000194710Sed// both double- and quad-register.
3001194710Sed// The destination register is also used as the first source operand register.
3002194710Sedclass N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3003199989Srdivacky                 bits<2> op17_16, bits<5> op11_7, bit op4,
3004199989Srdivacky                 string OpcodeStr, string Dt,
3005239462Sdim                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3006194710Sed  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
3007218893Sdim        (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vm), IIC_VPALiD,
3008218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",
3009218893Sdim        [(set DPR:$Vd, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$Vm))))]>;
3010194710Sedclass N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
3011199989Srdivacky                 bits<2> op17_16, bits<5> op11_7, bit op4,
3012199989Srdivacky                 string OpcodeStr, string Dt,
3013239462Sdim                 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
3014194710Sed  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4,
3015218893Sdim        (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vm), IIC_VPALiQ,
3016218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd",
3017218893Sdim        [(set QPR:$Vd, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$Vm))))]>;
3018194710Sed
3019194710Sed// Shift by immediate,
3020194710Sed// both double- and quad-register.
3021239462Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in {
3022198396Srdivackyclass N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3023221345Sdim             Format f, InstrItinClass itin, Operand ImmTy,
3024221345Sdim             string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>
3025198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, 0, op4,
3026221345Sdim           (outs DPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), f, itin,
3027218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3028218893Sdim           [(set DPR:$Vd, (Ty (OpNode (Ty DPR:$Vm), (i32 imm:$SIMM))))]>;
3029198396Srdivackyclass N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3030221345Sdim             Format f, InstrItinClass itin, Operand ImmTy,
3031221345Sdim             string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode>
3032198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, 1, op4,
3033221345Sdim           (outs QPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), f, itin,
3034218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3035218893Sdim           [(set QPR:$Vd, (Ty (OpNode (Ty QPR:$Vm), (i32 imm:$SIMM))))]>;
3036239462Sdim}
3037194710Sed
3038194710Sed// Long shift by immediate.
3039198396Srdivackyclass N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
3040199989Srdivacky             string OpcodeStr, string Dt,
3041234353Sdim             ValueType ResTy, ValueType OpTy, Operand ImmTy, SDNode OpNode>
3042198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, op6, op4,
3043234353Sdim           (outs QPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), N2RegVShLFrm,
3044218893Sdim           IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3045218893Sdim           [(set QPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm),
3046194710Sed                                          (i32 imm:$SIMM))))]>;
3047194710Sed
3048194710Sed// Narrow shift by immediate.
3049198396Srdivackyclass N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
3050199989Srdivacky             InstrItinClass itin, string OpcodeStr, string Dt,
3051221345Sdim             ValueType ResTy, ValueType OpTy, Operand ImmTy, SDNode OpNode>
3052198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, op6, op4,
3053221345Sdim           (outs DPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, itin,
3054218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3055218893Sdim           [(set DPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm),
3056194710Sed                                          (i32 imm:$SIMM))))]>;
3057194710Sed
3058194710Sed// Shift right by immediate and accumulate,
3059194710Sed// both double- and quad-register.
3060239462Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in {
3061198396Srdivackyclass N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3062221345Sdim                Operand ImmTy, string OpcodeStr, string Dt,
3063221345Sdim                ValueType Ty, SDNode ShOp>
3064218893Sdim  : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),
3065221345Sdim           (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,
3066218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3067218893Sdim           [(set DPR:$Vd, (Ty (add DPR:$src1,
3068218893Sdim                                (Ty (ShOp DPR:$Vm, (i32 imm:$SIMM))))))]>;
3069198396Srdivackyclass N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3070221345Sdim                Operand ImmTy, string OpcodeStr, string Dt,
3071221345Sdim                ValueType Ty, SDNode ShOp>
3072218893Sdim  : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),
3073221345Sdim           (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD,
3074218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3075218893Sdim           [(set QPR:$Vd, (Ty (add QPR:$src1,
3076218893Sdim                                (Ty (ShOp QPR:$Vm, (i32 imm:$SIMM))))))]>;
3077239462Sdim}
3078194710Sed
3079194710Sed// Shift by immediate and insert,
3080194710Sed// both double- and quad-register.
3081239462Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in {
3082198396Srdivackyclass N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3083221345Sdim                Operand ImmTy, Format f, string OpcodeStr, string Dt,
3084221345Sdim                ValueType Ty,SDNode ShOp>
3085218893Sdim  : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd),
3086221345Sdim           (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiD,
3087218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3088218893Sdim           [(set DPR:$Vd, (Ty (ShOp DPR:$src1, DPR:$Vm, (i32 imm:$SIMM))))]>;
3089198396Srdivackyclass N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3090221345Sdim                Operand ImmTy, Format f, string OpcodeStr, string Dt,
3091221345Sdim                ValueType Ty,SDNode ShOp>
3092218893Sdim  : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd),
3093221345Sdim           (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiQ,
3094218893Sdim           OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd",
3095218893Sdim           [(set QPR:$Vd, (Ty (ShOp QPR:$src1, QPR:$Vm, (i32 imm:$SIMM))))]>;
3096239462Sdim}
3097194710Sed
3098194710Sed// Convert, with fractional bits immediate,
3099194710Sed// both double- and quad-register.
3100198396Srdivackyclass N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3101199989Srdivacky              string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
3102239462Sdim              SDPatternOperator IntOp>
3103198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, 0, op4,
3104218893Sdim           (outs DPR:$Vd), (ins DPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,
3105218893Sdim           IIC_VUNAD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3106218893Sdim           [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (i32 imm:$SIMM))))]>;
3107198396Srdivackyclass N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
3108199989Srdivacky              string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
3109239462Sdim              SDPatternOperator IntOp>
3110198396Srdivacky  : N2VImm<op24, op23, op11_8, op7, 1, op4,
3111218893Sdim           (outs QPR:$Vd), (ins QPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm,
3112218893Sdim           IIC_VUNAQ, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "",
3113218893Sdim           [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (i32 imm:$SIMM))))]>;
3114194710Sed
3115194710Sed//===----------------------------------------------------------------------===//
3116194710Sed// Multiclasses
3117194710Sed//===----------------------------------------------------------------------===//
3118194710Sed
3119198090Srdivacky// Abbreviations used in multiclass suffixes:
3120198090Srdivacky//   Q = quarter int (8 bit) elements
3121198090Srdivacky//   H = half int (16 bit) elements
3122198090Srdivacky//   S = single int (32 bit) elements
3123198090Srdivacky//   D = double int (64 bit) elements
3124198090Srdivacky
3125218893Sdim// Neon 2-register vector operations and intrinsics.
3126204642Srdivacky
3127218893Sdim// Neon 2-register comparisons.
3128218893Sdim//   source operand element sizes of 8, 16 and 32 bits:
3129204642Srdivackymulticlass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3130204642Srdivacky                       bits<5> op11_7, bit op4, string opc, string Dt,
3131218893Sdim                       string asm, SDNode OpNode> {
3132204642Srdivacky  // 64-bit vector types.
3133204642Srdivacky  def v8i8  : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4,
3134218893Sdim                  (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3135218893Sdim                  opc, !strconcat(Dt, "8"), asm, "",
3136218893Sdim                  [(set DPR:$Vd, (v8i8 (OpNode (v8i8 DPR:$Vm))))]>;
3137204642Srdivacky  def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,
3138218893Sdim                  (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3139218893Sdim                  opc, !strconcat(Dt, "16"), asm, "",
3140218893Sdim                  [(set DPR:$Vd, (v4i16 (OpNode (v4i16 DPR:$Vm))))]>;
3141204642Srdivacky  def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
3142218893Sdim                  (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3143218893Sdim                  opc, !strconcat(Dt, "32"), asm, "",
3144218893Sdim                  [(set DPR:$Vd, (v2i32 (OpNode (v2i32 DPR:$Vm))))]>;
3145204642Srdivacky  def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
3146218893Sdim                  (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary,
3147218893Sdim                  opc, "f32", asm, "",
3148218893Sdim                  [(set DPR:$Vd, (v2i32 (OpNode (v2f32 DPR:$Vm))))]> {
3149204642Srdivacky    let Inst{10} = 1; // overwrite F = 1
3150204642Srdivacky  }
3151204642Srdivacky
3152204642Srdivacky  // 128-bit vector types.
3153204642Srdivacky  def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4,
3154218893Sdim                  (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3155218893Sdim                  opc, !strconcat(Dt, "8"), asm, "",
3156218893Sdim                  [(set QPR:$Vd, (v16i8 (OpNode (v16i8 QPR:$Vm))))]>;
3157204642Srdivacky  def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,
3158218893Sdim                  (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3159218893Sdim                  opc, !strconcat(Dt, "16"), asm, "",
3160218893Sdim                  [(set QPR:$Vd, (v8i16 (OpNode (v8i16 QPR:$Vm))))]>;
3161204642Srdivacky  def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
3162218893Sdim                  (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3163218893Sdim                  opc, !strconcat(Dt, "32"), asm, "",
3164218893Sdim                  [(set QPR:$Vd, (v4i32 (OpNode (v4i32 QPR:$Vm))))]>;
3165204642Srdivacky  def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
3166218893Sdim                  (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary,
3167218893Sdim                  opc, "f32", asm, "",
3168218893Sdim                  [(set QPR:$Vd, (v4i32 (OpNode (v4f32 QPR:$Vm))))]> {
3169204642Srdivacky    let Inst{10} = 1; // overwrite F = 1
3170204642Srdivacky  }
3171204642Srdivacky}
3172204642Srdivacky
3173218893Sdim
3174218893Sdim// Neon 2-register vector intrinsics,
3175218893Sdim//   element sizes of 8, 16 and 32 bits:
3176218893Sdimmulticlass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3177218893Sdim                      bits<5> op11_7, bit op4,
3178218893Sdim                      InstrItinClass itinD, InstrItinClass itinQ,
3179239462Sdim                      string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3180218893Sdim  // 64-bit vector types.
3181218893Sdim  def v8i8  : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3182218893Sdim                      itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
3183218893Sdim  def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3184218893Sdim                      itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>;
3185218893Sdim  def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3186218893Sdim                      itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>;
3187218893Sdim
3188218893Sdim  // 128-bit vector types.
3189218893Sdim  def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3190218893Sdim                      itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>;
3191218893Sdim  def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3192218893Sdim                      itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>;
3193218893Sdim  def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3194218893Sdim                      itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>;
3195218893Sdim}
3196218893Sdim
3197218893Sdim
3198218893Sdim// Neon Narrowing 2-register vector operations,
3199218893Sdim//   source operand element sizes of 16, 32 and 64 bits:
3200218893Sdimmulticlass N2VN_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3201218893Sdim                    bits<5> op11_7, bit op6, bit op4,
3202218893Sdim                    InstrItinClass itin, string OpcodeStr, string Dt,
3203218893Sdim                    SDNode OpNode> {
3204218893Sdim  def v8i8  : N2VN<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,
3205218893Sdim                   itin, OpcodeStr, !strconcat(Dt, "16"),
3206218893Sdim                   v8i8, v8i16, OpNode>;
3207218893Sdim  def v4i16 : N2VN<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,
3208218893Sdim                   itin, OpcodeStr, !strconcat(Dt, "32"),
3209218893Sdim                   v4i16, v4i32, OpNode>;
3210218893Sdim  def v2i32 : N2VN<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,
3211218893Sdim                   itin, OpcodeStr, !strconcat(Dt, "64"),
3212218893Sdim                   v2i32, v2i64, OpNode>;
3213218893Sdim}
3214218893Sdim
3215218893Sdim// Neon Narrowing 2-register vector intrinsics,
3216218893Sdim//   source operand element sizes of 16, 32 and 64 bits:
3217218893Sdimmulticlass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3218218893Sdim                       bits<5> op11_7, bit op6, bit op4,
3219218893Sdim                       InstrItinClass itin, string OpcodeStr, string Dt,
3220239462Sdim                       SDPatternOperator IntOp> {
3221218893Sdim  def v8i8  : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,
3222218893Sdim                      itin, OpcodeStr, !strconcat(Dt, "16"),
3223218893Sdim                      v8i8, v8i16, IntOp>;
3224218893Sdim  def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,
3225218893Sdim                      itin, OpcodeStr, !strconcat(Dt, "32"),
3226218893Sdim                      v4i16, v4i32, IntOp>;
3227218893Sdim  def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,
3228218893Sdim                      itin, OpcodeStr, !strconcat(Dt, "64"),
3229218893Sdim                      v2i32, v2i64, IntOp>;
3230218893Sdim}
3231218893Sdim
3232218893Sdim
3233218893Sdim// Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL).
3234218893Sdim//   source operand element sizes of 16, 32 and 64 bits:
3235218893Sdimmulticlass N2VL_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4,
3236218893Sdim                    string OpcodeStr, string Dt, SDNode OpNode> {
3237218893Sdim  def v8i16 : N2VL<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3238218893Sdim                   OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode>;
3239218893Sdim  def v4i32 : N2VL<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3240218893Sdim                   OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;
3241218893Sdim  def v2i64 : N2VL<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
3242218893Sdim                   OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;
3243218893Sdim}
3244218893Sdim
3245218893Sdim
3246194710Sed// Neon 3-register vector operations.
3247194710Sed
3248194710Sed// First with only element sizes of 8, 16 and 32 bits:
3249194710Sedmulticlass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3250198090Srdivacky                   InstrItinClass itinD16, InstrItinClass itinD32,
3251198090Srdivacky                   InstrItinClass itinQ16, InstrItinClass itinQ32,
3252199989Srdivacky                   string OpcodeStr, string Dt,
3253199989Srdivacky                   SDNode OpNode, bit Commutable = 0> {
3254194710Sed  // 64-bit vector types.
3255218893Sdim  def v8i8  : N3VD<op24, op23, 0b00, op11_8, op4, itinD16,
3256199989Srdivacky                   OpcodeStr, !strconcat(Dt, "8"),
3257199989Srdivacky                   v8i8, v8i8, OpNode, Commutable>;
3258198090Srdivacky  def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16,
3259204642Srdivacky                   OpcodeStr, !strconcat(Dt, "16"),
3260204642Srdivacky                   v4i16, v4i16, OpNode, Commutable>;
3261198090Srdivacky  def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32,
3262204642Srdivacky                   OpcodeStr, !strconcat(Dt, "32"),
3263204642Srdivacky                   v2i32, v2i32, OpNode, Commutable>;
3264194710Sed
3265194710Sed  // 128-bit vector types.
3266198090Srdivacky  def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16,
3267204642Srdivacky                   OpcodeStr, !strconcat(Dt, "8"),
3268204642Srdivacky                   v16i8, v16i8, OpNode, Commutable>;
3269198090Srdivacky  def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16,
3270204642Srdivacky                   OpcodeStr, !strconcat(Dt, "16"),
3271204642Srdivacky                   v8i16, v8i16, OpNode, Commutable>;
3272198090Srdivacky  def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32,
3273204642Srdivacky                   OpcodeStr, !strconcat(Dt, "32"),
3274204642Srdivacky                   v4i32, v4i32, OpNode, Commutable>;
3275194710Sed}
3276194710Sed
3277234353Sdimmulticlass N3VSL_HS<bits<4> op11_8, string OpcodeStr, SDNode ShOp> {
3278234353Sdim  def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, "i16", v4i16, ShOp>;
3279234353Sdim  def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, "i32", v2i32, ShOp>;
3280234353Sdim  def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, "i16", v8i16, v4i16, ShOp>;
3281234353Sdim  def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, "i32",
3282199989Srdivacky                     v4i32, v2i32, ShOp>;
3283198090Srdivacky}
3284198090Srdivacky
3285194710Sed// ....then also with element size 64 bits:
3286194710Sedmulticlass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3287198090Srdivacky                    InstrItinClass itinD, InstrItinClass itinQ,
3288199989Srdivacky                    string OpcodeStr, string Dt,
3289199989Srdivacky                    SDNode OpNode, bit Commutable = 0>
3290198090Srdivacky  : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ,
3291199989Srdivacky            OpcodeStr, Dt, OpNode, Commutable> {
3292198090Srdivacky  def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD,
3293199989Srdivacky                   OpcodeStr, !strconcat(Dt, "64"),
3294199989Srdivacky                   v1i64, v1i64, OpNode, Commutable>;
3295198090Srdivacky  def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ,
3296199989Srdivacky                   OpcodeStr, !strconcat(Dt, "64"),
3297199989Srdivacky                   v2i64, v2i64, OpNode, Commutable>;
3298194710Sed}
3299194710Sed
3300194710Sed
3301194710Sed// Neon 3-register vector intrinsics.
3302194710Sed
3303194710Sed// First with only element sizes of 16 and 32 bits:
3304206083Srdivackymulticlass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3305198090Srdivacky                     InstrItinClass itinD16, InstrItinClass itinD32,
3306198090Srdivacky                     InstrItinClass itinQ16, InstrItinClass itinQ32,
3307199989Srdivacky                     string OpcodeStr, string Dt,
3308239462Sdim                     SDPatternOperator IntOp, bit Commutable = 0> {
3309194710Sed  // 64-bit vector types.
3310206083Srdivacky  def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, f, itinD16,
3311199989Srdivacky                      OpcodeStr, !strconcat(Dt, "16"),
3312194710Sed                      v4i16, v4i16, IntOp, Commutable>;
3313206083Srdivacky  def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, f, itinD32,
3314199989Srdivacky                      OpcodeStr, !strconcat(Dt, "32"),
3315194710Sed                      v2i32, v2i32, IntOp, Commutable>;
3316194710Sed
3317194710Sed  // 128-bit vector types.
3318206083Srdivacky  def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, f, itinQ16,
3319199989Srdivacky                      OpcodeStr, !strconcat(Dt, "16"),
3320194710Sed                      v8i16, v8i16, IntOp, Commutable>;
3321206083Srdivacky  def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, f, itinQ32,
3322199989Srdivacky                      OpcodeStr, !strconcat(Dt, "32"),
3323194710Sed                      v4i32, v4i32, IntOp, Commutable>;
3324194710Sed}
3325218893Sdimmulticlass N3VInt_HSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3326218893Sdim                     InstrItinClass itinD16, InstrItinClass itinD32,
3327218893Sdim                     InstrItinClass itinQ16, InstrItinClass itinQ32,
3328218893Sdim                     string OpcodeStr, string Dt,
3329239462Sdim                     SDPatternOperator IntOp> {
3330218893Sdim  // 64-bit vector types.
3331218893Sdim  def v4i16 : N3VDIntSh<op24, op23, 0b01, op11_8, op4, f, itinD16,
3332218893Sdim                      OpcodeStr, !strconcat(Dt, "16"),
3333218893Sdim                      v4i16, v4i16, IntOp>;
3334218893Sdim  def v2i32 : N3VDIntSh<op24, op23, 0b10, op11_8, op4, f, itinD32,
3335218893Sdim                      OpcodeStr, !strconcat(Dt, "32"),
3336218893Sdim                      v2i32, v2i32, IntOp>;
3337194710Sed
3338218893Sdim  // 128-bit vector types.
3339218893Sdim  def v8i16 : N3VQIntSh<op24, op23, 0b01, op11_8, op4, f, itinQ16,
3340218893Sdim                      OpcodeStr, !strconcat(Dt, "16"),
3341218893Sdim                      v8i16, v8i16, IntOp>;
3342218893Sdim  def v4i32 : N3VQIntSh<op24, op23, 0b10, op11_8, op4, f, itinQ32,
3343218893Sdim                      OpcodeStr, !strconcat(Dt, "32"),
3344218893Sdim                      v4i32, v4i32, IntOp>;
3345218893Sdim}
3346218893Sdim
3347218893Sdimmulticlass N3VIntSL_HS<bits<4> op11_8,
3348198090Srdivacky                       InstrItinClass itinD16, InstrItinClass itinD32,
3349198090Srdivacky                       InstrItinClass itinQ16, InstrItinClass itinQ32,
3350239462Sdim                       string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3351199989Srdivacky  def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16,
3352199989Srdivacky                          OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>;
3353199989Srdivacky  def v2i32 : N3VDIntSL<0b10, op11_8, itinD32,
3354199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>;
3355199989Srdivacky  def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16,
3356204642Srdivacky                          OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;
3357199989Srdivacky  def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32,
3358199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>;
3359198090Srdivacky}
3360198090Srdivacky
3361194710Sed// ....then also with element size of 8 bits:
3362206083Srdivackymulticlass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3363198090Srdivacky                      InstrItinClass itinD16, InstrItinClass itinD32,
3364198090Srdivacky                      InstrItinClass itinQ16, InstrItinClass itinQ32,
3365199989Srdivacky                      string OpcodeStr, string Dt,
3366239462Sdim                      SDPatternOperator IntOp, bit Commutable = 0>
3367206083Srdivacky  : N3VInt_HS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3368199989Srdivacky              OpcodeStr, Dt, IntOp, Commutable> {
3369206083Srdivacky  def v8i8  : N3VDInt<op24, op23, 0b00, op11_8, op4, f, itinD16,
3370204642Srdivacky                      OpcodeStr, !strconcat(Dt, "8"),
3371204642Srdivacky                      v8i8, v8i8, IntOp, Commutable>;
3372206083Srdivacky  def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, f, itinQ16,
3373199989Srdivacky                      OpcodeStr, !strconcat(Dt, "8"),
3374199989Srdivacky                      v16i8, v16i8, IntOp, Commutable>;
3375194710Sed}
3376218893Sdimmulticlass N3VInt_QHSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3377218893Sdim                      InstrItinClass itinD16, InstrItinClass itinD32,
3378218893Sdim                      InstrItinClass itinQ16, InstrItinClass itinQ32,
3379218893Sdim                      string OpcodeStr, string Dt,
3380239462Sdim                      SDPatternOperator IntOp>
3381218893Sdim  : N3VInt_HSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3382218893Sdim              OpcodeStr, Dt, IntOp> {
3383218893Sdim  def v8i8  : N3VDIntSh<op24, op23, 0b00, op11_8, op4, f, itinD16,
3384218893Sdim                      OpcodeStr, !strconcat(Dt, "8"),
3385218893Sdim                      v8i8, v8i8, IntOp>;
3386218893Sdim  def v16i8 : N3VQIntSh<op24, op23, 0b00, op11_8, op4, f, itinQ16,
3387218893Sdim                      OpcodeStr, !strconcat(Dt, "8"),
3388218893Sdim                      v16i8, v16i8, IntOp>;
3389218893Sdim}
3390194710Sed
3391218893Sdim
3392194710Sed// ....then also with element size of 64 bits:
3393206083Srdivackymulticlass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3394198090Srdivacky                       InstrItinClass itinD16, InstrItinClass itinD32,
3395198090Srdivacky                       InstrItinClass itinQ16, InstrItinClass itinQ32,
3396199989Srdivacky                       string OpcodeStr, string Dt,
3397239462Sdim                       SDPatternOperator IntOp, bit Commutable = 0>
3398206083Srdivacky  : N3VInt_QHS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3399199989Srdivacky               OpcodeStr, Dt, IntOp, Commutable> {
3400206083Srdivacky  def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, f, itinD32,
3401204642Srdivacky                      OpcodeStr, !strconcat(Dt, "64"),
3402204642Srdivacky                      v1i64, v1i64, IntOp, Commutable>;
3403206083Srdivacky  def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, f, itinQ32,
3404204642Srdivacky                      OpcodeStr, !strconcat(Dt, "64"),
3405204642Srdivacky                      v2i64, v2i64, IntOp, Commutable>;
3406194710Sed}
3407218893Sdimmulticlass N3VInt_QHSDSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f,
3408218893Sdim                       InstrItinClass itinD16, InstrItinClass itinD32,
3409218893Sdim                       InstrItinClass itinQ16, InstrItinClass itinQ32,
3410218893Sdim                       string OpcodeStr, string Dt,
3411239462Sdim                       SDPatternOperator IntOp>
3412218893Sdim  : N3VInt_QHSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32,
3413218893Sdim               OpcodeStr, Dt, IntOp> {
3414218893Sdim  def v1i64 : N3VDIntSh<op24, op23, 0b11, op11_8, op4, f, itinD32,
3415218893Sdim                      OpcodeStr, !strconcat(Dt, "64"),
3416218893Sdim                      v1i64, v1i64, IntOp>;
3417218893Sdim  def v2i64 : N3VQIntSh<op24, op23, 0b11, op11_8, op4, f, itinQ32,
3418218893Sdim                      OpcodeStr, !strconcat(Dt, "64"),
3419218893Sdim                      v2i64, v2i64, IntOp>;
3420218893Sdim}
3421194710Sed
3422194710Sed// Neon Narrowing 3-register vector intrinsics,
3423194710Sed//   source operand element sizes of 16, 32 and 64 bits:
3424194710Sedmulticlass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3425199989Srdivacky                       string OpcodeStr, string Dt,
3426239462Sdim                       SDPatternOperator IntOp, bit Commutable = 0> {
3427199989Srdivacky  def v8i8  : N3VNInt<op24, op23, 0b00, op11_8, op4,
3428199989Srdivacky                      OpcodeStr, !strconcat(Dt, "16"),
3429194710Sed                      v8i8, v8i16, IntOp, Commutable>;
3430199989Srdivacky  def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4,
3431199989Srdivacky                      OpcodeStr, !strconcat(Dt, "32"),
3432194710Sed                      v4i16, v4i32, IntOp, Commutable>;
3433199989Srdivacky  def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4,
3434199989Srdivacky                      OpcodeStr, !strconcat(Dt, "64"),
3435194710Sed                      v2i32, v2i64, IntOp, Commutable>;
3436194710Sed}
3437194710Sed
3438194710Sed
3439212904Sdim// Neon Long 3-register vector operations.
3440212904Sdim
3441212904Sdimmulticlass N3VL_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3442212904Sdim                    InstrItinClass itin16, InstrItinClass itin32,
3443212904Sdim                    string OpcodeStr, string Dt,
3444212904Sdim                    SDNode OpNode, bit Commutable = 0> {
3445212904Sdim  def v8i16 : N3VL<op24, op23, 0b00, op11_8, op4, itin16,
3446212904Sdim                   OpcodeStr, !strconcat(Dt, "8"),
3447212904Sdim                   v8i16, v8i8, OpNode, Commutable>;
3448218893Sdim  def v4i32 : N3VL<op24, op23, 0b01, op11_8, op4, itin16,
3449212904Sdim                   OpcodeStr, !strconcat(Dt, "16"),
3450212904Sdim                   v4i32, v4i16, OpNode, Commutable>;
3451212904Sdim  def v2i64 : N3VL<op24, op23, 0b10, op11_8, op4, itin32,
3452212904Sdim                   OpcodeStr, !strconcat(Dt, "32"),
3453212904Sdim                   v2i64, v2i32, OpNode, Commutable>;
3454212904Sdim}
3455212904Sdim
3456212904Sdimmulticlass N3VLSL_HS<bit op24, bits<4> op11_8,
3457212904Sdim                     InstrItinClass itin, string OpcodeStr, string Dt,
3458212904Sdim                     SDNode OpNode> {
3459212904Sdim  def v4i16 : N3VLSL16<op24, 0b01, op11_8, itin, OpcodeStr,
3460212904Sdim                       !strconcat(Dt, "16"), v4i32, v4i16, OpNode>;
3461212904Sdim  def v2i32 : N3VLSL<op24, 0b10, op11_8, itin, OpcodeStr,
3462212904Sdim                     !strconcat(Dt, "32"), v2i64, v2i32, OpNode>;
3463212904Sdim}
3464212904Sdim
3465212904Sdimmulticlass N3VLExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3466212904Sdim                       InstrItinClass itin16, InstrItinClass itin32,
3467212904Sdim                       string OpcodeStr, string Dt,
3468212904Sdim                       SDNode OpNode, SDNode ExtOp, bit Commutable = 0> {
3469212904Sdim  def v8i16 : N3VLExt<op24, op23, 0b00, op11_8, op4, itin16,
3470212904Sdim                      OpcodeStr, !strconcat(Dt, "8"),
3471212904Sdim                      v8i16, v8i8, OpNode, ExtOp, Commutable>;
3472218893Sdim  def v4i32 : N3VLExt<op24, op23, 0b01, op11_8, op4, itin16,
3473212904Sdim                      OpcodeStr, !strconcat(Dt, "16"),
3474212904Sdim                      v4i32, v4i16, OpNode, ExtOp, Commutable>;
3475212904Sdim  def v2i64 : N3VLExt<op24, op23, 0b10, op11_8, op4, itin32,
3476212904Sdim                      OpcodeStr, !strconcat(Dt, "32"),
3477212904Sdim                      v2i64, v2i32, OpNode, ExtOp, Commutable>;
3478212904Sdim}
3479212904Sdim
3480194710Sed// Neon Long 3-register vector intrinsics.
3481194710Sed
3482194710Sed// First with only element sizes of 16 and 32 bits:
3483194710Sedmulticlass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
3484207618Srdivacky                      InstrItinClass itin16, InstrItinClass itin32,
3485207618Srdivacky                      string OpcodeStr, string Dt,
3486239462Sdim                      SDPatternOperator IntOp, bit Commutable = 0> {
3487218893Sdim  def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin16,
3488199989Srdivacky                      OpcodeStr, !strconcat(Dt, "16"),
3489199989Srdivacky                      v4i32, v4i16, IntOp, Commutable>;
3490207618Srdivacky  def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin32,
3491199989Srdivacky                      OpcodeStr, !strconcat(Dt, "32"),
3492199989Srdivacky                      v2i64, v2i32, IntOp, Commutable>;
3493194710Sed}
3494194710Sed
3495198090Srdivackymulticlass N3VLIntSL_HS<bit op24, bits<4> op11_8,
3496199989Srdivacky                        InstrItinClass itin, string OpcodeStr, string Dt,
3497239462Sdim                        SDPatternOperator IntOp> {
3498218893Sdim  def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin,
3499199989Srdivacky                          OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
3500198090Srdivacky  def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin,
3501199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3502198090Srdivacky}
3503198090Srdivacky
3504194710Sed// ....then also with element size of 8 bits:
3505194710Sedmulticlass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3506207618Srdivacky                       InstrItinClass itin16, InstrItinClass itin32,
3507207618Srdivacky                       string OpcodeStr, string Dt,
3508239462Sdim                       SDPatternOperator IntOp, bit Commutable = 0>
3509207618Srdivacky  : N3VLInt_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt,
3510199989Srdivacky               IntOp, Commutable> {
3511207618Srdivacky  def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin16,
3512199989Srdivacky                      OpcodeStr, !strconcat(Dt, "8"),
3513199989Srdivacky                      v8i16, v8i8, IntOp, Commutable>;
3514194710Sed}
3515194710Sed
3516212904Sdim// ....with explicit extend (VABDL).
3517212904Sdimmulticlass N3VLIntExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3518212904Sdim                       InstrItinClass itin, string OpcodeStr, string Dt,
3519239462Sdim                       SDPatternOperator IntOp, SDNode ExtOp, bit Commutable = 0> {
3520212904Sdim  def v8i16 : N3VLIntExt<op24, op23, 0b00, op11_8, op4, itin,
3521212904Sdim                         OpcodeStr, !strconcat(Dt, "8"),
3522212904Sdim                         v8i16, v8i8, IntOp, ExtOp, Commutable>;
3523218893Sdim  def v4i32 : N3VLIntExt<op24, op23, 0b01, op11_8, op4, itin,
3524212904Sdim                         OpcodeStr, !strconcat(Dt, "16"),
3525212904Sdim                         v4i32, v4i16, IntOp, ExtOp, Commutable>;
3526212904Sdim  def v2i64 : N3VLIntExt<op24, op23, 0b10, op11_8, op4, itin,
3527212904Sdim                         OpcodeStr, !strconcat(Dt, "32"),
3528212904Sdim                         v2i64, v2i32, IntOp, ExtOp, Commutable>;
3529212904Sdim}
3530194710Sed
3531212904Sdim
3532194710Sed// Neon Wide 3-register vector intrinsics,
3533194710Sed//   source operand element sizes of 8, 16 and 32 bits:
3534212904Sdimmulticlass N3VW_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3535212904Sdim                    string OpcodeStr, string Dt,
3536212904Sdim                    SDNode OpNode, SDNode ExtOp, bit Commutable = 0> {
3537212904Sdim  def v8i16 : N3VW<op24, op23, 0b00, op11_8, op4,
3538212904Sdim                   OpcodeStr, !strconcat(Dt, "8"),
3539212904Sdim                   v8i16, v8i8, OpNode, ExtOp, Commutable>;
3540212904Sdim  def v4i32 : N3VW<op24, op23, 0b01, op11_8, op4,
3541212904Sdim                   OpcodeStr, !strconcat(Dt, "16"),
3542212904Sdim                   v4i32, v4i16, OpNode, ExtOp, Commutable>;
3543212904Sdim  def v2i64 : N3VW<op24, op23, 0b10, op11_8, op4,
3544212904Sdim                   OpcodeStr, !strconcat(Dt, "32"),
3545212904Sdim                   v2i64, v2i32, OpNode, ExtOp, Commutable>;
3546194710Sed}
3547194710Sed
3548194710Sed
3549194710Sed// Neon Multiply-Op vector operations,
3550194710Sed//   element sizes of 8, 16 and 32 bits:
3551194710Sedmulticlass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3552198090Srdivacky                        InstrItinClass itinD16, InstrItinClass itinD32,
3553198090Srdivacky                        InstrItinClass itinQ16, InstrItinClass itinQ32,
3554199989Srdivacky                        string OpcodeStr, string Dt, SDNode OpNode> {
3555194710Sed  // 64-bit vector types.
3556198090Srdivacky  def v8i8  : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16,
3557199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>;
3558198090Srdivacky  def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16,
3559199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>;
3560198090Srdivacky  def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32,
3561199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>;
3562194710Sed
3563194710Sed  // 128-bit vector types.
3564198090Srdivacky  def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16,
3565199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>;
3566198090Srdivacky  def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16,
3567199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>;
3568198090Srdivacky  def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32,
3569199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>;
3570194710Sed}
3571194710Sed
3572218893Sdimmulticlass N3VMulOpSL_HS<bits<4> op11_8,
3573198090Srdivacky                         InstrItinClass itinD16, InstrItinClass itinD32,
3574198090Srdivacky                         InstrItinClass itinQ16, InstrItinClass itinQ32,
3575199989Srdivacky                         string OpcodeStr, string Dt, SDNode ShOp> {
3576198090Srdivacky  def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16,
3577199989Srdivacky                            OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>;
3578198090Srdivacky  def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,
3579199989Srdivacky                          OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>;
3580198090Srdivacky  def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16,
3581204642Srdivacky                            OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16,
3582204642Srdivacky                            mul, ShOp>;
3583198090Srdivacky  def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32,
3584204642Srdivacky                          OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32,
3585204642Srdivacky                          mul, ShOp>;
3586198090Srdivacky}
3587194710Sed
3588212904Sdim// Neon Intrinsic-Op vector operations,
3589212904Sdim//   element sizes of 8, 16 and 32 bits:
3590212904Sdimmulticlass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3591212904Sdim                        InstrItinClass itinD, InstrItinClass itinQ,
3592239462Sdim                        string OpcodeStr, string Dt, SDPatternOperator IntOp,
3593212904Sdim                        SDNode OpNode> {
3594212904Sdim  // 64-bit vector types.
3595212904Sdim  def v8i8  : N3VDIntOp<op24, op23, 0b00, op11_8, op4, itinD,
3596212904Sdim                        OpcodeStr, !strconcat(Dt, "8"), v8i8, IntOp, OpNode>;
3597212904Sdim  def v4i16 : N3VDIntOp<op24, op23, 0b01, op11_8, op4, itinD,
3598212904Sdim                        OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp, OpNode>;
3599212904Sdim  def v2i32 : N3VDIntOp<op24, op23, 0b10, op11_8, op4, itinD,
3600212904Sdim                        OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp, OpNode>;
3601212904Sdim
3602212904Sdim  // 128-bit vector types.
3603212904Sdim  def v16i8 : N3VQIntOp<op24, op23, 0b00, op11_8, op4, itinQ,
3604212904Sdim                        OpcodeStr, !strconcat(Dt, "8"), v16i8, IntOp, OpNode>;
3605212904Sdim  def v8i16 : N3VQIntOp<op24, op23, 0b01, op11_8, op4, itinQ,
3606212904Sdim                        OpcodeStr, !strconcat(Dt, "16"), v8i16, IntOp, OpNode>;
3607212904Sdim  def v4i32 : N3VQIntOp<op24, op23, 0b10, op11_8, op4, itinQ,
3608212904Sdim                        OpcodeStr, !strconcat(Dt, "32"), v4i32, IntOp, OpNode>;
3609212904Sdim}
3610212904Sdim
3611194710Sed// Neon 3-argument intrinsics,
3612194710Sed//   element sizes of 8, 16 and 32 bits:
3613194710Sedmulticlass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3614207618Srdivacky                       InstrItinClass itinD, InstrItinClass itinQ,
3615239462Sdim                       string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3616194710Sed  // 64-bit vector types.
3617207618Srdivacky  def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD,
3618204642Srdivacky                       OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
3619207618Srdivacky  def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD,
3620204642Srdivacky                       OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
3621207618Srdivacky  def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD,
3622204642Srdivacky                       OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
3623194710Sed
3624194710Sed  // 128-bit vector types.
3625207618Srdivacky  def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ,
3626204642Srdivacky                       OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
3627207618Srdivacky  def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ,
3628204642Srdivacky                       OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
3629207618Srdivacky  def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ,
3630204642Srdivacky                       OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
3631194710Sed}
3632194710Sed
3633194710Sed
3634212904Sdim// Neon Long Multiply-Op vector operations,
3635212904Sdim//   element sizes of 8, 16 and 32 bits:
3636212904Sdimmulticlass N3VLMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3637212904Sdim                         InstrItinClass itin16, InstrItinClass itin32,
3638212904Sdim                         string OpcodeStr, string Dt, SDNode MulOp,
3639212904Sdim                         SDNode OpNode> {
3640212904Sdim  def v8i16 : N3VLMulOp<op24, op23, 0b00, op11_8, op4, itin16, OpcodeStr,
3641212904Sdim                        !strconcat(Dt, "8"), v8i16, v8i8, MulOp, OpNode>;
3642212904Sdim  def v4i32 : N3VLMulOp<op24, op23, 0b01, op11_8, op4, itin16, OpcodeStr,
3643212904Sdim                        !strconcat(Dt, "16"), v4i32, v4i16, MulOp, OpNode>;
3644212904Sdim  def v2i64 : N3VLMulOp<op24, op23, 0b10, op11_8, op4, itin32, OpcodeStr,
3645212904Sdim                        !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;
3646212904Sdim}
3647212904Sdim
3648212904Sdimmulticlass N3VLMulOpSL_HS<bit op24, bits<4> op11_8, string OpcodeStr,
3649212904Sdim                          string Dt, SDNode MulOp, SDNode OpNode> {
3650212904Sdim  def v4i16 : N3VLMulOpSL16<op24, 0b01, op11_8, IIC_VMACi16D, OpcodeStr,
3651212904Sdim                            !strconcat(Dt,"16"), v4i32, v4i16, MulOp, OpNode>;
3652212904Sdim  def v2i32 : N3VLMulOpSL<op24, 0b10, op11_8, IIC_VMACi32D, OpcodeStr,
3653212904Sdim                          !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>;
3654212904Sdim}
3655212904Sdim
3656212904Sdim
3657194710Sed// Neon Long 3-argument intrinsics.
3658194710Sed
3659194710Sed// First with only element sizes of 16 and 32 bits:
3660194710Sedmulticlass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
3661207618Srdivacky                       InstrItinClass itin16, InstrItinClass itin32,
3662239462Sdim                       string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3663207618Srdivacky  def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, itin16,
3664199989Srdivacky                       OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
3665207618Srdivacky  def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, itin32,
3666199989Srdivacky                       OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3667194710Sed}
3668194710Sed
3669198090Srdivackymulticlass N3VLInt3SL_HS<bit op24, bits<4> op11_8,
3670239462Sdim                         string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3671198090Srdivacky  def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D,
3672199989Srdivacky                           OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>;
3673198090Srdivacky  def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D,
3674199989Srdivacky                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
3675198090Srdivacky}
3676198090Srdivacky
3677194710Sed// ....then also with element size of 8 bits:
3678194710Sedmulticlass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3679207618Srdivacky                        InstrItinClass itin16, InstrItinClass itin32,
3680239462Sdim                        string OpcodeStr, string Dt, SDPatternOperator IntOp>
3681207618Srdivacky  : N3VLInt3_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, IntOp> {
3682207618Srdivacky  def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, itin16,
3683199989Srdivacky                       OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>;
3684194710Sed}
3685194710Sed
3686212904Sdim// ....with explicit extend (VABAL).
3687212904Sdimmulticlass N3VLIntExtOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
3688212904Sdim                            InstrItinClass itin, string OpcodeStr, string Dt,
3689239462Sdim                            SDPatternOperator IntOp, SDNode ExtOp, SDNode OpNode> {
3690212904Sdim  def v8i16 : N3VLIntExtOp<op24, op23, 0b00, op11_8, op4, itin,
3691212904Sdim                           OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8,
3692212904Sdim                           IntOp, ExtOp, OpNode>;
3693212904Sdim  def v4i32 : N3VLIntExtOp<op24, op23, 0b01, op11_8, op4, itin,
3694212904Sdim                           OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16,
3695212904Sdim                           IntOp, ExtOp, OpNode>;
3696212904Sdim  def v2i64 : N3VLIntExtOp<op24, op23, 0b10, op11_8, op4, itin,
3697212904Sdim                           OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32,
3698212904Sdim                           IntOp, ExtOp, OpNode>;
3699212904Sdim}
3700194710Sed
3701212904Sdim
3702194710Sed// Neon Pairwise long 2-register intrinsics,
3703194710Sed//   element sizes of 8, 16 and 32 bits:
3704194710Sedmulticlass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3705194710Sed                        bits<5> op11_7, bit op4,
3706239462Sdim                        string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3707194710Sed  // 64-bit vector types.
3708194710Sed  def v8i8  : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3709199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
3710194710Sed  def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3711199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
3712194710Sed  def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3713199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
3714194710Sed
3715194710Sed  // 128-bit vector types.
3716194710Sed  def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3717199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
3718194710Sed  def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3719199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
3720194710Sed  def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3721199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
3722194710Sed}
3723194710Sed
3724194710Sed
3725194710Sed// Neon Pairwise long 2-register accumulate intrinsics,
3726194710Sed//   element sizes of 8, 16 and 32 bits:
3727194710Sedmulticlass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
3728194710Sed                         bits<5> op11_7, bit op4,
3729239462Sdim                         string OpcodeStr, string Dt, SDPatternOperator IntOp> {
3730194710Sed  // 64-bit vector types.
3731194710Sed  def v8i8  : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3732199989Srdivacky                         OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
3733194710Sed  def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3734199989Srdivacky                         OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
3735194710Sed  def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3736199989Srdivacky                         OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
3737194710Sed
3738194710Sed  // 128-bit vector types.
3739194710Sed  def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
3740199989Srdivacky                         OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
3741194710Sed  def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
3742199989Srdivacky                         OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
3743194710Sed  def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
3744199989Srdivacky                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
3745194710Sed}
3746194710Sed
3747194710Sed
3748194710Sed// Neon 2-register vector shift by immediate,
3749206083Srdivacky//   with f of either N2RegVShLFrm or N2RegVShRFrm
3750194710Sed//   element sizes of 8, 16, 32 and 64 bits:
3751221345Sdimmulticlass N2VShL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3752221345Sdim                       InstrItinClass itin, string OpcodeStr, string Dt,
3753221345Sdim                       SDNode OpNode> {
3754194710Sed  // 64-bit vector types.
3755221345Sdim  def v8i8  : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3756199989Srdivacky                     OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
3757198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3758198396Srdivacky  }
3759221345Sdim  def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3760199989Srdivacky                     OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
3761198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3762198396Srdivacky  }
3763221345Sdim  def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3764199989Srdivacky                     OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
3765198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3766198396Srdivacky  }
3767221345Sdim  def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,
3768199989Srdivacky                     OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
3769198396Srdivacky                             // imm6 = xxxxxx
3770194710Sed
3771194710Sed  // 128-bit vector types.
3772221345Sdim  def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3773199989Srdivacky                     OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
3774198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3775198396Srdivacky  }
3776221345Sdim  def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3777199989Srdivacky                     OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
3778198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3779198396Srdivacky  }
3780221345Sdim  def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm,
3781199989Srdivacky                     OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
3782198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3783198396Srdivacky  }
3784221345Sdim  def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm,
3785199989Srdivacky                     OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
3786198396Srdivacky                             // imm6 = xxxxxx
3787194710Sed}
3788221345Sdimmulticlass N2VShR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3789221345Sdim                       InstrItinClass itin, string OpcodeStr, string Dt,
3790234353Sdim                       string baseOpc, SDNode OpNode> {
3791221345Sdim  // 64-bit vector types.
3792221345Sdim  def v8i8  : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,
3793221345Sdim                     OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
3794221345Sdim    let Inst{21-19} = 0b001; // imm6 = 001xxx
3795221345Sdim  }
3796221345Sdim  def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,
3797221345Sdim                     OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
3798221345Sdim    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3799221345Sdim  }
3800221345Sdim  def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,
3801221345Sdim                     OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
3802221345Sdim    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3803221345Sdim  }
3804221345Sdim  def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,
3805221345Sdim                     OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
3806221345Sdim                             // imm6 = xxxxxx
3807194710Sed
3808221345Sdim  // 128-bit vector types.
3809221345Sdim  def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8,
3810221345Sdim                     OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
3811221345Sdim    let Inst{21-19} = 0b001; // imm6 = 001xxx
3812221345Sdim  }
3813221345Sdim  def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16,
3814221345Sdim                     OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
3815221345Sdim    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3816221345Sdim  }
3817221345Sdim  def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32,
3818221345Sdim                     OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
3819221345Sdim    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3820221345Sdim  }
3821221345Sdim  def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64,
3822221345Sdim                     OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
3823221345Sdim                             // imm6 = xxxxxx
3824221345Sdim}
3825221345Sdim
3826194710Sed// Neon Shift-Accumulate vector operations,
3827194710Sed//   element sizes of 8, 16, 32 and 64 bits:
3828194710Sedmulticlass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3829199989Srdivacky                         string OpcodeStr, string Dt, SDNode ShOp> {
3830194710Sed  // 64-bit vector types.
3831221345Sdim  def v8i8  : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm8,
3832199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> {
3833198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3834198396Srdivacky  }
3835221345Sdim  def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm16,
3836199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> {
3837198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3838198396Srdivacky  }
3839221345Sdim  def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm32,
3840199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> {
3841198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3842198396Srdivacky  }
3843221345Sdim  def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4, shr_imm64,
3844199989Srdivacky                        OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>;
3845198396Srdivacky                             // imm6 = xxxxxx
3846194710Sed
3847194710Sed  // 128-bit vector types.
3848221345Sdim  def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm8,
3849199989Srdivacky                        OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> {
3850198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3851198396Srdivacky  }
3852221345Sdim  def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm16,
3853199989Srdivacky                        OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> {
3854198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3855198396Srdivacky  }
3856221345Sdim  def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm32,
3857199989Srdivacky                        OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> {
3858198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3859198396Srdivacky  }
3860221345Sdim  def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4, shr_imm64,
3861199989Srdivacky                        OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>;
3862198396Srdivacky                             // imm6 = xxxxxx
3863194710Sed}
3864194710Sed
3865194710Sed// Neon Shift-Insert vector operations,
3866206083Srdivacky//   with f of either N2RegVShLFrm or N2RegVShRFrm
3867194710Sed//   element sizes of 8, 16, 32 and 64 bits:
3868221345Sdimmulticlass N2VShInsL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3869221345Sdim                          string OpcodeStr> {
3870194710Sed  // 64-bit vector types.
3871221345Sdim  def v8i8  : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
3872221345Sdim                        N2RegVShLFrm, OpcodeStr, "8", v8i8, NEONvsli> {
3873198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3874198396Srdivacky  }
3875221345Sdim  def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
3876221345Sdim                        N2RegVShLFrm, OpcodeStr, "16", v4i16, NEONvsli> {
3877198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3878198396Srdivacky  }
3879221345Sdim  def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm,
3880221345Sdim                        N2RegVShLFrm, OpcodeStr, "32", v2i32, NEONvsli> {
3881198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3882198396Srdivacky  }
3883221345Sdim  def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, i32imm,
3884221345Sdim                        N2RegVShLFrm, OpcodeStr, "64", v1i64, NEONvsli>;
3885198396Srdivacky                             // imm6 = xxxxxx
3886194710Sed
3887194710Sed  // 128-bit vector types.
3888221345Sdim  def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
3889221345Sdim                        N2RegVShLFrm, OpcodeStr, "8", v16i8, NEONvsli> {
3890198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3891198396Srdivacky  }
3892221345Sdim  def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
3893221345Sdim                        N2RegVShLFrm, OpcodeStr, "16", v8i16, NEONvsli> {
3894198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3895198396Srdivacky  }
3896221345Sdim  def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm,
3897221345Sdim                        N2RegVShLFrm, OpcodeStr, "32", v4i32, NEONvsli> {
3898198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3899198396Srdivacky  }
3900221345Sdim  def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, i32imm,
3901221345Sdim                        N2RegVShLFrm, OpcodeStr, "64", v2i64, NEONvsli>;
3902198396Srdivacky                             // imm6 = xxxxxx
3903194710Sed}
3904221345Sdimmulticlass N2VShInsR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
3905221345Sdim                          string OpcodeStr> {
3906221345Sdim  // 64-bit vector types.
3907221345Sdim  def v8i8  : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm8,
3908221345Sdim                        N2RegVShRFrm, OpcodeStr, "8", v8i8, NEONvsri> {
3909221345Sdim    let Inst{21-19} = 0b001; // imm6 = 001xxx
3910221345Sdim  }
3911221345Sdim  def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm16,
3912221345Sdim                        N2RegVShRFrm, OpcodeStr, "16", v4i16, NEONvsri> {
3913221345Sdim    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3914221345Sdim  }
3915221345Sdim  def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm32,
3916221345Sdim                        N2RegVShRFrm, OpcodeStr, "32", v2i32, NEONvsri> {
3917221345Sdim    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3918221345Sdim  }
3919221345Sdim  def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, shr_imm64,
3920221345Sdim                        N2RegVShRFrm, OpcodeStr, "64", v1i64, NEONvsri>;
3921221345Sdim                             // imm6 = xxxxxx
3922194710Sed
3923221345Sdim  // 128-bit vector types.
3924221345Sdim  def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm8,
3925221345Sdim                        N2RegVShRFrm, OpcodeStr, "8", v16i8, NEONvsri> {
3926221345Sdim    let Inst{21-19} = 0b001; // imm6 = 001xxx
3927221345Sdim  }
3928221345Sdim  def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm16,
3929221345Sdim                        N2RegVShRFrm, OpcodeStr, "16", v8i16, NEONvsri> {
3930221345Sdim    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3931221345Sdim  }
3932221345Sdim  def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm32,
3933221345Sdim                        N2RegVShRFrm, OpcodeStr, "32", v4i32, NEONvsri> {
3934221345Sdim    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3935221345Sdim  }
3936221345Sdim  def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, shr_imm64,
3937221345Sdim                        N2RegVShRFrm, OpcodeStr, "64", v2i64, NEONvsri>;
3938221345Sdim                             // imm6 = xxxxxx
3939221345Sdim}
3940221345Sdim
3941198396Srdivacky// Neon Shift Long operations,
3942198396Srdivacky//   element sizes of 8, 16, 32 bits:
3943198396Srdivackymulticlass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
3944199989Srdivacky                      bit op4, string OpcodeStr, string Dt, SDNode OpNode> {
3945198396Srdivacky  def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
3946234353Sdim              OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, imm1_7, OpNode> {
3947198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3948198396Srdivacky  }
3949198396Srdivacky  def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
3950234353Sdim               OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, imm1_15, OpNode> {
3951198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3952198396Srdivacky  }
3953198396Srdivacky  def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
3954234353Sdim               OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, imm1_31, OpNode> {
3955198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3956198396Srdivacky  }
3957198396Srdivacky}
3958198396Srdivacky
3959198396Srdivacky// Neon Shift Narrow operations,
3960198396Srdivacky//   element sizes of 16, 32, 64 bits:
3961198396Srdivackymulticlass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
3962199989Srdivacky                      bit op4, InstrItinClass itin, string OpcodeStr, string Dt,
3963198396Srdivacky                      SDNode OpNode> {
3964198396Srdivacky  def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
3965221345Sdim                    OpcodeStr, !strconcat(Dt, "16"),
3966221345Sdim                    v8i8, v8i16, shr_imm8, OpNode> {
3967198396Srdivacky    let Inst{21-19} = 0b001; // imm6 = 001xxx
3968198396Srdivacky  }
3969198396Srdivacky  def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
3970221345Sdim                     OpcodeStr, !strconcat(Dt, "32"),
3971221345Sdim                     v4i16, v4i32, shr_imm16, OpNode> {
3972198396Srdivacky    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
3973198396Srdivacky  }
3974198396Srdivacky  def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
3975221345Sdim                     OpcodeStr, !strconcat(Dt, "64"),
3976221345Sdim                     v2i32, v2i64, shr_imm32, OpNode> {
3977198396Srdivacky    let Inst{21} = 0b1;      // imm6 = 1xxxxx
3978198396Srdivacky  }
3979198396Srdivacky}
3980198396Srdivacky
3981194710Sed//===----------------------------------------------------------------------===//
3982194710Sed// Instruction Definitions.
3983194710Sed//===----------------------------------------------------------------------===//
3984194710Sed
3985194710Sed// Vector Add Operations.
3986194710Sed
3987194710Sed//   VADD     : Vector Add (integer and floating-point)
3988199989Srdivackydefm VADD     : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i",
3989199989Srdivacky                         add, 1>;
3990199989Srdivackydef  VADDfd   : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32",
3991199989Srdivacky                     v2f32, v2f32, fadd, 1>;
3992199989Srdivackydef  VADDfq   : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32",
3993199989Srdivacky                     v4f32, v4f32, fadd, 1>;
3994194710Sed//   VADDL    : Vector Add Long (Q = D + D)
3995212904Sdimdefm VADDLs   : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
3996212904Sdim                            "vaddl", "s", add, sext, 1>;
3997212904Sdimdefm VADDLu   : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
3998212904Sdim                            "vaddl", "u", add, zext, 1>;
3999194710Sed//   VADDW    : Vector Add Wide (Q = Q + D)
4000212904Sdimdefm VADDWs   : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>;
4001212904Sdimdefm VADDWu   : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zext, 0>;
4002194710Sed//   VHADD    : Vector Halving Add
4003206083Srdivackydefm VHADDs   : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm,
4004206083Srdivacky                           IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4005206083Srdivacky                           "vhadd", "s", int_arm_neon_vhadds, 1>;
4006206083Srdivackydefm VHADDu   : N3VInt_QHS<1, 0, 0b0000, 0, N3RegFrm,
4007206083Srdivacky                           IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4008206083Srdivacky                           "vhadd", "u", int_arm_neon_vhaddu, 1>;
4009194710Sed//   VRHADD   : Vector Rounding Halving Add
4010206083Srdivackydefm VRHADDs  : N3VInt_QHS<0, 0, 0b0001, 0, N3RegFrm,
4011206083Srdivacky                           IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4012206083Srdivacky                           "vrhadd", "s", int_arm_neon_vrhadds, 1>;
4013206083Srdivackydefm VRHADDu  : N3VInt_QHS<1, 0, 0b0001, 0, N3RegFrm,
4014206083Srdivacky                           IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4015206083Srdivacky                           "vrhadd", "u", int_arm_neon_vrhaddu, 1>;
4016194710Sed//   VQADD    : Vector Saturating Add
4017206083Srdivackydefm VQADDs   : N3VInt_QHSD<0, 0, 0b0000, 1, N3RegFrm,
4018206083Srdivacky                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4019206083Srdivacky                            "vqadd", "s", int_arm_neon_vqadds, 1>;
4020206083Srdivackydefm VQADDu   : N3VInt_QHSD<1, 0, 0b0000, 1, N3RegFrm,
4021206083Srdivacky                            IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
4022206083Srdivacky                            "vqadd", "u", int_arm_neon_vqaddu, 1>;
4023194710Sed//   VADDHN   : Vector Add and Narrow Returning High Half (D = Q + Q)
4024263508Sdimdefm VADDHN   : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i", null_frag, 1>;
4025194710Sed//   VRADDHN  : Vector Rounding Add and Narrow Returning High Half (D = Q + Q)
4026199989Srdivackydefm VRADDHN  : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i",
4027199989Srdivacky                            int_arm_neon_vraddhn, 1>;
4028194710Sed
4029263508Sdimdef : Pat<(v8i8  (trunc (NEONvshru (add (v8i16 QPR:$Vn), QPR:$Vm), 8))),
4030263508Sdim          (VADDHNv8i8 QPR:$Vn, QPR:$Vm)>;
4031263508Sdimdef : Pat<(v4i16 (trunc (NEONvshru (add (v4i32 QPR:$Vn), QPR:$Vm), 16))),
4032263508Sdim          (VADDHNv4i16 QPR:$Vn, QPR:$Vm)>;
4033263508Sdimdef : Pat<(v2i32 (trunc (NEONvshru (add (v2i64 QPR:$Vn), QPR:$Vm), 32))),
4034263508Sdim          (VADDHNv2i32 QPR:$Vn, QPR:$Vm)>;
4035263508Sdim
4036194710Sed// Vector Multiply Operations.
4037194710Sed
4038194710Sed//   VMUL     : Vector Multiply (integer, polynomial and floating-point)
4039199989Srdivackydefm VMUL     : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D,
4040199989Srdivacky                        IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>;
4041206083Srdivackydef  VMULpd   : N3VDInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16D, "vmul",
4042206083Srdivacky                        "p8", v8i8, v8i8, int_arm_neon_vmulp, 1>;
4043206083Srdivackydef  VMULpq   : N3VQInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16Q, "vmul",
4044206083Srdivacky                        "p8", v16i8, v16i8, int_arm_neon_vmulp, 1>;
4045218893Sdimdef  VMULfd   : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VFMULD, "vmul", "f32",
4046204642Srdivacky                     v2f32, v2f32, fmul, 1>;
4047218893Sdimdef  VMULfq   : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VFMULQ, "vmul", "f32",
4048204642Srdivacky                     v4f32, v4f32, fmul, 1>;
4049234353Sdimdefm VMULsl   : N3VSL_HS<0b1000, "vmul", mul>;
4050204642Srdivackydef  VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;
4051204642Srdivackydef  VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32,
4052204642Srdivacky                       v2f32, fmul>;
4053204642Srdivacky
4054198090Srdivackydef : Pat<(v8i16 (mul (v8i16 QPR:$src1),
4055198090Srdivacky                      (v8i16 (NEONvduplane (v8i16 QPR:$src2), imm:$lane)))),
4056198090Srdivacky          (v8i16 (VMULslv8i16 (v8i16 QPR:$src1),
4057198090Srdivacky                              (v4i16 (EXTRACT_SUBREG QPR:$src2,
4058204642Srdivacky                                      (DSubReg_i16_reg imm:$lane))),
4059198090Srdivacky                              (SubReg_i16_lane imm:$lane)))>;
4060198090Srdivackydef : Pat<(v4i32 (mul (v4i32 QPR:$src1),
4061198090Srdivacky                      (v4i32 (NEONvduplane (v4i32 QPR:$src2), imm:$lane)))),
4062198090Srdivacky          (v4i32 (VMULslv4i32 (v4i32 QPR:$src1),
4063198090Srdivacky                              (v2i32 (EXTRACT_SUBREG QPR:$src2,
4064204642Srdivacky                                      (DSubReg_i32_reg imm:$lane))),
4065198090Srdivacky                              (SubReg_i32_lane imm:$lane)))>;
4066198090Srdivackydef : Pat<(v4f32 (fmul (v4f32 QPR:$src1),
4067198090Srdivacky                       (v4f32 (NEONvduplane (v4f32 QPR:$src2), imm:$lane)))),
4068198090Srdivacky          (v4f32 (VMULslfq (v4f32 QPR:$src1),
4069198090Srdivacky                           (v2f32 (EXTRACT_SUBREG QPR:$src2,
4070204642Srdivacky                                   (DSubReg_i32_reg imm:$lane))),
4071198090Srdivacky                           (SubReg_i32_lane imm:$lane)))>;
4072198090Srdivacky
4073263508Sdim
4074263508Sdimdef : Pat<(v2f32 (fmul DPR:$Rn, (NEONvdup (f32 SPR:$Rm)))),
4075263508Sdim          (VMULslfd DPR:$Rn,
4076263508Sdim            (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),
4077263508Sdim            (i32 0))>;
4078263508Sdimdef : Pat<(v4f32 (fmul QPR:$Rn, (NEONvdup (f32 SPR:$Rm)))),
4079263508Sdim          (VMULslfq QPR:$Rn,
4080263508Sdim            (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0),
4081263508Sdim            (i32 0))>;
4082263508Sdim
4083263508Sdim
4084194710Sed//   VQDMULH  : Vector Saturating Doubling Multiply Returning High Half
4085206083Srdivackydefm VQDMULH  : N3VInt_HS<0, 0, 0b1011, 0, N3RegFrm, IIC_VMULi16D, IIC_VMULi32D,
4086218893Sdim                          IIC_VMULi16Q, IIC_VMULi32Q,
4087199989Srdivacky                          "vqdmulh", "s", int_arm_neon_vqdmulh, 1>;
4088198090Srdivackydefm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D,
4089198090Srdivacky                            IIC_VMULi16Q, IIC_VMULi32Q,
4090199989Srdivacky                            "vqdmulh", "s",  int_arm_neon_vqdmulh>;
4091198090Srdivackydef : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1),
4092199989Srdivacky                                       (v8i16 (NEONvduplane (v8i16 QPR:$src2),
4093199989Srdivacky                                                            imm:$lane)))),
4094198090Srdivacky          (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1),
4095198090Srdivacky                                 (v4i16 (EXTRACT_SUBREG QPR:$src2,
4096204642Srdivacky                                         (DSubReg_i16_reg imm:$lane))),
4097198090Srdivacky                                 (SubReg_i16_lane imm:$lane)))>;
4098198090Srdivackydef : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1),
4099199989Srdivacky                                       (v4i32 (NEONvduplane (v4i32 QPR:$src2),
4100199989Srdivacky                                                            imm:$lane)))),
4101198090Srdivacky          (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1),
4102198090Srdivacky                                 (v2i32 (EXTRACT_SUBREG QPR:$src2,
4103204642Srdivacky                                         (DSubReg_i32_reg imm:$lane))),
4104198090Srdivacky                                 (SubReg_i32_lane imm:$lane)))>;
4105198090Srdivacky
4106194710Sed//   VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half
4107206083Srdivackydefm VQRDMULH   : N3VInt_HS<1, 0, 0b1011, 0, N3RegFrm,
4108206083Srdivacky                            IIC_VMULi16D,IIC_VMULi32D,IIC_VMULi16Q,IIC_VMULi32Q,
4109199989Srdivacky                            "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>;
4110198090Srdivackydefm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D,
4111198090Srdivacky                              IIC_VMULi16Q, IIC_VMULi32Q,
4112199989Srdivacky                              "vqrdmulh", "s",  int_arm_neon_vqrdmulh>;
4113198090Srdivackydef : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1),
4114199989Srdivacky                                        (v8i16 (NEONvduplane (v8i16 QPR:$src2),
4115199989Srdivacky                                                             imm:$lane)))),
4116198090Srdivacky          (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1),
4117198090Srdivacky                                  (v4i16 (EXTRACT_SUBREG QPR:$src2,
4118204642Srdivacky                                          (DSubReg_i16_reg imm:$lane))),
4119198090Srdivacky                                  (SubReg_i16_lane imm:$lane)))>;
4120198090Srdivackydef : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1),
4121199989Srdivacky                                        (v4i32 (NEONvduplane (v4i32 QPR:$src2),
4122199989Srdivacky                                                             imm:$lane)))),
4123198090Srdivacky          (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1),
4124198090Srdivacky                                  (v2i32 (EXTRACT_SUBREG QPR:$src2,
4125204642Srdivacky                                          (DSubReg_i32_reg imm:$lane))),
4126198090Srdivacky                                  (SubReg_i32_lane imm:$lane)))>;
4127198090Srdivacky
4128194710Sed//   VMULL    : Vector Multiply Long (integer and polynomial) (Q = D * D)
4129263508Sdimlet PostEncoderMethod = "NEONThumb2DataIPostEncoder",
4130263508Sdim    DecoderNamespace = "NEONData" in {
4131263508Sdim  defm VMULLs   : N3VL_QHS<0,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,
4132263508Sdim                           "vmull", "s", NEONvmulls, 1>;
4133263508Sdim  defm VMULLu   : N3VL_QHS<1,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D,
4134263508Sdim                           "vmull", "u", NEONvmullu, 1>;
4135263508Sdim  def  VMULLp8   :  N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8",
4136263508Sdim                            v8i16, v8i8, int_arm_neon_vmullp, 1>;
4137263508Sdim  def  VMULLp64  : N3VLIntnp<0b00101, 0b10, 0b1110, 0, 0, NoItinerary,
4138263508Sdim                          "vmull", "p64", v2i64, v1i64, int_arm_neon_vmullp, 1>,
4139263508Sdim                    Requires<[HasV8, HasCrypto]>;
4140263508Sdim}
4141212904Sdimdefm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", NEONvmulls>;
4142212904Sdimdefm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", NEONvmullu>;
4143198090Srdivacky
4144194710Sed//   VQDMULL  : Vector Saturating Doubling Multiply Long (Q = D * D)
4145207618Srdivackydefm VQDMULL  : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, IIC_VMULi32D,
4146207618Srdivacky                           "vqdmull", "s", int_arm_neon_vqdmull, 1>;
4147207618Srdivackydefm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D,
4148207618Srdivacky                             "vqdmull", "s", int_arm_neon_vqdmull>;
4149194710Sed
4150194710Sed// Vector Multiply-Accumulate and Multiply-Subtract Operations.
4151194710Sed
4152194710Sed//   VMLA     : Vector Multiply Accumulate (integer and floating-point)
4153198090Srdivackydefm VMLA     : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4154199989Srdivacky                             IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
4155199989Srdivackydef  VMLAfd   : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32",
4156218893Sdim                          v2f32, fmul_su, fadd_mlx>,
4157234353Sdim                Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4158199989Srdivackydef  VMLAfq   : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32",
4159218893Sdim                          v4f32, fmul_su, fadd_mlx>,
4160234353Sdim                Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4161198090Srdivackydefm VMLAsl   : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D,
4162199989Srdivacky                              IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
4163199989Srdivackydef  VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32",
4164218893Sdim                            v2f32, fmul_su, fadd_mlx>,
4165218893Sdim                Requires<[HasNEON, UseFPVMLx]>;
4166199989Srdivackydef  VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32",
4167218893Sdim                            v4f32, v2f32, fmul_su, fadd_mlx>,
4168218893Sdim                Requires<[HasNEON, UseFPVMLx]>;
4169198090Srdivacky
4170198090Srdivackydef : Pat<(v8i16 (add (v8i16 QPR:$src1),
4171204642Srdivacky                  (mul (v8i16 QPR:$src2),
4172204642Srdivacky                       (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
4173204642Srdivacky          (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
4174198090Srdivacky                              (v4i16 (EXTRACT_SUBREG QPR:$src3,
4175204642Srdivacky                                      (DSubReg_i16_reg imm:$lane))),
4176198090Srdivacky                              (SubReg_i16_lane imm:$lane)))>;
4177198090Srdivacky
4178198090Srdivackydef : Pat<(v4i32 (add (v4i32 QPR:$src1),
4179204642Srdivacky                  (mul (v4i32 QPR:$src2),
4180204642Srdivacky                       (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
4181204642Srdivacky          (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
4182198090Srdivacky                              (v2i32 (EXTRACT_SUBREG QPR:$src3,
4183204642Srdivacky                                      (DSubReg_i32_reg imm:$lane))),
4184198090Srdivacky                              (SubReg_i32_lane imm:$lane)))>;
4185198090Srdivacky
4186218893Sdimdef : Pat<(v4f32 (fadd_mlx (v4f32 QPR:$src1),
4187218893Sdim                  (fmul_su (v4f32 QPR:$src2),
4188204642Srdivacky                        (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
4189198090Srdivacky          (v4f32 (VMLAslfq (v4f32 QPR:$src1),
4190198090Srdivacky                           (v4f32 QPR:$src2),
4191198090Srdivacky                           (v2f32 (EXTRACT_SUBREG QPR:$src3,
4192204642Srdivacky                                   (DSubReg_i32_reg imm:$lane))),
4193218893Sdim                           (SubReg_i32_lane imm:$lane)))>,
4194218893Sdim          Requires<[HasNEON, UseFPVMLx]>;
4195198090Srdivacky
4196194710Sed//   VMLAL    : Vector Multiply Accumulate Long (Q += D * D)
4197212904Sdimdefm VMLALs   : N3VLMulOp_QHS<0,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,
4198212904Sdim                              "vmlal", "s", NEONvmulls, add>;
4199212904Sdimdefm VMLALu   : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,
4200212904Sdim                              "vmlal", "u", NEONvmullu, add>;
4201198090Srdivacky
4202212904Sdimdefm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", NEONvmulls, add>;
4203212904Sdimdefm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", NEONvmullu, add>;
4204198090Srdivacky
4205194710Sed//   VQDMLAL  : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D)
4206207618Srdivackydefm VQDMLAL  : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4207263508Sdim                            "vqdmlal", "s", null_frag>;
4208263508Sdimdefm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", null_frag>;
4209198090Srdivacky
4210263508Sdimdef : Pat<(v4i32 (int_arm_neon_vqadds (v4i32 QPR:$src1),
4211263508Sdim                     (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4212263508Sdim                                                  (v4i16 DPR:$Vm))))),
4213263508Sdim          (VQDMLALv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4214263508Sdimdef : Pat<(v2i64 (int_arm_neon_vqadds (v2i64 QPR:$src1),
4215263508Sdim                     (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4216263508Sdim                                                  (v2i32 DPR:$Vm))))),
4217263508Sdim          (VQDMLALv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4218263508Sdimdef : Pat<(v4i32 (int_arm_neon_vqadds (v4i32 QPR:$src1),
4219263508Sdim                     (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4220263508Sdim                                (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4221263508Sdim                                                     imm:$lane)))))),
4222263508Sdim          (VQDMLALslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;
4223263508Sdimdef : Pat<(v2i64 (int_arm_neon_vqadds (v2i64 QPR:$src1),
4224263508Sdim                     (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4225263508Sdim                                (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4226263508Sdim                                                     imm:$lane)))))),
4227263508Sdim          (VQDMLALslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;
4228263508Sdim
4229194710Sed//   VMLS     : Vector Multiply Subtract (integer and floating-point)
4230198090Srdivackydefm VMLS     : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
4231199989Srdivacky                             IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
4232199989Srdivackydef  VMLSfd   : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32",
4233218893Sdim                          v2f32, fmul_su, fsub_mlx>,
4234234353Sdim                Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4235199989Srdivackydef  VMLSfq   : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32",
4236218893Sdim                          v4f32, fmul_su, fsub_mlx>,
4237234353Sdim                Requires<[HasNEON, UseFPVMLx, DontUseFusedMAC]>;
4238198090Srdivackydefm VMLSsl   : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D,
4239199989Srdivacky                              IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
4240199989Srdivackydef  VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32",
4241218893Sdim                            v2f32, fmul_su, fsub_mlx>,
4242218893Sdim                Requires<[HasNEON, UseFPVMLx]>;
4243199989Srdivackydef  VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32",
4244218893Sdim                            v4f32, v2f32, fmul_su, fsub_mlx>,
4245218893Sdim                Requires<[HasNEON, UseFPVMLx]>;
4246198090Srdivacky
4247198090Srdivackydef : Pat<(v8i16 (sub (v8i16 QPR:$src1),
4248204642Srdivacky                  (mul (v8i16 QPR:$src2),
4249204642Srdivacky                       (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
4250204642Srdivacky          (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
4251198090Srdivacky                              (v4i16 (EXTRACT_SUBREG QPR:$src3,
4252204642Srdivacky                                      (DSubReg_i16_reg imm:$lane))),
4253198090Srdivacky                              (SubReg_i16_lane imm:$lane)))>;
4254198090Srdivacky
4255198090Srdivackydef : Pat<(v4i32 (sub (v4i32 QPR:$src1),
4256204642Srdivacky                  (mul (v4i32 QPR:$src2),
4257204642Srdivacky                     (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
4258204642Srdivacky          (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
4259198090Srdivacky                              (v2i32 (EXTRACT_SUBREG QPR:$src3,
4260204642Srdivacky                                      (DSubReg_i32_reg imm:$lane))),
4261198090Srdivacky                              (SubReg_i32_lane imm:$lane)))>;
4262198090Srdivacky
4263218893Sdimdef : Pat<(v4f32 (fsub_mlx (v4f32 QPR:$src1),
4264218893Sdim                  (fmul_su (v4f32 QPR:$src2),
4265204642Srdivacky                        (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
4266204642Srdivacky          (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2),
4267198090Srdivacky                           (v2f32 (EXTRACT_SUBREG QPR:$src3,
4268204642Srdivacky                                   (DSubReg_i32_reg imm:$lane))),
4269218893Sdim                           (SubReg_i32_lane imm:$lane)))>,
4270218893Sdim          Requires<[HasNEON, UseFPVMLx]>;
4271198090Srdivacky
4272194710Sed//   VMLSL    : Vector Multiply Subtract Long (Q -= D * D)
4273212904Sdimdefm VMLSLs   : N3VLMulOp_QHS<0,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,
4274212904Sdim                              "vmlsl", "s", NEONvmulls, sub>;
4275212904Sdimdefm VMLSLu   : N3VLMulOp_QHS<1,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D,
4276212904Sdim                              "vmlsl", "u", NEONvmullu, sub>;
4277198090Srdivacky
4278212904Sdimdefm VMLSLsls : N3VLMulOpSL_HS<0, 0b0110, "vmlsl", "s", NEONvmulls, sub>;
4279212904Sdimdefm VMLSLslu : N3VLMulOpSL_HS<1, 0b0110, "vmlsl", "u", NEONvmullu, sub>;
4280198090Srdivacky
4281194710Sed//   VQDMLSL  : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D)
4282207618Srdivackydefm VQDMLSL  : N3VLInt3_HS<0, 1, 0b1011, 0, IIC_VMACi16D, IIC_VMACi32D,
4283263508Sdim                            "vqdmlsl", "s", null_frag>;
4284263508Sdimdefm VQDMLSLsl: N3VLInt3SL_HS<0, 0b111, "vqdmlsl", "s", null_frag>;
4285194710Sed
4286263508Sdimdef : Pat<(v4i32 (int_arm_neon_vqsubs (v4i32 QPR:$src1),
4287263508Sdim                     (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4288263508Sdim                                                  (v4i16 DPR:$Vm))))),
4289263508Sdim          (VQDMLSLv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4290263508Sdimdef : Pat<(v2i64 (int_arm_neon_vqsubs (v2i64 QPR:$src1),
4291263508Sdim                     (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4292263508Sdim                                                  (v2i32 DPR:$Vm))))),
4293263508Sdim          (VQDMLSLv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>;
4294263508Sdimdef : Pat<(v4i32 (int_arm_neon_vqsubs (v4i32 QPR:$src1),
4295263508Sdim                     (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn),
4296263508Sdim                                (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
4297263508Sdim                                                     imm:$lane)))))),
4298263508Sdim          (VQDMLSLslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>;
4299263508Sdimdef : Pat<(v2i64 (int_arm_neon_vqsubs (v2i64 QPR:$src1),
4300263508Sdim                     (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn),
4301263508Sdim                                (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
4302263508Sdim                                                     imm:$lane)))))),
4303263508Sdim          (VQDMLSLslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>;
4304263508Sdim
4305234353Sdim// Fused Vector Multiply-Accumulate and Fused Multiply-Subtract Operations.
4306234353Sdimdef  VFMAfd   : N3VDMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACD, "vfma", "f32",
4307234353Sdim                          v2f32, fmul_su, fadd_mlx>,
4308263508Sdim                Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4309234353Sdim
4310234353Sdimdef  VFMAfq   : N3VQMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACQ, "vfma", "f32",
4311234353Sdim                          v4f32, fmul_su, fadd_mlx>,
4312263508Sdim                Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4313234353Sdim
4314234353Sdim//   Fused Vector Multiply Subtract (floating-point)
4315234353Sdimdef  VFMSfd   : N3VDMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACD, "vfms", "f32",
4316234353Sdim                          v2f32, fmul_su, fsub_mlx>,
4317263508Sdim                Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4318234353Sdimdef  VFMSfq   : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32",
4319234353Sdim                          v4f32, fmul_su, fsub_mlx>,
4320263508Sdim                Requires<[HasNEON,HasVFP4,UseFusedMAC]>;
4321234353Sdim
4322234353Sdim// Match @llvm.fma.* intrinsics
4323239462Sdimdef : Pat<(v2f32 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)),
4324234353Sdim          (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4325234353Sdim          Requires<[HasVFP4]>;
4326239462Sdimdef : Pat<(v4f32 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)),
4327234353Sdim          (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4328234353Sdim          Requires<[HasVFP4]>;
4329239462Sdimdef : Pat<(v2f32 (fma (fneg DPR:$Vn), DPR:$Vm, DPR:$src1)),
4330234353Sdim          (VFMSfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4331234353Sdim      Requires<[HasVFP4]>;
4332239462Sdimdef : Pat<(v4f32 (fma (fneg QPR:$Vn), QPR:$Vm, QPR:$src1)),
4333234353Sdim          (VFMSfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4334234353Sdim      Requires<[HasVFP4]>;
4335234353Sdim
4336194710Sed// Vector Subtract Operations.
4337194710Sed
4338194710Sed//   VSUB     : Vector Subtract (integer and floating-point)
4339199989Srdivackydefm VSUB     : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ,
4340199989Srdivacky                         "vsub", "i", sub, 0>;
4341199989Srdivackydef  VSUBfd   : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32",
4342199989Srdivacky                     v2f32, v2f32, fsub, 0>;
4343199989Srdivackydef  VSUBfq   : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32",
4344199989Srdivacky                     v4f32, v4f32, fsub, 0>;
4345194710Sed//   VSUBL    : Vector Subtract Long (Q = D - D)
4346212904Sdimdefm VSUBLs   : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
4347212904Sdim                            "vsubl", "s", sub, sext, 0>;
4348212904Sdimdefm VSUBLu   : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
4349212904Sdim                            "vsubl", "u", sub, zext, 0>;
4350194710Sed//   VSUBW    : Vector Subtract Wide (Q = Q - D)
4351212904Sdimdefm VSUBWs   : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>;
4352212904Sdimdefm VSUBWu   : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zext, 0>;
4353194710Sed//   VHSUB    : Vector Halving Subtract
4354206083Srdivackydefm VHSUBs   : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm,
4355207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4356199989Srdivacky                           "vhsub", "s", int_arm_neon_vhsubs, 0>;
4357206083Srdivackydefm VHSUBu   : N3VInt_QHS<1, 0, 0b0010, 0, N3RegFrm,
4358207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4359199989Srdivacky                           "vhsub", "u", int_arm_neon_vhsubu, 0>;
4360194710Sed//   VQSUB    : Vector Saturing Subtract
4361206083Srdivackydefm VQSUBs   : N3VInt_QHSD<0, 0, 0b0010, 1, N3RegFrm,
4362207618Srdivacky                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4363199989Srdivacky                            "vqsub", "s", int_arm_neon_vqsubs, 0>;
4364206083Srdivackydefm VQSUBu   : N3VInt_QHSD<1, 0, 0b0010, 1, N3RegFrm,
4365207618Srdivacky                            IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4366199989Srdivacky                            "vqsub", "u", int_arm_neon_vqsubu, 0>;
4367194710Sed//   VSUBHN   : Vector Subtract and Narrow Returning High Half (D = Q - Q)
4368263508Sdimdefm VSUBHN   : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i", null_frag, 0>;
4369194710Sed//   VRSUBHN  : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q)
4370199989Srdivackydefm VRSUBHN  : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i",
4371199989Srdivacky                            int_arm_neon_vrsubhn, 0>;
4372194710Sed
4373263508Sdimdef : Pat<(v8i8  (trunc (NEONvshru (sub (v8i16 QPR:$Vn), QPR:$Vm), 8))),
4374263508Sdim          (VSUBHNv8i8 QPR:$Vn, QPR:$Vm)>;
4375263508Sdimdef : Pat<(v4i16 (trunc (NEONvshru (sub (v4i32 QPR:$Vn), QPR:$Vm), 16))),
4376263508Sdim          (VSUBHNv4i16 QPR:$Vn, QPR:$Vm)>;
4377263508Sdimdef : Pat<(v2i32 (trunc (NEONvshru (sub (v2i64 QPR:$Vn), QPR:$Vm), 32))),
4378263508Sdim          (VSUBHNv2i32 QPR:$Vn, QPR:$Vm)>;
4379263508Sdim
4380194710Sed// Vector Comparisons.
4381194710Sed
4382194710Sed//   VCEQ     : Vector Compare Equal
4383207618Srdivackydefm VCEQ     : N3V_QHS<1, 0, 0b1000, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4384207618Srdivacky                        IIC_VSUBi4Q, "vceq", "i", NEONvceq, 1>;
4385199989Srdivackydef  VCEQfd   : N3VD<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32,
4386199989Srdivacky                     NEONvceq, 1>;
4387199989Srdivackydef  VCEQfq   : N3VQ<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32,
4388199989Srdivacky                     NEONvceq, 1>;
4389218893Sdim
4390249423Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in
4391204642Srdivackydefm VCEQz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i",
4392218893Sdim                            "$Vd, $Vm, #0", NEONvceqz>;
4393204642Srdivacky
4394194710Sed//   VCGE     : Vector Compare Greater Than or Equal
4395207618Srdivackydefm VCGEs    : N3V_QHS<0, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4396207618Srdivacky                        IIC_VSUBi4Q, "vcge", "s", NEONvcge, 0>;
4397218893Sdimdefm VCGEu    : N3V_QHS<1, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4398207618Srdivacky                        IIC_VSUBi4Q, "vcge", "u", NEONvcgeu, 0>;
4399206083Srdivackydef  VCGEfd   : N3VD<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32", v2i32, v2f32,
4400206083Srdivacky                     NEONvcge, 0>;
4401199989Srdivackydef  VCGEfq   : N3VQ<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32,
4402199989Srdivacky                     NEONvcge, 0>;
4403218893Sdim
4404249423Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in {
4405204642Srdivackydefm VCGEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s",
4406218893Sdim                            "$Vd, $Vm, #0", NEONvcgez>;
4407204642Srdivackydefm VCLEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s",
4408218893Sdim                            "$Vd, $Vm, #0", NEONvclez>;
4409249423Sdim}
4410204642Srdivacky
4411194710Sed//   VCGT     : Vector Compare Greater Than
4412207618Srdivackydefm VCGTs    : N3V_QHS<0, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4413207618Srdivacky                        IIC_VSUBi4Q, "vcgt", "s", NEONvcgt, 0>;
4414207618Srdivackydefm VCGTu    : N3V_QHS<1, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q,
4415207618Srdivacky                        IIC_VSUBi4Q, "vcgt", "u", NEONvcgtu, 0>;
4416199989Srdivackydef  VCGTfd   : N3VD<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32,
4417199989Srdivacky                     NEONvcgt, 0>;
4418199989Srdivackydef  VCGTfq   : N3VQ<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32,
4419199989Srdivacky                     NEONvcgt, 0>;
4420218893Sdim
4421249423Sdimlet TwoOperandAliasConstraint = "$Vm = $Vd" in {
4422204642Srdivackydefm VCGTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s",
4423218893Sdim                            "$Vd, $Vm, #0", NEONvcgtz>;
4424204642Srdivackydefm VCLTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s",
4425218893Sdim                            "$Vd, $Vm, #0", NEONvcltz>;
4426249423Sdim}
4427204642Srdivacky
4428194710Sed//   VACGE    : Vector Absolute Compare Greater Than or Equal (aka VCAGE)
4429206083Srdivackydef  VACGEd   : N3VDInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge",
4430206083Srdivacky                        "f32", v2i32, v2f32, int_arm_neon_vacged, 0>;
4431206083Srdivackydef  VACGEq   : N3VQInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge",
4432206083Srdivacky                        "f32", v4i32, v4f32, int_arm_neon_vacgeq, 0>;
4433194710Sed//   VACGT    : Vector Absolute Compare Greater Than (aka VCAGT)
4434206083Srdivackydef  VACGTd   : N3VDInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt",
4435206083Srdivacky                        "f32", v2i32, v2f32, int_arm_neon_vacgtd, 0>;
4436206083Srdivackydef  VACGTq   : N3VQInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt",
4437206083Srdivacky                        "f32", v4i32, v4f32, int_arm_neon_vacgtq, 0>;
4438194710Sed//   VTST     : Vector Test Bits
4439218893Sdimdefm VTST     : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
4440202878Srdivacky                        IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;
4441194710Sed
4442251662Sdimdef: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",
4443251662Sdim                   (VACGTd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
4444251662Sdimdef: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm",
4445251662Sdim                   (VACGTq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
4446251662Sdimdef: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",
4447251662Sdim                   (VACGEd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>;
4448251662Sdimdef: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm",
4449251662Sdim                   (VACGEq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>;
4450251662Sdim
4451251662Sdimdef: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",
4452251662Sdim                   (VACGTd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
4453251662Sdimdef: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm",
4454251662Sdim                   (VACGTq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
4455251662Sdimdef: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",
4456251662Sdim                   (VACGEd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>;
4457251662Sdimdef: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm",
4458251662Sdim                   (VACGEq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>;
4459251662Sdim
4460194710Sed// Vector Bitwise Operations.
4461194710Sed
4462210299Seddef vnotd : PatFrag<(ops node:$in),
4463210299Sed                    (xor node:$in, (bitconvert (v8i8 NEONimmAllOnesV)))>;
4464210299Seddef vnotq : PatFrag<(ops node:$in),
4465210299Sed                    (xor node:$in, (bitconvert (v16i8 NEONimmAllOnesV)))>;
4466206083Srdivacky
4467206083Srdivacky
4468194710Sed//   VAND     : Vector Bitwise AND
4469199989Srdivackydef  VANDd    : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand",
4470199989Srdivacky                      v2i32, v2i32, and, 1>;
4471199989Srdivackydef  VANDq    : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand",
4472199989Srdivacky                      v4i32, v4i32, and, 1>;
4473194710Sed
4474194710Sed//   VEOR     : Vector Bitwise Exclusive OR
4475199989Srdivackydef  VEORd    : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor",
4476199989Srdivacky                      v2i32, v2i32, xor, 1>;
4477199989Srdivackydef  VEORq    : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor",
4478199989Srdivacky                      v4i32, v4i32, xor, 1>;
4479194710Sed
4480194710Sed//   VORR     : Vector Bitwise OR
4481199989Srdivackydef  VORRd    : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr",
4482199989Srdivacky                      v2i32, v2i32, or, 1>;
4483199989Srdivackydef  VORRq    : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr",
4484199989Srdivacky                      v4i32, v4i32, or, 1>;
4485194710Sed
4486218893Sdimdef VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1,
4487234353Sdim                          (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
4488218893Sdim                          IIC_VMOVImm,
4489218893Sdim                          "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
4490218893Sdim                          [(set DPR:$Vd,
4491218893Sdim                            (v4i16 (NEONvorrImm DPR:$src, timm:$SIMM)))]> {
4492218893Sdim  let Inst{9} = SIMM{9};
4493218893Sdim}
4494218893Sdim
4495218893Sdimdef VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1,
4496234353Sdim                          (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),
4497218893Sdim                          IIC_VMOVImm,
4498218893Sdim                          "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",
4499218893Sdim                          [(set DPR:$Vd,
4500218893Sdim                            (v2i32 (NEONvorrImm DPR:$src, timm:$SIMM)))]> {
4501218893Sdim  let Inst{10-9} = SIMM{10-9};
4502218893Sdim}
4503218893Sdim
4504218893Sdimdef VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1,
4505234353Sdim                          (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
4506218893Sdim                          IIC_VMOVImm,
4507218893Sdim                          "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
4508218893Sdim                          [(set QPR:$Vd,
4509218893Sdim                            (v8i16 (NEONvorrImm QPR:$src, timm:$SIMM)))]> {
4510218893Sdim  let Inst{9} = SIMM{9};
4511218893Sdim}
4512218893Sdim
4513218893Sdimdef VORRiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 0, 1,
4514234353Sdim                          (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),
4515218893Sdim                          IIC_VMOVImm,
4516218893Sdim                          "vorr", "i32", "$Vd, $SIMM", "$src = $Vd",
4517218893Sdim                          [(set QPR:$Vd,
4518218893Sdim                            (v4i32 (NEONvorrImm QPR:$src, timm:$SIMM)))]> {
4519218893Sdim  let Inst{10-9} = SIMM{10-9};
4520218893Sdim}
4521218893Sdim
4522218893Sdim
4523194710Sed//   VBIC     : Vector Bitwise Bit Clear (AND NOT)
4524239462Sdimlet TwoOperandAliasConstraint = "$Vn = $Vd" in {
4525218893Sdimdef  VBICd    : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
4526218893Sdim                     (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,
4527218893Sdim                     "vbic", "$Vd, $Vn, $Vm", "",
4528218893Sdim                     [(set DPR:$Vd, (v2i32 (and DPR:$Vn,
4529218893Sdim                                                 (vnotd DPR:$Vm))))]>;
4530218893Sdimdef  VBICq    : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
4531218893Sdim                     (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,
4532218893Sdim                     "vbic", "$Vd, $Vn, $Vm", "",
4533218893Sdim                     [(set QPR:$Vd, (v4i32 (and QPR:$Vn,
4534218893Sdim                                                 (vnotq QPR:$Vm))))]>;
4535239462Sdim}
4536194710Sed
4537218893Sdimdef VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1,
4538234353Sdim                          (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
4539218893Sdim                          IIC_VMOVImm,
4540218893Sdim                          "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
4541218893Sdim                          [(set DPR:$Vd,
4542218893Sdim                            (v4i16 (NEONvbicImm DPR:$src, timm:$SIMM)))]> {
4543218893Sdim  let Inst{9} = SIMM{9};
4544218893Sdim}
4545218893Sdim
4546218893Sdimdef VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1,
4547234353Sdim                          (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src),
4548218893Sdim                          IIC_VMOVImm,
4549218893Sdim                          "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",
4550218893Sdim                          [(set DPR:$Vd,
4551218893Sdim                            (v2i32 (NEONvbicImm DPR:$src, timm:$SIMM)))]> {
4552218893Sdim  let Inst{10-9} = SIMM{10-9};
4553218893Sdim}
4554218893Sdim
4555218893Sdimdef VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1,
4556234353Sdim                          (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
4557218893Sdim                          IIC_VMOVImm,
4558218893Sdim                          "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
4559218893Sdim                          [(set QPR:$Vd,
4560218893Sdim                            (v8i16 (NEONvbicImm QPR:$src, timm:$SIMM)))]> {
4561218893Sdim  let Inst{9} = SIMM{9};
4562218893Sdim}
4563218893Sdim
4564218893Sdimdef VBICiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 1, 1,
4565234353Sdim                          (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src),
4566218893Sdim                          IIC_VMOVImm,
4567218893Sdim                          "vbic", "i32", "$Vd, $SIMM", "$src = $Vd",
4568218893Sdim                          [(set QPR:$Vd,
4569218893Sdim                            (v4i32 (NEONvbicImm QPR:$src, timm:$SIMM)))]> {
4570218893Sdim  let Inst{10-9} = SIMM{10-9};
4571218893Sdim}
4572218893Sdim
4573194710Sed//   VORN     : Vector Bitwise OR NOT
4574218893Sdimdef  VORNd    : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$Vd),
4575218893Sdim                     (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD,
4576218893Sdim                     "vorn", "$Vd, $Vn, $Vm", "",
4577218893Sdim                     [(set DPR:$Vd, (v2i32 (or DPR:$Vn,
4578218893Sdim                                                (vnotd DPR:$Vm))))]>;
4579218893Sdimdef  VORNq    : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd),
4580218893Sdim                     (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ,
4581218893Sdim                     "vorn", "$Vd, $Vn, $Vm", "",
4582218893Sdim                     [(set QPR:$Vd, (v4i32 (or QPR:$Vn,
4583218893Sdim                                                (vnotq QPR:$Vm))))]>;
4584194710Sed
4585210299Sed//   VMVN     : Vector Bitwise NOT (Immediate)
4586210299Sed
4587210299Sedlet isReMaterializable = 1 in {
4588218893Sdim
4589218893Sdimdef VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd),
4590234353Sdim                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
4591218893Sdim                         "vmvn", "i16", "$Vd, $SIMM", "",
4592218893Sdim                         [(set DPR:$Vd, (v4i16 (NEONvmvnImm timm:$SIMM)))]> {
4593218893Sdim  let Inst{9} = SIMM{9};
4594218893Sdim}
4595218893Sdim
4596218893Sdimdef VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd),
4597234353Sdim                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
4598218893Sdim                         "vmvn", "i16", "$Vd, $SIMM", "",
4599218893Sdim                         [(set QPR:$Vd, (v8i16 (NEONvmvnImm timm:$SIMM)))]> {
4600218893Sdim  let Inst{9} = SIMM{9};
4601218893Sdim}
4602210299Sed
4603218893Sdimdef VMVNv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 1, 1, (outs DPR:$Vd),
4604234353Sdim                         (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
4605218893Sdim                         "vmvn", "i32", "$Vd, $SIMM", "",
4606218893Sdim                         [(set DPR:$Vd, (v2i32 (NEONvmvnImm timm:$SIMM)))]> {
4607218893Sdim  let Inst{11-8} = SIMM{11-8};
4608218893Sdim}
4609218893Sdim
4610218893Sdimdef VMVNv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 1, 1, (outs QPR:$Vd),
4611234353Sdim                         (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
4612218893Sdim                         "vmvn", "i32", "$Vd, $SIMM", "",
4613218893Sdim                         [(set QPR:$Vd, (v4i32 (NEONvmvnImm timm:$SIMM)))]> {
4614218893Sdim  let Inst{11-8} = SIMM{11-8};
4615210299Sed}
4616218893Sdim}
4617210299Sed
4618194710Sed//   VMVN     : Vector Bitwise NOT
4619199989Srdivackydef  VMVNd    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0,
4620218893Sdim                     (outs DPR:$Vd), (ins DPR:$Vm), IIC_VSUBiD,
4621218893Sdim                     "vmvn", "$Vd, $Vm", "",
4622218893Sdim                     [(set DPR:$Vd, (v2i32 (vnotd DPR:$Vm)))]>;
4623199989Srdivackydef  VMVNq    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0,
4624218893Sdim                     (outs QPR:$Vd), (ins QPR:$Vm), IIC_VSUBiD,
4625218893Sdim                     "vmvn", "$Vd, $Vm", "",
4626218893Sdim                     [(set QPR:$Vd, (v4i32 (vnotq QPR:$Vm)))]>;
4627210299Seddef : Pat<(v2i32 (vnotd DPR:$src)), (VMVNd DPR:$src)>;
4628210299Seddef : Pat<(v4i32 (vnotq QPR:$src)), (VMVNq QPR:$src)>;
4629194710Sed
4630194710Sed//   VBSL     : Vector Bitwise Select
4631218893Sdimdef  VBSLd    : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
4632218893Sdim                     (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
4633206083Srdivacky                     N3RegFrm, IIC_VCNTiD,
4634218893Sdim                     "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4635224145Sdim                     [(set DPR:$Vd,
4636224145Sdim                           (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, DPR:$Vm)))]>;
4637243830Sdimdef : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 DPR:$src1),
4638243830Sdim                                   (v8i8 DPR:$Vn), (v8i8 DPR:$Vm))),
4639243830Sdim          (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4640243830Sdim        Requires<[HasNEON]>;
4641243830Sdimdef : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 DPR:$src1),
4642243830Sdim                                    (v4i16 DPR:$Vn), (v4i16 DPR:$Vm))),
4643243830Sdim          (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4644243830Sdim        Requires<[HasNEON]>;
4645243830Sdimdef : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 DPR:$src1),
4646243830Sdim                                    (v2i32 DPR:$Vn), (v2i32 DPR:$Vm))),
4647243830Sdim          (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4648243830Sdim        Requires<[HasNEON]>;
4649243830Sdimdef : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 DPR:$src1),
4650243830Sdim                                    (v2f32 DPR:$Vn), (v2f32 DPR:$Vm))),
4651243830Sdim          (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4652243830Sdim        Requires<[HasNEON]>;
4653243830Sdimdef : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 DPR:$src1),
4654243830Sdim                                    (v1i64 DPR:$Vn), (v1i64 DPR:$Vm))),
4655243830Sdim          (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
4656243830Sdim        Requires<[HasNEON]>;
4657221345Sdim
4658221345Sdimdef : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),
4659221345Sdim                     (and DPR:$Vm, (vnotd DPR:$Vd)))),
4660243830Sdim          (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>,
4661243830Sdim        Requires<[HasNEON]>;
4662221345Sdim
4663243830Sdimdef : Pat<(v1i64 (or (and DPR:$Vn, DPR:$Vd),
4664243830Sdim                     (and DPR:$Vm, (vnotd DPR:$Vd)))),
4665243830Sdim          (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>,
4666243830Sdim        Requires<[HasNEON]>;
4667243830Sdim
4668218893Sdimdef  VBSLq    : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
4669218893Sdim                     (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
4670206083Srdivacky                     N3RegFrm, IIC_VCNTiQ,
4671218893Sdim                     "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4672224145Sdim                     [(set QPR:$Vd,
4673224145Sdim                           (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, QPR:$Vm)))]>;
4674194710Sed
4675243830Sdimdef : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 QPR:$src1),
4676243830Sdim                                   (v16i8 QPR:$Vn), (v16i8 QPR:$Vm))),
4677243830Sdim          (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4678243830Sdim        Requires<[HasNEON]>;
4679243830Sdimdef : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 QPR:$src1),
4680243830Sdim                                    (v8i16 QPR:$Vn), (v8i16 QPR:$Vm))),
4681243830Sdim          (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4682243830Sdim        Requires<[HasNEON]>;
4683243830Sdimdef : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 QPR:$src1),
4684243830Sdim                                    (v4i32 QPR:$Vn), (v4i32 QPR:$Vm))),
4685243830Sdim          (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4686243830Sdim        Requires<[HasNEON]>;
4687243830Sdimdef : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 QPR:$src1),
4688243830Sdim                                    (v4f32 QPR:$Vn), (v4f32 QPR:$Vm))),
4689243830Sdim          (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4690243830Sdim        Requires<[HasNEON]>;
4691243830Sdimdef : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 QPR:$src1),
4692243830Sdim                                    (v2i64 QPR:$Vn), (v2i64 QPR:$Vm))),
4693243830Sdim          (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
4694243830Sdim        Requires<[HasNEON]>;
4695243830Sdim
4696221345Sdimdef : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),
4697221345Sdim                     (and QPR:$Vm, (vnotq QPR:$Vd)))),
4698243830Sdim          (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>,
4699243830Sdim        Requires<[HasNEON]>;
4700243830Sdimdef : Pat<(v2i64 (or (and QPR:$Vn, QPR:$Vd),
4701243830Sdim                     (and QPR:$Vm, (vnotq QPR:$Vd)))),
4702243830Sdim          (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>,
4703243830Sdim        Requires<[HasNEON]>;
4704221345Sdim
4705194710Sed//   VBIF     : Vector Bitwise Insert if False
4706199989Srdivacky//              like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
4707218893Sdim// FIXME: This instruction's encoding MAY NOT BE correct.
4708203954Srdivackydef  VBIFd    : N3VX<1, 0, 0b11, 0b0001, 0, 1,
4709218893Sdim                     (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
4710206083Srdivacky                     N3RegFrm, IIC_VBINiD,
4711218893Sdim                     "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4712234353Sdim                     []>;
4713203954Srdivackydef  VBIFq    : N3VX<1, 0, 0b11, 0b0001, 1, 1,
4714218893Sdim                     (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
4715206083Srdivacky                     N3RegFrm, IIC_VBINiQ,
4716218893Sdim                     "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4717234353Sdim                     []>;
4718203954Srdivacky
4719194710Sed//   VBIT     : Vector Bitwise Insert if True
4720199989Srdivacky//              like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst",
4721218893Sdim// FIXME: This instruction's encoding MAY NOT BE correct.
4722203954Srdivackydef  VBITd    : N3VX<1, 0, 0b10, 0b0001, 0, 1,
4723218893Sdim                     (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
4724206083Srdivacky                     N3RegFrm, IIC_VBINiD,
4725218893Sdim                     "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4726234353Sdim                     []>;
4727203954Srdivackydef  VBITq    : N3VX<1, 0, 0b10, 0b0001, 1, 1,
4728218893Sdim                     (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
4729206083Srdivacky                     N3RegFrm, IIC_VBINiQ,
4730218893Sdim                     "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd",
4731234353Sdim                     []>;
4732203954Srdivacky
4733203954Srdivacky// VBIT/VBIF are not yet implemented.  The TwoAddress pass will not go looking
4734194710Sed// for equivalent operations with different register constraints; it just
4735194710Sed// inserts copies.
4736194710Sed
4737194710Sed// Vector Absolute Differences.
4738194710Sed
4739194710Sed//   VABD     : Vector Absolute Difference
4740206083Srdivackydefm VABDs    : N3VInt_QHS<0, 0, 0b0111, 0, N3RegFrm,
4741207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4742212904Sdim                           "vabd", "s", int_arm_neon_vabds, 1>;
4743206083Srdivackydefm VABDu    : N3VInt_QHS<1, 0, 0b0111, 0, N3RegFrm,
4744207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4745212904Sdim                           "vabd", "u", int_arm_neon_vabdu, 1>;
4746206083Srdivackydef  VABDfd   : N3VDInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBIND,
4747212904Sdim                        "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 1>;
4748206083Srdivackydef  VABDfq   : N3VQInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBINQ,
4749212904Sdim                        "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 1>;
4750194710Sed
4751194710Sed//   VABDL    : Vector Absolute Difference Long (Q = | D - D |)
4752212904Sdimdefm VABDLs   : N3VLIntExt_QHS<0,1,0b0111,0, IIC_VSUBi4Q,
4753212904Sdim                               "vabdl", "s", int_arm_neon_vabds, zext, 1>;
4754212904Sdimdefm VABDLu   : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q,
4755212904Sdim                               "vabdl", "u", int_arm_neon_vabdu, zext, 1>;
4756194710Sed
4757194710Sed//   VABA     : Vector Absolute Difference and Accumulate
4758212904Sdimdefm VABAs    : N3VIntOp_QHS<0,0,0b0111,1, IIC_VABAD, IIC_VABAQ,
4759212904Sdim                             "vaba", "s", int_arm_neon_vabds, add>;
4760212904Sdimdefm VABAu    : N3VIntOp_QHS<1,0,0b0111,1, IIC_VABAD, IIC_VABAQ,
4761212904Sdim                             "vaba", "u", int_arm_neon_vabdu, add>;
4762194710Sed
4763194710Sed//   VABAL    : Vector Absolute Difference and Accumulate Long (Q += | D - D |)
4764212904Sdimdefm VABALs   : N3VLIntExtOp_QHS<0,1,0b0101,0, IIC_VABAD,
4765212904Sdim                                 "vabal", "s", int_arm_neon_vabds, zext, add>;
4766212904Sdimdefm VABALu   : N3VLIntExtOp_QHS<1,1,0b0101,0, IIC_VABAD,
4767212904Sdim                                 "vabal", "u", int_arm_neon_vabdu, zext, add>;
4768194710Sed
4769194710Sed// Vector Maximum and Minimum.
4770194710Sed
4771194710Sed//   VMAX     : Vector Maximum
4772206083Srdivackydefm VMAXs    : N3VInt_QHS<0, 0, 0b0110, 0, N3RegFrm,
4773207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4774206083Srdivacky                           "vmax", "s", int_arm_neon_vmaxs, 1>;
4775206083Srdivackydefm VMAXu    : N3VInt_QHS<1, 0, 0b0110, 0, N3RegFrm,
4776207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4777206083Srdivacky                           "vmax", "u", int_arm_neon_vmaxu, 1>;
4778207618Srdivackydef  VMAXfd   : N3VDInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBIND,
4779207618Srdivacky                        "vmax", "f32",
4780207618Srdivacky                        v2f32, v2f32, int_arm_neon_vmaxs, 1>;
4781207618Srdivackydef  VMAXfq   : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ,
4782207618Srdivacky                        "vmax", "f32",
4783207618Srdivacky                        v4f32, v4f32, int_arm_neon_vmaxs, 1>;
4784194710Sed
4785263508Sdim// VMAXNM
4786263508Sdimlet PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
4787263508Sdim  def VMAXNMND  : N3VDIntnp<0b00110, 0b00, 0b1111, 0, 1,
4788263508Sdim                            N3RegFrm, NoItinerary, "vmaxnm", "f32",
4789263508Sdim                            v2f32, v2f32, int_arm_neon_vmaxnm, 1>,
4790263508Sdim                            Requires<[HasV8, HasNEON]>;
4791263508Sdim  def VMAXNMNQ  : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1,
4792263508Sdim                            N3RegFrm, NoItinerary, "vmaxnm", "f32",
4793263508Sdim                            v4f32, v4f32, int_arm_neon_vmaxnm, 1>,
4794263508Sdim                            Requires<[HasV8, HasNEON]>;
4795263508Sdim}
4796263508Sdim
4797194710Sed//   VMIN     : Vector Minimum
4798206083Srdivackydefm VMINs    : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm,
4799207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4800206083Srdivacky                           "vmin", "s", int_arm_neon_vmins, 1>;
4801206083Srdivackydefm VMINu    : N3VInt_QHS<1, 0, 0b0110, 1, N3RegFrm,
4802207618Srdivacky                           IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
4803206083Srdivacky                           "vmin", "u", int_arm_neon_vminu, 1>;
4804207618Srdivackydef  VMINfd   : N3VDInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBIND,
4805207618Srdivacky                        "vmin", "f32",
4806207618Srdivacky                        v2f32, v2f32, int_arm_neon_vmins, 1>;
4807207618Srdivackydef  VMINfq   : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ,
4808207618Srdivacky                        "vmin", "f32",
4809207618Srdivacky                        v4f32, v4f32, int_arm_neon_vmins, 1>;
4810194710Sed
4811263508Sdim// VMINNM
4812263508Sdimlet PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
4813263508Sdim  def VMINNMND  : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1,
4814263508Sdim                            N3RegFrm, NoItinerary, "vminnm", "f32",
4815263508Sdim                            v2f32, v2f32, int_arm_neon_vminnm, 1>,
4816263508Sdim                            Requires<[HasV8, HasNEON]>;
4817263508Sdim  def VMINNMNQ  : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1,
4818263508Sdim                            N3RegFrm, NoItinerary, "vminnm", "f32",
4819263508Sdim                            v4f32, v4f32, int_arm_neon_vminnm, 1>,
4820263508Sdim                            Requires<[HasV8, HasNEON]>;
4821263508Sdim}
4822263508Sdim
4823194710Sed// Vector Pairwise Operations.
4824194710Sed
4825194710Sed//   VPADD    : Vector Pairwise Add
4826207618Srdivackydef  VPADDi8  : N3VDInt<0, 0, 0b00, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
4827207618Srdivacky                        "vpadd", "i8",
4828207618Srdivacky                        v8i8, v8i8, int_arm_neon_vpadd, 0>;
4829207618Srdivackydef  VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
4830207618Srdivacky                        "vpadd", "i16",
4831207618Srdivacky                        v4i16, v4i16, int_arm_neon_vpadd, 0>;
4832207618Srdivackydef  VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, N3RegFrm, IIC_VSHLiD,
4833207618Srdivacky                        "vpadd", "i32",
4834207618Srdivacky                        v2i32, v2i32, int_arm_neon_vpadd, 0>;
4835218893Sdimdef  VPADDf   : N3VDInt<1, 0, 0b00, 0b1101, 0, N3RegFrm,
4836218893Sdim                        IIC_VPBIND, "vpadd", "f32",
4837207618Srdivacky                        v2f32, v2f32, int_arm_neon_vpadd, 0>;
4838194710Sed
4839194710Sed//   VPADDL   : Vector Pairwise Add Long
4840199989Srdivackydefm VPADDLs  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s",
4841194710Sed                             int_arm_neon_vpaddls>;
4842199989Srdivackydefm VPADDLu  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u",
4843194710Sed                             int_arm_neon_vpaddlu>;
4844194710Sed
4845194710Sed//   VPADAL   : Vector Pairwise Add and Accumulate Long
4846199989Srdivackydefm VPADALs  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s",
4847194710Sed                              int_arm_neon_vpadals>;
4848199989Srdivackydefm VPADALu  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u",
4849194710Sed                              int_arm_neon_vpadalu>;
4850194710Sed
4851194710Sed//   VPMAX    : Vector Pairwise Maximum
4852207618Srdivackydef  VPMAXs8  : N3VDInt<0, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4853206083Srdivacky                        "s8", v8i8, v8i8, int_arm_neon_vpmaxs, 0>;
4854207618Srdivackydef  VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4855206083Srdivacky                        "s16", v4i16, v4i16, int_arm_neon_vpmaxs, 0>;
4856207618Srdivackydef  VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4857206083Srdivacky                        "s32", v2i32, v2i32, int_arm_neon_vpmaxs, 0>;
4858207618Srdivackydef  VPMAXu8  : N3VDInt<1, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4859206083Srdivacky                        "u8", v8i8, v8i8, int_arm_neon_vpmaxu, 0>;
4860207618Srdivackydef  VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4861206083Srdivacky                        "u16", v4i16, v4i16, int_arm_neon_vpmaxu, 0>;
4862207618Srdivackydef  VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax",
4863206083Srdivacky                        "u32", v2i32, v2i32, int_arm_neon_vpmaxu, 0>;
4864218893Sdimdef  VPMAXf   : N3VDInt<1, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax",
4865206083Srdivacky                        "f32", v2f32, v2f32, int_arm_neon_vpmaxs, 0>;
4866194710Sed
4867194710Sed//   VPMIN    : Vector Pairwise Minimum
4868207618Srdivackydef  VPMINs8  : N3VDInt<0, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4869206083Srdivacky                        "s8", v8i8, v8i8, int_arm_neon_vpmins, 0>;
4870207618Srdivackydef  VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4871206083Srdivacky                        "s16", v4i16, v4i16, int_arm_neon_vpmins, 0>;
4872207618Srdivackydef  VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4873206083Srdivacky                        "s32", v2i32, v2i32, int_arm_neon_vpmins, 0>;
4874207618Srdivackydef  VPMINu8  : N3VDInt<1, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4875206083Srdivacky                        "u8", v8i8, v8i8, int_arm_neon_vpminu, 0>;
4876207618Srdivackydef  VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4877206083Srdivacky                        "u16", v4i16, v4i16, int_arm_neon_vpminu, 0>;
4878207618Srdivackydef  VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin",
4879206083Srdivacky                        "u32", v2i32, v2i32, int_arm_neon_vpminu, 0>;
4880218893Sdimdef  VPMINf   : N3VDInt<1, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin",
4881206083Srdivacky                        "f32", v2f32, v2f32, int_arm_neon_vpmins, 0>;
4882194710Sed
4883194710Sed// Vector Reciprocal and Reciprocal Square Root Estimate and Step.
4884194710Sed
4885194710Sed//   VRECPE   : Vector Reciprocal Estimate
4886218893Sdimdef  VRECPEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,
4887199989Srdivacky                        IIC_VUNAD, "vrecpe", "u32",
4888194710Sed                        v2i32, v2i32, int_arm_neon_vrecpe>;
4889218893Sdimdef  VRECPEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0,
4890199989Srdivacky                        IIC_VUNAQ, "vrecpe", "u32",
4891194710Sed                        v4i32, v4i32, int_arm_neon_vrecpe>;
4892198090Srdivackydef  VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
4893199989Srdivacky                        IIC_VUNAD, "vrecpe", "f32",
4894198090Srdivacky                        v2f32, v2f32, int_arm_neon_vrecpe>;
4895198090Srdivackydef  VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
4896199989Srdivacky                        IIC_VUNAQ, "vrecpe", "f32",
4897198090Srdivacky                        v4f32, v4f32, int_arm_neon_vrecpe>;
4898194710Sed
4899194710Sed//   VRECPS   : Vector Reciprocal Step
4900206083Srdivackydef  VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,
4901199989Srdivacky                        IIC_VRECSD, "vrecps", "f32",
4902199989Srdivacky                        v2f32, v2f32, int_arm_neon_vrecps, 1>;
4903206083Srdivackydef  VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, N3RegFrm,
4904199989Srdivacky                        IIC_VRECSQ, "vrecps", "f32",
4905199989Srdivacky                        v4f32, v4f32, int_arm_neon_vrecps, 1>;
4906194710Sed
4907194710Sed//   VRSQRTE  : Vector Reciprocal Square Root Estimate
4908198090Srdivackydef  VRSQRTEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
4909199989Srdivacky                         IIC_VUNAD, "vrsqrte", "u32",
4910198090Srdivacky                         v2i32, v2i32, int_arm_neon_vrsqrte>;
4911198090Srdivackydef  VRSQRTEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
4912199989Srdivacky                         IIC_VUNAQ, "vrsqrte", "u32",
4913198090Srdivacky                         v4i32, v4i32, int_arm_neon_vrsqrte>;
4914198090Srdivackydef  VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,
4915199989Srdivacky                         IIC_VUNAD, "vrsqrte", "f32",
4916198090Srdivacky                         v2f32, v2f32, int_arm_neon_vrsqrte>;
4917218893Sdimdef  VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,
4918199989Srdivacky                         IIC_VUNAQ, "vrsqrte", "f32",
4919198090Srdivacky                         v4f32, v4f32, int_arm_neon_vrsqrte>;
4920194710Sed
4921194710Sed//   VRSQRTS  : Vector Reciprocal Square Root Step
4922206083Srdivackydef VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,
4923199989Srdivacky                        IIC_VRECSD, "vrsqrts", "f32",
4924199989Srdivacky                        v2f32, v2f32, int_arm_neon_vrsqrts, 1>;
4925206083Srdivackydef VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, N3RegFrm,
4926199989Srdivacky                        IIC_VRECSQ, "vrsqrts", "f32",
4927199989Srdivacky                        v4f32, v4f32, int_arm_neon_vrsqrts, 1>;
4928194710Sed
4929194710Sed// Vector Shifts.
4930194710Sed
4931194710Sed//   VSHL     : Vector Shift
4932218893Sdimdefm VSHLs    : N3VInt_QHSDSh<0, 0, 0b0100, 0, N3RegVShFrm,
4933206083Srdivacky                            IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,
4934218893Sdim                            "vshl", "s", int_arm_neon_vshifts>;
4935218893Sdimdefm VSHLu    : N3VInt_QHSDSh<1, 0, 0b0100, 0, N3RegVShFrm,
4936206083Srdivacky                            IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ,
4937218893Sdim                            "vshl", "u", int_arm_neon_vshiftu>;
4938221345Sdim
4939194710Sed//   VSHL     : Vector Shift Left (Immediate)
4940221345Sdimdefm VSHLi    : N2VShL_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>;
4941221345Sdim
4942194710Sed//   VSHR     : Vector Shift Right (Immediate)
4943234353Sdimdefm VSHRs    : N2VShR_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", "VSHRs",
4944234353Sdim                            NEONvshrs>;
4945234353Sdimdefm VSHRu    : N2VShR_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", "VSHRu",
4946234353Sdim                            NEONvshru>;
4947194710Sed
4948194710Sed//   VSHLL    : Vector Shift Left Long
4949199989Srdivackydefm VSHLLs   : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s", NEONvshlls>;
4950199989Srdivackydefm VSHLLu   : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u", NEONvshllu>;
4951194710Sed
4952194710Sed//   VSHLL    : Vector Shift Left Long (with maximum shift count)
4953198396Srdivackyclass N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
4954199989Srdivacky                bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy,
4955234353Sdim                ValueType OpTy, Operand ImmTy, SDNode OpNode>
4956199989Srdivacky  : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,
4957234353Sdim           ResTy, OpTy, ImmTy, OpNode> {
4958198396Srdivacky  let Inst{21-16} = op21_16;
4959226633Sdim  let DecoderMethod = "DecodeVSHLMaxInstruction";
4960198396Srdivacky}
4961199989Srdivackydef  VSHLLi8  : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",
4962234353Sdim                          v8i16, v8i8, imm8, NEONvshlli>;
4963199989Srdivackydef  VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16",
4964234353Sdim                          v4i32, v4i16, imm16, NEONvshlli>;
4965199989Srdivackydef  VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32",
4966234353Sdim                          v2i64, v2i32, imm32, NEONvshlli>;
4967194710Sed
4968194710Sed//   VSHRN    : Vector Shift Right and Narrow
4969204642Srdivackydefm VSHRN    : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i",
4970204642Srdivacky                           NEONvshrn>;
4971194710Sed
4972194710Sed//   VRSHL    : Vector Rounding Shift
4973218893Sdimdefm VRSHLs   : N3VInt_QHSDSh<0, 0, 0b0101, 0, N3RegVShFrm,
4974206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
4975218893Sdim                            "vrshl", "s", int_arm_neon_vrshifts>;
4976218893Sdimdefm VRSHLu   : N3VInt_QHSDSh<1, 0, 0b0101, 0, N3RegVShFrm,
4977206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
4978218893Sdim                            "vrshl", "u", int_arm_neon_vrshiftu>;
4979194710Sed//   VRSHR    : Vector Rounding Shift Right
4980234353Sdimdefm VRSHRs   : N2VShR_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", "VRSHRs",
4981234353Sdim                            NEONvrshrs>;
4982234353Sdimdefm VRSHRu   : N2VShR_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", "VRSHRu",
4983234353Sdim                            NEONvrshru>;
4984194710Sed
4985194710Sed//   VRSHRN   : Vector Rounding Shift Right and Narrow
4986199989Srdivackydefm VRSHRN   : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",
4987198396Srdivacky                           NEONvrshrn>;
4988194710Sed
4989194710Sed//   VQSHL    : Vector Saturating Shift
4990218893Sdimdefm VQSHLs   : N3VInt_QHSDSh<0, 0, 0b0100, 1, N3RegVShFrm,
4991206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
4992218893Sdim                            "vqshl", "s", int_arm_neon_vqshifts>;
4993218893Sdimdefm VQSHLu   : N3VInt_QHSDSh<1, 0, 0b0100, 1, N3RegVShFrm,
4994206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
4995218893Sdim                            "vqshl", "u", int_arm_neon_vqshiftu>;
4996194710Sed//   VQSHL    : Vector Saturating Shift Left (Immediate)
4997221345Sdimdefm VQSHLsi  : N2VShL_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s",NEONvqshls>;
4998221345Sdimdefm VQSHLui  : N2VShL_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u",NEONvqshlu>;
4999221345Sdim
5000194710Sed//   VQSHLU   : Vector Saturating Shift Left (Immediate, Unsigned)
5001221345Sdimdefm VQSHLsu  : N2VShL_QHSD<1,1,0b0110,1, IIC_VSHLi4D,"vqshlu","s",NEONvqshlsu>;
5002194710Sed
5003194710Sed//   VQSHRN   : Vector Saturating Shift Right and Narrow
5004199989Srdivackydefm VQSHRNs  : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",
5005198396Srdivacky                           NEONvqshrns>;
5006199989Srdivackydefm VQSHRNu  : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u",
5007198396Srdivacky                           NEONvqshrnu>;
5008194710Sed
5009194710Sed//   VQSHRUN  : Vector Saturating Shift Right and Narrow (Unsigned)
5010199989Srdivackydefm VQSHRUN  : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s",
5011198396Srdivacky                           NEONvqshrnsu>;
5012194710Sed
5013194710Sed//   VQRSHL   : Vector Saturating Rounding Shift
5014218893Sdimdefm VQRSHLs  : N3VInt_QHSDSh<0, 0, 0b0101, 1, N3RegVShFrm,
5015206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5016218893Sdim                            "vqrshl", "s", int_arm_neon_vqrshifts>;
5017218893Sdimdefm VQRSHLu  : N3VInt_QHSDSh<1, 0, 0b0101, 1, N3RegVShFrm,
5018206083Srdivacky                            IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q,
5019218893Sdim                            "vqrshl", "u", int_arm_neon_vqrshiftu>;
5020194710Sed
5021194710Sed//   VQRSHRN  : Vector Saturating Rounding Shift Right and Narrow
5022199989Srdivackydefm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s",
5023198396Srdivacky                           NEONvqrshrns>;
5024199989Srdivackydefm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u",
5025198396Srdivacky                           NEONvqrshrnu>;
5026194710Sed
5027194710Sed//   VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned)
5028199989Srdivackydefm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s",
5029198396Srdivacky                           NEONvqrshrnsu>;
5030194710Sed
5031194710Sed//   VSRA     : Vector Shift Right and Accumulate
5032199989Srdivackydefm VSRAs    : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", NEONvshrs>;
5033199989Srdivackydefm VSRAu    : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", NEONvshru>;
5034194710Sed//   VRSRA    : Vector Rounding Shift Right and Accumulate
5035199989Srdivackydefm VRSRAs   : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrs>;
5036199989Srdivackydefm VRSRAu   : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshru>;
5037194710Sed
5038194710Sed//   VSLI     : Vector Shift Left and Insert
5039221345Sdimdefm VSLI     : N2VShInsL_QHSD<1, 1, 0b0101, 1, "vsli">;
5040221345Sdim
5041194710Sed//   VSRI     : Vector Shift Right and Insert
5042221345Sdimdefm VSRI     : N2VShInsR_QHSD<1, 1, 0b0100, 1, "vsri">;
5043194710Sed
5044194710Sed// Vector Absolute and Saturating Absolute.
5045194710Sed
5046194710Sed//   VABS     : Vector Absolute Value
5047218893Sdimdefm VABS     : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0,
5048199989Srdivacky                           IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s",
5049194710Sed                           int_arm_neon_vabs>;
5050249423Sdimdef  VABSfd   : N2VD<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
5051249423Sdim                     "vabs", "f32",
5052249423Sdim                     v2f32, v2f32, fabs>;
5053249423Sdimdef  VABSfq   : N2VQ<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
5054249423Sdim                     "vabs", "f32",
5055249423Sdim                      v4f32, v4f32, fabs>;
5056194710Sed
5057251662Sdimdef : Pat<(xor (v2i32 (bitconvert (v8i8 (NEONvshrs DPR:$src, (i32 7))))),
5058251662Sdim               (v2i32 (bitconvert (v8i8 (add DPR:$src,
5059251662Sdim                                             (NEONvshrs DPR:$src, (i32 7))))))),
5060251662Sdim          (VABSv8i8 DPR:$src)>;
5061251662Sdimdef : Pat<(xor (v2i32 (bitconvert (v4i16 (NEONvshrs DPR:$src, (i32 15))))),
5062251662Sdim               (v2i32 (bitconvert (v4i16 (add DPR:$src,
5063251662Sdim                                            (NEONvshrs DPR:$src, (i32 15))))))),
5064251662Sdim          (VABSv4i16 DPR:$src)>;
5065251662Sdimdef : Pat<(xor (v2i32 (NEONvshrs DPR:$src, (i32 31))),
5066251662Sdim               (v2i32 (add DPR:$src, (NEONvshrs DPR:$src, (i32 31))))),
5067251662Sdim          (VABSv2i32 DPR:$src)>;
5068251662Sdimdef : Pat<(xor (v4i32 (bitconvert (v16i8 (NEONvshrs QPR:$src, (i32 7))))),
5069251662Sdim               (v4i32 (bitconvert (v16i8 (add QPR:$src,
5070251662Sdim                                             (NEONvshrs QPR:$src, (i32 7))))))),
5071251662Sdim          (VABSv16i8 QPR:$src)>;
5072251662Sdimdef : Pat<(xor (v4i32 (bitconvert (v8i16 (NEONvshrs QPR:$src, (i32 15))))),
5073251662Sdim               (v4i32 (bitconvert (v8i16 (add QPR:$src,
5074251662Sdim                                            (NEONvshrs QPR:$src, (i32 15))))))),
5075251662Sdim          (VABSv8i16 QPR:$src)>;
5076251662Sdimdef : Pat<(xor (v4i32 (NEONvshrs QPR:$src, (i32 31))),
5077251662Sdim               (v4i32 (add QPR:$src, (NEONvshrs QPR:$src, (i32 31))))),
5078251662Sdim          (VABSv4i32 QPR:$src)>;
5079251662Sdim
5080249423Sdimdef : Pat<(v2f32 (int_arm_neon_vabs (v2f32 DPR:$src))), (VABSfd DPR:$src)>;
5081249423Sdimdef : Pat<(v4f32 (int_arm_neon_vabs (v4f32 QPR:$src))), (VABSfq QPR:$src)>;
5082249423Sdim
5083194710Sed//   VQABS    : Vector Saturating Absolute Value
5084218893Sdimdefm VQABS    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0,
5085199989Srdivacky                           IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s",
5086194710Sed                           int_arm_neon_vqabs>;
5087194710Sed
5088194710Sed// Vector Negate.
5089194710Sed
5090210299Seddef vnegd  : PatFrag<(ops node:$in),
5091210299Sed                     (sub (bitconvert (v2i32 NEONimmAllZerosV)), node:$in)>;
5092210299Seddef vnegq  : PatFrag<(ops node:$in),
5093210299Sed                     (sub (bitconvert (v4i32 NEONimmAllZerosV)), node:$in)>;
5094194710Sed
5095199989Srdivackyclass VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
5096218893Sdim  : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm),
5097218893Sdim        IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "",
5098218893Sdim        [(set DPR:$Vd, (Ty (vnegd DPR:$Vm)))]>;
5099199989Srdivackyclass VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
5100218893Sdim  : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$Vd), (ins QPR:$Vm),
5101218893Sdim        IIC_VSHLiQ, OpcodeStr, Dt, "$Vd, $Vm", "",
5102218893Sdim        [(set QPR:$Vd, (Ty (vnegq QPR:$Vm)))]>;
5103194710Sed
5104206083Srdivacky//   VNEG     : Vector Negate (integer)
5105199989Srdivackydef  VNEGs8d  : VNEGD<0b00, "vneg", "s8", v8i8>;
5106199989Srdivackydef  VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>;
5107199989Srdivackydef  VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>;
5108199989Srdivackydef  VNEGs8q  : VNEGQ<0b00, "vneg", "s8", v16i8>;
5109199989Srdivackydef  VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>;
5110199989Srdivackydef  VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>;
5111194710Sed
5112194710Sed//   VNEG     : Vector Negate (floating-point)
5113204642Srdivackydef  VNEGfd   : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
5114218893Sdim                    (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD,
5115218893Sdim                    "vneg", "f32", "$Vd, $Vm", "",
5116218893Sdim                    [(set DPR:$Vd, (v2f32 (fneg DPR:$Vm)))]>;
5117194710Seddef  VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0,
5118218893Sdim                    (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ,
5119218893Sdim                    "vneg", "f32", "$Vd, $Vm", "",
5120218893Sdim                    [(set QPR:$Vd, (v4f32 (fneg QPR:$Vm)))]>;
5121194710Sed
5122210299Seddef : Pat<(v8i8  (vnegd  DPR:$src)), (VNEGs8d DPR:$src)>;
5123210299Seddef : Pat<(v4i16 (vnegd  DPR:$src)), (VNEGs16d DPR:$src)>;
5124210299Seddef : Pat<(v2i32 (vnegd  DPR:$src)), (VNEGs32d DPR:$src)>;
5125210299Seddef : Pat<(v16i8 (vnegq QPR:$src)), (VNEGs8q QPR:$src)>;
5126210299Seddef : Pat<(v8i16 (vnegq QPR:$src)), (VNEGs16q QPR:$src)>;
5127210299Seddef : Pat<(v4i32 (vnegq QPR:$src)), (VNEGs32q QPR:$src)>;
5128194710Sed
5129194710Sed//   VQNEG    : Vector Saturating Negate
5130218893Sdimdefm VQNEG    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0,
5131199989Srdivacky                           IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s",
5132194710Sed                           int_arm_neon_vqneg>;
5133194710Sed
5134194710Sed// Vector Bit Counting Operations.
5135194710Sed
5136194710Sed//   VCLS     : Vector Count Leading Sign Bits
5137218893Sdimdefm VCLS     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0,
5138199989Srdivacky                           IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s",
5139194710Sed                           int_arm_neon_vcls>;
5140194710Sed//   VCLZ     : Vector Count Leading Zeros
5141218893Sdimdefm VCLZ     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0,
5142199989Srdivacky                           IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i",
5143239462Sdim                           ctlz>;
5144194710Sed//   VCNT     : Vector Count One Bits
5145218893Sdimdef  VCNTd    : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
5146199989Srdivacky                        IIC_VCNTiD, "vcnt", "8",
5147239462Sdim                        v8i8, v8i8, ctpop>;
5148198090Srdivackydef  VCNTq    : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
5149199989Srdivacky                        IIC_VCNTiQ, "vcnt", "8",
5150239462Sdim                        v16i8, v16i8, ctpop>;
5151194710Sed
5152234353Sdim// Vector Swap
5153204642Srdivackydef  VSWPd    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
5154234353Sdim                     (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2),
5155234353Sdim                     NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
5156234353Sdim                     []>;
5157204642Srdivackydef  VSWPq    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
5158234353Sdim                     (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2),
5159234353Sdim                     NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
5160234353Sdim                     []>;
5161204642Srdivacky
5162194710Sed// Vector Move Operations.
5163194710Sed
5164194710Sed//   VMOV     : Vector Move (Register)
5165263508Sdimdef : NEONInstAlias<"vmov${p} $Vd, $Vm",
5166263508Sdim                    (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;
5167263508Sdimdef : NEONInstAlias<"vmov${p} $Vd, $Vm",
5168263508Sdim                    (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;
5169194710Sed
5170194710Sed//   VMOV     : Vector Move (Immediate)
5171194710Sed
5172208599Srdivackylet isReMaterializable = 1 in {
5173218893Sdimdef VMOVv8i8  : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$Vd),
5174234353Sdim                         (ins nImmSplatI8:$SIMM), IIC_VMOVImm,
5175218893Sdim                         "vmov", "i8", "$Vd, $SIMM", "",
5176218893Sdim                         [(set DPR:$Vd, (v8i8 (NEONvmovImm timm:$SIMM)))]>;
5177218893Sdimdef VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd),
5178234353Sdim                         (ins nImmSplatI8:$SIMM), IIC_VMOVImm,
5179218893Sdim                         "vmov", "i8", "$Vd, $SIMM", "",
5180218893Sdim                         [(set QPR:$Vd, (v16i8 (NEONvmovImm timm:$SIMM)))]>;
5181194710Sed
5182218893Sdimdef VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd),
5183234353Sdim                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5184218893Sdim                         "vmov", "i16", "$Vd, $SIMM", "",
5185218893Sdim                         [(set DPR:$Vd, (v4i16 (NEONvmovImm timm:$SIMM)))]> {
5186218893Sdim  let Inst{9} = SIMM{9};
5187218893Sdim}
5188218893Sdim
5189218893Sdimdef VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd),
5190234353Sdim                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
5191218893Sdim                         "vmov", "i16", "$Vd, $SIMM", "",
5192218893Sdim                         [(set QPR:$Vd, (v8i16 (NEONvmovImm timm:$SIMM)))]> {
5193218893Sdim let Inst{9} = SIMM{9};
5194218893Sdim}
5195194710Sed
5196218893Sdimdef VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 0, 1, (outs DPR:$Vd),
5197234353Sdim                         (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5198218893Sdim                         "vmov", "i32", "$Vd, $SIMM", "",
5199218893Sdim                         [(set DPR:$Vd, (v2i32 (NEONvmovImm timm:$SIMM)))]> {
5200218893Sdim  let Inst{11-8} = SIMM{11-8};
5201218893Sdim}
5202218893Sdim
5203218893Sdimdef VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 0, 1, (outs QPR:$Vd),
5204234353Sdim                         (ins nImmVMOVI32:$SIMM), IIC_VMOVImm,
5205218893Sdim                         "vmov", "i32", "$Vd, $SIMM", "",
5206218893Sdim                         [(set QPR:$Vd, (v4i32 (NEONvmovImm timm:$SIMM)))]> {
5207218893Sdim  let Inst{11-8} = SIMM{11-8};
5208218893Sdim}
5209194710Sed
5210218893Sdimdef VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$Vd),
5211234353Sdim                         (ins nImmSplatI64:$SIMM), IIC_VMOVImm,
5212218893Sdim                         "vmov", "i64", "$Vd, $SIMM", "",
5213218893Sdim                         [(set DPR:$Vd, (v1i64 (NEONvmovImm timm:$SIMM)))]>;
5214218893Sdimdef VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$Vd),
5215234353Sdim                         (ins nImmSplatI64:$SIMM), IIC_VMOVImm,
5216218893Sdim                         "vmov", "i64", "$Vd, $SIMM", "",
5217218893Sdim                         [(set QPR:$Vd, (v2i64 (NEONvmovImm timm:$SIMM)))]>;
5218234353Sdim
5219234353Sdimdef VMOVv2f32 : N1ModImm<1, 0b000, 0b1111, 0, 0, 0, 1, (outs DPR:$Vd),
5220234353Sdim                         (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,
5221234353Sdim                         "vmov", "f32", "$Vd, $SIMM", "",
5222234353Sdim                         [(set DPR:$Vd, (v2f32 (NEONvmovFPImm timm:$SIMM)))]>;
5223234353Sdimdef VMOVv4f32 : N1ModImm<1, 0b000, 0b1111, 0, 1, 0, 1, (outs QPR:$Vd),
5224234353Sdim                         (ins nImmVMOVF32:$SIMM), IIC_VMOVImm,
5225234353Sdim                         "vmov", "f32", "$Vd, $SIMM", "",
5226234353Sdim                         [(set QPR:$Vd, (v4f32 (NEONvmovFPImm timm:$SIMM)))]>;
5227208599Srdivacky} // isReMaterializable
5228194710Sed
5229194710Sed//   VMOV     : Vector Get Lane (move scalar to ARM core register)
5230194710Sed
5231199989Srdivackydef VGETLNs8  : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?},
5232234353Sdim                          (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),
5233234353Sdim                          IIC_VMOVSI, "vmov", "s8", "$R, $V$lane",
5234218893Sdim                          [(set GPR:$R, (NEONvgetlanes (v8i8 DPR:$V),
5235218893Sdim                                           imm:$lane))]> {
5236218893Sdim  let Inst{21}  = lane{2};
5237218893Sdim  let Inst{6-5} = lane{1-0};
5238218893Sdim}
5239199989Srdivackydef VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1},
5240234353Sdim                          (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),
5241234353Sdim                          IIC_VMOVSI, "vmov", "s16", "$R, $V$lane",
5242218893Sdim                          [(set GPR:$R, (NEONvgetlanes (v4i16 DPR:$V),
5243218893Sdim                                           imm:$lane))]> {
5244218893Sdim  let Inst{21} = lane{1};
5245218893Sdim  let Inst{6}  = lane{0};
5246218893Sdim}
5247199989Srdivackydef VGETLNu8  : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?},
5248234353Sdim                          (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane),
5249234353Sdim                          IIC_VMOVSI, "vmov", "u8", "$R, $V$lane",
5250218893Sdim                          [(set GPR:$R, (NEONvgetlaneu (v8i8 DPR:$V),
5251218893Sdim                                           imm:$lane))]> {
5252218893Sdim  let Inst{21}  = lane{2};
5253218893Sdim  let Inst{6-5} = lane{1-0};
5254218893Sdim}
5255199989Srdivackydef VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1},
5256234353Sdim                          (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane),
5257234353Sdim                          IIC_VMOVSI, "vmov", "u16", "$R, $V$lane",
5258218893Sdim                          [(set GPR:$R, (NEONvgetlaneu (v4i16 DPR:$V),
5259218893Sdim                                           imm:$lane))]> {
5260218893Sdim  let Inst{21} = lane{1};
5261218893Sdim  let Inst{6}  = lane{0};
5262218893Sdim}
5263199989Srdivackydef VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00,
5264234353Sdim                          (outs GPR:$R), (ins DPR:$V, VectorIndex32:$lane),
5265234353Sdim                          IIC_VMOVSI, "vmov", "32", "$R, $V$lane",
5266218893Sdim                          [(set GPR:$R, (extractelt (v2i32 DPR:$V),
5267243830Sdim                                           imm:$lane))]>,
5268243830Sdim                Requires<[HasNEON, HasFastVGETLNi32]> {
5269218893Sdim  let Inst{21} = lane{0};
5270218893Sdim}
5271194710Sed// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td
5272194710Seddef : Pat<(NEONvgetlanes (v16i8 QPR:$src), imm:$lane),
5273194710Sed          (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src,
5274198090Srdivacky                           (DSubReg_i8_reg imm:$lane))),
5275194710Sed                     (SubReg_i8_lane imm:$lane))>;
5276194710Seddef : Pat<(NEONvgetlanes (v8i16 QPR:$src), imm:$lane),
5277194710Sed          (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src,
5278198090Srdivacky                             (DSubReg_i16_reg imm:$lane))),
5279194710Sed                     (SubReg_i16_lane imm:$lane))>;
5280194710Seddef : Pat<(NEONvgetlaneu (v16i8 QPR:$src), imm:$lane),
5281194710Sed          (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src,
5282198090Srdivacky                           (DSubReg_i8_reg imm:$lane))),
5283194710Sed                     (SubReg_i8_lane imm:$lane))>;
5284194710Seddef : Pat<(NEONvgetlaneu (v8i16 QPR:$src), imm:$lane),
5285194710Sed          (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src,
5286198090Srdivacky                             (DSubReg_i16_reg imm:$lane))),
5287194710Sed                     (SubReg_i16_lane imm:$lane))>;
5288194710Seddef : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
5289194710Sed          (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src,
5290198090Srdivacky                             (DSubReg_i32_reg imm:$lane))),
5291243830Sdim                     (SubReg_i32_lane imm:$lane))>,
5292243830Sdim      Requires<[HasNEON, HasFastVGETLNi32]>;
5293243830Sdimdef : Pat<(extractelt (v2i32 DPR:$src), imm:$lane),
5294243830Sdim          (COPY_TO_REGCLASS
5295243830Sdim            (i32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,
5296243830Sdim      Requires<[HasNEON, HasSlowVGETLNi32]>;
5297243830Sdimdef : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
5298243830Sdim          (COPY_TO_REGCLASS
5299243830Sdim            (i32 (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>,
5300243830Sdim      Requires<[HasNEON, HasSlowVGETLNi32]>;
5301198090Srdivackydef : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2),
5302204642Srdivacky          (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)),
5303198090Srdivacky                          (SSubReg_f32_reg imm:$src2))>;
5304198090Srdivackydef : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2),
5305204642Srdivacky          (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)),
5306198090Srdivacky                          (SSubReg_f32_reg imm:$src2))>;
5307194710Sed//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2),
5308198090Srdivacky//          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
5309194710Seddef : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2),
5310198090Srdivacky          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
5311194710Sed
5312194710Sed
5313194710Sed//   VMOV     : Vector Set Lane (move ARM core register to scalar)
5314194710Sed
5315218893Sdimlet Constraints = "$src1 = $V" in {
5316218893Sdimdef VSETLNi8  : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$V),
5317234353Sdim                          (ins DPR:$src1, GPR:$R, VectorIndex8:$lane),
5318234353Sdim                          IIC_VMOVISL, "vmov", "8", "$V$lane, $R",
5319218893Sdim                          [(set DPR:$V, (vector_insert (v8i8 DPR:$src1),
5320218893Sdim                                           GPR:$R, imm:$lane))]> {
5321218893Sdim  let Inst{21}  = lane{2};
5322218893Sdim  let Inst{6-5} = lane{1-0};
5323194710Sed}
5324218893Sdimdef VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$V),
5325234353Sdim                          (ins DPR:$src1, GPR:$R, VectorIndex16:$lane),
5326234353Sdim                          IIC_VMOVISL, "vmov", "16", "$V$lane, $R",
5327218893Sdim                          [(set DPR:$V, (vector_insert (v4i16 DPR:$src1),
5328218893Sdim                                           GPR:$R, imm:$lane))]> {
5329218893Sdim  let Inst{21} = lane{1};
5330218893Sdim  let Inst{6}  = lane{0};
5331218893Sdim}
5332218893Sdimdef VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V),
5333234353Sdim                          (ins DPR:$src1, GPR:$R, VectorIndex32:$lane),
5334234353Sdim                          IIC_VMOVISL, "vmov", "32", "$V$lane, $R",
5335218893Sdim                          [(set DPR:$V, (insertelt (v2i32 DPR:$src1),
5336218893Sdim                                           GPR:$R, imm:$lane))]> {
5337218893Sdim  let Inst{21} = lane{0};
5338218893Sdim}
5339218893Sdim}
5340194710Seddef : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane),
5341218893Sdim          (v16i8 (INSERT_SUBREG QPR:$src1,
5342204961Srdivacky                  (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,
5343198090Srdivacky                                   (DSubReg_i8_reg imm:$lane))),
5344204961Srdivacky                            GPR:$src2, (SubReg_i8_lane imm:$lane))),
5345198090Srdivacky                  (DSubReg_i8_reg imm:$lane)))>;
5346194710Seddef : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane),
5347218893Sdim          (v8i16 (INSERT_SUBREG QPR:$src1,
5348204961Srdivacky                  (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,
5349198090Srdivacky                                     (DSubReg_i16_reg imm:$lane))),
5350204961Srdivacky                             GPR:$src2, (SubReg_i16_lane imm:$lane))),
5351198090Srdivacky                  (DSubReg_i16_reg imm:$lane)))>;
5352194710Seddef : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane),
5353218893Sdim          (v4i32 (INSERT_SUBREG QPR:$src1,
5354204961Srdivacky                  (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,
5355198090Srdivacky                                     (DSubReg_i32_reg imm:$lane))),
5356204961Srdivacky                             GPR:$src2, (SubReg_i32_lane imm:$lane))),
5357198090Srdivacky                  (DSubReg_i32_reg imm:$lane)))>;
5358194710Sed
5359198090Srdivackydef : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)),
5360198892Srdivacky          (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)),
5361198892Srdivacky                                SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
5362198090Srdivackydef : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)),
5363198892Srdivacky          (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)),
5364198892Srdivacky                                SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
5365198090Srdivacky
5366194710Sed//def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
5367198090Srdivacky//          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
5368194710Seddef : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
5369198090Srdivacky          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
5370194710Sed
5371198090Srdivackydef : Pat<(v2f32 (scalar_to_vector SPR:$src)),
5372208599Srdivacky          (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
5373205218Srdivackydef : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))),
5374208599Srdivacky          (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>;
5375198090Srdivackydef : Pat<(v4f32 (scalar_to_vector SPR:$src)),
5376208599Srdivacky          (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
5377198090Srdivacky
5378198090Srdivackydef : Pat<(v8i8 (scalar_to_vector GPR:$src)),
5379198090Srdivacky          (VSETLNi8  (v8i8  (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
5380198090Srdivackydef : Pat<(v4i16 (scalar_to_vector GPR:$src)),
5381198090Srdivacky          (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
5382198090Srdivackydef : Pat<(v2i32 (scalar_to_vector GPR:$src)),
5383198090Srdivacky          (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
5384198090Srdivacky
5385198090Srdivackydef : Pat<(v16i8 (scalar_to_vector GPR:$src)),
5386198090Srdivacky          (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
5387198090Srdivacky                         (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
5388208599Srdivacky                         dsub_0)>;
5389198090Srdivackydef : Pat<(v8i16 (scalar_to_vector GPR:$src)),
5390198090Srdivacky          (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)),
5391198090Srdivacky                         (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
5392208599Srdivacky                         dsub_0)>;
5393198090Srdivackydef : Pat<(v4i32 (scalar_to_vector GPR:$src)),
5394198090Srdivacky          (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
5395198090Srdivacky                         (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
5396208599Srdivacky                         dsub_0)>;
5397198090Srdivacky
5398194710Sed//   VDUP     : Vector Duplicate (from ARM core register to all elements)
5399194710Sed
5400199989Srdivackyclass VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
5401218893Sdim  : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$V), (ins GPR:$R),
5402218893Sdim          IIC_VMOVIS, "vdup", Dt, "$V, $R",
5403218893Sdim          [(set DPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>;
5404199989Srdivackyclass VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
5405218893Sdim  : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$V), (ins GPR:$R),
5406218893Sdim          IIC_VMOVIS, "vdup", Dt, "$V, $R",
5407218893Sdim          [(set QPR:$V, (Ty (NEONvdup (i32 GPR:$R))))]>;
5408194710Sed
5409199989Srdivackydef  VDUP8d   : VDUPD<0b11101100, 0b00, "8", v8i8>;
5410199989Srdivackydef  VDUP16d  : VDUPD<0b11101000, 0b01, "16", v4i16>;
5411243830Sdimdef  VDUP32d  : VDUPD<0b11101000, 0b00, "32", v2i32>,
5412243830Sdim                Requires<[HasNEON, HasFastVDUP32]>;
5413199989Srdivackydef  VDUP8q   : VDUPQ<0b11101110, 0b00, "8", v16i8>;
5414199989Srdivackydef  VDUP16q  : VDUPQ<0b11101010, 0b01, "16", v8i16>;
5415199989Srdivackydef  VDUP32q  : VDUPQ<0b11101010, 0b00, "32", v4i32>;
5416194710Sed
5417243830Sdim// NEONvdup patterns for uarchs with fast VDUP.32.
5418243830Sdimdef : Pat<(v2f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32d GPR:$R)>,
5419243830Sdim      Requires<[HasNEON,HasFastVDUP32]>;
5420221345Sdimdef : Pat<(v4f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>;
5421194710Sed
5422243830Sdim// NEONvdup patterns for uarchs with slow VDUP.32 - use VMOVDRR instead.
5423243830Sdimdef : Pat<(v2i32 (NEONvdup (i32 GPR:$R))), (VMOVDRR GPR:$R, GPR:$R)>,
5424243830Sdim      Requires<[HasNEON,HasSlowVDUP32]>;
5425243830Sdimdef : Pat<(v2f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VMOVDRR GPR:$R, GPR:$R)>,
5426243830Sdim      Requires<[HasNEON,HasSlowVDUP32]>;
5427243830Sdim
5428194710Sed//   VDUP     : Vector Duplicate Lane (from scalar to all elements)
5429194710Sed
5430206083Srdivackyclass VDUPLND<bits<4> op19_16, string OpcodeStr, string Dt,
5431226633Sdim              ValueType Ty, Operand IdxTy>
5432226633Sdim  : NVDupLane<op19_16, 0, (outs DPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),
5433226633Sdim              IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane",
5434218893Sdim              [(set DPR:$Vd, (Ty (NEONvduplane (Ty DPR:$Vm), imm:$lane)))]>;
5435194710Sed
5436206083Srdivackyclass VDUPLNQ<bits<4> op19_16, string OpcodeStr, string Dt,
5437226633Sdim              ValueType ResTy, ValueType OpTy, Operand IdxTy>
5438226633Sdim  : NVDupLane<op19_16, 1, (outs QPR:$Vd), (ins DPR:$Vm, IdxTy:$lane),
5439226633Sdim              IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane",
5440218893Sdim              [(set QPR:$Vd, (ResTy (NEONvduplane (OpTy DPR:$Vm),
5441226633Sdim                                      VectorIndex32:$lane)))]>;
5442194710Sed
5443198396Srdivacky// Inst{19-16} is partially specified depending on the element size.
5444194710Sed
5445226633Sdimdef VDUPLN8d  : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> {
5446226633Sdim  bits<3> lane;
5447218893Sdim  let Inst{19-17} = lane{2-0};
5448218893Sdim}
5449226633Sdimdef VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> {
5450226633Sdim  bits<2> lane;
5451218893Sdim  let Inst{19-18} = lane{1-0};
5452218893Sdim}
5453226633Sdimdef VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> {
5454226633Sdim  bits<1> lane;
5455218893Sdim  let Inst{19} = lane{0};
5456218893Sdim}
5457226633Sdimdef VDUPLN8q  : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> {
5458226633Sdim  bits<3> lane;
5459218893Sdim  let Inst{19-17} = lane{2-0};
5460218893Sdim}
5461226633Sdimdef VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> {
5462226633Sdim  bits<2> lane;
5463218893Sdim  let Inst{19-18} = lane{1-0};
5464218893Sdim}
5465226633Sdimdef VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> {
5466226633Sdim  bits<1> lane;
5467218893Sdim  let Inst{19} = lane{0};
5468218893Sdim}
5469198396Srdivacky
5470221345Sdimdef : Pat<(v2f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)),
5471221345Sdim          (VDUPLN32d DPR:$Vm, imm:$lane)>;
5472221345Sdim
5473221345Sdimdef : Pat<(v4f32 (NEONvduplane (v2f32 DPR:$Vm), imm:$lane)),
5474221345Sdim          (VDUPLN32q DPR:$Vm, imm:$lane)>;
5475221345Sdim
5476198090Srdivackydef : Pat<(v16i8 (NEONvduplane (v16i8 QPR:$src), imm:$lane)),
5477198090Srdivacky          (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src,
5478198090Srdivacky                                  (DSubReg_i8_reg imm:$lane))),
5479198090Srdivacky                           (SubReg_i8_lane imm:$lane)))>;
5480198090Srdivackydef : Pat<(v8i16 (NEONvduplane (v8i16 QPR:$src), imm:$lane)),
5481198090Srdivacky          (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src,
5482198090Srdivacky                                    (DSubReg_i16_reg imm:$lane))),
5483198090Srdivacky                            (SubReg_i16_lane imm:$lane)))>;
5484198090Srdivackydef : Pat<(v4i32 (NEONvduplane (v4i32 QPR:$src), imm:$lane)),
5485198090Srdivacky          (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src,
5486198090Srdivacky                                    (DSubReg_i32_reg imm:$lane))),
5487198090Srdivacky                            (SubReg_i32_lane imm:$lane)))>;
5488198090Srdivackydef : Pat<(v4f32 (NEONvduplane (v4f32 QPR:$src), imm:$lane)),
5489221345Sdim          (v4f32 (VDUPLN32q (v2f32 (EXTRACT_SUBREG QPR:$src,
5490198090Srdivacky                                   (DSubReg_i32_reg imm:$lane))),
5491198090Srdivacky                           (SubReg_i32_lane imm:$lane)))>;
5492198090Srdivacky
5493218893Sdimdef  VDUPfdf : PseudoNeonI<(outs DPR:$dst), (ins SPR:$src), IIC_VMOVD, "",
5494199989Srdivacky                    [(set DPR:$dst, (v2f32 (NEONvdup (f32 SPR:$src))))]>;
5495218893Sdimdef  VDUPfqf : PseudoNeonI<(outs QPR:$dst), (ins SPR:$src), IIC_VMOVD, "",
5496199989Srdivacky                    [(set QPR:$dst, (v4f32 (NEONvdup (f32 SPR:$src))))]>;
5497198090Srdivacky
5498194710Sed//   VMOVN    : Vector Narrowing Move
5499218893Sdimdefm VMOVN    : N2VN_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVN,
5500212904Sdim                         "vmovn", "i", trunc>;
5501194710Sed//   VQMOVN   : Vector Saturating Narrowing Move
5502199989Srdivackydefm VQMOVNs  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD,
5503199989Srdivacky                            "vqmovn", "s", int_arm_neon_vqmovns>;
5504199989Srdivackydefm VQMOVNu  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD,
5505199989Srdivacky                            "vqmovn", "u", int_arm_neon_vqmovnu>;
5506199989Srdivackydefm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD,
5507199989Srdivacky                            "vqmovun", "s", int_arm_neon_vqmovnsu>;
5508194710Sed//   VMOVL    : Vector Lengthening Move
5509212904Sdimdefm VMOVLs   : N2VL_QHS<0b01,0b10100,0,1, "vmovl", "s", sext>;
5510212904Sdimdefm VMOVLu   : N2VL_QHS<0b11,0b10100,0,1, "vmovl", "u", zext>;
5511234353Sdimdef : Pat<(v8i16 (anyext (v8i8 DPR:$Vm))), (VMOVLuv8i16 DPR:$Vm)>;
5512234353Sdimdef : Pat<(v4i32 (anyext (v4i16 DPR:$Vm))), (VMOVLuv4i32 DPR:$Vm)>;
5513234353Sdimdef : Pat<(v2i64 (anyext (v2i32 DPR:$Vm))), (VMOVLuv2i64 DPR:$Vm)>;
5514194710Sed
5515194710Sed// Vector Conversions.
5516194710Sed
5517194710Sed//   VCVT     : Vector Convert Between Floating-Point and Integers
5518199989Srdivackydef  VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
5519194710Sed                     v2i32, v2f32, fp_to_sint>;
5520199989Srdivackydef  VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
5521194710Sed                     v2i32, v2f32, fp_to_uint>;
5522199989Srdivackydef  VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
5523194710Sed                     v2f32, v2i32, sint_to_fp>;
5524199989Srdivackydef  VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
5525194710Sed                     v2f32, v2i32, uint_to_fp>;
5526194710Sed
5527199989Srdivackydef  VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
5528194710Sed                     v4i32, v4f32, fp_to_sint>;
5529199989Srdivackydef  VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
5530194710Sed                     v4i32, v4f32, fp_to_uint>;
5531199989Srdivackydef  VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
5532194710Sed                     v4f32, v4i32, sint_to_fp>;
5533199989Srdivackydef  VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
5534194710Sed                     v4f32, v4i32, uint_to_fp>;
5535194710Sed
5536263508Sdim// VCVT{A, N, P, M}
5537263508Sdimmulticlass VCVT_FPI<string op, bits<3> op10_8, SDPatternOperator IntS,
5538263508Sdim                    SDPatternOperator IntU> {
5539263508Sdim  let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
5540263508Sdim    def SD : N2VDIntnp<0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
5541263508Sdim                       "s32.f32", v2i32, v2f32, IntS>, Requires<[HasV8, HasNEON]>;
5542263508Sdim    def SQ : N2VQIntnp<0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op),
5543263508Sdim                       "s32.f32", v4i32, v4f32, IntS>, Requires<[HasV8, HasNEON]>;
5544263508Sdim    def UD : N2VDIntnp<0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
5545263508Sdim                       "u32.f32", v2i32, v2f32, IntU>, Requires<[HasV8, HasNEON]>;
5546263508Sdim    def UQ : N2VQIntnp<0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op),
5547263508Sdim                       "u32.f32", v4i32, v4f32, IntU>, Requires<[HasV8, HasNEON]>;
5548263508Sdim  }
5549263508Sdim}
5550263508Sdim
5551263508Sdimdefm VCVTAN : VCVT_FPI<"a", 0b000, int_arm_neon_vcvtas, int_arm_neon_vcvtau>;
5552263508Sdimdefm VCVTNN : VCVT_FPI<"n", 0b001, int_arm_neon_vcvtns, int_arm_neon_vcvtnu>;
5553263508Sdimdefm VCVTPN : VCVT_FPI<"p", 0b010, int_arm_neon_vcvtps, int_arm_neon_vcvtpu>;
5554263508Sdimdefm VCVTMN : VCVT_FPI<"m", 0b011, int_arm_neon_vcvtms, int_arm_neon_vcvtmu>;
5555263508Sdim
5556194710Sed//   VCVT     : Vector Convert Between Floating-Point and Fixed-Point.
5557234353Sdimlet DecoderMethod = "DecodeVCVTD" in {
5558199989Srdivackydef VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
5559194710Sed                        v2i32, v2f32, int_arm_neon_vcvtfp2fxs>;
5560199989Srdivackydef VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
5561194710Sed                        v2i32, v2f32, int_arm_neon_vcvtfp2fxu>;
5562199989Srdivackydef VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
5563194710Sed                        v2f32, v2i32, int_arm_neon_vcvtfxs2fp>;
5564199989Srdivackydef VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
5565194710Sed                        v2f32, v2i32, int_arm_neon_vcvtfxu2fp>;
5566234353Sdim}
5567194710Sed
5568234353Sdimlet DecoderMethod = "DecodeVCVTQ" in {
5569199989Srdivackydef VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
5570194710Sed                        v4i32, v4f32, int_arm_neon_vcvtfp2fxs>;
5571199989Srdivackydef VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
5572194710Sed                        v4i32, v4f32, int_arm_neon_vcvtfp2fxu>;
5573199989Srdivackydef VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
5574194710Sed                        v4f32, v4i32, int_arm_neon_vcvtfxs2fp>;
5575199989Srdivackydef VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
5576194710Sed                        v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;
5577234353Sdim}
5578194710Sed
5579263508Sdimdef : NEONInstAlias<"vcvt${p}.s32.f32 $Dd, $Dm, #0", 
5580263508Sdim                    (VCVTf2sd DPR:$Dd, DPR:$Dm, pred:$p)>;
5581263508Sdimdef : NEONInstAlias<"vcvt${p}.u32.f32 $Dd, $Dm, #0", 
5582263508Sdim                    (VCVTf2ud DPR:$Dd, DPR:$Dm, pred:$p)>;
5583263508Sdimdef : NEONInstAlias<"vcvt${p}.f32.s32 $Dd, $Dm, #0", 
5584263508Sdim                    (VCVTs2fd DPR:$Dd, DPR:$Dm, pred:$p)>;
5585263508Sdimdef : NEONInstAlias<"vcvt${p}.f32.u32 $Dd, $Dm, #0", 
5586263508Sdim                    (VCVTu2fd DPR:$Dd, DPR:$Dm, pred:$p)>;
5587263508Sdim
5588263508Sdimdef : NEONInstAlias<"vcvt${p}.s32.f32 $Qd, $Qm, #0", 
5589263508Sdim                    (VCVTf2sq QPR:$Qd, QPR:$Qm, pred:$p)>;
5590263508Sdimdef : NEONInstAlias<"vcvt${p}.u32.f32 $Qd, $Qm, #0", 
5591263508Sdim                    (VCVTf2uq QPR:$Qd, QPR:$Qm, pred:$p)>;
5592263508Sdimdef : NEONInstAlias<"vcvt${p}.f32.s32 $Qd, $Qm, #0", 
5593263508Sdim                    (VCVTs2fq QPR:$Qd, QPR:$Qm, pred:$p)>;
5594263508Sdimdef : NEONInstAlias<"vcvt${p}.f32.u32 $Qd, $Qm, #0", 
5595263508Sdim                    (VCVTu2fq QPR:$Qd, QPR:$Qm, pred:$p)>;
5596263508Sdim
5597263508Sdim
5598218893Sdim//   VCVT     : Vector Convert Between Half-Precision and Single-Precision.
5599218893Sdimdef  VCVTf2h  : N2VNInt<0b11, 0b11, 0b01, 0b10, 0b01100, 0, 0,
5600218893Sdim                        IIC_VUNAQ, "vcvt", "f16.f32",
5601218893Sdim                        v4i16, v4f32, int_arm_neon_vcvtfp2hf>,
5602218893Sdim                Requires<[HasNEON, HasFP16]>;
5603218893Sdimdef  VCVTh2f  : N2VLInt<0b11, 0b11, 0b01, 0b10, 0b01110, 0, 0,
5604218893Sdim                        IIC_VUNAQ, "vcvt", "f32.f16",
5605218893Sdim                        v4f32, v4i16, int_arm_neon_vcvthf2fp>,
5606218893Sdim                Requires<[HasNEON, HasFP16]>;
5607218893Sdim
5608198090Srdivacky// Vector Reverse.
5609198090Srdivacky
5610198090Srdivacky//   VREV64   : Vector Reverse elements within 64-bit doublewords
5611198090Srdivacky
5612199989Srdivackyclass VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5613218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$Vd),
5614218893Sdim        (ins DPR:$Vm), IIC_VMOVD,
5615218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5616218893Sdim        [(set DPR:$Vd, (Ty (NEONvrev64 (Ty DPR:$Vm))))]>;
5617199989Srdivackyclass VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5618218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$Vd),
5619218893Sdim        (ins QPR:$Vm), IIC_VMOVQ,
5620218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5621218893Sdim        [(set QPR:$Vd, (Ty (NEONvrev64 (Ty QPR:$Vm))))]>;
5622198090Srdivacky
5623199989Srdivackydef VREV64d8  : VREV64D<0b00, "vrev64", "8", v8i8>;
5624199989Srdivackydef VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>;
5625199989Srdivackydef VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>;
5626221345Sdimdef : Pat<(v2f32 (NEONvrev64 (v2f32 DPR:$Vm))), (VREV64d32 DPR:$Vm)>;
5627198090Srdivacky
5628199989Srdivackydef VREV64q8  : VREV64Q<0b00, "vrev64", "8", v16i8>;
5629199989Srdivackydef VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>;
5630199989Srdivackydef VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>;
5631221345Sdimdef : Pat<(v4f32 (NEONvrev64 (v4f32 QPR:$Vm))), (VREV64q32 QPR:$Vm)>;
5632198090Srdivacky
5633198090Srdivacky//   VREV32   : Vector Reverse elements within 32-bit words
5634198090Srdivacky
5635199989Srdivackyclass VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5636218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$Vd),
5637218893Sdim        (ins DPR:$Vm), IIC_VMOVD,
5638218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5639218893Sdim        [(set DPR:$Vd, (Ty (NEONvrev32 (Ty DPR:$Vm))))]>;
5640199989Srdivackyclass VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5641218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$Vd),
5642218893Sdim        (ins QPR:$Vm), IIC_VMOVQ,
5643218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5644218893Sdim        [(set QPR:$Vd, (Ty (NEONvrev32 (Ty QPR:$Vm))))]>;
5645198090Srdivacky
5646199989Srdivackydef VREV32d8  : VREV32D<0b00, "vrev32", "8", v8i8>;
5647199989Srdivackydef VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>;
5648198090Srdivacky
5649199989Srdivackydef VREV32q8  : VREV32Q<0b00, "vrev32", "8", v16i8>;
5650199989Srdivackydef VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>;
5651198090Srdivacky
5652198090Srdivacky//   VREV16   : Vector Reverse elements within 16-bit halfwords
5653198090Srdivacky
5654199989Srdivackyclass VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5655218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$Vd),
5656218893Sdim        (ins DPR:$Vm), IIC_VMOVD,
5657218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5658218893Sdim        [(set DPR:$Vd, (Ty (NEONvrev16 (Ty DPR:$Vm))))]>;
5659199989Srdivackyclass VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
5660218893Sdim  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$Vd),
5661218893Sdim        (ins QPR:$Vm), IIC_VMOVQ,
5662218893Sdim        OpcodeStr, Dt, "$Vd, $Vm", "",
5663218893Sdim        [(set QPR:$Vd, (Ty (NEONvrev16 (Ty QPR:$Vm))))]>;
5664198090Srdivacky
5665199989Srdivackydef VREV16d8  : VREV16D<0b00, "vrev16", "8", v8i8>;
5666199989Srdivackydef VREV16q8  : VREV16Q<0b00, "vrev16", "8", v16i8>;
5667198090Srdivacky
5668198090Srdivacky// Other Vector Shuffles.
5669198090Srdivacky
5670218893Sdim//  Aligned extractions: really just dropping registers
5671218893Sdim
5672218893Sdimclass AlignedVEXTq<ValueType DestTy, ValueType SrcTy, SDNodeXForm LaneCVT>
5673218893Sdim      : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))),
5674218893Sdim             (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>;
5675218893Sdim
5676218893Sdimdef : AlignedVEXTq<v8i8, v16i8, DSubReg_i8_reg>;
5677218893Sdim
5678218893Sdimdef : AlignedVEXTq<v4i16, v8i16, DSubReg_i16_reg>;
5679218893Sdim
5680218893Sdimdef : AlignedVEXTq<v2i32, v4i32, DSubReg_i32_reg>;
5681218893Sdim
5682218893Sdimdef : AlignedVEXTq<v1i64, v2i64, DSubReg_f64_reg>;
5683218893Sdim
5684218893Sdimdef : AlignedVEXTq<v2f32, v4f32, DSubReg_i32_reg>;
5685218893Sdim
5686218893Sdim
5687198090Srdivacky//   VEXT     : Vector Extract
5688198090Srdivacky
5689239462Sdim
5690239462Sdim// All of these have a two-operand InstAlias.
5691239462Sdimlet TwoOperandAliasConstraint = "$Vn = $Vd" in {
5692234353Sdimclass VEXTd<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>
5693218893Sdim  : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd),
5694234353Sdim        (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm,
5695218893Sdim        IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",
5696218893Sdim        [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn),
5697234353Sdim                                     (Ty DPR:$Vm), imm:$index)))]> {
5698263508Sdim  bits<3> index;
5699263508Sdim  let Inst{11} = 0b0;
5700263508Sdim  let Inst{10-8} = index{2-0};
5701218893Sdim}
5702198090Srdivacky
5703234353Sdimclass VEXTq<string OpcodeStr, string Dt, ValueType Ty, Operand immTy>
5704218893Sdim  : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd),
5705234353Sdim        (ins QPR:$Vn, QPR:$Vm, imm0_15:$index), NVExtFrm,
5706218893Sdim        IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "",
5707218893Sdim        [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn),
5708234353Sdim                                     (Ty QPR:$Vm), imm:$index)))]> {
5709218893Sdim  bits<4> index;
5710218893Sdim  let Inst{11-8} = index{3-0};
5711218893Sdim}
5712239462Sdim}
5713198090Srdivacky
5714234353Sdimdef VEXTd8  : VEXTd<"vext", "8",  v8i8, imm0_7> {
5715263508Sdim  let Inst{10-8} = index{2-0};
5716218893Sdim}
5717234353Sdimdef VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> {
5718263508Sdim  let Inst{10-9} = index{1-0};
5719218893Sdim  let Inst{8}    = 0b0;
5720218893Sdim}
5721234353Sdimdef VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> {
5722263508Sdim  let Inst{10}     = index{0};
5723218893Sdim  let Inst{9-8}    = 0b00;
5724218893Sdim}
5725224145Sdimdef : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn),
5726224145Sdim                           (v2f32 DPR:$Vm),
5727224145Sdim                           (i32 imm:$index))),
5728224145Sdim          (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>;
5729223017Sdim
5730234353Sdimdef VEXTq8  : VEXTq<"vext", "8",  v16i8, imm0_15> {
5731218893Sdim  let Inst{11-8} = index{3-0};
5732218893Sdim}
5733234353Sdimdef VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> {
5734218893Sdim  let Inst{11-9} = index{2-0};
5735218893Sdim  let Inst{8}    = 0b0;
5736218893Sdim}
5737234353Sdimdef VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> {
5738218893Sdim  let Inst{11-10} = index{1-0};
5739218893Sdim  let Inst{9-8}    = 0b00;
5740218893Sdim}
5741234353Sdimdef VEXTq64 : VEXTq<"vext", "64", v2i64, imm0_1> {
5742234353Sdim  let Inst{11} = index{0};
5743234353Sdim  let Inst{10-8}    = 0b000;
5744234353Sdim}
5745224145Sdimdef : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn),
5746224145Sdim                           (v4f32 QPR:$Vm),
5747224145Sdim                           (i32 imm:$index))),
5748224145Sdim          (VEXTq32 QPR:$Vn, QPR:$Vm, imm:$index)>;
5749198090Srdivacky
5750198090Srdivacky//   VTRN     : Vector Transpose
5751198090Srdivacky
5752199989Srdivackydef  VTRNd8   : N2VDShuffle<0b00, 0b00001, "vtrn", "8">;
5753199989Srdivackydef  VTRNd16  : N2VDShuffle<0b01, 0b00001, "vtrn", "16">;
5754199989Srdivackydef  VTRNd32  : N2VDShuffle<0b10, 0b00001, "vtrn", "32">;
5755198090Srdivacky
5756199989Srdivackydef  VTRNq8   : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">;
5757199989Srdivackydef  VTRNq16  : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">;
5758199989Srdivackydef  VTRNq32  : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">;
5759198090Srdivacky
5760198090Srdivacky//   VUZP     : Vector Unzip (Deinterleave)
5761198090Srdivacky
5762199989Srdivackydef  VUZPd8   : N2VDShuffle<0b00, 0b00010, "vuzp", "8">;
5763199989Srdivackydef  VUZPd16  : N2VDShuffle<0b01, 0b00010, "vuzp", "16">;
5764234353Sdim// vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
5765234353Sdimdef : NEONInstAlias<"vuzp${p}.32 $Dd, $Dm",
5766234353Sdim                    (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;
5767198090Srdivacky
5768199989Srdivackydef  VUZPq8   : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">;
5769199989Srdivackydef  VUZPq16  : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">;
5770199989Srdivackydef  VUZPq32  : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">;
5771198090Srdivacky
5772198090Srdivacky//   VZIP     : Vector Zip (Interleave)
5773198090Srdivacky
5774199989Srdivackydef  VZIPd8   : N2VDShuffle<0b00, 0b00011, "vzip", "8">;
5775199989Srdivackydef  VZIPd16  : N2VDShuffle<0b01, 0b00011, "vzip", "16">;
5776234353Sdim// vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
5777234353Sdimdef : NEONInstAlias<"vzip${p}.32 $Dd, $Dm",
5778234353Sdim                    (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>;
5779198090Srdivacky
5780199989Srdivackydef  VZIPq8   : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">;
5781199989Srdivackydef  VZIPq16  : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">;
5782199989Srdivackydef  VZIPq32  : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">;
5783198090Srdivacky
5784198090Srdivacky// Vector Table Lookup and Table Extension.
5785198090Srdivacky
5786198090Srdivacky//   VTBL     : Vector Table Lookup
5787226633Sdimlet DecoderMethod = "DecodeTBLInstruction" in {
5788198090Srdivackydef  VTBL1
5789218893Sdim  : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd),
5790234353Sdim        (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,
5791234353Sdim        "vtbl", "8", "$Vd, $Vn, $Vm", "",
5792234353Sdim        [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 VecListOneD:$Vn, DPR:$Vm)))]>;
5793198090Srdivackylet hasExtraSrcRegAllocReq = 1 in {
5794198090Srdivackydef  VTBL2
5795218893Sdim  : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd),
5796234353Sdim        (ins VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB2,
5797234353Sdim        "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
5798198090Srdivackydef  VTBL3
5799218893Sdim  : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$Vd),
5800234353Sdim        (ins VecListThreeD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB3,
5801234353Sdim        "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
5802198090Srdivackydef  VTBL4
5803218893Sdim  : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$Vd),
5804234353Sdim        (ins VecListFourD:$Vn, DPR:$Vm),
5805206083Srdivacky        NVTBLFrm, IIC_VTB4,
5806234353Sdim        "vtbl", "8", "$Vd, $Vn, $Vm", "", []>;
5807198090Srdivacky} // hasExtraSrcRegAllocReq = 1
5808198090Srdivacky
5809218893Sdimdef  VTBL3Pseudo
5810218893Sdim  : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB3, "", []>;
5811218893Sdimdef  VTBL4Pseudo
5812218893Sdim  : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB4, "", []>;
5813218893Sdim
5814198090Srdivacky//   VTBX     : Vector Table Extension
5815198090Srdivackydef  VTBX1
5816218893Sdim  : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$Vd),
5817234353Sdim        (ins DPR:$orig, VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX1,
5818234353Sdim        "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd",
5819218893Sdim        [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbx1
5820234353Sdim                               DPR:$orig, VecListOneD:$Vn, DPR:$Vm)))]>;
5821198090Srdivackylet hasExtraSrcRegAllocReq = 1 in {
5822198090Srdivackydef  VTBX2
5823218893Sdim  : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$Vd),
5824234353Sdim        (ins DPR:$orig, VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX2,
5825234353Sdim        "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", []>;
5826198090Srdivackydef  VTBX3
5827218893Sdim  : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$Vd),
5828234353Sdim        (ins DPR:$orig, VecListThreeD:$Vn, DPR:$Vm),
5829206083Srdivacky        NVTBLFrm, IIC_VTBX3,
5830234353Sdim        "vtbx", "8", "$Vd, $Vn, $Vm",
5831218893Sdim        "$orig = $Vd", []>;
5832198090Srdivackydef  VTBX4
5833234353Sdim  : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$Vd),
5834234353Sdim        (ins DPR:$orig, VecListFourD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX4,
5835234353Sdim        "vtbx", "8", "$Vd, $Vn, $Vm",
5836218893Sdim        "$orig = $Vd", []>;
5837198090Srdivacky} // hasExtraSrcRegAllocReq = 1
5838198090Srdivacky
5839218893Sdimdef  VTBX3Pseudo
5840218893Sdim  : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),
5841218893Sdim                IIC_VTBX3, "$orig = $dst", []>;
5842218893Sdimdef  VTBX4Pseudo
5843218893Sdim  : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),
5844218893Sdim                IIC_VTBX4, "$orig = $dst", []>;
5845226633Sdim} // DecoderMethod = "DecodeTBLInstruction"
5846218893Sdim
5847263508Sdim// VRINT      : Vector Rounding
5848263508Sdimmulticlass VRINT_FPI<string op, bits<3> op9_7, SDPatternOperator Int> {
5849263508Sdim  let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
5850263508Sdim    def D : N2VDIntnp<0b10, 0b100, 0, NoItinerary,
5851263508Sdim                      !strconcat("vrint", op), "f32",
5852263508Sdim                      v2f32, v2f32, Int>, Requires<[HasV8, HasNEON]> {
5853263508Sdim      let Inst{9-7} = op9_7;
5854263508Sdim    }
5855263508Sdim    def Q : N2VQIntnp<0b10, 0b100, 0, NoItinerary,
5856263508Sdim                      !strconcat("vrint", op), "f32",
5857263508Sdim                      v4f32, v4f32, Int>, Requires<[HasV8, HasNEON]> {
5858263508Sdim      let Inst{9-7} = op9_7;
5859263508Sdim    }
5860263508Sdim  }
5861263508Sdim
5862263508Sdim  def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Dd, $Dm"),
5863263508Sdim                  (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm)>;
5864263508Sdim  def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Qd, $Qm"),
5865263508Sdim                  (!cast<Instruction>(NAME#"Q") QPR:$Qd, QPR:$Qm)>;
5866263508Sdim}
5867263508Sdim
5868263508Sdimdefm VRINTNN : VRINT_FPI<"n", 0b000, int_arm_neon_vrintn>;
5869263508Sdimdefm VRINTXN : VRINT_FPI<"x", 0b001, int_arm_neon_vrintx>;
5870263508Sdimdefm VRINTAN : VRINT_FPI<"a", 0b010, int_arm_neon_vrinta>;
5871263508Sdimdefm VRINTZN : VRINT_FPI<"z", 0b011, int_arm_neon_vrintz>;
5872263508Sdimdefm VRINTMN : VRINT_FPI<"m", 0b101, int_arm_neon_vrintm>;
5873263508Sdimdefm VRINTPN : VRINT_FPI<"p", 0b111, int_arm_neon_vrintp>;
5874263508Sdim
5875263508Sdim// Cryptography instructions
5876263508Sdimlet PostEncoderMethod = "NEONThumb2DataIPostEncoder",
5877263508Sdim    DecoderNamespace = "v8Crypto" in {
5878263508Sdim  class AES<string op, bit op7, bit op6, SDPatternOperator Int>
5879263508Sdim    : N2VQIntXnp<0b00, 0b00, 0b011, op6, op7, NoItinerary,
5880263508Sdim                 !strconcat("aes", op), "8", v16i8, v16i8, Int>,
5881263508Sdim      Requires<[HasV8, HasCrypto]>;
5882263508Sdim  class AES2Op<string op, bit op7, bit op6, SDPatternOperator Int>
5883263508Sdim    : N2VQIntX2np<0b00, 0b00, 0b011, op6, op7, NoItinerary,
5884263508Sdim                 !strconcat("aes", op), "8", v16i8, v16i8, Int>,
5885263508Sdim      Requires<[HasV8, HasCrypto]>;
5886263508Sdim  class N2SHA<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
5887263508Sdim              SDPatternOperator Int>
5888263508Sdim    : N2VQIntXnp<0b10, op17_16, op10_8, op6, op7, NoItinerary,
5889263508Sdim                 !strconcat("sha", op), "32", v4i32, v4i32, Int>,
5890263508Sdim      Requires<[HasV8, HasCrypto]>;
5891263508Sdim  class N2SHA2Op<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
5892263508Sdim              SDPatternOperator Int>
5893263508Sdim    : N2VQIntX2np<0b10, op17_16, op10_8, op6, op7, NoItinerary,
5894263508Sdim                 !strconcat("sha", op), "32", v4i32, v4i32, Int>,
5895263508Sdim      Requires<[HasV8, HasCrypto]>;
5896263508Sdim  class N3SHA3Op<string op, bits<5> op27_23, bits<2> op21_20, SDPatternOperator Int>
5897263508Sdim    : N3VQInt3np<op27_23, op21_20, 0b1100, 1, 0, N3RegFrm, NoItinerary,
5898263508Sdim                !strconcat("sha", op), "32", v4i32, v4i32, Int, 0>,
5899263508Sdim      Requires<[HasV8, HasCrypto]>;
5900263508Sdim}
5901263508Sdim
5902263508Sdimdef AESD : AES2Op<"d", 0, 1, int_arm_neon_aesd>;
5903263508Sdimdef AESE : AES2Op<"e", 0, 0, int_arm_neon_aese>;
5904263508Sdimdef AESIMC : AES<"imc", 1, 1, int_arm_neon_aesimc>;
5905263508Sdimdef AESMC : AES<"mc", 1, 0, int_arm_neon_aesmc>;
5906263508Sdim
5907263508Sdimdef SHA1H : N2SHA<"1h", 0b01, 0b010, 1, 1, int_arm_neon_sha1h>;
5908263508Sdimdef SHA1SU1 : N2SHA2Op<"1su1", 0b10, 0b011, 1, 0, int_arm_neon_sha1su1>;
5909263508Sdimdef SHA256SU0 : N2SHA2Op<"256su0", 0b10, 0b011, 1, 1, int_arm_neon_sha256su0>;
5910263508Sdimdef SHA1C : N3SHA3Op<"1c", 0b00100, 0b00, int_arm_neon_sha1c>;
5911263508Sdimdef SHA1M : N3SHA3Op<"1m", 0b00100, 0b10, int_arm_neon_sha1m>;
5912263508Sdimdef SHA1P : N3SHA3Op<"1p", 0b00100, 0b01, int_arm_neon_sha1p>;
5913263508Sdimdef SHA1SU0 : N3SHA3Op<"1su0", 0b00100, 0b11, int_arm_neon_sha1su0>;
5914263508Sdimdef SHA256H : N3SHA3Op<"256h", 0b00110, 0b00, int_arm_neon_sha256h>;
5915263508Sdimdef SHA256H2 : N3SHA3Op<"256h2", 0b00110, 0b01, int_arm_neon_sha256h2>;
5916263508Sdimdef SHA256SU1 : N3SHA3Op<"256su1", 0b00110, 0b10, int_arm_neon_sha256su1>;
5917263508Sdim
5918194710Sed//===----------------------------------------------------------------------===//
5919198090Srdivacky// NEON instructions for single-precision FP math
5920198090Srdivacky//===----------------------------------------------------------------------===//
5921198090Srdivacky
5922218893Sdimclass N2VSPat<SDNode OpNode, NeonI Inst>
5923218893Sdim  : NEONFPPat<(f32 (OpNode SPR:$a)),
5924218893Sdim              (EXTRACT_SUBREG
5925218893Sdim               (v2f32 (COPY_TO_REGCLASS (Inst
5926218893Sdim                (INSERT_SUBREG
5927218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5928218893Sdim                 SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>;
5929204642Srdivacky
5930204642Srdivackyclass N3VSPat<SDNode OpNode, NeonI Inst>
5931204642Srdivacky  : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
5932218893Sdim              (EXTRACT_SUBREG
5933218893Sdim               (v2f32 (COPY_TO_REGCLASS (Inst
5934218893Sdim                (INSERT_SUBREG
5935218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5936218893Sdim                 SPR:$a, ssub_0),
5937218893Sdim                (INSERT_SUBREG
5938218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5939218893Sdim                 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;
5940204642Srdivacky
5941204642Srdivackyclass N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>
5942204642Srdivacky  : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),
5943218893Sdim              (EXTRACT_SUBREG
5944218893Sdim               (v2f32 (COPY_TO_REGCLASS (Inst
5945218893Sdim                (INSERT_SUBREG
5946218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5947218893Sdim                 SPR:$acc, ssub_0),
5948218893Sdim                (INSERT_SUBREG
5949218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5950218893Sdim                 SPR:$a, ssub_0),
5951218893Sdim                (INSERT_SUBREG
5952218893Sdim                 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)),
5953218893Sdim                 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>;
5954204642Srdivacky
5955218893Sdimdef : N3VSPat<fadd, VADDfd>;
5956218893Sdimdef : N3VSPat<fsub, VSUBfd>;
5957218893Sdimdef : N3VSPat<fmul, VMULfd>;
5958218893Sdimdef : N3VSMulOpPat<fmul, fadd, VMLAfd>,
5959234353Sdim      Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>;
5960218893Sdimdef : N3VSMulOpPat<fmul, fsub, VMLSfd>,
5961234353Sdim      Requires<[HasNEON, UseNEONForFP, UseFPVMLx, DontUseFusedMAC]>;
5962234353Sdimdef : N3VSMulOpPat<fmul, fadd, VFMAfd>,
5963234353Sdim      Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;
5964234353Sdimdef : N3VSMulOpPat<fmul, fsub, VFMSfd>,
5965234353Sdim      Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>;
5966218893Sdimdef : N2VSPat<fabs, VABSfd>;
5967218893Sdimdef : N2VSPat<fneg, VNEGfd>;
5968218893Sdimdef : N3VSPat<NEONfmax, VMAXfd>;
5969218893Sdimdef : N3VSPat<NEONfmin, VMINfd>;
5970218893Sdimdef : N2VSPat<arm_ftosi, VCVTf2sd>;
5971218893Sdimdef : N2VSPat<arm_ftoui, VCVTf2ud>;
5972218893Sdimdef : N2VSPat<arm_sitof, VCVTs2fd>;
5973218893Sdimdef : N2VSPat<arm_uitof, VCVTu2fd>;
5974198090Srdivacky
5975243830Sdim// Prefer VMOVDRR for i32 -> f32 bitcasts, it can write all DPR registers.
5976243830Sdimdef : Pat<(f32 (bitconvert GPR:$a)),
5977243830Sdim          (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>,
5978243830Sdim        Requires<[HasNEON, DontUseVMOVSR]>;
5979243830Sdim
5980198090Srdivacky//===----------------------------------------------------------------------===//
5981194710Sed// Non-Instruction Patterns
5982194710Sed//===----------------------------------------------------------------------===//
5983194710Sed
5984194710Sed// bit_convert
5985194710Seddef : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>;
5986194710Seddef : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>;
5987194710Seddef : Pat<(v1i64 (bitconvert (v8i8  DPR:$src))), (v1i64 DPR:$src)>;
5988194710Seddef : Pat<(v1i64 (bitconvert (f64   DPR:$src))), (v1i64 DPR:$src)>;
5989194710Seddef : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>;
5990194710Seddef : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>;
5991194710Seddef : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>;
5992194710Seddef : Pat<(v2i32 (bitconvert (v8i8  DPR:$src))), (v2i32 DPR:$src)>;
5993194710Seddef : Pat<(v2i32 (bitconvert (f64   DPR:$src))), (v2i32 DPR:$src)>;
5994194710Seddef : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>;
5995194710Seddef : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>;
5996194710Seddef : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>;
5997194710Seddef : Pat<(v4i16 (bitconvert (v8i8  DPR:$src))), (v4i16 DPR:$src)>;
5998194710Seddef : Pat<(v4i16 (bitconvert (f64   DPR:$src))), (v4i16 DPR:$src)>;
5999194710Seddef : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>;
6000194710Seddef : Pat<(v8i8  (bitconvert (v1i64 DPR:$src))), (v8i8  DPR:$src)>;
6001194710Seddef : Pat<(v8i8  (bitconvert (v2i32 DPR:$src))), (v8i8  DPR:$src)>;
6002194710Seddef : Pat<(v8i8  (bitconvert (v4i16 DPR:$src))), (v8i8  DPR:$src)>;
6003194710Seddef : Pat<(v8i8  (bitconvert (f64   DPR:$src))), (v8i8  DPR:$src)>;
6004194710Seddef : Pat<(v8i8  (bitconvert (v2f32 DPR:$src))), (v8i8  DPR:$src)>;
6005194710Seddef : Pat<(f64   (bitconvert (v1i64 DPR:$src))), (f64   DPR:$src)>;
6006194710Seddef : Pat<(f64   (bitconvert (v2i32 DPR:$src))), (f64   DPR:$src)>;
6007194710Seddef : Pat<(f64   (bitconvert (v4i16 DPR:$src))), (f64   DPR:$src)>;
6008194710Seddef : Pat<(f64   (bitconvert (v8i8  DPR:$src))), (f64   DPR:$src)>;
6009194710Seddef : Pat<(f64   (bitconvert (v2f32 DPR:$src))), (f64   DPR:$src)>;
6010194710Seddef : Pat<(v2f32 (bitconvert (f64   DPR:$src))), (v2f32 DPR:$src)>;
6011194710Seddef : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>;
6012194710Seddef : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>;
6013194710Seddef : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>;
6014194710Seddef : Pat<(v2f32 (bitconvert (v8i8  DPR:$src))), (v2f32 DPR:$src)>;
6015194710Sed
6016194710Seddef : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>;
6017194710Seddef : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>;
6018194710Seddef : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>;
6019194710Seddef : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>;
6020194710Seddef : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>;
6021194710Seddef : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>;
6022194710Seddef : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>;
6023194710Seddef : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>;
6024194710Seddef : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>;
6025194710Seddef : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>;
6026194710Seddef : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>;
6027194710Seddef : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>;
6028194710Seddef : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>;
6029194710Seddef : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>;
6030194710Seddef : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>;
6031194710Seddef : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>;
6032194710Seddef : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>;
6033194710Seddef : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>;
6034194710Seddef : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>;
6035194710Seddef : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>;
6036194710Seddef : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>;
6037194710Seddef : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>;
6038194710Seddef : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>;
6039194710Seddef : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>;
6040194710Seddef : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>;
6041194710Seddef : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>;
6042194710Seddef : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>;
6043194710Seddef : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>;
6044194710Seddef : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>;
6045194710Seddef : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>;
6046234353Sdim
6047249423Sdim// Fold extracting an element out of a v2i32 into a vfp register.
6048249423Sdimdef : Pat<(f32 (bitconvert (i32 (extractelt (v2i32 DPR:$src), imm:$lane)))),
6049249423Sdim          (f32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>;
6050249423Sdim
6051234353Sdim// Vector lengthening move with load, matching extending loads.
6052234353Sdim
6053234353Sdim// extload, zextload and sextload for a standard lengthening load. Example:
6054239462Sdim// Lengthen_Single<"8", "i16", "8"> = 
6055239462Sdim//     Pat<(v8i16 (extloadvi8 addrmode6:$addr))
6056239462Sdim//         (VMOVLuv8i16 (VLD1d8 addrmode6:$addr,
6057239462Sdim//                              (f64 (IMPLICIT_DEF)), (i32 0)))>;
6058234353Sdimmulticlass Lengthen_Single<string DestLanes, string DestTy, string SrcTy> {
6059239462Sdim  let AddedComplexity = 10 in {
6060234353Sdim  def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6061239462Sdim                    (!cast<PatFrag>("extloadvi" # SrcTy) addrmode6:$addr)),
6062234353Sdim                  (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)
6063239462Sdim                    (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
6064239462Sdim
6065234353Sdim  def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6066239462Sdim                  (!cast<PatFrag>("zextloadvi" # SrcTy) addrmode6:$addr)),
6067234353Sdim                (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy)
6068239462Sdim                    (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
6069239462Sdim
6070234353Sdim  def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6071239462Sdim                  (!cast<PatFrag>("sextloadvi" # SrcTy) addrmode6:$addr)),
6072234353Sdim                (!cast<Instruction>("VMOVLsv" # DestLanes # DestTy)
6073239462Sdim                    (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>;
6074239462Sdim  }
6075234353Sdim}
6076234353Sdim
6077234353Sdim// extload, zextload and sextload for a lengthening load which only uses
6078234353Sdim// half the lanes available. Example:
6079234353Sdim// Lengthen_HalfSingle<"4", "i16", "8", "i16", "i8"> =
6080239462Sdim//     Pat<(v4i16 (extloadvi8 addrmode6oneL32:$addr)),
6081239462Sdim//         (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr, 
6082239462Sdim//                                      (f64 (IMPLICIT_DEF)), (i32 0))),
6083234353Sdim//                         dsub_0)>;
6084234353Sdimmulticlass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy,
6085234353Sdim                               string InsnLanes, string InsnTy> {
6086234353Sdim  def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6087239462Sdim                   (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
6088234353Sdim       (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
6089239462Sdim         (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6090234353Sdim         dsub_0)>;
6091234353Sdim  def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6092239462Sdim                   (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
6093234353Sdim       (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy)
6094239462Sdim         (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6095234353Sdim         dsub_0)>;
6096234353Sdim  def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6097239462Sdim                   (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
6098234353Sdim       (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy)
6099239462Sdim         (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6100234353Sdim         dsub_0)>;
6101234353Sdim}
6102234353Sdim
6103234353Sdim// extload, zextload and sextload for a lengthening load followed by another
6104234353Sdim// lengthening load, to quadruple the initial length.
6105234982Sdim//
6106239462Sdim// Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32"> =
6107239462Sdim//     Pat<(v4i32 (extloadvi8 addrmode6oneL32:$addr))
6108239462Sdim//         (EXTRACT_SUBREG (VMOVLuv4i32
6109239462Sdim//           (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr,
6110239462Sdim//                                                   (f64 (IMPLICIT_DEF)),
6111239462Sdim//                                                   (i32 0))),
6112234353Sdim//                           dsub_0)),
6113239462Sdim//           dsub_0)>;
6114234353Sdimmulticlass Lengthen_Double<string DestLanes, string DestTy, string SrcTy,
6115234353Sdim                           string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
6116234982Sdim                           string Insn2Ty> {
6117234353Sdim  def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6118239462Sdim                   (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)),
6119234982Sdim         (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
6120234982Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
6121239462Sdim             (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6122239462Sdim             dsub_0))>;
6123234982Sdim  def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6124239462Sdim                   (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)),
6125234982Sdim         (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
6126234982Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
6127239462Sdim             (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6128239462Sdim             dsub_0))>;
6129234982Sdim  def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6130239462Sdim                   (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)),
6131234982Sdim         (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
6132234982Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
6133239462Sdim             (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6134239462Sdim             dsub_0))>;
6135234982Sdim}
6136234982Sdim
6137234982Sdim// extload, zextload and sextload for a lengthening load followed by another
6138234982Sdim// lengthening load, to quadruple the initial length, but which ends up only
6139234982Sdim// requiring half the available lanes (a 64-bit outcome instead of a 128-bit).
6140234982Sdim//
6141234982Sdim// Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> =
6142239462Sdim// Pat<(v2i32 (extloadvi8 addrmode6:$addr))
6143239462Sdim//     (EXTRACT_SUBREG (VMOVLuv4i32
6144239462Sdim//       (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd16 addrmode6:$addr,
6145239462Sdim//                                               (f64 (IMPLICIT_DEF)), (i32 0))),
6146239462Sdim//                       dsub_0)),
6147239462Sdim//       dsub_0)>;
6148234982Sdimmulticlass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy,
6149234982Sdim                           string Insn1Lanes, string Insn1Ty, string Insn2Lanes,
6150234982Sdim                           string Insn2Ty> {
6151234982Sdim  def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6152239462Sdim                   (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)),
6153234353Sdim         (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
6154234353Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
6155239462Sdim             (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6156239462Sdim             dsub_0)),
6157234982Sdim          dsub_0)>;
6158234353Sdim  def _Z   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6159239462Sdim                   (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)),
6160234353Sdim         (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty)
6161234353Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty)
6162239462Sdim             (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6163239462Sdim             dsub_0)),
6164234982Sdim          dsub_0)>;
6165234353Sdim  def _S   : Pat<(!cast<ValueType>("v" # DestLanes # DestTy)
6166239462Sdim                   (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)),
6167234353Sdim         (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty)
6168234353Sdim           (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty)
6169239462Sdim             (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))),
6170239462Sdim             dsub_0)),
6171234982Sdim          dsub_0)>;
6172234353Sdim}
6173234353Sdim
6174239462Sdimdefm : Lengthen_Single<"8", "i16", "8">; // v8i8 -> v8i16
6175239462Sdimdefm : Lengthen_Single<"4", "i32", "16">; // v4i16 -> v4i32
6176239462Sdimdefm : Lengthen_Single<"2", "i64", "32">; // v2i32 -> v2i64
6177234353Sdim
6178234353Sdimdefm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i16
6179234353Sdimdefm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i32
6180234353Sdim
6181234982Sdim// Double lengthening - v4i8 -> v4i16 -> v4i32
6182234982Sdimdefm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">;
6183234353Sdim// v2i8 -> v2i16 -> v2i32
6184234982Sdimdefm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">;
6185234353Sdim// v2i16 -> v2i32 -> v2i64
6186234982Sdimdefm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">;
6187234353Sdim
6188234353Sdim// Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i64
6189239462Sdimdef : Pat<(v2i64 (extloadvi8 addrmode6:$addr)),
6190234353Sdim      (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
6191239462Sdim         (VLD1LNd16 addrmode6:$addr, 
6192239462Sdim                    (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
6193239462Sdimdef : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)),
6194234353Sdim      (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16
6195239462Sdim         (VLD1LNd16 addrmode6:$addr,
6196239462Sdim                    (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
6197239462Sdimdef : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)),
6198234353Sdim      (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16
6199239462Sdim         (VLD1LNd16 addrmode6:$addr,
6200239462Sdim                    (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
6201234353Sdim
6202234353Sdim//===----------------------------------------------------------------------===//
6203234353Sdim// Assembler aliases
6204234353Sdim//
6205234353Sdim
6206234353Sdimdef : VFP2InstAlias<"fmdhr${p} $Dd, $Rn",
6207234353Sdim                    (VSETLNi32 DPR:$Dd, GPR:$Rn, 1, pred:$p)>;
6208234353Sdimdef : VFP2InstAlias<"fmdlr${p} $Dd, $Rn",
6209234353Sdim                    (VSETLNi32 DPR:$Dd, GPR:$Rn, 0, pred:$p)>;
6210234353Sdim
6211234353Sdim// VAND/VBIC/VEOR/VORR accept but do not require a type suffix.
6212234353Sdimdefm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",
6213234353Sdim                         (VANDd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
6214234353Sdimdefm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm",
6215234353Sdim                         (VANDq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
6216234353Sdimdefm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",
6217234353Sdim                         (VBICd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
6218234353Sdimdefm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm",
6219234353Sdim                         (VBICq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
6220234353Sdimdefm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",
6221234353Sdim                         (VEORd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
6222234353Sdimdefm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm",
6223234353Sdim                         (VEORq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
6224234353Sdimdefm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",
6225234353Sdim                         (VORRd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
6226234353Sdimdefm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm",
6227234353Sdim                         (VORRq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
6228234353Sdim// ... two-operand aliases
6229234353Sdimdefm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",
6230234353Sdim                         (VANDd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
6231234353Sdimdefm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm",
6232234353Sdim                         (VANDq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
6233234353Sdimdefm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",
6234234353Sdim                         (VEORd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
6235234353Sdimdefm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm",
6236234353Sdim                         (VEORq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
6237234353Sdimdefm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",
6238234353Sdim                         (VORRd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>;
6239234353Sdimdefm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm",
6240234353Sdim                         (VORRq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>;
6241234353Sdim
6242234353Sdim// VLD1 single-lane pseudo-instructions. These need special handling for
6243234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6244234353Sdimdef VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr",
6245234353Sdim                 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6246234353Sdimdef VLD1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr",
6247234353Sdim                 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6248234353Sdimdef VLD1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr",
6249234353Sdim                 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6250234353Sdim
6251234353Sdimdef VLD1LNdWB_fixed_Asm_8 :
6252234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr!",
6253234353Sdim                 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6254234353Sdimdef VLD1LNdWB_fixed_Asm_16 :
6255234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr!",
6256234353Sdim                 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6257234353Sdimdef VLD1LNdWB_fixed_Asm_32 :
6258234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr!",
6259234353Sdim                 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6260234353Sdimdef VLD1LNdWB_register_Asm_8 :
6261234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr, $Rm",
6262234353Sdim                  (ins VecListOneDByteIndexed:$list, addrmode6:$addr,
6263234353Sdim                       rGPR:$Rm, pred:$p)>;
6264234353Sdimdef VLD1LNdWB_register_Asm_16 :
6265234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr, $Rm",
6266234353Sdim                  (ins VecListOneDHWordIndexed:$list, addrmode6:$addr,
6267234353Sdim                       rGPR:$Rm, pred:$p)>;
6268234353Sdimdef VLD1LNdWB_register_Asm_32 :
6269234353Sdim        NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr, $Rm",
6270234353Sdim                  (ins VecListOneDWordIndexed:$list, addrmode6:$addr,
6271234353Sdim                       rGPR:$Rm, pred:$p)>;
6272234353Sdim
6273234353Sdim
6274234353Sdim// VST1 single-lane pseudo-instructions. These need special handling for
6275234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6276234353Sdimdef VST1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr",
6277234353Sdim                 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6278234353Sdimdef VST1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr",
6279234353Sdim                 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6280234353Sdimdef VST1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr",
6281234353Sdim                 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6282234353Sdim
6283234353Sdimdef VST1LNdWB_fixed_Asm_8 :
6284234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr!",
6285234353Sdim                 (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6286234353Sdimdef VST1LNdWB_fixed_Asm_16 :
6287234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr!",
6288234353Sdim                 (ins VecListOneDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6289234353Sdimdef VST1LNdWB_fixed_Asm_32 :
6290234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr!",
6291234353Sdim                 (ins VecListOneDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6292234353Sdimdef VST1LNdWB_register_Asm_8 :
6293234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr, $Rm",
6294234353Sdim                  (ins VecListOneDByteIndexed:$list, addrmode6:$addr,
6295234353Sdim                       rGPR:$Rm, pred:$p)>;
6296234353Sdimdef VST1LNdWB_register_Asm_16 :
6297234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr, $Rm",
6298234353Sdim                  (ins VecListOneDHWordIndexed:$list, addrmode6:$addr,
6299234353Sdim                       rGPR:$Rm, pred:$p)>;
6300234353Sdimdef VST1LNdWB_register_Asm_32 :
6301234353Sdim        NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr, $Rm",
6302234353Sdim                  (ins VecListOneDWordIndexed:$list, addrmode6:$addr,
6303234353Sdim                       rGPR:$Rm, pred:$p)>;
6304234353Sdim
6305234353Sdim// VLD2 single-lane pseudo-instructions. These need special handling for
6306234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6307234353Sdimdef VLD2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr",
6308234353Sdim                 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6309234353Sdimdef VLD2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",
6310234353Sdim                 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6311234353Sdimdef VLD2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",
6312234353Sdim                 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6313234353Sdimdef VLD2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr",
6314234353Sdim                 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6315234353Sdimdef VLD2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr",
6316234353Sdim                 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6317234353Sdim
6318234353Sdimdef VLD2LNdWB_fixed_Asm_8 :
6319234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr!",
6320234353Sdim                 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6321234353Sdimdef VLD2LNdWB_fixed_Asm_16 :
6322234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",
6323234353Sdim                 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6324234353Sdimdef VLD2LNdWB_fixed_Asm_32 :
6325234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",
6326234353Sdim                 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6327234353Sdimdef VLD2LNqWB_fixed_Asm_16 :
6328234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!",
6329234353Sdim                 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6330234353Sdimdef VLD2LNqWB_fixed_Asm_32 :
6331234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!",
6332234353Sdim                 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6333234353Sdimdef VLD2LNdWB_register_Asm_8 :
6334234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr, $Rm",
6335234353Sdim                  (ins VecListTwoDByteIndexed:$list, addrmode6:$addr,
6336234353Sdim                       rGPR:$Rm, pred:$p)>;
6337234353Sdimdef VLD2LNdWB_register_Asm_16 :
6338234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",
6339234353Sdim                  (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr,
6340234353Sdim                       rGPR:$Rm, pred:$p)>;
6341234353Sdimdef VLD2LNdWB_register_Asm_32 :
6342234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",
6343234353Sdim                  (ins VecListTwoDWordIndexed:$list, addrmode6:$addr,
6344234353Sdim                       rGPR:$Rm, pred:$p)>;
6345234353Sdimdef VLD2LNqWB_register_Asm_16 :
6346234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm",
6347234353Sdim                  (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr,
6348234353Sdim                       rGPR:$Rm, pred:$p)>;
6349234353Sdimdef VLD2LNqWB_register_Asm_32 :
6350234353Sdim        NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm",
6351234353Sdim                  (ins VecListTwoQWordIndexed:$list, addrmode6:$addr,
6352234353Sdim                       rGPR:$Rm, pred:$p)>;
6353234353Sdim
6354234353Sdim
6355234353Sdim// VST2 single-lane pseudo-instructions. These need special handling for
6356234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6357234353Sdimdef VST2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr",
6358234353Sdim                 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6359234353Sdimdef VST2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",
6360234353Sdim                 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6361234353Sdimdef VST2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",
6362234353Sdim                 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6363234353Sdimdef VST2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr",
6364234353Sdim                 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6365234353Sdimdef VST2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr",
6366234353Sdim                 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6367234353Sdim
6368234353Sdimdef VST2LNdWB_fixed_Asm_8 :
6369234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr!",
6370234353Sdim                 (ins VecListTwoDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6371234353Sdimdef VST2LNdWB_fixed_Asm_16 :
6372234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",
6373234353Sdim                 (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6374234353Sdimdef VST2LNdWB_fixed_Asm_32 :
6375234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",
6376234353Sdim                 (ins VecListTwoDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6377234353Sdimdef VST2LNqWB_fixed_Asm_16 :
6378234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!",
6379234353Sdim                 (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6380234353Sdimdef VST2LNqWB_fixed_Asm_32 :
6381234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!",
6382234353Sdim                 (ins VecListTwoQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6383234353Sdimdef VST2LNdWB_register_Asm_8 :
6384234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr, $Rm",
6385234353Sdim                  (ins VecListTwoDByteIndexed:$list, addrmode6:$addr,
6386234353Sdim                       rGPR:$Rm, pred:$p)>;
6387234353Sdimdef VST2LNdWB_register_Asm_16 :
6388234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",
6389234353Sdim                  (ins VecListTwoDHWordIndexed:$list, addrmode6:$addr,
6390234353Sdim                       rGPR:$Rm, pred:$p)>;
6391234353Sdimdef VST2LNdWB_register_Asm_32 :
6392234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",
6393234353Sdim                  (ins VecListTwoDWordIndexed:$list, addrmode6:$addr,
6394234353Sdim                       rGPR:$Rm, pred:$p)>;
6395234353Sdimdef VST2LNqWB_register_Asm_16 :
6396234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm",
6397234353Sdim                  (ins VecListTwoQHWordIndexed:$list, addrmode6:$addr,
6398234353Sdim                       rGPR:$Rm, pred:$p)>;
6399234353Sdimdef VST2LNqWB_register_Asm_32 :
6400234353Sdim        NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm",
6401234353Sdim                  (ins VecListTwoQWordIndexed:$list, addrmode6:$addr,
6402234353Sdim                       rGPR:$Rm, pred:$p)>;
6403234353Sdim
6404234353Sdim// VLD3 all-lanes pseudo-instructions. These need special handling for
6405234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6406239462Sdimdef VLD3DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
6407234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6408239462Sdimdef VLD3DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6409234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6410239462Sdimdef VLD3DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6411234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6412239462Sdimdef VLD3DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
6413234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6414239462Sdimdef VLD3DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6415234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6416239462Sdimdef VLD3DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6417234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6418234353Sdim
6419234353Sdimdef VLD3DUPdWB_fixed_Asm_8 :
6420234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
6421234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6422234353Sdimdef VLD3DUPdWB_fixed_Asm_16 :
6423234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6424234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6425234353Sdimdef VLD3DUPdWB_fixed_Asm_32 :
6426234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6427234353Sdim               (ins VecListThreeDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6428234353Sdimdef VLD3DUPqWB_fixed_Asm_8 :
6429234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
6430234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6431234353Sdimdef VLD3DUPqWB_fixed_Asm_16 :
6432234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6433234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6434234353Sdimdef VLD3DUPqWB_fixed_Asm_32 :
6435234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6436234353Sdim               (ins VecListThreeQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6437234353Sdimdef VLD3DUPdWB_register_Asm_8 :
6438234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
6439234353Sdim                  (ins VecListThreeDAllLanes:$list, addrmode6:$addr,
6440234353Sdim                       rGPR:$Rm, pred:$p)>;
6441234353Sdimdef VLD3DUPdWB_register_Asm_16 :
6442234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6443234353Sdim                  (ins VecListThreeDAllLanes:$list, addrmode6:$addr,
6444234353Sdim                       rGPR:$Rm, pred:$p)>;
6445234353Sdimdef VLD3DUPdWB_register_Asm_32 :
6446234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6447234353Sdim                  (ins VecListThreeDAllLanes:$list, addrmode6:$addr,
6448234353Sdim                       rGPR:$Rm, pred:$p)>;
6449234353Sdimdef VLD3DUPqWB_register_Asm_8 :
6450234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
6451234353Sdim                  (ins VecListThreeQAllLanes:$list, addrmode6:$addr,
6452234353Sdim                       rGPR:$Rm, pred:$p)>;
6453234353Sdimdef VLD3DUPqWB_register_Asm_16 :
6454234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6455234353Sdim                  (ins VecListThreeQAllLanes:$list, addrmode6:$addr,
6456234353Sdim                       rGPR:$Rm, pred:$p)>;
6457234353Sdimdef VLD3DUPqWB_register_Asm_32 :
6458234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6459234353Sdim                  (ins VecListThreeQAllLanes:$list, addrmode6:$addr,
6460234353Sdim                       rGPR:$Rm, pred:$p)>;
6461234353Sdim
6462234353Sdim
6463234353Sdim// VLD3 single-lane pseudo-instructions. These need special handling for
6464234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6465234353Sdimdef VLD3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
6466234353Sdim               (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6467234353Sdimdef VLD3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6468234353Sdim               (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6469234353Sdimdef VLD3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6470234353Sdim               (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6471234353Sdimdef VLD3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6472234353Sdim               (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6473234353Sdimdef VLD3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6474234353Sdim               (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6475234353Sdim
6476234353Sdimdef VLD3LNdWB_fixed_Asm_8 :
6477234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
6478234353Sdim               (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6479234353Sdimdef VLD3LNdWB_fixed_Asm_16 :
6480234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6481234353Sdim               (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6482234353Sdimdef VLD3LNdWB_fixed_Asm_32 :
6483234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6484234353Sdim               (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6485234353Sdimdef VLD3LNqWB_fixed_Asm_16 :
6486234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6487234353Sdim               (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6488234353Sdimdef VLD3LNqWB_fixed_Asm_32 :
6489234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6490234353Sdim               (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6491234353Sdimdef VLD3LNdWB_register_Asm_8 :
6492234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
6493234353Sdim                  (ins VecListThreeDByteIndexed:$list, addrmode6:$addr,
6494234353Sdim                       rGPR:$Rm, pred:$p)>;
6495234353Sdimdef VLD3LNdWB_register_Asm_16 :
6496234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6497234353Sdim                  (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr,
6498234353Sdim                       rGPR:$Rm, pred:$p)>;
6499234353Sdimdef VLD3LNdWB_register_Asm_32 :
6500234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6501234353Sdim                  (ins VecListThreeDWordIndexed:$list, addrmode6:$addr,
6502234353Sdim                       rGPR:$Rm, pred:$p)>;
6503234353Sdimdef VLD3LNqWB_register_Asm_16 :
6504234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6505234353Sdim                  (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr,
6506234353Sdim                       rGPR:$Rm, pred:$p)>;
6507234353Sdimdef VLD3LNqWB_register_Asm_32 :
6508234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6509234353Sdim                  (ins VecListThreeQWordIndexed:$list, addrmode6:$addr,
6510234353Sdim                       rGPR:$Rm, pred:$p)>;
6511234353Sdim
6512234353Sdim// VLD3 multiple structure pseudo-instructions. These need special handling for
6513234353Sdim// the vector operands that the normal instructions don't yet model.
6514234353Sdim// FIXME: Remove these when the register classes and instructions are updated.
6515234353Sdimdef VLD3dAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
6516234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6517234353Sdimdef VLD3dAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6518234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6519234353Sdimdef VLD3dAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6520234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6521234353Sdimdef VLD3qAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr",
6522234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6523234353Sdimdef VLD3qAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr",
6524234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6525234353Sdimdef VLD3qAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr",
6526234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6527234353Sdim
6528234353Sdimdef VLD3dWB_fixed_Asm_8 :
6529234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
6530234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6531234353Sdimdef VLD3dWB_fixed_Asm_16 :
6532234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6533234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6534234353Sdimdef VLD3dWB_fixed_Asm_32 :
6535234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6536234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6537234353Sdimdef VLD3qWB_fixed_Asm_8 :
6538234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!",
6539234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6540234353Sdimdef VLD3qWB_fixed_Asm_16 :
6541234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!",
6542234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6543234353Sdimdef VLD3qWB_fixed_Asm_32 :
6544234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!",
6545234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6546234353Sdimdef VLD3dWB_register_Asm_8 :
6547234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
6548234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6549234353Sdim                       rGPR:$Rm, pred:$p)>;
6550234353Sdimdef VLD3dWB_register_Asm_16 :
6551234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6552234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6553234353Sdim                       rGPR:$Rm, pred:$p)>;
6554234353Sdimdef VLD3dWB_register_Asm_32 :
6555234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6556234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6557234353Sdim                       rGPR:$Rm, pred:$p)>;
6558234353Sdimdef VLD3qWB_register_Asm_8 :
6559234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm",
6560234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6561234353Sdim                       rGPR:$Rm, pred:$p)>;
6562234353Sdimdef VLD3qWB_register_Asm_16 :
6563234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm",
6564234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6565234353Sdim                       rGPR:$Rm, pred:$p)>;
6566234353Sdimdef VLD3qWB_register_Asm_32 :
6567234353Sdim        NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm",
6568234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6569234353Sdim                       rGPR:$Rm, pred:$p)>;
6570234353Sdim
6571234353Sdim// VST3 single-lane pseudo-instructions. These need special handling for
6572234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6573234353Sdimdef VST3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
6574234353Sdim               (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6575234353Sdimdef VST3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
6576234353Sdim               (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6577234353Sdimdef VST3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
6578234353Sdim               (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6579234353Sdimdef VST3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
6580234353Sdim               (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6581234353Sdimdef VST3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
6582234353Sdim               (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6583234353Sdim
6584234353Sdimdef VST3LNdWB_fixed_Asm_8 :
6585234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
6586234353Sdim               (ins VecListThreeDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6587234353Sdimdef VST3LNdWB_fixed_Asm_16 :
6588234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
6589234353Sdim               (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6590234353Sdimdef VST3LNdWB_fixed_Asm_32 :
6591234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
6592234353Sdim               (ins VecListThreeDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6593234353Sdimdef VST3LNqWB_fixed_Asm_16 :
6594234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
6595234353Sdim               (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6596234353Sdimdef VST3LNqWB_fixed_Asm_32 :
6597234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
6598234353Sdim               (ins VecListThreeQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6599234353Sdimdef VST3LNdWB_register_Asm_8 :
6600234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
6601234353Sdim                  (ins VecListThreeDByteIndexed:$list, addrmode6:$addr,
6602234353Sdim                       rGPR:$Rm, pred:$p)>;
6603234353Sdimdef VST3LNdWB_register_Asm_16 :
6604234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
6605234353Sdim                  (ins VecListThreeDHWordIndexed:$list, addrmode6:$addr,
6606234353Sdim                       rGPR:$Rm, pred:$p)>;
6607234353Sdimdef VST3LNdWB_register_Asm_32 :
6608234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
6609234353Sdim                  (ins VecListThreeDWordIndexed:$list, addrmode6:$addr,
6610234353Sdim                       rGPR:$Rm, pred:$p)>;
6611234353Sdimdef VST3LNqWB_register_Asm_16 :
6612234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
6613234353Sdim                  (ins VecListThreeQHWordIndexed:$list, addrmode6:$addr,
6614234353Sdim                       rGPR:$Rm, pred:$p)>;
6615234353Sdimdef VST3LNqWB_register_Asm_32 :
6616234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
6617234353Sdim                  (ins VecListThreeQWordIndexed:$list, addrmode6:$addr,
6618234353Sdim                       rGPR:$Rm, pred:$p)>;
6619234353Sdim
6620234353Sdim
6621234353Sdim// VST3 multiple structure pseudo-instructions. These need special handling for
6622234353Sdim// the vector operands that the normal instructions don't yet model.
6623234353Sdim// FIXME: Remove these when the register classes and instructions are updated.
6624234353Sdimdef VST3dAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
6625234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6626234353Sdimdef VST3dAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
6627234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6628234353Sdimdef VST3dAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
6629234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6630234353Sdimdef VST3qAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr",
6631234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6632234353Sdimdef VST3qAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr",
6633234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6634234353Sdimdef VST3qAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr",
6635234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6636234353Sdim
6637234353Sdimdef VST3dWB_fixed_Asm_8 :
6638234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
6639234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6640234353Sdimdef VST3dWB_fixed_Asm_16 :
6641234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
6642234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6643234353Sdimdef VST3dWB_fixed_Asm_32 :
6644234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
6645234353Sdim               (ins VecListThreeD:$list, addrmode6:$addr, pred:$p)>;
6646234353Sdimdef VST3qWB_fixed_Asm_8 :
6647234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!",
6648234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6649234353Sdimdef VST3qWB_fixed_Asm_16 :
6650234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!",
6651234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6652234353Sdimdef VST3qWB_fixed_Asm_32 :
6653234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!",
6654234353Sdim               (ins VecListThreeQ:$list, addrmode6:$addr, pred:$p)>;
6655234353Sdimdef VST3dWB_register_Asm_8 :
6656234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
6657234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6658234353Sdim                       rGPR:$Rm, pred:$p)>;
6659234353Sdimdef VST3dWB_register_Asm_16 :
6660234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
6661234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6662234353Sdim                       rGPR:$Rm, pred:$p)>;
6663234353Sdimdef VST3dWB_register_Asm_32 :
6664234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
6665234353Sdim                  (ins VecListThreeD:$list, addrmode6:$addr,
6666234353Sdim                       rGPR:$Rm, pred:$p)>;
6667234353Sdimdef VST3qWB_register_Asm_8 :
6668234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm",
6669234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6670234353Sdim                       rGPR:$Rm, pred:$p)>;
6671234353Sdimdef VST3qWB_register_Asm_16 :
6672234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm",
6673234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6674234353Sdim                       rGPR:$Rm, pred:$p)>;
6675234353Sdimdef VST3qWB_register_Asm_32 :
6676234353Sdim        NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm",
6677234353Sdim                  (ins VecListThreeQ:$list, addrmode6:$addr,
6678234353Sdim                       rGPR:$Rm, pred:$p)>;
6679234353Sdim
6680234353Sdim// VLD4 all-lanes pseudo-instructions. These need special handling for
6681234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6682239462Sdimdef VLD4DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
6683234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6684239462Sdimdef VLD4DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6685234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6686239462Sdimdef VLD4DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6687234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6688239462Sdimdef VLD4DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
6689234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6690239462Sdimdef VLD4DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6691234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6692239462Sdimdef VLD4DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6693234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6694234353Sdim
6695234353Sdimdef VLD4DUPdWB_fixed_Asm_8 :
6696234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
6697234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6698234353Sdimdef VLD4DUPdWB_fixed_Asm_16 :
6699234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6700234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6701234353Sdimdef VLD4DUPdWB_fixed_Asm_32 :
6702234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6703234353Sdim               (ins VecListFourDAllLanes:$list, addrmode6:$addr, pred:$p)>;
6704234353Sdimdef VLD4DUPqWB_fixed_Asm_8 :
6705234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
6706234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6707234353Sdimdef VLD4DUPqWB_fixed_Asm_16 :
6708234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6709234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6710234353Sdimdef VLD4DUPqWB_fixed_Asm_32 :
6711234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6712234353Sdim               (ins VecListFourQAllLanes:$list, addrmode6:$addr, pred:$p)>;
6713234353Sdimdef VLD4DUPdWB_register_Asm_8 :
6714234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
6715234353Sdim                  (ins VecListFourDAllLanes:$list, addrmode6:$addr,
6716234353Sdim                       rGPR:$Rm, pred:$p)>;
6717234353Sdimdef VLD4DUPdWB_register_Asm_16 :
6718234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6719234353Sdim                  (ins VecListFourDAllLanes:$list, addrmode6:$addr,
6720234353Sdim                       rGPR:$Rm, pred:$p)>;
6721234353Sdimdef VLD4DUPdWB_register_Asm_32 :
6722234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6723234353Sdim                  (ins VecListFourDAllLanes:$list, addrmode6:$addr,
6724234353Sdim                       rGPR:$Rm, pred:$p)>;
6725234353Sdimdef VLD4DUPqWB_register_Asm_8 :
6726234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
6727234353Sdim                  (ins VecListFourQAllLanes:$list, addrmode6:$addr,
6728234353Sdim                       rGPR:$Rm, pred:$p)>;
6729234353Sdimdef VLD4DUPqWB_register_Asm_16 :
6730234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6731234353Sdim                  (ins VecListFourQAllLanes:$list, addrmode6:$addr,
6732234353Sdim                       rGPR:$Rm, pred:$p)>;
6733234353Sdimdef VLD4DUPqWB_register_Asm_32 :
6734234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6735234353Sdim                  (ins VecListFourQAllLanes:$list, addrmode6:$addr,
6736234353Sdim                       rGPR:$Rm, pred:$p)>;
6737234353Sdim
6738234353Sdim
6739234353Sdim// VLD4 single-lane pseudo-instructions. These need special handling for
6740234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6741234353Sdimdef VLD4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
6742234353Sdim               (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6743234353Sdimdef VLD4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6744234353Sdim               (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6745234353Sdimdef VLD4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6746234353Sdim               (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6747234353Sdimdef VLD4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6748234353Sdim               (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6749234353Sdimdef VLD4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6750234353Sdim               (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6751234353Sdim
6752234353Sdimdef VLD4LNdWB_fixed_Asm_8 :
6753234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
6754234353Sdim               (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6755234353Sdimdef VLD4LNdWB_fixed_Asm_16 :
6756234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6757234353Sdim               (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6758234353Sdimdef VLD4LNdWB_fixed_Asm_32 :
6759234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6760234353Sdim               (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6761234353Sdimdef VLD4LNqWB_fixed_Asm_16 :
6762234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6763234353Sdim               (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6764234353Sdimdef VLD4LNqWB_fixed_Asm_32 :
6765234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6766234353Sdim               (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6767234353Sdimdef VLD4LNdWB_register_Asm_8 :
6768234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
6769234353Sdim                  (ins VecListFourDByteIndexed:$list, addrmode6:$addr,
6770234353Sdim                       rGPR:$Rm, pred:$p)>;
6771234353Sdimdef VLD4LNdWB_register_Asm_16 :
6772234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6773234353Sdim                  (ins VecListFourDHWordIndexed:$list, addrmode6:$addr,
6774234353Sdim                       rGPR:$Rm, pred:$p)>;
6775234353Sdimdef VLD4LNdWB_register_Asm_32 :
6776234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6777234353Sdim                  (ins VecListFourDWordIndexed:$list, addrmode6:$addr,
6778234353Sdim                       rGPR:$Rm, pred:$p)>;
6779234353Sdimdef VLD4LNqWB_register_Asm_16 :
6780234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6781234353Sdim                  (ins VecListFourQHWordIndexed:$list, addrmode6:$addr,
6782234353Sdim                       rGPR:$Rm, pred:$p)>;
6783234353Sdimdef VLD4LNqWB_register_Asm_32 :
6784234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6785234353Sdim                  (ins VecListFourQWordIndexed:$list, addrmode6:$addr,
6786234353Sdim                       rGPR:$Rm, pred:$p)>;
6787234353Sdim
6788234353Sdim
6789234353Sdim
6790234353Sdim// VLD4 multiple structure pseudo-instructions. These need special handling for
6791234353Sdim// the vector operands that the normal instructions don't yet model.
6792234353Sdim// FIXME: Remove these when the register classes and instructions are updated.
6793234353Sdimdef VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
6794234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6795234353Sdimdef VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6796234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6797234353Sdimdef VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6798234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6799234353Sdimdef VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr",
6800234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6801234353Sdimdef VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr",
6802234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6803234353Sdimdef VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr",
6804234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6805234353Sdim
6806234353Sdimdef VLD4dWB_fixed_Asm_8 :
6807234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
6808234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6809234353Sdimdef VLD4dWB_fixed_Asm_16 :
6810234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6811234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6812234353Sdimdef VLD4dWB_fixed_Asm_32 :
6813234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6814234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6815234353Sdimdef VLD4qWB_fixed_Asm_8 :
6816234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!",
6817234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6818234353Sdimdef VLD4qWB_fixed_Asm_16 :
6819234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!",
6820234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6821234353Sdimdef VLD4qWB_fixed_Asm_32 :
6822234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!",
6823234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6824234353Sdimdef VLD4dWB_register_Asm_8 :
6825234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
6826234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6827234353Sdim                       rGPR:$Rm, pred:$p)>;
6828234353Sdimdef VLD4dWB_register_Asm_16 :
6829234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6830234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6831234353Sdim                       rGPR:$Rm, pred:$p)>;
6832234353Sdimdef VLD4dWB_register_Asm_32 :
6833234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6834234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6835234353Sdim                       rGPR:$Rm, pred:$p)>;
6836234353Sdimdef VLD4qWB_register_Asm_8 :
6837234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm",
6838234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6839234353Sdim                       rGPR:$Rm, pred:$p)>;
6840234353Sdimdef VLD4qWB_register_Asm_16 :
6841234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm",
6842234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6843234353Sdim                       rGPR:$Rm, pred:$p)>;
6844234353Sdimdef VLD4qWB_register_Asm_32 :
6845234353Sdim        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm",
6846234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6847234353Sdim                       rGPR:$Rm, pred:$p)>;
6848234353Sdim
6849234353Sdim// VST4 single-lane pseudo-instructions. These need special handling for
6850234353Sdim// the lane index that an InstAlias can't handle, so we use these instead.
6851234353Sdimdef VST4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
6852234353Sdim               (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6853234353Sdimdef VST4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
6854234353Sdim               (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6855234353Sdimdef VST4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
6856234353Sdim               (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6857234353Sdimdef VST4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
6858234353Sdim               (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6859234353Sdimdef VST4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
6860234353Sdim               (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6861234353Sdim
6862234353Sdimdef VST4LNdWB_fixed_Asm_8 :
6863234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
6864234353Sdim               (ins VecListFourDByteIndexed:$list, addrmode6:$addr, pred:$p)>;
6865234353Sdimdef VST4LNdWB_fixed_Asm_16 :
6866234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
6867234353Sdim               (ins VecListFourDHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6868234353Sdimdef VST4LNdWB_fixed_Asm_32 :
6869234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
6870234353Sdim               (ins VecListFourDWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6871234353Sdimdef VST4LNqWB_fixed_Asm_16 :
6872234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
6873234353Sdim               (ins VecListFourQHWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6874234353Sdimdef VST4LNqWB_fixed_Asm_32 :
6875234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
6876234353Sdim               (ins VecListFourQWordIndexed:$list, addrmode6:$addr, pred:$p)>;
6877234353Sdimdef VST4LNdWB_register_Asm_8 :
6878234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
6879234353Sdim                  (ins VecListFourDByteIndexed:$list, addrmode6:$addr,
6880234353Sdim                       rGPR:$Rm, pred:$p)>;
6881234353Sdimdef VST4LNdWB_register_Asm_16 :
6882234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
6883234353Sdim                  (ins VecListFourDHWordIndexed:$list, addrmode6:$addr,
6884234353Sdim                       rGPR:$Rm, pred:$p)>;
6885234353Sdimdef VST4LNdWB_register_Asm_32 :
6886234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
6887234353Sdim                  (ins VecListFourDWordIndexed:$list, addrmode6:$addr,
6888234353Sdim                       rGPR:$Rm, pred:$p)>;
6889234353Sdimdef VST4LNqWB_register_Asm_16 :
6890234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
6891234353Sdim                  (ins VecListFourQHWordIndexed:$list, addrmode6:$addr,
6892234353Sdim                       rGPR:$Rm, pred:$p)>;
6893234353Sdimdef VST4LNqWB_register_Asm_32 :
6894234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
6895234353Sdim                  (ins VecListFourQWordIndexed:$list, addrmode6:$addr,
6896234353Sdim                       rGPR:$Rm, pred:$p)>;
6897234353Sdim
6898234353Sdim
6899234353Sdim// VST4 multiple structure pseudo-instructions. These need special handling for
6900234353Sdim// the vector operands that the normal instructions don't yet model.
6901234353Sdim// FIXME: Remove these when the register classes and instructions are updated.
6902234353Sdimdef VST4dAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
6903234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6904234353Sdimdef VST4dAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
6905234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6906234353Sdimdef VST4dAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
6907234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6908234353Sdimdef VST4qAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr",
6909234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6910234353Sdimdef VST4qAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr",
6911234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6912234353Sdimdef VST4qAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr",
6913234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6914234353Sdim
6915234353Sdimdef VST4dWB_fixed_Asm_8 :
6916234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
6917234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6918234353Sdimdef VST4dWB_fixed_Asm_16 :
6919234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
6920234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6921234353Sdimdef VST4dWB_fixed_Asm_32 :
6922234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
6923234353Sdim               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>;
6924234353Sdimdef VST4qWB_fixed_Asm_8 :
6925234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!",
6926234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6927234353Sdimdef VST4qWB_fixed_Asm_16 :
6928234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!",
6929234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6930234353Sdimdef VST4qWB_fixed_Asm_32 :
6931234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!",
6932234353Sdim               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>;
6933234353Sdimdef VST4dWB_register_Asm_8 :
6934234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
6935234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6936234353Sdim                       rGPR:$Rm, pred:$p)>;
6937234353Sdimdef VST4dWB_register_Asm_16 :
6938234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
6939234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6940234353Sdim                       rGPR:$Rm, pred:$p)>;
6941234353Sdimdef VST4dWB_register_Asm_32 :
6942234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
6943234353Sdim                  (ins VecListFourD:$list, addrmode6:$addr,
6944234353Sdim                       rGPR:$Rm, pred:$p)>;
6945234353Sdimdef VST4qWB_register_Asm_8 :
6946234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm",
6947234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6948234353Sdim                       rGPR:$Rm, pred:$p)>;
6949234353Sdimdef VST4qWB_register_Asm_16 :
6950234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm",
6951234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6952234353Sdim                       rGPR:$Rm, pred:$p)>;
6953234353Sdimdef VST4qWB_register_Asm_32 :
6954234353Sdim        NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm",
6955234353Sdim                  (ins VecListFourQ:$list, addrmode6:$addr,
6956234353Sdim                       rGPR:$Rm, pred:$p)>;
6957234353Sdim
6958263508Sdim// VMOV/VMVN takes an optional datatype suffix
6959234353Sdimdefm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",
6960234353Sdim                         (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>;
6961234353Sdimdefm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",
6962234353Sdim                         (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>;
6963234353Sdim
6964263508Sdimdefm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",
6965263508Sdim                         (VMVNd DPR:$Vd, DPR:$Vm, pred:$p)>;
6966263508Sdimdefm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm",
6967263508Sdim                         (VMVNq QPR:$Vd, QPR:$Vm, pred:$p)>;
6968263508Sdim
6969234353Sdim// VCLT (register) is an assembler alias for VCGT w/ the operands reversed.
6970234353Sdim// D-register versions.
6971234353Sdimdef : NEONInstAlias<"vcle${p}.s8 $Dd, $Dn, $Dm",
6972234353Sdim                    (VCGEsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6973234353Sdimdef : NEONInstAlias<"vcle${p}.s16 $Dd, $Dn, $Dm",
6974234353Sdim                    (VCGEsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6975234353Sdimdef : NEONInstAlias<"vcle${p}.s32 $Dd, $Dn, $Dm",
6976234353Sdim                    (VCGEsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6977234353Sdimdef : NEONInstAlias<"vcle${p}.u8 $Dd, $Dn, $Dm",
6978234353Sdim                    (VCGEuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6979234353Sdimdef : NEONInstAlias<"vcle${p}.u16 $Dd, $Dn, $Dm",
6980234353Sdim                    (VCGEuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6981234353Sdimdef : NEONInstAlias<"vcle${p}.u32 $Dd, $Dn, $Dm",
6982234353Sdim                    (VCGEuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6983234353Sdimdef : NEONInstAlias<"vcle${p}.f32 $Dd, $Dn, $Dm",
6984234353Sdim                    (VCGEfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
6985234353Sdim// Q-register versions.
6986234353Sdimdef : NEONInstAlias<"vcle${p}.s8 $Qd, $Qn, $Qm",
6987234353Sdim                    (VCGEsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6988234353Sdimdef : NEONInstAlias<"vcle${p}.s16 $Qd, $Qn, $Qm",
6989234353Sdim                    (VCGEsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6990234353Sdimdef : NEONInstAlias<"vcle${p}.s32 $Qd, $Qn, $Qm",
6991234353Sdim                    (VCGEsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6992234353Sdimdef : NEONInstAlias<"vcle${p}.u8 $Qd, $Qn, $Qm",
6993234353Sdim                    (VCGEuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6994234353Sdimdef : NEONInstAlias<"vcle${p}.u16 $Qd, $Qn, $Qm",
6995234353Sdim                    (VCGEuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6996234353Sdimdef : NEONInstAlias<"vcle${p}.u32 $Qd, $Qn, $Qm",
6997234353Sdim                    (VCGEuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
6998234353Sdimdef : NEONInstAlias<"vcle${p}.f32 $Qd, $Qn, $Qm",
6999234353Sdim                    (VCGEfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7000234353Sdim
7001234353Sdim// VCLT (register) is an assembler alias for VCGT w/ the operands reversed.
7002234353Sdim// D-register versions.
7003234353Sdimdef : NEONInstAlias<"vclt${p}.s8 $Dd, $Dn, $Dm",
7004234353Sdim                    (VCGTsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7005234353Sdimdef : NEONInstAlias<"vclt${p}.s16 $Dd, $Dn, $Dm",
7006234353Sdim                    (VCGTsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7007234353Sdimdef : NEONInstAlias<"vclt${p}.s32 $Dd, $Dn, $Dm",
7008234353Sdim                    (VCGTsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7009234353Sdimdef : NEONInstAlias<"vclt${p}.u8 $Dd, $Dn, $Dm",
7010234353Sdim                    (VCGTuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7011234353Sdimdef : NEONInstAlias<"vclt${p}.u16 $Dd, $Dn, $Dm",
7012234353Sdim                    (VCGTuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7013234353Sdimdef : NEONInstAlias<"vclt${p}.u32 $Dd, $Dn, $Dm",
7014234353Sdim                    (VCGTuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7015234353Sdimdef : NEONInstAlias<"vclt${p}.f32 $Dd, $Dn, $Dm",
7016234353Sdim                    (VCGTfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>;
7017234353Sdim// Q-register versions.
7018234353Sdimdef : NEONInstAlias<"vclt${p}.s8 $Qd, $Qn, $Qm",
7019234353Sdim                    (VCGTsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7020234353Sdimdef : NEONInstAlias<"vclt${p}.s16 $Qd, $Qn, $Qm",
7021234353Sdim                    (VCGTsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7022234353Sdimdef : NEONInstAlias<"vclt${p}.s32 $Qd, $Qn, $Qm",
7023234353Sdim                    (VCGTsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7024234353Sdimdef : NEONInstAlias<"vclt${p}.u8 $Qd, $Qn, $Qm",
7025234353Sdim                    (VCGTuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7026234353Sdimdef : NEONInstAlias<"vclt${p}.u16 $Qd, $Qn, $Qm",
7027234353Sdim                    (VCGTuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7028234353Sdimdef : NEONInstAlias<"vclt${p}.u32 $Qd, $Qn, $Qm",
7029234353Sdim                    (VCGTuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7030234353Sdimdef : NEONInstAlias<"vclt${p}.f32 $Qd, $Qn, $Qm",
7031234353Sdim                    (VCGTfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>;
7032234353Sdim
7033234353Sdim// VSWP allows, but does not require, a type suffix.
7034234353Sdimdefm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",
7035234353Sdim                         (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>;
7036234353Sdimdefm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm",
7037234353Sdim                         (VSWPq QPR:$Vd, QPR:$Vm, pred:$p)>;
7038234353Sdim
7039234353Sdim// VBIF, VBIT, and VBSL allow, but do not require, a type suffix.
7040234353Sdimdefm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",
7041234353Sdim                         (VBIFd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7042234353Sdimdefm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",
7043234353Sdim                         (VBITd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7044234353Sdimdefm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",
7045234353Sdim                         (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>;
7046234353Sdimdefm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm",
7047234353Sdim                         (VBIFq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7048234353Sdimdefm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm",
7049234353Sdim                         (VBITq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7050234353Sdimdefm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm",
7051234353Sdim                         (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>;
7052234353Sdim
7053234353Sdim// "vmov Rd, #-imm" can be handled via "vmvn".
7054234353Sdimdef : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",
7055234353Sdim                    (VMVNv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
7056234353Sdimdef : NEONInstAlias<"vmov${p}.i32 $Vd, $imm",
7057234353Sdim                    (VMVNv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
7058234353Sdimdef : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",
7059234353Sdim                    (VMOVv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
7060234353Sdimdef : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm",
7061234353Sdim                    (VMOVv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>;
7062234353Sdim
7063234353Sdim// 'gas' compatibility aliases for quad-word instructions. Strictly speaking,
7064234353Sdim// these should restrict to just the Q register variants, but the register
7065234353Sdim// classes are enough to match correctly regardless, so we keep it simple
7066234353Sdim// and just use MnemonicAlias.
7067234353Sdimdef : NEONMnemonicAlias<"vbicq", "vbic">;
7068234353Sdimdef : NEONMnemonicAlias<"vandq", "vand">;
7069234353Sdimdef : NEONMnemonicAlias<"veorq", "veor">;
7070234353Sdimdef : NEONMnemonicAlias<"vorrq", "vorr">;
7071234353Sdim
7072234353Sdimdef : NEONMnemonicAlias<"vmovq", "vmov">;
7073234353Sdimdef : NEONMnemonicAlias<"vmvnq", "vmvn">;
7074234353Sdim// Explicit versions for floating point so that the FPImm variants get
7075234353Sdim// handled early. The parser gets confused otherwise.
7076234353Sdimdef : NEONMnemonicAlias<"vmovq.f32", "vmov.f32">;
7077234353Sdimdef : NEONMnemonicAlias<"vmovq.f64", "vmov.f64">;
7078234353Sdim
7079234353Sdimdef : NEONMnemonicAlias<"vaddq", "vadd">;
7080234353Sdimdef : NEONMnemonicAlias<"vsubq", "vsub">;
7081234353Sdim
7082234353Sdimdef : NEONMnemonicAlias<"vminq", "vmin">;
7083234353Sdimdef : NEONMnemonicAlias<"vmaxq", "vmax">;
7084234353Sdim
7085234353Sdimdef : NEONMnemonicAlias<"vmulq", "vmul">;
7086234353Sdim
7087234353Sdimdef : NEONMnemonicAlias<"vabsq", "vabs">;
7088234353Sdim
7089234353Sdimdef : NEONMnemonicAlias<"vshlq", "vshl">;
7090234353Sdimdef : NEONMnemonicAlias<"vshrq", "vshr">;
7091234353Sdim
7092234353Sdimdef : NEONMnemonicAlias<"vcvtq", "vcvt">;
7093234353Sdim
7094234353Sdimdef : NEONMnemonicAlias<"vcleq", "vcle">;
7095234353Sdimdef : NEONMnemonicAlias<"vceqq", "vceq">;
7096234353Sdim
7097234353Sdimdef : NEONMnemonicAlias<"vzipq", "vzip">;
7098234353Sdimdef : NEONMnemonicAlias<"vswpq", "vswp">;
7099234353Sdim
7100234353Sdimdef : NEONMnemonicAlias<"vrecpeq.f32", "vrecpe.f32">;
7101234353Sdimdef : NEONMnemonicAlias<"vrecpeq.u32", "vrecpe.u32">;
7102234353Sdim
7103234353Sdim
7104234353Sdim// Alias for loading floating point immediates that aren't representable
7105234353Sdim// using the vmov.f32 encoding but the bitpattern is representable using
7106234353Sdim// the .i32 encoding.
7107234353Sdimdef : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",
7108234353Sdim                     (VMOVv4i32 QPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;
7109234353Sdimdef : NEONInstAlias<"vmov${p}.f32 $Vd, $imm",
7110234353Sdim                     (VMOVv2i32 DPR:$Vd, nImmVMOVI32:$imm, pred:$p)>;
7111