OSDN Git Service

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