OSDN Git Service

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