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