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