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