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