Thumb2 pre/post indexed loads.
[oota-llvm.git] / lib / Target / ARM / ARMInstrFormats.td
1 //===- ARMInstrFormats.td - ARM Instruction Formats --*- tablegen -*---------=//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9
10 //===----------------------------------------------------------------------===//
11 //
12 // ARM Instruction Format Definitions.
13 //
14
15 // Format specifies the encoding used by the instruction.  This is part of the
16 // ad-hoc solution used to emit machine instruction encodings by our machine
17 // code emitter.
18 class Format<bits<5> val> {
19   bits<5> Value = val;
20 }
21
22 def Pseudo        : Format<0>;
23 def MulFrm        : Format<1>;
24 def BrFrm         : Format<2>;
25 def BrMiscFrm     : Format<3>;
26
27 def DPFrm         : Format<4>;
28 def DPSoRegFrm    : Format<5>;
29
30 def LdFrm         : Format<6>;
31 def StFrm         : Format<7>;
32 def LdMiscFrm     : Format<8>;
33 def StMiscFrm     : Format<9>;
34 def LdStMulFrm    : Format<10>;
35
36 def ArithMiscFrm  : Format<11>;
37 def ExtFrm        : Format<12>;
38
39 def VFPUnaryFrm   : Format<13>;
40 def VFPBinaryFrm  : Format<14>;
41 def VFPConv1Frm   : Format<15>;
42 def VFPConv2Frm   : Format<16>;
43 def VFPConv3Frm   : Format<17>;
44 def VFPConv4Frm   : Format<18>;
45 def VFPConv5Frm   : Format<19>;
46 def VFPLdStFrm    : Format<20>;
47 def VFPLdStMulFrm : Format<21>;
48 def VFPMiscFrm    : Format<22>;
49
50 def ThumbFrm      : Format<23>;
51
52 def NEONFrm       : Format<24>;
53 def NEONGetLnFrm  : Format<25>;
54 def NEONSetLnFrm  : Format<26>;
55 def NEONDupFrm    : Format<27>;
56
57 // Misc flag for data processing instructions that indicates whether
58 // the instruction has a Rn register operand.
59 class UnaryDP  { bit isUnaryDataProc = 1; }
60
61 //===----------------------------------------------------------------------===//
62 // ARM Instruction flags.  These need to match ARMInstrInfo.h.
63 //
64
65 // Addressing mode.
66 class AddrMode<bits<4> val> {
67   bits<4> Value = val;
68 }
69 def AddrModeNone  : AddrMode<0>;
70 def AddrMode1     : AddrMode<1>;
71 def AddrMode2     : AddrMode<2>;
72 def AddrMode3     : AddrMode<3>;
73 def AddrMode4     : AddrMode<4>;
74 def AddrMode5     : AddrMode<5>;
75 def AddrMode6     : AddrMode<6>;
76 def AddrModeT1_1  : AddrMode<7>;
77 def AddrModeT1_2  : AddrMode<8>;
78 def AddrModeT1_4  : AddrMode<9>;
79 def AddrModeT1_s  : AddrMode<10>;
80 def AddrModeT2_i12: AddrMode<12>;
81 def AddrModeT2_i8 : AddrMode<12>;
82 def AddrModeT2_so : AddrMode<13>;
83 def AddrModeT2_pc : AddrMode<14>;
84 def AddrModeT2_i8s4 : AddrMode<15>;
85
86 // Instruction size.
87 class SizeFlagVal<bits<3> val> {
88   bits<3> Value = val;
89 }
90 def SizeInvalid  : SizeFlagVal<0>;  // Unset.
91 def SizeSpecial  : SizeFlagVal<1>;  // Pseudo or special.
92 def Size8Bytes   : SizeFlagVal<2>;
93 def Size4Bytes   : SizeFlagVal<3>;
94 def Size2Bytes   : SizeFlagVal<4>;
95
96 // Load / store index mode.
97 class IndexMode<bits<2> val> {
98   bits<2> Value = val;
99 }
100 def IndexModeNone : IndexMode<0>;
101 def IndexModePre  : IndexMode<1>;
102 def IndexModePost : IndexMode<2>;
103
104 //===----------------------------------------------------------------------===//
105
106 // ARM Instruction templates.
107 //
108
109 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
110               Format f, string cstr>
111   : Instruction {
112   field bits<32> Inst;
113
114   let Namespace = "ARM";
115
116   // TSFlagsFields
117   AddrMode AM = am;
118   bits<4> AddrModeBits = AM.Value;
119   
120   SizeFlagVal SZ = sz;
121   bits<3> SizeFlag = SZ.Value;
122
123   IndexMode IM = im;
124   bits<2> IndexModeBits = IM.Value;
125   
126   Format F = f;
127   bits<5> Form = F.Value;
128
129   //
130   // Attributes specific to ARM instructions...
131   //
132   bit isUnaryDataProc = 0;
133   
134   let Constraints = cstr;
135 }
136
137 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
138   : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
139   let OutOperandList = oops;
140   let InOperandList = iops;
141   let AsmString   = asm;
142   let Pattern = pattern;
143 }
144
145 // Almost all ARM instructions are predicable.
146 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
147         IndexMode im, Format f, string opc, string asm, string cstr,
148         list<dag> pattern>
149   : InstARM<am, sz, im, f, cstr> {
150   let OutOperandList = oops;
151   let InOperandList = !con(iops, (ops pred:$p));
152   let AsmString   = !strconcat(opc, !strconcat("${p}", asm));
153   let Pattern = pattern;
154   list<Predicate> Predicates = [IsARM];
155 }
156
157 // Same as I except it can optionally modify CPSR. Note it's modeled as
158 // an input operand since by default it's a zero register. It will
159 // become an implicit def once it's "flipped".
160 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
161          IndexMode im, Format f, string opc, string asm, string cstr,
162          list<dag> pattern>
163   : InstARM<am, sz, im, f, cstr> {
164   let OutOperandList = oops;
165   let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
166   let AsmString   = !strconcat(opc, !strconcat("${p}${s}", asm));
167   let Pattern = pattern;
168   list<Predicate> Predicates = [IsARM];
169 }
170
171 // Special cases
172 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
173          IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
174   : InstARM<am, sz, im, f, cstr> {
175   let OutOperandList = oops;
176   let InOperandList = iops;
177   let AsmString   = asm;
178   let Pattern = pattern;
179   list<Predicate> Predicates = [IsARM];
180 }
181
182 class AI<dag oops, dag iops, Format f, string opc,
183          string asm, list<dag> pattern>
184   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
185       asm, "", pattern>;
186 class AsI<dag oops, dag iops, Format f, string opc,
187           string asm, list<dag> pattern>
188   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
189        asm, "", pattern>;
190 class AXI<dag oops, dag iops, Format f, string asm,
191           list<dag> pattern>
192   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
193        "", pattern>;
194
195 // Ctrl flow instructions
196 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
197          string asm, list<dag> pattern>
198   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
199       asm, "", pattern> {
200   let Inst{27-24} = opcod;
201 }
202 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
203   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
204        "", pattern> {
205   let Inst{27-24} = opcod;
206 }
207 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
208   : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
209        "", pattern>;
210
211 // BR_JT instructions
212 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
213   : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
214        asm, "", pattern>;
215
216 // addrmode1 instructions
217 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
218           string asm, list<dag> pattern>
219   : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
220       asm, "", pattern> {
221   let Inst{24-21} = opcod;
222   let Inst{27-26} = {0,0};
223 }
224 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
225            string asm, list<dag> pattern>
226   : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
227        asm, "", pattern> {
228   let Inst{24-21} = opcod;
229   let Inst{27-26} = {0,0};
230 }
231 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
232            list<dag> pattern>
233   : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
234        "", pattern> {
235   let Inst{24-21} = opcod;
236   let Inst{27-26} = {0,0};
237 }
238 class AI1x2<dag oops, dag iops, Format f, string opc,
239             string asm, list<dag> pattern>
240   : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
241       asm, "", pattern>;
242
243
244 // addrmode2 loads and stores
245 class AI2<dag oops, dag iops, Format f, string opc,
246           string asm, list<dag> pattern>
247   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
248       asm, "", pattern> {
249   let Inst{27-26} = {0,1};
250 }
251
252 // loads
253 class AI2ldw<dag oops, dag iops, Format f, string opc,
254           string asm, list<dag> pattern>
255   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
256       asm, "", pattern> {
257   let Inst{20}    = 1; // L bit
258   let Inst{21}    = 0; // W bit
259   let Inst{22}    = 0; // B bit
260   let Inst{24}    = 1; // P bit
261   let Inst{27-26} = {0,1};
262 }
263 class AXI2ldw<dag oops, dag iops, Format f, string asm,
264            list<dag> pattern>
265   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
266        asm, "", pattern> {
267   let Inst{20}    = 1; // L bit
268   let Inst{21}    = 0; // W bit
269   let Inst{22}    = 0; // B bit
270   let Inst{24}    = 1; // P bit
271   let Inst{27-26} = {0,1};
272 }
273 class AI2ldb<dag oops, dag iops, Format f, string opc,
274           string asm, list<dag> pattern>
275   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
276       asm, "", pattern> {
277   let Inst{20}    = 1; // L bit
278   let Inst{21}    = 0; // W bit
279   let Inst{22}    = 1; // B bit
280   let Inst{24}    = 1; // P bit
281   let Inst{27-26} = {0,1};
282 }
283 class AXI2ldb<dag oops, dag iops, Format f, string asm,
284            list<dag> pattern>
285   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
286        asm, "", pattern> {
287   let Inst{20}    = 1; // L bit
288   let Inst{21}    = 0; // W bit
289   let Inst{22}    = 1; // B bit
290   let Inst{24}    = 1; // P bit
291   let Inst{27-26} = {0,1};
292 }
293
294 // stores
295 class AI2stw<dag oops, dag iops, Format f, string opc,
296           string asm, list<dag> pattern>
297   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
298       asm, "", pattern> {
299   let Inst{20}    = 0; // L bit
300   let Inst{21}    = 0; // W bit
301   let Inst{22}    = 0; // B bit
302   let Inst{24}    = 1; // P bit
303   let Inst{27-26} = {0,1};
304 }
305 class AXI2stw<dag oops, dag iops, Format f, string asm,
306            list<dag> pattern>
307   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
308        asm, "", pattern> {
309   let Inst{20}    = 0; // L bit
310   let Inst{21}    = 0; // W bit
311   let Inst{22}    = 0; // B bit
312   let Inst{24}    = 1; // P bit
313   let Inst{27-26} = {0,1};
314 }
315 class AI2stb<dag oops, dag iops, Format f, string opc,
316           string asm, list<dag> pattern>
317   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
318       asm, "", pattern> {
319   let Inst{20}    = 0; // L bit
320   let Inst{21}    = 0; // W bit
321   let Inst{22}    = 1; // B bit
322   let Inst{24}    = 1; // P bit
323   let Inst{27-26} = {0,1};
324 }
325 class AXI2stb<dag oops, dag iops, Format f, string asm,
326            list<dag> pattern>
327   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
328        asm, "", pattern> {
329   let Inst{20}    = 0; // L bit
330   let Inst{21}    = 0; // W bit
331   let Inst{22}    = 1; // B bit
332   let Inst{24}    = 1; // P bit
333   let Inst{27-26} = {0,1};
334 }
335
336 // Pre-indexed loads
337 class AI2ldwpr<dag oops, dag iops, Format f, string opc,
338             string asm, string cstr, list<dag> pattern>
339   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
340       asm, cstr, pattern> {
341   let Inst{20}    = 1; // L bit
342   let Inst{21}    = 1; // W bit
343   let Inst{22}    = 0; // B bit
344   let Inst{24}    = 1; // P bit
345   let Inst{27-26} = {0,1};
346 }
347 class AI2ldbpr<dag oops, dag iops, Format f, string opc,
348             string asm, string cstr, list<dag> pattern>
349   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
350       asm, cstr, pattern> {
351   let Inst{20}    = 1; // L bit
352   let Inst{21}    = 1; // W bit
353   let Inst{22}    = 1; // B bit
354   let Inst{24}    = 1; // P bit
355   let Inst{27-26} = {0,1};
356 }
357
358 // Pre-indexed stores
359 class AI2stwpr<dag oops, dag iops, Format f, string opc,
360             string asm, string cstr, list<dag> pattern>
361   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
362       asm, cstr, pattern> {
363   let Inst{20}    = 0; // L bit
364   let Inst{21}    = 1; // W bit
365   let Inst{22}    = 0; // B bit
366   let Inst{24}    = 1; // P bit
367   let Inst{27-26} = {0,1};
368 }
369 class AI2stbpr<dag oops, dag iops, Format f, string opc,
370             string asm, string cstr, list<dag> pattern>
371   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
372       asm, cstr, pattern> {
373   let Inst{20}    = 0; // L bit
374   let Inst{21}    = 1; // W bit
375   let Inst{22}    = 1; // B bit
376   let Inst{24}    = 1; // P bit
377   let Inst{27-26} = {0,1};
378 }
379
380 // Post-indexed loads
381 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
382             string asm, string cstr, list<dag> pattern>
383   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
384       asm, cstr,pattern> {
385   let Inst{20}    = 1; // L bit
386   let Inst{21}    = 0; // W bit
387   let Inst{22}    = 0; // B bit
388   let Inst{24}    = 0; // P bit
389   let Inst{27-26} = {0,1};
390 }
391 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
392             string asm, string cstr, list<dag> pattern>
393   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
394       asm, cstr,pattern> {
395   let Inst{20}    = 1; // L bit
396   let Inst{21}    = 0; // W bit
397   let Inst{22}    = 1; // B bit
398   let Inst{24}    = 0; // P bit
399   let Inst{27-26} = {0,1};
400 }
401
402 // Post-indexed stores
403 class AI2stwpo<dag oops, dag iops, Format f, string opc,
404             string asm, string cstr, list<dag> pattern>
405   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
406       asm, cstr,pattern> {
407   let Inst{20}    = 0; // L bit
408   let Inst{21}    = 0; // W bit
409   let Inst{22}    = 0; // B bit
410   let Inst{24}    = 0; // P bit
411   let Inst{27-26} = {0,1};
412 }
413 class AI2stbpo<dag oops, dag iops, Format f, string opc,
414             string asm, string cstr, list<dag> pattern>
415   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
416       asm, cstr,pattern> {
417   let Inst{20}    = 0; // L bit
418   let Inst{21}    = 0; // W bit
419   let Inst{22}    = 1; // B bit
420   let Inst{24}    = 0; // P bit
421   let Inst{27-26} = {0,1};
422 }
423
424 // addrmode3 instructions
425 class AI3<dag oops, dag iops, Format f, string opc,
426           string asm, list<dag> pattern>
427   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
428       asm, "", pattern>;
429 class AXI3<dag oops, dag iops, Format f, string asm,
430            list<dag> pattern>
431   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
432        "", pattern>;
433
434 // loads
435 class AI3ldh<dag oops, dag iops, Format f, string opc,
436           string asm, list<dag> pattern>
437   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
438       asm, "", pattern> {
439   let Inst{4}     = 1;
440   let Inst{5}     = 1; // H bit
441   let Inst{6}     = 0; // S bit
442   let Inst{7}     = 1;
443   let Inst{20}    = 1; // L bit
444   let Inst{21}    = 0; // W bit
445   let Inst{24}    = 1; // P bit
446 }
447 class AXI3ldh<dag oops, dag iops, Format f, string asm,
448            list<dag> pattern>
449   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
450        asm, "", pattern> {
451   let Inst{4}     = 1;
452   let Inst{5}     = 1; // H bit
453   let Inst{6}     = 0; // S bit
454   let Inst{7}     = 1;
455   let Inst{20}    = 1; // L bit
456   let Inst{21}    = 0; // W bit
457   let Inst{24}    = 1; // P bit
458 }
459 class AI3ldsh<dag oops, dag iops, Format f, string opc,
460           string asm, list<dag> pattern>
461   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
462       asm, "", pattern> {
463   let Inst{4}     = 1;
464   let Inst{5}     = 1; // H bit
465   let Inst{6}     = 1; // S bit
466   let Inst{7}     = 1;
467   let Inst{20}    = 1; // L bit
468   let Inst{21}    = 0; // W bit
469   let Inst{24}    = 1; // P bit
470 }
471 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
472            list<dag> pattern>
473   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
474        asm, "", pattern> {
475   let Inst{4}     = 1;
476   let Inst{5}     = 1; // H bit
477   let Inst{6}     = 1; // S bit
478   let Inst{7}     = 1;
479   let Inst{20}    = 1; // L bit
480   let Inst{21}    = 0; // W bit
481   let Inst{24}    = 1; // P bit
482 }
483 class AI3ldsb<dag oops, dag iops, Format f, string opc,
484           string asm, list<dag> pattern>
485   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
486       asm, "", pattern> {
487   let Inst{4}     = 1;
488   let Inst{5}     = 0; // H bit
489   let Inst{6}     = 1; // S bit
490   let Inst{7}     = 1;
491   let Inst{20}    = 1; // L bit
492   let Inst{21}    = 0; // W bit
493   let Inst{24}    = 1; // P bit
494 }
495 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
496            list<dag> pattern>
497   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
498        asm, "", pattern> {
499   let Inst{4}     = 1;
500   let Inst{5}     = 0; // H bit
501   let Inst{6}     = 1; // S bit
502   let Inst{7}     = 1;
503   let Inst{20}    = 1; // L bit
504   let Inst{21}    = 0; // W bit
505   let Inst{24}    = 1; // P bit
506 }
507 class AI3ldd<dag oops, dag iops, Format f, string opc,
508           string asm, list<dag> pattern>
509   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
510       asm, "", pattern> {
511   let Inst{4}     = 1;
512   let Inst{5}     = 0; // H bit
513   let Inst{6}     = 1; // S bit
514   let Inst{7}     = 1;
515   let Inst{20}    = 0; // L bit
516   let Inst{21}    = 0; // W bit
517   let Inst{24}    = 1; // P bit
518 }
519
520 // stores
521 class AI3sth<dag oops, dag iops, Format f, string opc,
522           string asm, list<dag> pattern>
523   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
524       asm, "", pattern> {
525   let Inst{4}     = 1;
526   let Inst{5}     = 1; // H bit
527   let Inst{6}     = 0; // S bit
528   let Inst{7}     = 1;
529   let Inst{20}    = 0; // L bit
530   let Inst{21}    = 0; // W bit
531   let Inst{24}    = 1; // P bit
532 }
533 class AXI3sth<dag oops, dag iops, Format f, string asm,
534            list<dag> pattern>
535   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
536        asm, "", pattern> {
537   let Inst{4}     = 1;
538   let Inst{5}     = 1; // H bit
539   let Inst{6}     = 0; // S bit
540   let Inst{7}     = 1;
541   let Inst{20}    = 0; // L bit
542   let Inst{21}    = 0; // W bit
543   let Inst{24}    = 1; // P bit
544 }
545 class AI3std<dag oops, dag iops, Format f, string opc,
546           string asm, list<dag> pattern>
547   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
548       asm, "", pattern> {
549   let Inst{4}     = 1;
550   let Inst{5}     = 1; // H bit
551   let Inst{6}     = 1; // S bit
552   let Inst{7}     = 1;
553   let Inst{20}    = 0; // L bit
554   let Inst{21}    = 0; // W bit
555   let Inst{24}    = 1; // P bit
556 }
557
558 // Pre-indexed loads
559 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
560             string asm, string cstr, list<dag> pattern>
561   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
562       asm, cstr, pattern> {
563   let Inst{4}     = 1;
564   let Inst{5}     = 1; // H bit
565   let Inst{6}     = 0; // S bit
566   let Inst{7}     = 1;
567   let Inst{20}    = 1; // L bit
568   let Inst{21}    = 1; // W bit
569   let Inst{24}    = 1; // P bit
570 }
571 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
572             string asm, string cstr, list<dag> pattern>
573   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
574       asm, cstr, pattern> {
575   let Inst{4}     = 1;
576   let Inst{5}     = 1; // H bit
577   let Inst{6}     = 1; // S bit
578   let Inst{7}     = 1;
579   let Inst{20}    = 1; // L bit
580   let Inst{21}    = 1; // W bit
581   let Inst{24}    = 1; // P bit
582 }
583 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
584             string asm, string cstr, list<dag> pattern>
585   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
586       asm, cstr, pattern> {
587   let Inst{4}     = 1;
588   let Inst{5}     = 0; // H bit
589   let Inst{6}     = 1; // S bit
590   let Inst{7}     = 1;
591   let Inst{20}    = 1; // L bit
592   let Inst{21}    = 1; // W bit
593   let Inst{24}    = 1; // P bit
594 }
595
596 // Pre-indexed stores
597 class AI3sthpr<dag oops, dag iops, Format f, string opc,
598             string asm, string cstr, list<dag> pattern>
599   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
600       asm, cstr, pattern> {
601   let Inst{4}     = 1;
602   let Inst{5}     = 1; // H bit
603   let Inst{6}     = 0; // S bit
604   let Inst{7}     = 1;
605   let Inst{20}    = 0; // L bit
606   let Inst{21}    = 1; // W bit
607   let Inst{24}    = 1; // P bit
608 }
609
610 // Post-indexed loads
611 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
612             string asm, string cstr, list<dag> pattern>
613   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
614       asm, cstr,pattern> {
615   let Inst{4}     = 1;
616   let Inst{5}     = 1; // H bit
617   let Inst{6}     = 0; // S bit
618   let Inst{7}     = 1;
619   let Inst{20}    = 1; // L bit
620   let Inst{21}    = 1; // W bit
621   let Inst{24}    = 0; // P bit
622 }
623 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
624             string asm, string cstr, list<dag> pattern>
625   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
626       asm, cstr,pattern> {
627   let Inst{4}     = 1;
628   let Inst{5}     = 1; // H bit
629   let Inst{6}     = 1; // S bit
630   let Inst{7}     = 1;
631   let Inst{20}    = 1; // L bit
632   let Inst{21}    = 1; // W bit
633   let Inst{24}    = 0; // P bit
634 }
635 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
636             string asm, string cstr, list<dag> pattern>
637   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
638       asm, cstr,pattern> {
639   let Inst{4}     = 1;
640   let Inst{5}     = 0; // H bit
641   let Inst{6}     = 1; // S bit
642   let Inst{7}     = 1;
643   let Inst{20}    = 1; // L bit
644   let Inst{21}    = 1; // W bit
645   let Inst{24}    = 0; // P bit
646 }
647
648 // Post-indexed stores
649 class AI3sthpo<dag oops, dag iops, Format f, string opc,
650             string asm, string cstr, list<dag> pattern>
651   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
652       asm, cstr,pattern> {
653   let Inst{4}     = 1;
654   let Inst{5}     = 1; // H bit
655   let Inst{6}     = 0; // S bit
656   let Inst{7}     = 1;
657   let Inst{20}    = 0; // L bit
658   let Inst{21}    = 1; // W bit
659   let Inst{24}    = 0; // P bit
660 }
661
662
663 // addrmode4 instructions
664 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
665   : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
666        "", pattern> {
667   let Inst{20}    = 1; // L bit
668   let Inst{22}    = 0; // S bit
669   let Inst{27-25} = 0b100;
670 }
671 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
672   : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
673        "", pattern> {
674   let Inst{20}    = 0; // L bit
675   let Inst{22}    = 0; // S bit
676   let Inst{27-25} = 0b100;
677 }
678
679 // Unsigned multiply, multiply-accumulate instructions.
680 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
681          string asm, list<dag> pattern>
682   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
683       asm, "", pattern> {
684   let Inst{7-4}   = 0b1001;
685   let Inst{20}    = 0; // S bit
686   let Inst{27-21} = opcod;
687 }
688 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
689           string asm, list<dag> pattern>
690   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
691        asm, "", pattern> {
692   let Inst{7-4}   = 0b1001;
693   let Inst{27-21} = opcod;
694 }
695
696 // Most significant word multiply
697 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
698          string asm, list<dag> pattern>
699   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
700       asm, "", pattern> {
701   let Inst{7-4}   = 0b1001;
702   let Inst{20}    = 1;
703   let Inst{27-21} = opcod;
704 }
705
706 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
707 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
708          string asm, list<dag> pattern>
709   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
710       asm, "", pattern> {
711   let Inst{4}     = 0;
712   let Inst{7}     = 1;
713   let Inst{20}    = 0;
714   let Inst{27-21} = opcod;
715 }
716
717 // Extend instructions.
718 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
719             string asm, list<dag> pattern>
720   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
721       asm, "", pattern> {
722   let Inst{7-4}   = 0b0111;
723   let Inst{27-20} = opcod;
724 }
725
726 // Misc Arithmetic instructions.
727 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
728                string asm, list<dag> pattern>
729   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
730       asm, "", pattern> {
731   let Inst{27-20} = opcod;
732 }
733
734 //===----------------------------------------------------------------------===//
735
736 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
737 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
738   list<Predicate> Predicates = [IsARM];
739 }
740 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
741   list<Predicate> Predicates = [IsARM, HasV5TE];
742 }
743 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
744   list<Predicate> Predicates = [IsARM, HasV6];
745 }
746
747 //===----------------------------------------------------------------------===//
748 //
749 // Thumb Instruction Format Definitions.
750 //
751
752 // TI - Thumb instruction.
753
754 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
755              string asm, string cstr, list<dag> pattern>
756   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
757   let OutOperandList = outs;
758   let InOperandList = ins;
759   let AsmString   = asm;
760   let Pattern = pattern;
761   list<Predicate> Predicates = [IsThumb];
762 }
763
764 class TI<dag outs, dag ins, string asm, list<dag> pattern>
765   : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
766
767 // BL, BLX(1) are translated by assembler into two instructions
768 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
769   : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
770
771 // BR_JT instructions
772 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
773   : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
774
775 // TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
776 class TPat<dag pattern, dag result> : Pat<pattern, result> {
777   list<Predicate> Predicates = [IsThumb];
778 }
779
780 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
781   list<Predicate> Predicates = [IsThumb, HasV5T];
782 }
783
784 // Thumb1 only
785 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
786              string asm, string cstr, list<dag> pattern>
787   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
788   let OutOperandList = outs;
789   let InOperandList = ins;
790   let AsmString   = asm;
791   let Pattern = pattern;
792   list<Predicate> Predicates = [IsThumb1Only];
793 }
794
795 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
796   : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
797 class T1I1<dag outs, dag ins, string asm, list<dag> pattern>
798   : Thumb1I<outs, ins, AddrModeT1_1, Size2Bytes, asm, "", pattern>;
799 class T1I2<dag outs, dag ins, string asm, list<dag> pattern>
800   : Thumb1I<outs, ins, AddrModeT1_2, Size2Bytes, asm, "", pattern>;
801 class T1I4<dag outs, dag ins, string asm, list<dag> pattern>
802   : Thumb1I<outs, ins, AddrModeT1_4, Size2Bytes, asm, "", pattern>;
803 class T1Is<dag outs, dag ins, string asm, list<dag> pattern>
804   : Thumb1I<outs, ins, AddrModeT1_s, Size2Bytes, asm, "", pattern>;
805 class T1Ix2<dag outs, dag ins, string asm, list<dag> pattern>
806   : Thumb1I<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
807 class T1JTI<dag outs, dag ins, string asm, list<dag> pattern>
808   : Thumb1I<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
809
810 // Two-address instructions
811 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
812   : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
813
814 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
815   list<Predicate> Predicates = [IsThumb1Only];
816 }
817
818 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
819 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
820               string opc, string asm, string cstr, list<dag> pattern>
821   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
822   let OutOperandList = oops;
823   let InOperandList = !con(iops, (ops pred:$p));
824   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
825   let Pattern = pattern;
826   list<Predicate> Predicates = [IsThumb2];
827 }
828
829 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
830 // an input operand since by default it's a zero register. It will
831 // become an implicit def once it's "flipped".
832 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
833 // more consistent.
834 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
835                string opc, string asm, string cstr, list<dag> pattern>
836   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
837   let OutOperandList = oops;
838   let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
839   let AsmString   = !strconcat(opc, !strconcat("${s}${p}", asm));
840   let Pattern = pattern;
841   list<Predicate> Predicates = [IsThumb2];
842 }
843
844 // Special cases
845 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
846                string asm, string cstr, list<dag> pattern>
847   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
848   let OutOperandList = oops;
849   let InOperandList = iops;
850   let AsmString   = asm;
851   let Pattern = pattern;
852   list<Predicate> Predicates = [IsThumb2];
853 }
854
855 class T2I<dag oops, dag iops, string opc, string asm, list<dag> pattern>
856   : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
857 class T2Ii12<dag oops, dag iops, string opc, string asm, list<dag> pattern>
858   : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, opc, asm, "", pattern>;
859 class T2Ii8<dag oops, dag iops, string opc, string asm, list<dag> pattern>
860   : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, opc, asm, "", pattern>;
861 class T2Iso<dag oops, dag iops, string opc, string asm, list<dag> pattern>
862   : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, opc, asm, "", pattern>;
863 class T2Ipc<dag oops, dag iops, string opc, string asm, list<dag> pattern>
864   : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, opc, asm, "", pattern>;
865 class T2Ii8s4<dag oops, dag iops, string opc, string asm, list<dag> pattern>
866   : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, opc, asm, "", pattern>;
867
868 class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
869   : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
870
871 class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
872   : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
873 class T2JTI<dag oops, dag iops, string asm, list<dag> pattern>
874   : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, asm, "", pattern>;
875
876 // T2Iidxldst - Thumb2 indexed load / store instructions.
877 class T2Iidxldst<dag oops, dag iops, AddrMode am, IndexMode im,
878                  string opc, string asm, string cstr, list<dag> pattern>
879   : InstARM<am, Size4Bytes, im, ThumbFrm, cstr> {
880   let OutOperandList = oops;
881   let InOperandList = !con(iops, (ops pred:$p));
882   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
883   let Pattern = pattern;
884   list<Predicate> Predicates = [IsThumb2];
885 }
886
887
888 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
889 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
890   list<Predicate> Predicates = [IsThumb2];
891 }
892
893 //===----------------------------------------------------------------------===//
894
895 //===----------------------------------------------------------------------===//
896 // ARM VFP Instruction templates.
897 //
898
899 // ARM VFP addrmode5 loads and stores
900 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
901            string opc, string asm, list<dag> pattern>
902   : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
903       VFPLdStFrm, opc, asm, "", pattern> {
904   // TODO: Mark the instructions with the appropriate subtarget info.
905   let Inst{27-24} = opcod1;
906   let Inst{21-20} = opcod2;
907   let Inst{11-8}  = 0b1011;
908 }
909
910 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
911            string opc, string asm, list<dag> pattern>
912   : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
913       VFPLdStFrm, opc, asm, "", pattern> {
914   // TODO: Mark the instructions with the appropriate subtarget info.
915   let Inst{27-24} = opcod1;
916   let Inst{21-20} = opcod2;
917   let Inst{11-8}  = 0b1010;
918 }
919
920 // Load / store multiple
921 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
922   : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
923        VFPLdStMulFrm, asm, "", pattern> {
924   // TODO: Mark the instructions with the appropriate subtarget info.
925   let Inst{27-25} = 0b110;
926   let Inst{11-8}  = 0b1011;
927 }
928
929 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
930   : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
931        VFPLdStMulFrm, asm, "", pattern> {
932   // TODO: Mark the instructions with the appropriate subtarget info.
933   let Inst{27-25} = 0b110;
934   let Inst{11-8}  = 0b1010;
935 }
936
937
938 // Double precision, unary
939 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
940            string opc, string asm, list<dag> pattern>
941   : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
942   let Inst{27-20} = opcod1;
943   let Inst{19-16} = opcod2;
944   let Inst{11-8}  = 0b1011;
945   let Inst{7-4}   = opcod3;
946 }
947
948 // Double precision, binary
949 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
950            string asm, list<dag> pattern>
951   : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
952   let Inst{27-20} = opcod;
953   let Inst{11-8}  = 0b1011;
954 }
955
956 // Single precision, unary
957 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
958            string opc, string asm, list<dag> pattern>
959   : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
960   // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
961   let Inst{27-20} = opcod1;
962   let Inst{19-16} = opcod2;
963   let Inst{11-8}  = 0b1010;
964   let Inst{7-4}   = opcod3;
965 }
966
967 // Single precision, binary
968 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
969            string asm, list<dag> pattern>
970   : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
971   // Bit 22 (D bit) can be changed during instruction encoding.
972   let Inst{27-20} = opcod;
973   let Inst{11-8}  = 0b1010;
974 }
975
976 // VFP conversion instructions
977 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
978                dag oops, dag iops, string opc, string asm, list<dag> pattern>
979   : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
980   let Inst{27-20} = opcod1;
981   let Inst{19-16} = opcod2;
982   let Inst{11-8}  = opcod3;
983   let Inst{6}     = 1;
984 }
985
986 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
987              string opc, string asm, list<dag> pattern>
988   : AI<oops, iops, f, opc, asm, pattern> {
989   let Inst{27-20} = opcod1;
990   let Inst{11-8}  = opcod2;
991   let Inst{4}     = 1;
992 }
993
994 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
995               string asm, list<dag> pattern>
996   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
997
998 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
999               string asm, list<dag> pattern>
1000   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
1001
1002 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
1003               string asm, list<dag> pattern>
1004   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
1005
1006 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
1007               string asm, list<dag> pattern>
1008   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
1009
1010 //===----------------------------------------------------------------------===//
1011
1012 //===----------------------------------------------------------------------===//
1013 // ARM NEON Instruction templates.
1014 //
1015
1016 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
1017             string cstr, list<dag> pattern>
1018   : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
1019   let OutOperandList = oops;
1020   let InOperandList = iops;
1021   let AsmString = asm;
1022   let Pattern = pattern;
1023   list<Predicate> Predicates = [HasNEON];
1024 }
1025
1026 class NI<dag oops, dag iops, string asm, list<dag> pattern>
1027   : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
1028 }
1029
1030 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1031   : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
1032   let Inst{31-25} = 0b1111001;
1033 }
1034
1035 // NEON "one register and a modified immediate" format.
1036 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1037                bit op5, bit op4,
1038                dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1039   : NDataI<oops, iops, asm, cstr, pattern> {
1040   let Inst{23} = op23;
1041   let Inst{21-19} = op21_19;
1042   let Inst{11-8} = op11_8;
1043   let Inst{7} = op7;
1044   let Inst{6} = op6;
1045   let Inst{5} = op5;
1046   let Inst{4} = op4;
1047 }
1048
1049 // NEON 2 vector register format.
1050 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1051           bits<5> op11_7, bit op6, bit op4,
1052           dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1053   : NDataI<oops, iops, asm, cstr, pattern> {
1054   let Inst{24-23} = op24_23;
1055   let Inst{21-20} = op21_20;
1056   let Inst{19-18} = op19_18;
1057   let Inst{17-16} = op17_16;
1058   let Inst{11-7} = op11_7;
1059   let Inst{6} = op6;
1060   let Inst{4} = op4;
1061 }
1062
1063 // NEON 2 vector register with immediate.
1064 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
1065              bit op6, bit op4,
1066              dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1067   : NDataI<oops, iops, asm, cstr, pattern> {
1068   let Inst{24} = op24;
1069   let Inst{23} = op23;
1070   let Inst{21-16} = op21_16;
1071   let Inst{11-8} = op11_8;
1072   let Inst{7} = op7;
1073   let Inst{6} = op6;
1074   let Inst{4} = op4;
1075 }
1076
1077 // NEON 3 vector register format.
1078 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1079           dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1080   : NDataI<oops, iops, asm, cstr, pattern> {
1081   let Inst{24} = op24;
1082   let Inst{23} = op23;
1083   let Inst{21-20} = op21_20;
1084   let Inst{11-8} = op11_8;
1085   let Inst{6} = op6;
1086   let Inst{4} = op4;
1087 }
1088
1089 // NEON VMOVs between scalar and core registers.
1090 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1091                dag oops, dag iops, Format f, string opc, string asm,
1092                list<dag> pattern>
1093   : AI<oops, iops, f, opc, asm, pattern> {
1094   let Inst{27-20} = opcod1;
1095   let Inst{11-8} = opcod2;
1096   let Inst{6-5} = opcod3;
1097   let Inst{4} = 1;
1098   list<Predicate> Predicates = [HasNEON];
1099 }
1100 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1101                 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1102   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1103              pattern>;
1104 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1105                 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1106   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1107              pattern>;
1108 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1109             dag oops, dag iops, string opc, string asm, list<dag> pattern>
1110   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;