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