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