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