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