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