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