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