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