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