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