fix typo
[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<6> val> {
19   bits<6> 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 LdStExFrm     : Format<11>;
37
38 def ArithMiscFrm  : Format<12>;
39 def ExtFrm        : Format<13>;
40
41 def VFPUnaryFrm   : Format<14>;
42 def VFPBinaryFrm  : Format<15>;
43 def VFPConv1Frm   : Format<16>;
44 def VFPConv2Frm   : Format<17>;
45 def VFPConv3Frm   : Format<18>;
46 def VFPConv4Frm   : Format<19>;
47 def VFPConv5Frm   : Format<20>;
48 def VFPLdStFrm    : Format<21>;
49 def VFPLdStMulFrm : Format<22>;
50 def VFPMiscFrm    : Format<23>;
51
52 def ThumbFrm      : Format<24>;
53
54 def NEONFrm       : Format<25>;
55 def NEONGetLnFrm  : Format<26>;
56 def NEONSetLnFrm  : Format<27>;
57 def NEONDupFrm    : Format<28>;
58
59 def MiscFrm       : Format<29>;
60 def ThumbMiscFrm  : Format<30>;
61
62 def NLdStFrm       : Format<31>;
63 def N1RegModImmFrm : Format<32>;
64 def N2RegFrm       : Format<33>;
65 def NVCVTFrm       : Format<34>;
66 def NVDupLnFrm     : Format<35>;
67 def N2RegVShLFrm   : Format<36>;
68 def N2RegVShRFrm   : Format<37>;
69 def N3RegFrm       : Format<38>;
70 def N3RegVShFrm    : Format<39>;
71 def NVExtFrm       : Format<40>;
72 def NVMulSLFrm     : Format<41>;
73 def NVTBLFrm       : Format<42>;
74
75 // Misc flags.
76
77 // the instruction has a Rn register operand.
78 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
79 // it doesn't have a Rn operand.
80 class UnaryDP    { bit isUnaryDataProc = 1; }
81
82 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
83 // a 16-bit Thumb instruction if certain conditions are met.
84 class Xform16Bit { bit canXformTo16Bit = 1; }
85
86 //===----------------------------------------------------------------------===//
87 // ARM Instruction flags.  These need to match ARMBaseInstrInfo.h.
88 //
89
90 // Addressing mode.
91 class AddrMode<bits<4> val> {
92   bits<4> Value = val;
93 }
94 def AddrModeNone  : AddrMode<0>;
95 def AddrMode1     : AddrMode<1>;
96 def AddrMode2     : AddrMode<2>;
97 def AddrMode3     : AddrMode<3>;
98 def AddrMode4     : AddrMode<4>;
99 def AddrMode5     : AddrMode<5>;
100 def AddrMode6     : AddrMode<6>;
101 def AddrModeT1_1  : AddrMode<7>;
102 def AddrModeT1_2  : AddrMode<8>;
103 def AddrModeT1_4  : AddrMode<9>;
104 def AddrModeT1_s  : AddrMode<10>;
105 def AddrModeT2_i12: AddrMode<11>;
106 def AddrModeT2_i8 : AddrMode<12>;
107 def AddrModeT2_so : AddrMode<13>;
108 def AddrModeT2_pc : AddrMode<14>;
109 def AddrModeT2_i8s4 : AddrMode<15>;
110
111 // Instruction size.
112 class SizeFlagVal<bits<3> val> {
113   bits<3> Value = val;
114 }
115 def SizeInvalid  : SizeFlagVal<0>;  // Unset.
116 def SizeSpecial  : SizeFlagVal<1>;  // Pseudo or special.
117 def Size8Bytes   : SizeFlagVal<2>;
118 def Size4Bytes   : SizeFlagVal<3>;
119 def Size2Bytes   : SizeFlagVal<4>;
120
121 // Load / store index mode.
122 class IndexMode<bits<2> val> {
123   bits<2> Value = val;
124 }
125 def IndexModeNone : IndexMode<0>;
126 def IndexModePre  : IndexMode<1>;
127 def IndexModePost : IndexMode<2>;
128 def IndexModeUpd  : IndexMode<3>;
129
130 // Instruction execution domain.
131 class Domain<bits<2> val> {
132   bits<2> Value = val;
133 }
134 def GenericDomain : Domain<0>;
135 def VFPDomain     : Domain<1>; // Instructions in VFP domain only
136 def NeonDomain    : Domain<2>; // Instructions in Neon domain only
137 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
138
139 //===----------------------------------------------------------------------===//
140
141 // ARM special operands.
142 //
143
144 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
145 // register whose default is 0 (no register).
146 def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
147                                      (ops (i32 14), (i32 zero_reg))> {
148   let PrintMethod = "printPredicateOperand";
149 }
150
151 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
152 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
153   let PrintMethod = "printSBitModifierOperand";
154 }
155
156 // Same as cc_out except it defaults to setting CPSR.
157 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
158   let PrintMethod = "printSBitModifierOperand";
159 }
160
161 // ARM special operands for disassembly only.
162 //
163
164 def cps_opt : Operand<i32> {
165   let PrintMethod = "printCPSOptionOperand";
166 }
167
168 def msr_mask : Operand<i32> {
169   let PrintMethod = "printMSRMaskOperand";
170 }
171
172 // A8.6.117, A8.6.118.  Different instructions are generated for #0 and #-0.
173 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
174 def neg_zero : Operand<i32> {
175   let PrintMethod = "printNegZeroOperand";
176 }
177
178 //===----------------------------------------------------------------------===//
179
180 // ARM Instruction templates.
181 //
182
183 class InstTemplate<AddrMode am, SizeFlagVal sz, IndexMode im,
184                    Format f, Domain d, string cstr, InstrItinClass itin>
185   : Instruction {
186   let Namespace = "ARM";
187
188   AddrMode AM = am;
189   SizeFlagVal SZ = sz;
190   IndexMode IM = im;
191   bits<2> IndexModeBits = IM.Value;
192   Format F = f;
193   bits<6> Form = F.Value;
194   Domain D = d;
195   bit isUnaryDataProc = 0;
196   bit canXformTo16Bit = 0;
197
198   // The layout of TSFlags should be kept in sync with ARMBaseInstrInfo.h.
199   let TSFlags{3-0}   = AM.Value;
200   let TSFlags{6-4}   = SZ.Value;
201   let TSFlags{8-7}   = IndexModeBits;
202   let TSFlags{14-9}  = Form;
203   let TSFlags{15}    = isUnaryDataProc;
204   let TSFlags{16}    = canXformTo16Bit;
205   let TSFlags{18-17} = D.Value;
206
207   let Constraints = cstr;
208   let Itinerary = itin;
209 }
210
211 class Encoding {
212   field bits<32> Inst;
213 }
214
215 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
216               Format f, Domain d, string cstr, InstrItinClass itin>
217   : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding;
218
219 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
220 // on by adding flavors to specific instructions.
221 class InstThumb<AddrMode am, SizeFlagVal sz, IndexMode im,
222                 Format f, Domain d, string cstr, InstrItinClass itin>
223   : InstTemplate<am, sz, im, f, d, cstr, itin>;
224
225 class PseudoInst<dag oops, dag iops, InstrItinClass itin,
226                  string asm, list<dag> pattern>
227   : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, GenericDomain,
228             "", itin> {
229   let OutOperandList = oops;
230   let InOperandList = iops;
231   let AsmString = asm;
232   let Pattern = pattern;
233 }
234
235 // Almost all ARM instructions are predicable.
236 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
237         IndexMode im, Format f, InstrItinClass itin,
238         string opc, string asm, string cstr,
239         list<dag> pattern>
240   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
241   let OutOperandList = oops;
242   let InOperandList = !con(iops, (ins pred:$p));
243   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
244   let Pattern = pattern;
245   list<Predicate> Predicates = [IsARM];
246 }
247 // A few are not predicable
248 class InoP<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
249            IndexMode im, Format f, InstrItinClass itin,
250            string opc, string asm, string cstr,
251            list<dag> pattern>
252   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
253   let OutOperandList = oops;
254   let InOperandList = iops;
255   let AsmString = !strconcat(opc, asm);
256   let Pattern = pattern;
257   let isPredicable = 0;
258   list<Predicate> Predicates = [IsARM];
259 }
260
261 // Same as I except it can optionally modify CPSR. Note it's modeled as
262 // an input operand since by default it's a zero register. It will
263 // become an implicit def once it's "flipped".
264 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
265          IndexMode im, Format f, InstrItinClass itin,
266          string opc, string asm, string cstr,
267          list<dag> pattern>
268   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
269   let OutOperandList = oops;
270   let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
271   let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
272   let Pattern = pattern;
273   list<Predicate> Predicates = [IsARM];
274 }
275
276 // Special cases
277 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
278          IndexMode im, Format f, InstrItinClass itin,
279          string asm, string cstr, list<dag> pattern>
280   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
281   let OutOperandList = oops;
282   let InOperandList = iops;
283   let AsmString = asm;
284   let Pattern = pattern;
285   list<Predicate> Predicates = [IsARM];
286 }
287
288 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
289          string opc, string asm, list<dag> pattern>
290   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
291       opc, asm, "", pattern>;
292 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
293           string opc, string asm, list<dag> pattern>
294   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
295        opc, asm, "", pattern>;
296 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
297           string asm, list<dag> pattern>
298   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
299        asm, "", pattern>;
300 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
301             string opc, string asm, list<dag> pattern>
302   : InoP<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
303          opc, asm, "", pattern>;
304
305 // Ctrl flow instructions
306 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
307           string opc, string asm, list<dag> pattern>
308   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
309       opc, asm, "", pattern> {
310   let Inst{27-24} = opcod;
311 }
312 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
313            string asm, list<dag> pattern>
314   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
315        asm, "", pattern> {
316   let Inst{27-24} = opcod;
317 }
318 class ABXIx2<dag oops, dag iops, InstrItinClass itin,
319              string asm, list<dag> pattern>
320   : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, itin,
321        asm, "", pattern>;
322
323 // BR_JT instructions
324 class JTI<dag oops, dag iops, InstrItinClass itin,
325           string asm, list<dag> pattern>
326   : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm, itin,
327        asm, "", pattern>;
328
329
330 // Atomic load/store instructions
331
332 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
333               string opc, string asm, list<dag> pattern>
334   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
335       opc, asm, "", pattern> {
336   let Inst{27-23} = 0b00011;
337   let Inst{22-21} = opcod;
338   let Inst{20} = 1;
339   let Inst{11-0}  = 0b111110011111;
340 }
341 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
342               string opc, string asm, list<dag> pattern>
343   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
344       opc, asm, "", pattern> {
345   let Inst{27-23} = 0b00011;
346   let Inst{22-21} = opcod;
347   let Inst{20} = 0;
348   let Inst{11-4}  = 0b11111001;
349 }
350
351 // addrmode1 instructions
352 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
353           string opc, string asm, list<dag> pattern>
354   : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
355       opc, asm, "", pattern> {
356   let Inst{24-21} = opcod;
357   let Inst{27-26} = {0,0};
358 }
359 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
360            string opc, string asm, list<dag> pattern>
361   : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
362        opc, asm, "", pattern> {
363   let Inst{24-21} = opcod;
364   let Inst{27-26} = {0,0};
365 }
366 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
367            string asm, list<dag> pattern>
368   : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
369        asm, "", pattern> {
370   let Inst{24-21} = opcod;
371   let Inst{27-26} = {0,0};
372 }
373 class AI1x2<dag oops, dag iops, Format f, InstrItinClass itin,
374             string opc, string asm, list<dag> pattern>
375   : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, itin,
376       opc, asm, "", pattern>;
377
378
379 // addrmode2 loads and stores
380 class AI2<dag oops, dag iops, Format f, InstrItinClass itin,
381           string opc, string asm, list<dag> pattern>
382   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
383       opc, asm, "", pattern> {
384   let Inst{27-26} = {0,1};
385 }
386
387 // loads
388 class AI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
389              string opc, string asm, list<dag> pattern>
390   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
391       opc, asm, "", pattern> {
392   let Inst{20}    = 1; // L bit
393   let Inst{21}    = 0; // W bit
394   let Inst{22}    = 0; // B bit
395   let Inst{24}    = 1; // P bit
396   let Inst{27-26} = {0,1};
397 }
398 class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
399               string asm, list<dag> pattern>
400   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
401        asm, "", pattern> {
402   let Inst{20}    = 1; // L bit
403   let Inst{21}    = 0; // W bit
404   let Inst{22}    = 0; // B bit
405   let Inst{24}    = 1; // P bit
406   let Inst{27-26} = {0,1};
407 }
408 class AI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
409              string opc, string asm, list<dag> pattern>
410   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
411       opc, asm, "", pattern> {
412   let Inst{20}    = 1; // L bit
413   let Inst{21}    = 0; // W bit
414   let Inst{22}    = 1; // B bit
415   let Inst{24}    = 1; // P bit
416   let Inst{27-26} = {0,1};
417 }
418 class AXI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
419               string asm, list<dag> pattern>
420   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
421        asm, "", pattern> {
422   let Inst{20}    = 1; // L bit
423   let Inst{21}    = 0; // W bit
424   let Inst{22}    = 1; // B bit
425   let Inst{24}    = 1; // P bit
426   let Inst{27-26} = {0,1};
427 }
428
429 // stores
430 class AI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
431              string opc, string asm, list<dag> pattern>
432   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
433       opc, asm, "", pattern> {
434   let Inst{20}    = 0; // L bit
435   let Inst{21}    = 0; // W bit
436   let Inst{22}    = 0; // B bit
437   let Inst{24}    = 1; // P bit
438   let Inst{27-26} = {0,1};
439 }
440 class AXI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
441               string asm, list<dag> pattern>
442   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
443        asm, "", pattern> {
444   let Inst{20}    = 0; // L bit
445   let Inst{21}    = 0; // W bit
446   let Inst{22}    = 0; // B bit
447   let Inst{24}    = 1; // P bit
448   let Inst{27-26} = {0,1};
449 }
450 class AI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
451              string opc, string asm, list<dag> pattern>
452   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
453       opc, asm, "", pattern> {
454   let Inst{20}    = 0; // L bit
455   let Inst{21}    = 0; // W bit
456   let Inst{22}    = 1; // B bit
457   let Inst{24}    = 1; // P bit
458   let Inst{27-26} = {0,1};
459 }
460 class AXI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
461               string asm, list<dag> pattern>
462   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
463        asm, "", pattern> {
464   let Inst{20}    = 0; // L bit
465   let Inst{21}    = 0; // W bit
466   let Inst{22}    = 1; // B bit
467   let Inst{24}    = 1; // P bit
468   let Inst{27-26} = {0,1};
469 }
470
471 // Pre-indexed loads
472 class AI2ldwpr<dag oops, dag iops, Format f, InstrItinClass itin,
473                string opc, string asm, string cstr, list<dag> pattern>
474   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
475       opc, asm, cstr, pattern> {
476   let Inst{20}    = 1; // L bit
477   let Inst{21}    = 1; // W bit
478   let Inst{22}    = 0; // B bit
479   let Inst{24}    = 1; // P bit
480   let Inst{27-26} = {0,1};
481 }
482 class AI2ldbpr<dag oops, dag iops, Format f, InstrItinClass itin,
483                string opc, string asm, string cstr, list<dag> pattern>
484   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
485       opc, asm, cstr, pattern> {
486   let Inst{20}    = 1; // L bit
487   let Inst{21}    = 1; // W bit
488   let Inst{22}    = 1; // B bit
489   let Inst{24}    = 1; // P bit
490   let Inst{27-26} = {0,1};
491 }
492
493 // Pre-indexed stores
494 class AI2stwpr<dag oops, dag iops, Format f, InstrItinClass itin,
495                string opc, string asm, string cstr, list<dag> pattern>
496   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
497       opc, asm, cstr, pattern> {
498   let Inst{20}    = 0; // L bit
499   let Inst{21}    = 1; // W bit
500   let Inst{22}    = 0; // B bit
501   let Inst{24}    = 1; // P bit
502   let Inst{27-26} = {0,1};
503 }
504 class AI2stbpr<dag oops, dag iops, Format f, InstrItinClass itin,
505                string opc, string asm, string cstr, list<dag> pattern>
506   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
507       opc, asm, cstr, pattern> {
508   let Inst{20}    = 0; // L bit
509   let Inst{21}    = 1; // W bit
510   let Inst{22}    = 1; // B bit
511   let Inst{24}    = 1; // P bit
512   let Inst{27-26} = {0,1};
513 }
514
515 // Post-indexed loads
516 class AI2ldwpo<dag oops, dag iops, Format f, InstrItinClass itin,
517                string opc, string asm, string cstr, list<dag> pattern>
518   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
519       opc, asm, cstr,pattern> {
520   let Inst{20}    = 1; // L bit
521   let Inst{21}    = 0; // W bit
522   let Inst{22}    = 0; // B bit
523   let Inst{24}    = 0; // P bit
524   let Inst{27-26} = {0,1};
525 }
526 class AI2ldbpo<dag oops, dag iops, Format f, InstrItinClass itin,
527                string opc, string asm, string cstr, list<dag> pattern>
528   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
529       opc, asm, cstr,pattern> {
530   let Inst{20}    = 1; // L bit
531   let Inst{21}    = 0; // W bit
532   let Inst{22}    = 1; // B bit
533   let Inst{24}    = 0; // P bit
534   let Inst{27-26} = {0,1};
535 }
536
537 // Post-indexed stores
538 class AI2stwpo<dag oops, dag iops, Format f, InstrItinClass itin,
539                string opc, string asm, string cstr, list<dag> pattern>
540   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
541       opc, asm, cstr,pattern> {
542   let Inst{20}    = 0; // L bit
543   let Inst{21}    = 0; // W bit
544   let Inst{22}    = 0; // B bit
545   let Inst{24}    = 0; // P bit
546   let Inst{27-26} = {0,1};
547 }
548 class AI2stbpo<dag oops, dag iops, Format f, InstrItinClass itin,
549                string opc, string asm, string cstr, list<dag> pattern>
550   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
551       opc, asm, cstr,pattern> {
552   let Inst{20}    = 0; // L bit
553   let Inst{21}    = 0; // W bit
554   let Inst{22}    = 1; // B bit
555   let Inst{24}    = 0; // P bit
556   let Inst{27-26} = {0,1};
557 }
558
559 // addrmode3 instructions
560 class AI3<dag oops, dag iops, Format f, InstrItinClass itin,
561           string opc, string asm, list<dag> pattern>
562   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
563       opc, asm, "", pattern>;
564 class AXI3<dag oops, dag iops, Format f, InstrItinClass itin,
565            string asm, list<dag> pattern>
566   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
567        asm, "", pattern>;
568
569 // loads
570 class AI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
571              string opc, string asm, list<dag> pattern>
572   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
573       opc, asm, "", pattern> {
574   let Inst{4}     = 1;
575   let Inst{5}     = 1; // H bit
576   let Inst{6}     = 0; // S bit
577   let Inst{7}     = 1;
578   let Inst{20}    = 1; // L bit
579   let Inst{21}    = 0; // W bit
580   let Inst{24}    = 1; // P bit
581   let Inst{27-25} = 0b000;
582 }
583 class AXI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
584               string asm, list<dag> pattern>
585   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
586        asm, "", pattern> {
587   let Inst{4}     = 1;
588   let Inst{5}     = 1; // H bit
589   let Inst{6}     = 0; // S bit
590   let Inst{7}     = 1;
591   let Inst{20}    = 1; // L bit
592   let Inst{21}    = 0; // W bit
593   let Inst{24}    = 1; // P bit
594 }
595 class AI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
596               string opc, string asm, list<dag> pattern>
597   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
598       opc, asm, "", pattern> {
599   let Inst{4}     = 1;
600   let Inst{5}     = 1; // H bit
601   let Inst{6}     = 1; // S bit
602   let Inst{7}     = 1;
603   let Inst{20}    = 1; // L bit
604   let Inst{21}    = 0; // W bit
605   let Inst{24}    = 1; // P bit
606   let Inst{27-25} = 0b000;
607 }
608 class AXI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
609                string asm, list<dag> pattern>
610   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
611        asm, "", pattern> {
612   let Inst{4}     = 1;
613   let Inst{5}     = 1; // H bit
614   let Inst{6}     = 1; // S bit
615   let Inst{7}     = 1;
616   let Inst{20}    = 1; // L bit
617   let Inst{21}    = 0; // W bit
618   let Inst{24}    = 1; // P bit
619 }
620 class AI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
621               string opc, string asm, list<dag> pattern>
622   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
623       opc, asm, "", pattern> {
624   let Inst{4}     = 1;
625   let Inst{5}     = 0; // H bit
626   let Inst{6}     = 1; // S bit
627   let Inst{7}     = 1;
628   let Inst{20}    = 1; // L bit
629   let Inst{21}    = 0; // W bit
630   let Inst{24}    = 1; // P bit
631   let Inst{27-25} = 0b000;
632 }
633 class AXI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
634                string asm, list<dag> pattern>
635   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
636        asm, "", pattern> {
637   let Inst{4}     = 1;
638   let Inst{5}     = 0; // H bit
639   let Inst{6}     = 1; // S bit
640   let Inst{7}     = 1;
641   let Inst{20}    = 1; // L bit
642   let Inst{21}    = 0; // W bit
643   let Inst{24}    = 1; // P bit
644 }
645 class AI3ldd<dag oops, dag iops, Format f, InstrItinClass itin,
646              string opc, string asm, list<dag> pattern>
647   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
648       opc, asm, "", pattern> {
649   let Inst{4}     = 1;
650   let Inst{5}     = 0; // H bit
651   let Inst{6}     = 1; // S bit
652   let Inst{7}     = 1;
653   let Inst{20}    = 0; // L bit
654   let Inst{21}    = 0; // W bit
655   let Inst{24}    = 1; // P bit
656   let Inst{27-25} = 0b000;
657 }
658
659 // stores
660 class AI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
661              string opc, string asm, list<dag> pattern>
662   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
663       opc, asm, "", pattern> {
664   let Inst{4}     = 1;
665   let Inst{5}     = 1; // H bit
666   let Inst{6}     = 0; // S bit
667   let Inst{7}     = 1;
668   let Inst{20}    = 0; // L bit
669   let Inst{21}    = 0; // W bit
670   let Inst{24}    = 1; // P bit
671   let Inst{27-25} = 0b000;
672 }
673 class AXI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
674               string asm, list<dag> pattern>
675   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
676        asm, "", pattern> {
677   let Inst{4}     = 1;
678   let Inst{5}     = 1; // H bit
679   let Inst{6}     = 0; // S bit
680   let Inst{7}     = 1;
681   let Inst{20}    = 0; // L bit
682   let Inst{21}    = 0; // W bit
683   let Inst{24}    = 1; // P bit
684 }
685 class AI3std<dag oops, dag iops, Format f, InstrItinClass itin,
686              string opc, string asm, list<dag> pattern>
687   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
688       opc, asm, "", pattern> {
689   let Inst{4}     = 1;
690   let Inst{5}     = 1; // H bit
691   let Inst{6}     = 1; // S bit
692   let Inst{7}     = 1;
693   let Inst{20}    = 0; // L bit
694   let Inst{21}    = 0; // W bit
695   let Inst{24}    = 1; // P bit
696   let Inst{27-25} = 0b000;
697 }
698
699 // Pre-indexed loads
700 class AI3ldhpr<dag oops, dag iops, Format f, InstrItinClass itin,
701                string opc, string asm, string cstr, list<dag> pattern>
702   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
703       opc, asm, cstr, pattern> {
704   let Inst{4}     = 1;
705   let Inst{5}     = 1; // H bit
706   let Inst{6}     = 0; // S bit
707   let Inst{7}     = 1;
708   let Inst{20}    = 1; // L bit
709   let Inst{21}    = 1; // W bit
710   let Inst{24}    = 1; // P bit
711   let Inst{27-25} = 0b000;
712 }
713 class AI3ldshpr<dag oops, dag iops, Format f, InstrItinClass itin,
714                 string opc, string asm, string cstr, list<dag> pattern>
715   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
716       opc, asm, cstr, pattern> {
717   let Inst{4}     = 1;
718   let Inst{5}     = 1; // H bit
719   let Inst{6}     = 1; // S bit
720   let Inst{7}     = 1;
721   let Inst{20}    = 1; // L bit
722   let Inst{21}    = 1; // W bit
723   let Inst{24}    = 1; // P bit
724   let Inst{27-25} = 0b000;
725 }
726 class AI3ldsbpr<dag oops, dag iops, Format f, InstrItinClass itin,
727                 string opc, string asm, string cstr, list<dag> pattern>
728   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
729       opc, asm, cstr, pattern> {
730   let Inst{4}     = 1;
731   let Inst{5}     = 0; // H bit
732   let Inst{6}     = 1; // S bit
733   let Inst{7}     = 1;
734   let Inst{20}    = 1; // L bit
735   let Inst{21}    = 1; // W bit
736   let Inst{24}    = 1; // P bit
737   let Inst{27-25} = 0b000;
738 }
739 class AI3lddpr<dag oops, dag iops, Format f, InstrItinClass itin,
740              string opc, string asm, string cstr, list<dag> pattern>
741   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
742       opc, asm, cstr, pattern> {
743   let Inst{4}     = 1;
744   let Inst{5}     = 0; // H bit
745   let Inst{6}     = 1; // S bit
746   let Inst{7}     = 1;
747   let Inst{20}    = 0; // L bit
748   let Inst{21}    = 1; // W bit
749   let Inst{24}    = 1; // P bit
750   let Inst{27-25} = 0b000;
751 }
752
753
754 // Pre-indexed stores
755 class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
756                string opc, string asm, string cstr, list<dag> pattern>
757   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
758       opc, asm, cstr, pattern> {
759   let Inst{4}     = 1;
760   let Inst{5}     = 1; // H bit
761   let Inst{6}     = 0; // S bit
762   let Inst{7}     = 1;
763   let Inst{20}    = 0; // L bit
764   let Inst{21}    = 1; // W bit
765   let Inst{24}    = 1; // P bit
766   let Inst{27-25} = 0b000;
767 }
768 class AI3stdpr<dag oops, dag iops, Format f, InstrItinClass itin,
769              string opc, string asm, string cstr, list<dag> pattern>
770   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
771       opc, asm, cstr, pattern> {
772   let Inst{4}     = 1;
773   let Inst{5}     = 1; // H bit
774   let Inst{6}     = 1; // S bit
775   let Inst{7}     = 1;
776   let Inst{20}    = 0; // L bit
777   let Inst{21}    = 1; // W bit
778   let Inst{24}    = 1; // P bit
779   let Inst{27-25} = 0b000;
780 }
781
782 // Post-indexed loads
783 class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin,
784                string opc, string asm, string cstr, list<dag> pattern>
785   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
786       opc, asm, cstr,pattern> {
787   let Inst{4}     = 1;
788   let Inst{5}     = 1; // H bit
789   let Inst{6}     = 0; // S bit
790   let Inst{7}     = 1;
791   let Inst{20}    = 1; // L bit
792   let Inst{21}    = 0; // W bit
793   let Inst{24}    = 0; // P bit
794   let Inst{27-25} = 0b000;
795 }
796 class AI3ldshpo<dag oops, dag iops, Format f, InstrItinClass itin,
797                 string opc, string asm, string cstr, list<dag> pattern>
798   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
799       opc, asm, cstr,pattern> {
800   let Inst{4}     = 1;
801   let Inst{5}     = 1; // H bit
802   let Inst{6}     = 1; // S bit
803   let Inst{7}     = 1;
804   let Inst{20}    = 1; // L bit
805   let Inst{21}    = 0; // W bit
806   let Inst{24}    = 0; // P bit
807   let Inst{27-25} = 0b000;
808 }
809 class AI3ldsbpo<dag oops, dag iops, Format f, InstrItinClass itin,
810                 string opc, string asm, string cstr, list<dag> pattern>
811   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
812       opc, asm, cstr,pattern> {
813   let Inst{4}     = 1;
814   let Inst{5}     = 0; // H bit
815   let Inst{6}     = 1; // S bit
816   let Inst{7}     = 1;
817   let Inst{20}    = 1; // L bit
818   let Inst{21}    = 0; // W bit
819   let Inst{24}    = 0; // P bit
820   let Inst{27-25} = 0b000;
821 }
822 class AI3lddpo<dag oops, dag iops, Format f, InstrItinClass itin,
823              string opc, string asm, string cstr, list<dag> pattern>
824   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
825       opc, asm, cstr, pattern> {
826   let Inst{4}     = 1;
827   let Inst{5}     = 0; // H bit
828   let Inst{6}     = 1; // S bit
829   let Inst{7}     = 1;
830   let Inst{20}    = 0; // L bit
831   let Inst{21}    = 0; // W bit
832   let Inst{24}    = 0; // P bit
833   let Inst{27-25} = 0b000;
834 }
835
836 // Post-indexed stores
837 class AI3sthpo<dag oops, dag iops, Format f, InstrItinClass itin,
838                string opc, string asm, string cstr, list<dag> pattern>
839   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
840       opc, asm, cstr,pattern> {
841   let Inst{4}     = 1;
842   let Inst{5}     = 1; // H bit
843   let Inst{6}     = 0; // S bit
844   let Inst{7}     = 1;
845   let Inst{20}    = 0; // L bit
846   let Inst{21}    = 0; // W bit
847   let Inst{24}    = 0; // P bit
848   let Inst{27-25} = 0b000;
849 }
850 class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
851              string opc, string asm, string cstr, list<dag> pattern>
852   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
853       opc, asm, cstr, pattern> {
854   let Inst{4}     = 1;
855   let Inst{5}     = 1; // H bit
856   let Inst{6}     = 1; // S bit
857   let Inst{7}     = 1;
858   let Inst{20}    = 0; // L bit
859   let Inst{21}    = 0; // W bit
860   let Inst{24}    = 0; // P bit
861   let Inst{27-25} = 0b000;
862 }
863
864 // addrmode4 instructions
865 class AXI4ld<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
866              string asm, string cstr, list<dag> pattern>
867   : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
868        asm, cstr, pattern> {
869   let Inst{20}    = 1; // L bit
870   let Inst{22}    = 0; // S bit
871   let Inst{27-25} = 0b100;
872 }
873 class AXI4st<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
874              string asm, string cstr, list<dag> pattern>
875   : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
876        asm, cstr, pattern> {
877   let Inst{20}    = 0; // L bit
878   let Inst{22}    = 0; // S bit
879   let Inst{27-25} = 0b100;
880 }
881
882 // Unsigned multiply, multiply-accumulate instructions.
883 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
884              string opc, string asm, list<dag> pattern>
885   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
886       opc, asm, "", pattern> {
887   let Inst{7-4}   = 0b1001;
888   let Inst{20}    = 0; // S bit
889   let Inst{27-21} = opcod;
890 }
891 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
892               string opc, string asm, list<dag> pattern>
893   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
894        opc, asm, "", pattern> {
895   let Inst{7-4}   = 0b1001;
896   let Inst{27-21} = opcod;
897 }
898
899 // Most significant word multiply
900 class AMul2I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
901              string opc, string asm, list<dag> pattern>
902   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
903       opc, asm, "", pattern> {
904   let Inst{7-4}   = 0b1001;
905   let Inst{20}    = 1;
906   let Inst{27-21} = opcod;
907 }
908
909 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
910 class AMulxyI<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
911               string opc, string asm, list<dag> pattern>
912   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
913       opc, asm, "", pattern> {
914   let Inst{4}     = 0;
915   let Inst{7}     = 1;
916   let Inst{20}    = 0;
917   let Inst{27-21} = opcod;
918 }
919
920 // Extend instructions.
921 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
922             string opc, string asm, list<dag> pattern>
923   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin,
924       opc, asm, "", pattern> {
925   let Inst{7-4}   = 0b0111;
926   let Inst{27-20} = opcod;
927 }
928
929 // Misc Arithmetic instructions.
930 class AMiscA1I<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
931                string opc, string asm, list<dag> pattern>
932   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin,
933       opc, asm, "", pattern> {
934   let Inst{27-20} = opcod;
935 }
936
937 //===----------------------------------------------------------------------===//
938
939 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
940 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
941   list<Predicate> Predicates = [IsARM];
942 }
943 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
944   list<Predicate> Predicates = [IsARM, HasV5TE];
945 }
946 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
947   list<Predicate> Predicates = [IsARM, HasV6];
948 }
949
950 //===----------------------------------------------------------------------===//
951 //
952 // Thumb Instruction Format Definitions.
953 //
954
955 // TI - Thumb instruction.
956
957 class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
958              InstrItinClass itin, string asm, string cstr, list<dag> pattern>
959   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
960   let OutOperandList = oops;
961   let InOperandList = iops;
962   let AsmString = asm;
963   let Pattern = pattern;
964   list<Predicate> Predicates = [IsThumb];
965 }
966
967 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
968   : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
969
970 // Two-address instructions
971 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
972           list<dag> pattern>
973   : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "$lhs = $dst",
974            pattern>;
975
976 // tBL, tBX 32-bit instructions
977 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
978            dag oops, dag iops, InstrItinClass itin, string asm,
979            list<dag> pattern>
980     : ThumbI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>,
981       Encoding {
982   let Inst{31-27} = opcod1;
983   let Inst{15-14} = opcod2;
984   let Inst{12} = opcod3;
985 }
986
987 // BR_JT instructions
988 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
989            list<dag> pattern>
990   : ThumbI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
991
992 // Thumb1 only
993 class Thumb1I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
994               InstrItinClass itin, string asm, string cstr, list<dag> pattern>
995   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
996   let OutOperandList = oops;
997   let InOperandList = iops;
998   let AsmString = asm;
999   let Pattern = pattern;
1000   list<Predicate> Predicates = [IsThumb1Only];
1001 }
1002
1003 class T1I<dag oops, dag iops, InstrItinClass itin,
1004           string asm, list<dag> pattern>
1005   : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
1006 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1007             string asm, list<dag> pattern>
1008   : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
1009 class T1JTI<dag oops, dag iops, InstrItinClass itin,
1010             string asm, list<dag> pattern>
1011   : Thumb1I<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
1012
1013 // Two-address instructions
1014 class T1It<dag oops, dag iops, InstrItinClass itin,
1015            string asm, string cstr, list<dag> pattern>
1016   : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin,
1017             asm, cstr, pattern>;
1018
1019 // Thumb1 instruction that can either be predicated or set CPSR.
1020 class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1021                InstrItinClass itin,
1022                string opc, string asm, string cstr, list<dag> pattern>
1023   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1024   let OutOperandList = !con(oops, (outs s_cc_out:$s));
1025   let InOperandList = !con(iops, (ins pred:$p));
1026   let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
1027   let Pattern = pattern;
1028   list<Predicate> Predicates = [IsThumb1Only];
1029 }
1030
1031 class T1sI<dag oops, dag iops, InstrItinClass itin,
1032            string opc, string asm, list<dag> pattern>
1033   : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
1034
1035 // Two-address instructions
1036 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1037             string opc, string asm, list<dag> pattern>
1038   : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
1039              "$lhs = $dst", pattern>;
1040
1041 // Thumb1 instruction that can be predicated.
1042 class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1043                InstrItinClass itin,
1044                string opc, string asm, string cstr, list<dag> pattern>
1045   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1046   let OutOperandList = oops;
1047   let InOperandList = !con(iops, (ins pred:$p));
1048   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1049   let Pattern = pattern;
1050   list<Predicate> Predicates = [IsThumb1Only];
1051 }
1052
1053 class T1pI<dag oops, dag iops, InstrItinClass itin,
1054            string opc, string asm, list<dag> pattern>
1055   : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
1056
1057 // Two-address instructions
1058 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1059             string opc, string asm, list<dag> pattern>
1060   : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
1061              "$lhs = $dst", pattern>;
1062
1063 class T1pI1<dag oops, dag iops, InstrItinClass itin,
1064             string opc, string asm, list<dag> pattern>
1065   : Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, itin, opc, asm, "", pattern>;
1066 class T1pI2<dag oops, dag iops, InstrItinClass itin,
1067             string opc, string asm, list<dag> pattern>
1068   : Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, itin, opc, asm, "", pattern>;
1069 class T1pI4<dag oops, dag iops, InstrItinClass itin,
1070             string opc, string asm, list<dag> pattern>
1071   : Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, itin, opc, asm, "", pattern>;
1072 class T1pIs<dag oops, dag iops,
1073             InstrItinClass itin, string opc, string asm, list<dag> pattern>
1074   : Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, itin, opc, asm, "", pattern>;
1075
1076 class Encoding16 : Encoding {
1077   let Inst{31-16} = 0x0000;
1078 }
1079
1080 // A6.2 16-bit Thumb instruction encoding
1081 class T1Encoding<bits<6> opcode> : Encoding16 {
1082   let Inst{15-10} = opcode;
1083 }
1084
1085 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1086 class T1General<bits<5> opcode> : Encoding16 {
1087   let Inst{15-14} = 0b00;
1088   let Inst{13-9} = opcode;
1089 }
1090
1091 // A6.2.2 Data-processing encoding.
1092 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1093   let Inst{15-10} = 0b010000;
1094   let Inst{9-6} = opcode;
1095 }
1096
1097 // A6.2.3 Special data instructions and branch and exchange encoding.
1098 class T1Special<bits<4> opcode> : Encoding16 {
1099   let Inst{15-10} = 0b010001;
1100   let Inst{9-6} = opcode;
1101 }
1102
1103 // A6.2.4 Load/store single data item encoding.
1104 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1105   let Inst{15-12} = opA;
1106   let Inst{11-9} = opB;
1107 }
1108 class T1LdSt<bits<3> opB> : T1LoadStore<0b0101, opB>;
1109 class T1LdSt4Imm<bits<3> opB> : T1LoadStore<0b0110, opB>; // Immediate, 4 bytes
1110 class T1LdSt1Imm<bits<3> opB> : T1LoadStore<0b0111, opB>; // Immediate, 1 byte
1111 class T1LdSt2Imm<bits<3> opB> : T1LoadStore<0b1000, opB>; // Immediate, 2 bytes
1112 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>;   // SP relative
1113
1114 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1115 class T1Misc<bits<7> opcode> : Encoding16 {
1116   let Inst{15-12} = 0b1011;
1117   let Inst{11-5} = opcode;
1118 }
1119
1120 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1121 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1122               InstrItinClass itin,
1123               string opc, string asm, string cstr, list<dag> pattern>
1124   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1125   let OutOperandList = oops;
1126   let InOperandList = !con(iops, (ins pred:$p));
1127   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1128   let Pattern = pattern;
1129   list<Predicate> Predicates = [IsThumb2];
1130 }
1131
1132 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
1133 // an input operand since by default it's a zero register. It will
1134 // become an implicit def once it's "flipped".
1135 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1136 // more consistent.
1137 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1138                InstrItinClass itin,
1139                string opc, string asm, string cstr, list<dag> pattern>
1140   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1141   let OutOperandList = oops;
1142   let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1143   let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
1144   let Pattern = pattern;
1145   list<Predicate> Predicates = [IsThumb2];
1146 }
1147
1148 // Special cases
1149 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1150                InstrItinClass itin,
1151                string asm, string cstr, list<dag> pattern>
1152   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1153   let OutOperandList = oops;
1154   let InOperandList = iops;
1155   let AsmString = asm;
1156   let Pattern = pattern;
1157   list<Predicate> Predicates = [IsThumb2];
1158 }
1159
1160 class ThumbXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1161               InstrItinClass itin,
1162               string asm, string cstr, list<dag> pattern>
1163   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1164   let OutOperandList = oops;
1165   let InOperandList = iops;
1166   let AsmString = asm;
1167   let Pattern = pattern;
1168   list<Predicate> Predicates = [IsThumb1Only];
1169 }
1170
1171 class T2I<dag oops, dag iops, InstrItinClass itin,
1172           string opc, string asm, list<dag> pattern>
1173   : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1174 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1175              string opc, string asm, list<dag> pattern>
1176   : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, itin, opc, asm, "",pattern>;
1177 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1178             string opc, string asm, list<dag> pattern>
1179   : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, itin, opc, asm, "", pattern>;
1180 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1181             string opc, string asm, list<dag> pattern>
1182   : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, itin, opc, asm, "", pattern>;
1183 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1184             string opc, string asm, list<dag> pattern>
1185   : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, itin, opc, asm, "", pattern>;
1186 class T2Ii8s4<bit P, bit W, bit load, dag oops, dag iops, InstrItinClass itin,
1187               string opc, string asm, list<dag> pattern>
1188   : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, itin, opc, asm, "",
1189             pattern> {
1190   let Inst{31-27} = 0b11101;
1191   let Inst{26-25} = 0b00;
1192   let Inst{24} = P;
1193   let Inst{23} = ?; // The U bit.
1194   let Inst{22} = 1;
1195   let Inst{21} = W;
1196   let Inst{20} = load;
1197 }
1198
1199 class T2sI<dag oops, dag iops, InstrItinClass itin,
1200            string opc, string asm, list<dag> pattern>
1201   : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1202
1203 class T2XI<dag oops, dag iops, InstrItinClass itin,
1204            string asm, list<dag> pattern>
1205   : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
1206 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1207             string asm, list<dag> pattern>
1208   : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
1209
1210 class T2Ix2<dag oops, dag iops, InstrItinClass itin,
1211             string opc, string asm, list<dag> pattern>
1212   : Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>;
1213
1214 // Two-address instructions
1215 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1216             string asm, string cstr, list<dag> pattern>
1217   : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, cstr, pattern>;
1218
1219 // T2Iidxldst - Thumb2 indexed load / store instructions.
1220 class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
1221                  dag oops, dag iops,
1222                  AddrMode am, IndexMode im, InstrItinClass itin,
1223                  string opc, string asm, string cstr, list<dag> pattern>
1224   : InstARM<am, Size4Bytes, im, ThumbFrm, GenericDomain, cstr, itin> {
1225   let OutOperandList = oops;
1226   let InOperandList = !con(iops, (ins pred:$p));
1227   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1228   let Pattern = pattern;
1229   list<Predicate> Predicates = [IsThumb2];
1230   let Inst{31-27} = 0b11111;
1231   let Inst{26-25} = 0b00;
1232   let Inst{24} = signed;
1233   let Inst{23} = 0;
1234   let Inst{22-21} = opcod;
1235   let Inst{20} = load;
1236   let Inst{11} = 1;
1237   // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1238   let Inst{10} = pre; // The P bit.
1239   let Inst{8} = 1; // The W bit.
1240 }
1241
1242 // Helper class for disassembly only
1243 // A6.3.16 & A6.3.17
1244 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1245 class T2I_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, dag iops,
1246              InstrItinClass itin, string opc, string asm, list<dag> pattern>
1247   : T2I<oops, iops, itin, opc, asm, pattern> {
1248   let Inst{31-27} = 0b11111;
1249   let Inst{26-24} = 0b011;
1250   let Inst{23} = long;
1251   let Inst{22-20} = op22_20;
1252   let Inst{7-4} = op7_4;
1253 }
1254
1255 // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
1256 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
1257   list<Predicate> Predicates = [IsThumb1Only, HasV5T];
1258 }
1259
1260 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1261 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1262   list<Predicate> Predicates = [IsThumb1Only];
1263 }
1264
1265 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1266 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1267   list<Predicate> Predicates = [IsThumb2];
1268 }
1269
1270 //===----------------------------------------------------------------------===//
1271
1272 //===----------------------------------------------------------------------===//
1273 // ARM VFP Instruction templates.
1274 //
1275
1276 // Almost all VFP instructions are predicable.
1277 class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1278            IndexMode im, Format f, InstrItinClass itin,
1279            string opc, string asm, string cstr, list<dag> pattern>
1280   : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1281   let OutOperandList = oops;
1282   let InOperandList = !con(iops, (ins pred:$p));
1283   let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1284   let Pattern = pattern;
1285   list<Predicate> Predicates = [HasVFP2];
1286 }
1287
1288 // Special cases
1289 class VFPXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1290             IndexMode im, Format f, InstrItinClass itin,
1291             string asm, string cstr, list<dag> pattern>
1292   : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1293   let OutOperandList = oops;
1294   let InOperandList = iops;
1295   let AsmString = asm;
1296   let Pattern = pattern;
1297   list<Predicate> Predicates = [HasVFP2];
1298 }
1299
1300 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1301             string opc, string asm, list<dag> pattern>
1302   : VFPI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
1303          opc, asm, "", pattern>;
1304
1305 // ARM VFP addrmode5 loads and stores
1306 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1307            InstrItinClass itin,
1308            string opc, string asm, list<dag> pattern>
1309   : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1310          VFPLdStFrm, itin, opc, asm, "", pattern> {
1311   // TODO: Mark the instructions with the appropriate subtarget info.
1312   let Inst{27-24} = opcod1;
1313   let Inst{21-20} = opcod2;
1314   let Inst{11-8}  = 0b1011;
1315
1316   // 64-bit loads & stores operate on both NEON and VFP pipelines.
1317   let D = VFPNeonDomain;
1318 }
1319
1320 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1321            InstrItinClass itin,
1322            string opc, string asm, list<dag> pattern>
1323   : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1324          VFPLdStFrm, itin, opc, asm, "", pattern> {
1325   // TODO: Mark the instructions with the appropriate subtarget info.
1326   let Inst{27-24} = opcod1;
1327   let Inst{21-20} = opcod2;
1328   let Inst{11-8}  = 0b1010;
1329 }
1330
1331 // Load / store multiple
1332 class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1333             string asm, string cstr, list<dag> pattern>
1334   : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
1335           VFPLdStMulFrm, itin, asm, cstr, pattern> {
1336   // TODO: Mark the instructions with the appropriate subtarget info.
1337   let Inst{27-25} = 0b110;
1338   let Inst{11-8}  = 0b1011;
1339
1340   // 64-bit loads & stores operate on both NEON and VFP pipelines.
1341   let D = VFPNeonDomain;
1342 }
1343
1344 class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1345             string asm, string cstr, list<dag> pattern>
1346   : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
1347           VFPLdStMulFrm, itin, asm, cstr, pattern> {
1348   // TODO: Mark the instructions with the appropriate subtarget info.
1349   let Inst{27-25} = 0b110;
1350   let Inst{11-8}  = 0b1010;
1351 }
1352
1353 // Double precision, unary
1354 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1355            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1356            string asm, list<dag> pattern>
1357   : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1358   let Inst{27-23} = opcod1;
1359   let Inst{21-20} = opcod2;
1360   let Inst{19-16} = opcod3;
1361   let Inst{11-8}  = 0b1011;
1362   let Inst{7-6}   = opcod4;
1363   let Inst{4}     = opcod5;
1364 }
1365
1366 // Double precision, binary
1367 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1368            dag iops, InstrItinClass itin, string opc, string asm,
1369            list<dag> pattern>
1370   : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1371   let Inst{27-23} = opcod1;
1372   let Inst{21-20} = opcod2;
1373   let Inst{11-8}  = 0b1011;
1374   let Inst{6} = op6;
1375   let Inst{4} = op4;
1376 }
1377
1378 // Double precision, binary, VML[AS] (for additional predicate)
1379 class ADbI_vmlX<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1380            dag iops, InstrItinClass itin, string opc, string asm,
1381            list<dag> pattern>
1382   : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1383   let Inst{27-23} = opcod1;
1384   let Inst{21-20} = opcod2;
1385   let Inst{11-8}  = 0b1011;
1386   let Inst{6} = op6;
1387   let Inst{4} = op4;
1388   list<Predicate> Predicates = [HasVFP2, UseVMLx];
1389 }
1390
1391
1392 // Single precision, unary
1393 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1394            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1395            string asm, list<dag> pattern>
1396   : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1397   let Inst{27-23} = opcod1;
1398   let Inst{21-20} = opcod2;
1399   let Inst{19-16} = opcod3;
1400   let Inst{11-8}  = 0b1010;
1401   let Inst{7-6}   = opcod4;
1402   let Inst{4}     = opcod5;
1403 }
1404
1405 // Single precision unary, if no NEON
1406 // Same as ASuI except not available if NEON is enabled
1407 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1408             bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1409             string asm, list<dag> pattern>
1410   : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1411          pattern> {
1412   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1413 }
1414
1415 // Single precision, binary
1416 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1417            InstrItinClass itin, string opc, string asm, list<dag> pattern>
1418   : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1419   let Inst{27-23} = opcod1;
1420   let Inst{21-20} = opcod2;
1421   let Inst{11-8}  = 0b1010;
1422   let Inst{6} = op6;
1423   let Inst{4} = op4;
1424 }
1425
1426 // Single precision binary, if no NEON
1427 // Same as ASbI except not available if NEON is enabled
1428 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1429             dag iops, InstrItinClass itin, string opc, string asm,
1430             list<dag> pattern>
1431   : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1432   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1433 }
1434
1435 // VFP conversion instructions
1436 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1437                dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1438                list<dag> pattern>
1439   : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1440   let Inst{27-23} = opcod1;
1441   let Inst{21-20} = opcod2;
1442   let Inst{19-16} = opcod3;
1443   let Inst{11-8}  = opcod4;
1444   let Inst{6}     = 1;
1445   let Inst{4}     = 0;
1446 }
1447
1448 // VFP conversion between floating-point and fixed-point
1449 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
1450                 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1451                 list<dag> pattern>
1452   : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
1453   // size (fixed-point number): sx == 0 ? 16 : 32
1454   let Inst{7} = op5; // sx
1455 }
1456
1457 // VFP conversion instructions, if no NEON
1458 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1459                 dag oops, dag iops, InstrItinClass itin,
1460                 string opc, string asm, list<dag> pattern>
1461   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1462              pattern> {
1463   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1464 }
1465
1466 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
1467                InstrItinClass itin,
1468                string opc, string asm, list<dag> pattern>
1469   : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
1470   let Inst{27-20} = opcod1;
1471   let Inst{11-8}  = opcod2;
1472   let Inst{4}     = 1;
1473 }
1474
1475 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1476                InstrItinClass itin, string opc, string asm, list<dag> pattern>
1477   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
1478
1479 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1480                InstrItinClass itin, string opc, string asm, list<dag> pattern>
1481   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
1482
1483 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1484                InstrItinClass itin, string opc, string asm, list<dag> pattern>
1485   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
1486
1487 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1488                InstrItinClass itin, string opc, string asm, list<dag> pattern>
1489   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
1490
1491 //===----------------------------------------------------------------------===//
1492
1493 //===----------------------------------------------------------------------===//
1494 // ARM NEON Instruction templates.
1495 //
1496
1497 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1498             InstrItinClass itin, string opc, string dt, string asm, string cstr,
1499             list<dag> pattern>
1500   : InstARM<am, Size4Bytes, im, f, NeonDomain, cstr, itin> {
1501   let OutOperandList = oops;
1502   let InOperandList = !con(iops, (ins pred:$p));
1503   let AsmString = !strconcat(
1504                      !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1505                      !strconcat("\t", asm));
1506   let Pattern = pattern;
1507   list<Predicate> Predicates = [HasNEON];
1508 }
1509
1510 // Same as NeonI except it does not have a "data type" specifier.
1511 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1512              InstrItinClass itin, string opc, string asm, string cstr,
1513              list<dag> pattern>
1514   : InstARM<am, Size4Bytes, im, f, NeonDomain, cstr, itin> {
1515   let OutOperandList = oops;
1516   let InOperandList = !con(iops, (ins pred:$p));
1517   let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
1518   let Pattern = pattern;
1519   list<Predicate> Predicates = [HasNEON];
1520 }
1521
1522 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1523             dag oops, dag iops, InstrItinClass itin,
1524             string opc, string dt, string asm, string cstr, list<dag> pattern>
1525   : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
1526           cstr, pattern> {
1527   let Inst{31-24} = 0b11110100;
1528   let Inst{23} = op23;
1529   let Inst{21-20} = op21_20;
1530   let Inst{11-8} = op11_8;
1531   let Inst{7-4} = op7_4;
1532 }
1533
1534 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
1535              string opc, string dt, string asm, string cstr, list<dag> pattern>
1536   : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
1537           pattern> {
1538   let Inst{31-25} = 0b1111001;
1539 }
1540
1541 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
1542               string opc, string asm, string cstr, list<dag> pattern>
1543   : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
1544            cstr, pattern> {
1545   let Inst{31-25} = 0b1111001;
1546 }
1547
1548 // NEON "one register and a modified immediate" format.
1549 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1550                bit op5, bit op4,
1551                dag oops, dag iops, InstrItinClass itin,
1552                string opc, string dt, string asm, string cstr,
1553                list<dag> pattern>
1554   : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
1555   let Inst{23} = op23;
1556   let Inst{21-19} = op21_19;
1557   let Inst{11-8} = op11_8;
1558   let Inst{7} = op7;
1559   let Inst{6} = op6;
1560   let Inst{5} = op5;
1561   let Inst{4} = op4;
1562 }
1563
1564 // NEON 2 vector register format.
1565 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1566           bits<5> op11_7, bit op6, bit op4,
1567           dag oops, dag iops, InstrItinClass itin,
1568           string opc, string dt, string asm, string cstr, list<dag> pattern>
1569   : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
1570   let Inst{24-23} = op24_23;
1571   let Inst{21-20} = op21_20;
1572   let Inst{19-18} = op19_18;
1573   let Inst{17-16} = op17_16;
1574   let Inst{11-7} = op11_7;
1575   let Inst{6} = op6;
1576   let Inst{4} = op4;
1577 }
1578
1579 // Same as N2V except it doesn't have a datatype suffix.
1580 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1581            bits<5> op11_7, bit op6, bit op4,
1582            dag oops, dag iops, InstrItinClass itin,
1583            string opc, string asm, string cstr, list<dag> pattern>
1584   : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
1585   let Inst{24-23} = op24_23;
1586   let Inst{21-20} = op21_20;
1587   let Inst{19-18} = op19_18;
1588   let Inst{17-16} = op17_16;
1589   let Inst{11-7} = op11_7;
1590   let Inst{6} = op6;
1591   let Inst{4} = op4;
1592 }
1593
1594 // NEON 2 vector register with immediate.
1595 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
1596              dag oops, dag iops, Format f, InstrItinClass itin,
1597              string opc, string dt, string asm, string cstr, list<dag> pattern>
1598   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
1599   let Inst{24} = op24;
1600   let Inst{23} = op23;
1601   let Inst{11-8} = op11_8;
1602   let Inst{7} = op7;
1603   let Inst{6} = op6;
1604   let Inst{4} = op4;
1605 }
1606
1607 // NEON 3 vector register format.
1608 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1609           dag oops, dag iops, Format f, InstrItinClass itin,
1610           string opc, string dt, string asm, string cstr, list<dag> pattern>
1611   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
1612   let Inst{24} = op24;
1613   let Inst{23} = op23;
1614   let Inst{21-20} = op21_20;
1615   let Inst{11-8} = op11_8;
1616   let Inst{6} = op6;
1617   let Inst{4} = op4;
1618 }
1619
1620 // Same as N3V except it doesn't have a data type suffix.
1621 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
1622            bit op4,
1623            dag oops, dag iops, Format f, InstrItinClass itin,
1624            string opc, string asm, string cstr, list<dag> pattern>
1625   : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
1626   let Inst{24} = op24;
1627   let Inst{23} = op23;
1628   let Inst{21-20} = op21_20;
1629   let Inst{11-8} = op11_8;
1630   let Inst{6} = op6;
1631   let Inst{4} = op4;
1632 }
1633
1634 // NEON VMOVs between scalar and core registers.
1635 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1636                dag oops, dag iops, Format f, InstrItinClass itin,
1637                string opc, string dt, string asm, list<dag> pattern>
1638   : InstARM<AddrModeNone, Size4Bytes, IndexModeNone, f, GenericDomain,
1639             "", itin> {
1640   let Inst{27-20} = opcod1;
1641   let Inst{11-8} = opcod2;
1642   let Inst{6-5} = opcod3;
1643   let Inst{4} = 1;
1644
1645   let OutOperandList = oops;
1646   let InOperandList = !con(iops, (ins pred:$p));
1647   let AsmString = !strconcat(
1648                      !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1649                      !strconcat("\t", asm));
1650   let Pattern = pattern;
1651   list<Predicate> Predicates = [HasNEON];
1652 }
1653 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1654                 dag oops, dag iops, InstrItinClass itin,
1655                 string opc, string dt, string asm, list<dag> pattern>
1656   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, itin,
1657              opc, dt, asm, pattern>;
1658 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1659                 dag oops, dag iops, InstrItinClass itin,
1660                 string opc, string dt, string asm, list<dag> pattern>
1661   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, itin,
1662              opc, dt, asm, pattern>;
1663 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1664             dag oops, dag iops, InstrItinClass itin,
1665             string opc, string dt, string asm, list<dag> pattern>
1666   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, itin,
1667              opc, dt, asm, pattern>;
1668
1669 // Vector Duplicate Lane (from scalar to all elements)
1670 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
1671                 InstrItinClass itin, string opc, string dt, string asm,
1672                 list<dag> pattern>
1673   : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
1674   let Inst{24-23} = 0b11;
1675   let Inst{21-20} = 0b11;
1676   let Inst{19-16} = op19_16;
1677   let Inst{11-7} = 0b11000;
1678   let Inst{6} = op6;
1679   let Inst{4} = 0;
1680 }
1681
1682 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
1683 // for single-precision FP.
1684 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
1685   list<Predicate> Predicates = [HasNEON,UseNEONForFP];
1686 }