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