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