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