ARMInstrFormats.td revision 199989
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.
18class Format<bits<5> val> {
19  bits<5> Value = val;
20}
21
22def Pseudo        : Format<0>;
23def MulFrm        : Format<1>;
24def BrFrm         : Format<2>;
25def BrMiscFrm     : Format<3>;
26
27def DPFrm         : Format<4>;
28def DPSoRegFrm    : Format<5>;
29
30def LdFrm         : Format<6>;
31def StFrm         : Format<7>;
32def LdMiscFrm     : Format<8>;
33def StMiscFrm     : Format<9>;
34def LdStMulFrm    : Format<10>;
35
36def ArithMiscFrm  : Format<11>;
37def ExtFrm        : Format<12>;
38
39def VFPUnaryFrm   : Format<13>;
40def VFPBinaryFrm  : Format<14>;
41def VFPConv1Frm   : Format<15>;
42def VFPConv2Frm   : Format<16>;
43def VFPConv3Frm   : Format<17>;
44def VFPConv4Frm   : Format<18>;
45def VFPConv5Frm   : Format<19>;
46def VFPLdStFrm    : Format<20>;
47def VFPLdStMulFrm : Format<21>;
48def VFPMiscFrm    : Format<22>;
49
50def ThumbFrm      : Format<23>;
51
52def NEONFrm       : Format<24>;
53def NEONGetLnFrm  : Format<25>;
54def NEONSetLnFrm  : Format<26>;
55def 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.
62class 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.
66class Xform16Bit { bit canXformTo16Bit = 1; }
67
68//===----------------------------------------------------------------------===//
69// ARM Instruction flags.  These need to match ARMInstrInfo.h.
70//
71
72// Addressing mode.
73class AddrMode<bits<4> val> {
74  bits<4> Value = val;
75}
76def AddrModeNone  : AddrMode<0>;
77def AddrMode1     : AddrMode<1>;
78def AddrMode2     : AddrMode<2>;
79def AddrMode3     : AddrMode<3>;
80def AddrMode4     : AddrMode<4>;
81def AddrMode5     : AddrMode<5>;
82def AddrMode6     : AddrMode<6>;
83def AddrModeT1_1  : AddrMode<7>;
84def AddrModeT1_2  : AddrMode<8>;
85def AddrModeT1_4  : AddrMode<9>;
86def AddrModeT1_s  : AddrMode<10>;
87def AddrModeT2_i12: AddrMode<11>;
88def AddrModeT2_i8 : AddrMode<12>;
89def AddrModeT2_so : AddrMode<13>;
90def AddrModeT2_pc : AddrMode<14>;
91def AddrModeT2_i8s4 : AddrMode<15>;
92
93// Instruction size.
94class SizeFlagVal<bits<3> val> {
95  bits<3> Value = val;
96}
97def SizeInvalid  : SizeFlagVal<0>;  // Unset.
98def SizeSpecial  : SizeFlagVal<1>;  // Pseudo or special.
99def Size8Bytes   : SizeFlagVal<2>;
100def Size4Bytes   : SizeFlagVal<3>;
101def Size2Bytes   : SizeFlagVal<4>;
102
103// Load / store index mode.
104class IndexMode<bits<2> val> {
105  bits<2> Value = val;
106}
107def IndexModeNone : IndexMode<0>;
108def IndexModePre  : IndexMode<1>;
109def IndexModePost : IndexMode<2>;
110
111// Instruction execution domain.
112class Domain<bits<2> val> {
113  bits<2> Value = val;
114}
115def GenericDomain : Domain<0>;
116def VFPDomain     : Domain<1>; // Instructions in VFP domain only
117def NeonDomain    : Domain<2>; // Instructions in Neon domain only
118def 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).
127def 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.
133def 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.
138def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
139  let PrintMethod = "printSBitModifierOperand";
140}
141
142//===----------------------------------------------------------------------===//
143
144// ARM Instruction templates.
145//
146
147class 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
180class 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.
191class 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".
206class 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
219class 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
230class 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>;
234class 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>;
238class 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
244class 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}
250class 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}
256class 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
262class 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
268class 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}
275class 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}
282class 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}
289class 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
296class 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
304class 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}
314class 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}
324class 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}
334class 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
346class 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}
356class 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}
366class 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}
376class 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
388class 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}
398class 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
410class 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}
420class 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
432class 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}
442class 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
454class 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}
464class 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
476class 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>;
480class 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
486class 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}
499class 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}
511class 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}
524class 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}
536class 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}
549class 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}
561class 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
576class 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}
589class 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}
601class 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
616class 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}
629class 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}
642class 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
657class 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
672class 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}
685class 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}
698class 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
713class 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
729class 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}
737class 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.
747class 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}
755class 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
764class 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>
774class 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.
785class 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.
794class 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.
804class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
805  list<Predicate> Predicates = [IsARM];
806}
807class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
808  list<Predicate> Predicates = [IsARM, HasV5TE];
809}
810class 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
821class 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
831class 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
835class 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
839class 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
843class 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
847class 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
857class T1I<dag oops, dag iops, InstrItinClass itin,
858          string asm, list<dag> pattern>
859  : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
860class T1Ix2<dag oops, dag iops, InstrItinClass itin,
861            string asm, list<dag> pattern>
862  : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
863class 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
868class 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.
874class 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
885class 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
890class 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.
896class 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
907class 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
912class 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
917class 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>;
920class 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>;
923class 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>;
926class 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.
931class 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.
947class 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
959class 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
970class 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>;
973class 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>;
976class 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>;
979class 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>;
982class 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>;
985class 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
989class 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
993class T2XI<dag oops, dag iops, InstrItinClass itin,
994           string asm, list<dag> pattern>
995  : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
996class T2JTI<dag oops, dag iops, InstrItinClass itin,
997            string asm, list<dag> pattern>
998  : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
999
1000class 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.
1006class 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.
1018class 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.
1023class 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.
1028class 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.
1039class 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
1051class 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
1062class 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
1068class 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
1082class 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
1094class 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
1106class 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
1116class 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
1126class 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
1134class 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
1146class 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
1153class 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
1163class 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
1170class 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
1181class 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
1188class 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
1197class 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
1201class 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
1205class 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
1209class 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
1219class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
1220            string opc, string dt, 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(
1225                     !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1226                     !strconcat("\t", asm));
1227  let Pattern = pattern;
1228  list<Predicate> Predicates = [HasNEON];
1229}
1230
1231// Same as NeonI except it does not have a "data type" specifier.
1232class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
1233            string opc, string asm, string cstr, list<dag> pattern>
1234  : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
1235  let OutOperandList = oops;
1236  let InOperandList = !con(iops, (ops pred:$p));
1237  let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
1238  let Pattern = pattern;
1239  list<Predicate> Predicates = [HasNEON];
1240}
1241
1242class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1243         list<dag> pattern>
1244  : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, "",
1245          pattern> {
1246}
1247
1248class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
1249          string asm, list<dag> pattern>
1250  : NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "",
1251          pattern> {
1252}
1253
1254class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1255            dag oops, dag iops, InstrItinClass itin,
1256            string opc, string dt, string asm, string cstr, list<dag> pattern>
1257  : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, dt, asm, cstr,
1258          pattern> {
1259  let Inst{31-24} = 0b11110100;
1260  let Inst{23} = op23;
1261  let Inst{21-20} = op21_20;
1262  let Inst{11-8} = op11_8;
1263  let Inst{7-4} = op7_4;
1264}
1265
1266class NDataI<dag oops, dag iops, InstrItinClass itin,
1267             string opc, string dt, string asm, string cstr, list<dag> pattern>
1268  : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, dt, asm,
1269         cstr, pattern> {
1270  let Inst{31-25} = 0b1111001;
1271}
1272
1273class NDataXI<dag oops, dag iops, InstrItinClass itin,
1274             string opc, string asm, string cstr, list<dag> pattern>
1275  : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm,
1276         cstr, pattern> {
1277  let Inst{31-25} = 0b1111001;
1278}
1279
1280// NEON "one register and a modified immediate" format.
1281class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1282               bit op5, bit op4,
1283               dag oops, dag iops, InstrItinClass itin,
1284               string opc, string dt, string asm, string cstr, list<dag> pattern>
1285  : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1286  let Inst{23} = op23;
1287  let Inst{21-19} = op21_19;
1288  let Inst{11-8} = op11_8;
1289  let Inst{7} = op7;
1290  let Inst{6} = op6;
1291  let Inst{5} = op5;
1292  let Inst{4} = op4;
1293}
1294
1295// NEON 2 vector register format.
1296class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1297          bits<5> op11_7, bit op6, bit op4,
1298          dag oops, dag iops, InstrItinClass itin,
1299          string opc, string dt, string asm, string cstr, list<dag> pattern>
1300  : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1301  let Inst{24-23} = op24_23;
1302  let Inst{21-20} = op21_20;
1303  let Inst{19-18} = op19_18;
1304  let Inst{17-16} = op17_16;
1305  let Inst{11-7} = op11_7;
1306  let Inst{6} = op6;
1307  let Inst{4} = op4;
1308}
1309
1310// Same as N2V except it doesn't have a datatype suffix.
1311class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1312          bits<5> op11_7, bit op6, bit op4,
1313          dag oops, dag iops, InstrItinClass itin,
1314          string opc, string asm, string cstr, list<dag> pattern>
1315  : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> {
1316  let Inst{24-23} = op24_23;
1317  let Inst{21-20} = op21_20;
1318  let Inst{19-18} = op19_18;
1319  let Inst{17-16} = op17_16;
1320  let Inst{11-7} = op11_7;
1321  let Inst{6} = op6;
1322  let Inst{4} = op4;
1323}
1324
1325// NEON 2 vector register with immediate.
1326class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
1327             dag oops, dag iops, InstrItinClass itin,
1328             string opc, string dt, string asm, string cstr, list<dag> pattern>
1329  : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1330  let Inst{24} = op24;
1331  let Inst{23} = op23;
1332  let Inst{11-8} = op11_8;
1333  let Inst{7} = op7;
1334  let Inst{6} = op6;
1335  let Inst{4} = op4;
1336}
1337
1338// NEON 3 vector register format.
1339class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1340          dag oops, dag iops, InstrItinClass itin,
1341          string opc, string dt, string asm, string cstr, list<dag> pattern>
1342  : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1343  let Inst{24} = op24;
1344  let Inst{23} = op23;
1345  let Inst{21-20} = op21_20;
1346  let Inst{11-8} = op11_8;
1347  let Inst{6} = op6;
1348  let Inst{4} = op4;
1349}
1350
1351// Same as N3VX except it doesn't have a data type suffix.
1352class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1353          dag oops, dag iops, InstrItinClass itin,
1354          string opc, string asm, string cstr, list<dag> pattern>
1355  : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> {
1356  let Inst{24} = op24;
1357  let Inst{23} = op23;
1358  let Inst{21-20} = op21_20;
1359  let Inst{11-8} = op11_8;
1360  let Inst{6} = op6;
1361  let Inst{4} = op4;
1362}
1363
1364// NEON VMOVs between scalar and core registers.
1365class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1366               dag oops, dag iops, Format f, InstrItinClass itin,
1367               string opc, string dt, string asm, list<dag> pattern>
1368  : InstARM<AddrModeNone, Size4Bytes, IndexModeNone, f, GenericDomain,
1369    "", itin> {
1370  let Inst{27-20} = opcod1;
1371  let Inst{11-8} = opcod2;
1372  let Inst{6-5} = opcod3;
1373  let Inst{4} = 1;
1374
1375  let OutOperandList = oops;
1376  let InOperandList = !con(iops, (ops pred:$p));
1377  let AsmString = !strconcat(
1378                     !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1379                     !strconcat("\t", asm));
1380  let Pattern = pattern;
1381  list<Predicate> Predicates = [HasNEON];
1382}
1383class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1384                dag oops, dag iops, InstrItinClass itin,
1385                string opc, string dt, string asm, list<dag> pattern>
1386  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, itin,
1387             opc, dt, asm, pattern>;
1388class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1389                dag oops, dag iops, InstrItinClass itin,
1390                string opc, string dt, string asm, list<dag> pattern>
1391  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, itin,
1392             opc, dt, asm, pattern>;
1393class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1394            dag oops, dag iops, InstrItinClass itin,
1395            string opc, string dt, string asm, list<dag> pattern>
1396  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, itin,
1397             opc, dt, asm, pattern>;
1398
1399// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
1400// for single-precision FP.
1401class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
1402  list<Predicate> Predicates = [HasNEON,UseNEONForFP];
1403}
1404