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