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