ARMInstrFormats.td revision 261991
1234353Sdim//===-- ARMInstrFormats.td - ARM Instruction Formats -------*- tablegen -*-===//
2206083Srdivacky//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7206083Srdivacky//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed
10193323Sed//===----------------------------------------------------------------------===//
11193323Sed//
12193323Sed// ARM Instruction Format Definitions.
13193323Sed//
14193323Sed
15193323Sed// Format specifies the encoding used by the instruction.  This is part of the
16193323Sed// ad-hoc solution used to emit machine instruction encodings by our machine
17193323Sed// code emitter.
18205407Srdivackyclass Format<bits<6> val> {
19205407Srdivacky  bits<6> Value = val;
20193323Sed}
21193323Sed
22193323Seddef Pseudo        : Format<0>;
23193323Seddef MulFrm        : Format<1>;
24193323Seddef BrFrm         : Format<2>;
25193323Seddef BrMiscFrm     : Format<3>;
26193323Sed
27193323Seddef DPFrm         : Format<4>;
28226633Sdimdef DPSoRegRegFrm    : Format<5>;
29193323Sed
30193323Seddef LdFrm         : Format<6>;
31193323Seddef StFrm         : Format<7>;
32193323Seddef LdMiscFrm     : Format<8>;
33193323Seddef StMiscFrm     : Format<9>;
34193323Seddef LdStMulFrm    : Format<10>;
35193323Sed
36205407Srdivackydef LdStExFrm     : Format<11>;
37200581Srdivacky
38205407Srdivackydef ArithMiscFrm  : Format<12>;
39212904Sdimdef SatFrm        : Format<13>;
40212904Sdimdef ExtFrm        : Format<14>;
41193323Sed
42212904Sdimdef VFPUnaryFrm   : Format<15>;
43212904Sdimdef VFPBinaryFrm  : Format<16>;
44212904Sdimdef VFPConv1Frm   : Format<17>;
45212904Sdimdef VFPConv2Frm   : Format<18>;
46212904Sdimdef VFPConv3Frm   : Format<19>;
47212904Sdimdef VFPConv4Frm   : Format<20>;
48212904Sdimdef VFPConv5Frm   : Format<21>;
49212904Sdimdef VFPLdStFrm    : Format<22>;
50212904Sdimdef VFPLdStMulFrm : Format<23>;
51212904Sdimdef VFPMiscFrm    : Format<24>;
52193323Sed
53212904Sdimdef ThumbFrm      : Format<25>;
54212904Sdimdef MiscFrm       : Format<26>;
55193323Sed
56212904Sdimdef NGetLnFrm     : Format<27>;
57212904Sdimdef NSetLnFrm     : Format<28>;
58212904Sdimdef NDupFrm       : Format<29>;
59212904Sdimdef NLdStFrm      : Format<30>;
60212904Sdimdef N1RegModImmFrm: Format<31>;
61212904Sdimdef N2RegFrm      : Format<32>;
62212904Sdimdef NVCVTFrm      : Format<33>;
63212904Sdimdef NVDupLnFrm    : Format<34>;
64212904Sdimdef N2RegVShLFrm  : Format<35>;
65212904Sdimdef N2RegVShRFrm  : Format<36>;
66212904Sdimdef N3RegFrm      : Format<37>;
67212904Sdimdef N3RegVShFrm   : Format<38>;
68212904Sdimdef NVExtFrm      : Format<39>;
69212904Sdimdef NVMulSLFrm    : Format<40>;
70212904Sdimdef NVTBLFrm      : Format<41>;
71226633Sdimdef DPSoRegImmFrm  : Format<42>;
72194710Sed
73198090Srdivacky// Misc flags.
74198090Srdivacky
75218893Sdim// The instruction has an Rn register operand.
76198090Srdivacky// UnaryDP - Indicates this is a unary data processing instruction, i.e.
77198090Srdivacky// it doesn't have a Rn operand.
78198090Srdivackyclass UnaryDP    { bit isUnaryDataProc = 1; }
79193323Sed
80198090Srdivacky// Xform16Bit - Indicates this Thumb2 instruction may be transformed into
81198090Srdivacky// a 16-bit Thumb instruction if certain conditions are met.
82198090Srdivackyclass Xform16Bit { bit canXformTo16Bit = 1; }
83198090Srdivacky
84193323Sed//===----------------------------------------------------------------------===//
85205407Srdivacky// ARM Instruction flags.  These need to match ARMBaseInstrInfo.h.
86195340Sed//
87193323Sed
88218893Sdim// FIXME: Once the JIT is MC-ized, these can go away.
89195340Sed// Addressing mode.
90218893Sdimclass AddrMode<bits<5> val> {
91218893Sdim  bits<5> Value = val;
92195340Sed}
93212904Sdimdef AddrModeNone    : AddrMode<0>;
94212904Sdimdef AddrMode1       : AddrMode<1>;
95212904Sdimdef AddrMode2       : AddrMode<2>;
96212904Sdimdef AddrMode3       : AddrMode<3>;
97212904Sdimdef AddrMode4       : AddrMode<4>;
98212904Sdimdef AddrMode5       : AddrMode<5>;
99212904Sdimdef AddrMode6       : AddrMode<6>;
100212904Sdimdef AddrModeT1_1    : AddrMode<7>;
101212904Sdimdef AddrModeT1_2    : AddrMode<8>;
102212904Sdimdef AddrModeT1_4    : AddrMode<9>;
103212904Sdimdef AddrModeT1_s    : AddrMode<10>;
104212904Sdimdef AddrModeT2_i12  : AddrMode<11>;
105212904Sdimdef AddrModeT2_i8   : AddrMode<12>;
106212904Sdimdef AddrModeT2_so   : AddrMode<13>;
107212904Sdimdef AddrModeT2_pc   : AddrMode<14>;
108195340Seddef AddrModeT2_i8s4 : AddrMode<15>;
109218893Sdimdef AddrMode_i12    : AddrMode<16>;
110195340Sed
111195340Sed// Load / store index mode.
112195340Sedclass IndexMode<bits<2> val> {
113195340Sed  bits<2> Value = val;
114195340Sed}
115195340Seddef IndexModeNone : IndexMode<0>;
116195340Seddef IndexModePre  : IndexMode<1>;
117195340Seddef IndexModePost : IndexMode<2>;
118205218Srdivackydef IndexModeUpd  : IndexMode<3>;
119195340Sed
120198892Srdivacky// Instruction execution domain.
121219077Sdimclass Domain<bits<3> val> {
122219077Sdim  bits<3> Value = val;
123198892Srdivacky}
124198892Srdivackydef GenericDomain : Domain<0>;
125198892Srdivackydef VFPDomain     : Domain<1>; // Instructions in VFP domain only
126198892Srdivackydef NeonDomain    : Domain<2>; // Instructions in Neon domain only
127198892Srdivackydef VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
128219077Sdimdef VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
129198892Srdivacky
130195340Sed//===----------------------------------------------------------------------===//
131198090Srdivacky// ARM special operands.
132198090Srdivacky//
133198090Srdivacky
134226633Sdim// ARM imod and iflag operands, used only by the CPS instruction.
135226633Sdimdef imod_op : Operand<i32> {
136226633Sdim  let PrintMethod = "printCPSIMod";
137212904Sdim}
138212904Sdim
139218893Sdimdef ProcIFlagsOperand : AsmOperandClass {
140218893Sdim  let Name = "ProcIFlags";
141226633Sdim  let ParserMethod = "parseProcIFlagsOperand";
142218893Sdim}
143218893Sdimdef iflags_op : Operand<i32> {
144218893Sdim  let PrintMethod = "printCPSIFlag";
145218893Sdim  let ParserMatchClass = ProcIFlagsOperand;
146218893Sdim}
147218893Sdim
148198090Srdivacky// ARM Predicate operand. Default to 14 = always (AL). Second part is CC
149198090Srdivacky// register whose default is 0 (no register).
150226633Sdimdef CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
151226633Sdimdef pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
152198090Srdivacky                                     (ops (i32 14), (i32 zero_reg))> {
153198090Srdivacky  let PrintMethod = "printPredicateOperand";
154212904Sdim  let ParserMatchClass = CondCodeOperand;
155226633Sdim  let DecoderMethod = "DecodePredicateOperand";
156198090Srdivacky}
157198090Srdivacky
158261991Sdim// Selectable predicate operand for CMOV instructions. We can't use a normal
159261991Sdim// predicate because the default values interfere with instruction selection. In
160261991Sdim// all other respects it is identical though: pseudo-instruction expansion
161261991Sdim// relies on the MachineOperands being compatible.
162261991Sdimdef cmovpred : Operand<i32>, PredicateOp,
163261991Sdim               ComplexPattern<i32, 2, "SelectCMOVPred"> {
164261991Sdim  let MIOperandInfo = (ops i32imm, i32imm);
165261991Sdim  let PrintMethod = "printPredicateOperand";
166261991Sdim}
167261991Sdim
168198090Srdivacky// Conditional code result for instructions whose 's' bit is set, e.g. subs.
169226633Sdimdef CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
170198090Srdivackydef cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
171218893Sdim  let EncoderMethod = "getCCOutOpValue";
172198090Srdivacky  let PrintMethod = "printSBitModifierOperand";
173218893Sdim  let ParserMatchClass = CCOutOperand;
174226633Sdim  let DecoderMethod = "DecodeCCOutOperand";
175198090Srdivacky}
176198090Srdivacky
177198090Srdivacky// Same as cc_out except it defaults to setting CPSR.
178198090Srdivackydef s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
179218893Sdim  let EncoderMethod = "getCCOutOpValue";
180198090Srdivacky  let PrintMethod = "printSBitModifierOperand";
181218893Sdim  let ParserMatchClass = CCOutOperand;
182226633Sdim  let DecoderMethod = "DecodeCCOutOperand";
183198090Srdivacky}
184198090Srdivacky
185205218Srdivacky// ARM special operands for disassembly only.
186205218Srdivacky//
187234353Sdimdef SetEndAsmOperand : ImmAsmOperand {
188226633Sdim  let Name = "SetEndImm";
189226633Sdim  let ParserMethod = "parseSetEndImm";
190226633Sdim}
191218893Sdimdef setend_op : Operand<i32> {
192218893Sdim  let PrintMethod = "printSetendOperand";
193226633Sdim  let ParserMatchClass = SetEndAsmOperand;
194218893Sdim}
195205218Srdivacky
196226633Sdimdef MSRMaskOperand : AsmOperandClass {
197226633Sdim  let Name = "MSRMask";
198226633Sdim  let ParserMethod = "parseMSRMaskOperand";
199226633Sdim}
200205218Srdivackydef msr_mask : Operand<i32> {
201205218Srdivacky  let PrintMethod = "printMSRMaskOperand";
202226633Sdim  let DecoderMethod = "DecodeMSRMask";
203218893Sdim  let ParserMatchClass = MSRMaskOperand;
204205218Srdivacky}
205205218Srdivacky
206221345Sdim// Shift Right Immediate - A shift right immediate is encoded differently from
207221345Sdim// other shift immediates. The imm6 field is encoded like so:
208221345Sdim//
209221345Sdim//    Offset    Encoding
210221345Sdim//     8        imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
211221345Sdim//     16       imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
212221345Sdim//     32       imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
213221345Sdim//     64       64 - <imm> is encoded in imm6<5:0>
214234353Sdimdef shr_imm8_asm_operand : ImmAsmOperand { let Name = "ShrImm8"; }
215221345Sdimdef shr_imm8  : Operand<i32> {
216221345Sdim  let EncoderMethod = "getShiftRight8Imm";
217226633Sdim  let DecoderMethod = "DecodeShiftRight8Imm";
218234353Sdim  let ParserMatchClass = shr_imm8_asm_operand;
219205218Srdivacky}
220234353Sdimdef shr_imm16_asm_operand : ImmAsmOperand { let Name = "ShrImm16"; }
221221345Sdimdef shr_imm16 : Operand<i32> {
222221345Sdim  let EncoderMethod = "getShiftRight16Imm";
223226633Sdim  let DecoderMethod = "DecodeShiftRight16Imm";
224234353Sdim  let ParserMatchClass = shr_imm16_asm_operand;
225221345Sdim}
226234353Sdimdef shr_imm32_asm_operand : ImmAsmOperand { let Name = "ShrImm32"; }
227221345Sdimdef shr_imm32 : Operand<i32> {
228221345Sdim  let EncoderMethod = "getShiftRight32Imm";
229226633Sdim  let DecoderMethod = "DecodeShiftRight32Imm";
230234353Sdim  let ParserMatchClass = shr_imm32_asm_operand;
231221345Sdim}
232234353Sdimdef shr_imm64_asm_operand : ImmAsmOperand { let Name = "ShrImm64"; }
233221345Sdimdef shr_imm64 : Operand<i32> {
234221345Sdim  let EncoderMethod = "getShiftRight64Imm";
235226633Sdim  let DecoderMethod = "DecodeShiftRight64Imm";
236234353Sdim  let ParserMatchClass = shr_imm64_asm_operand;
237221345Sdim}
238205218Srdivacky
239198090Srdivacky//===----------------------------------------------------------------------===//
240226633Sdim// ARM Assembler alias templates.
241226633Sdim//
242226633Sdimclass ARMInstAlias<string Asm, dag Result, bit Emit = 0b1>
243226633Sdim      : InstAlias<Asm, Result, Emit>, Requires<[IsARM]>;
244226633Sdimclass  tInstAlias<string Asm, dag Result, bit Emit = 0b1>
245226633Sdim      : InstAlias<Asm, Result, Emit>, Requires<[IsThumb]>;
246226633Sdimclass t2InstAlias<string Asm, dag Result, bit Emit = 0b1>
247226633Sdim      : InstAlias<Asm, Result, Emit>, Requires<[IsThumb2]>;
248226633Sdimclass VFP2InstAlias<string Asm, dag Result, bit Emit = 0b1>
249226633Sdim      : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2]>;
250261991Sdimclass VFP2DPInstAlias<string Asm, dag Result, bit Emit = 0b1>
251261991Sdim      : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2,HasDPVFP]>;
252226633Sdimclass VFP3InstAlias<string Asm, dag Result, bit Emit = 0b1>
253226633Sdim      : InstAlias<Asm, Result, Emit>, Requires<[HasVFP3]>;
254234353Sdimclass NEONInstAlias<string Asm, dag Result, bit Emit = 0b1>
255234353Sdim      : InstAlias<Asm, Result, Emit>, Requires<[HasNEON]>;
256226633Sdim
257234353Sdim
258234353Sdimclass VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
259234353Sdim          Requires<[HasVFP2]>;
260234353Sdimclass NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
261234353Sdim          Requires<[HasNEON]>;
262234353Sdim
263226633Sdim//===----------------------------------------------------------------------===//
264193323Sed// ARM Instruction templates.
265193323Sed//
266193323Sed
267226633Sdim
268224145Sdimclass InstTemplate<AddrMode am, int sz, IndexMode im,
269201360Srdivacky                   Format f, Domain d, string cstr, InstrItinClass itin>
270193323Sed  : Instruction {
271193323Sed  let Namespace = "ARM";
272193323Sed
273193323Sed  AddrMode AM = am;
274224145Sdim  int Size = sz;
275193323Sed  IndexMode IM = im;
276193323Sed  bits<2> IndexModeBits = IM.Value;
277193323Sed  Format F = f;
278205407Srdivacky  bits<6> Form = F.Value;
279198892Srdivacky  Domain D = d;
280193323Sed  bit isUnaryDataProc = 0;
281198090Srdivacky  bit canXformTo16Bit = 0;
282226633Sdim  // The instruction is a 16-bit flag setting Thumb instruction. Used
283226633Sdim  // by the parser to determine whether to require the 'S' suffix on the
284226633Sdim  // mnemonic (when not in an IT block) or preclude it (when in an IT block).
285226633Sdim  bit thumbArithFlagSetting = 0;
286206083Srdivacky
287218893Sdim  // If this is a pseudo instruction, mark it isCodeGenOnly.
288218893Sdim  let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
289218893Sdim
290226633Sdim  // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
291218893Sdim  let TSFlags{4-0}   = AM.Value;
292224145Sdim  let TSFlags{6-5}   = IndexModeBits;
293224145Sdim  let TSFlags{12-7} = Form;
294224145Sdim  let TSFlags{13}    = isUnaryDataProc;
295224145Sdim  let TSFlags{14}    = canXformTo16Bit;
296224145Sdim  let TSFlags{17-15} = D.Value;
297226633Sdim  let TSFlags{18}    = thumbArithFlagSetting;
298206274Srdivacky
299193323Sed  let Constraints = cstr;
300198090Srdivacky  let Itinerary = itin;
301193323Sed}
302193323Sed
303201360Srdivackyclass Encoding {
304201360Srdivacky  field bits<32> Inst;
305234353Sdim  // Mask of bits that cause an encoding to be UNPREDICTABLE.
306234353Sdim  // If a bit is set, then if the corresponding bit in the
307234353Sdim  // target encoding differs from its value in the "Inst" field,
308234353Sdim  // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
309234353Sdim  field bits<32> Unpredictable = 0;
310234353Sdim  // SoftFail is the generic name for this field, but we alias it so
311234353Sdim  // as to make it more obvious what it means in ARM-land.
312234353Sdim  field bits<32> SoftFail = Unpredictable;
313201360Srdivacky}
314201360Srdivacky
315224145Sdimclass InstARM<AddrMode am, int sz, IndexMode im,
316201360Srdivacky              Format f, Domain d, string cstr, InstrItinClass itin>
317226633Sdim  : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
318226633Sdim  let DecoderNamespace = "ARM";
319226633Sdim}
320201360Srdivacky
321201360Srdivacky// This Encoding-less class is used by Thumb1 to specify the encoding bits later
322201360Srdivacky// on by adding flavors to specific instructions.
323224145Sdimclass InstThumb<AddrMode am, int sz, IndexMode im,
324201360Srdivacky                Format f, Domain d, string cstr, InstrItinClass itin>
325226633Sdim  : InstTemplate<am, sz, im, f, d, cstr, itin> {
326226633Sdim  let DecoderNamespace = "Thumb";
327226633Sdim}
328201360Srdivacky
329234353Sdim// Pseudo-instructions for alternate assembly syntax (never used by codegen).
330234353Sdim// These are aliases that require C++ handling to convert to the target
331234353Sdim// instruction, while InstAliases can be handled directly by tblgen.
332234353Sdimclass AsmPseudoInst<string asm, dag iops>
333234353Sdim  : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
334234353Sdim                 "", NoItinerary> {
335234353Sdim  let OutOperandList = (outs);
336234353Sdim  let InOperandList = iops;
337234353Sdim  let Pattern = [];
338234353Sdim  let isCodeGenOnly = 0; // So we get asm matcher for it.
339234353Sdim  let AsmString = asm;
340234353Sdim  let isPseudo = 1;
341234353Sdim}
342234353Sdim
343234353Sdimclass ARMAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
344234353Sdim        Requires<[IsARM]>;
345234353Sdimclass tAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
346234353Sdim        Requires<[IsThumb]>;
347234353Sdimclass t2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
348234353Sdim        Requires<[IsThumb2]>;
349234353Sdimclass VFP2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
350234353Sdim        Requires<[HasVFP2]>;
351234353Sdimclass NEONAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
352234353Sdim        Requires<[HasNEON]>;
353234353Sdim
354234353Sdim// Pseudo instructions for the code generator.
355218893Sdimclass PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
356224145Sdim  : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
357224145Sdim                 GenericDomain, "", itin> {
358193323Sed  let OutOperandList = oops;
359193323Sed  let InOperandList = iops;
360193323Sed  let Pattern = pattern;
361221345Sdim  let isCodeGenOnly = 1;
362224145Sdim  let isPseudo = 1;
363193323Sed}
364193323Sed
365218893Sdim// PseudoInst that's ARM-mode only.
366224145Sdimclass ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
367218893Sdim                    list<dag> pattern>
368218893Sdim  : PseudoInst<oops, iops, itin, pattern> {
369224145Sdim  let Size = sz;
370218893Sdim  list<Predicate> Predicates = [IsARM];
371218893Sdim}
372218893Sdim
373218893Sdim// PseudoInst that's Thumb-mode only.
374224145Sdimclass tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
375218893Sdim                    list<dag> pattern>
376218893Sdim  : PseudoInst<oops, iops, itin, pattern> {
377224145Sdim  let Size = sz;
378218893Sdim  list<Predicate> Predicates = [IsThumb];
379218893Sdim}
380218893Sdim
381218893Sdim// PseudoInst that's Thumb2-mode only.
382224145Sdimclass t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
383218893Sdim                    list<dag> pattern>
384218893Sdim  : PseudoInst<oops, iops, itin, pattern> {
385224145Sdim  let Size = sz;
386218893Sdim  list<Predicate> Predicates = [IsThumb2];
387218893Sdim}
388224145Sdim
389224145Sdimclass ARMPseudoExpand<dag oops, dag iops, int sz,
390224145Sdim                      InstrItinClass itin, list<dag> pattern,
391224145Sdim                      dag Result>
392224145Sdim  : ARMPseudoInst<oops, iops, sz, itin, pattern>,
393224145Sdim    PseudoInstExpansion<Result>;
394224145Sdim
395224145Sdimclass tPseudoExpand<dag oops, dag iops, int sz,
396224145Sdim                    InstrItinClass itin, list<dag> pattern,
397224145Sdim                    dag Result>
398224145Sdim  : tPseudoInst<oops, iops, sz, itin, pattern>,
399224145Sdim    PseudoInstExpansion<Result>;
400224145Sdim
401224145Sdimclass t2PseudoExpand<dag oops, dag iops, int sz,
402224145Sdim                    InstrItinClass itin, list<dag> pattern,
403224145Sdim                    dag Result>
404224145Sdim  : t2PseudoInst<oops, iops, sz, itin, pattern>,
405224145Sdim    PseudoInstExpansion<Result>;
406224145Sdim
407193323Sed// Almost all ARM instructions are predicable.
408224145Sdimclass I<dag oops, dag iops, AddrMode am, int sz,
409206083Srdivacky        IndexMode im, Format f, InstrItinClass itin,
410198090Srdivacky        string opc, string asm, string cstr,
411193323Sed        list<dag> pattern>
412198892Srdivacky  : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
413218893Sdim  bits<4> p;
414218893Sdim  let Inst{31-28} = p;
415193323Sed  let OutOperandList = oops;
416205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
417218893Sdim  let AsmString = !strconcat(opc, "${p}", asm);
418193323Sed  let Pattern = pattern;
419193323Sed  list<Predicate> Predicates = [IsARM];
420193323Sed}
421212904Sdim
422200581Srdivacky// A few are not predicable
423224145Sdimclass InoP<dag oops, dag iops, AddrMode am, int sz,
424206083Srdivacky           IndexMode im, Format f, InstrItinClass itin,
425206083Srdivacky           string opc, string asm, string cstr,
426206083Srdivacky           list<dag> pattern>
427200581Srdivacky  : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
428200581Srdivacky  let OutOperandList = oops;
429200581Srdivacky  let InOperandList = iops;
430208599Srdivacky  let AsmString = !strconcat(opc, asm);
431200581Srdivacky  let Pattern = pattern;
432200581Srdivacky  let isPredicable = 0;
433200581Srdivacky  list<Predicate> Predicates = [IsARM];
434200581Srdivacky}
435193323Sed
436212904Sdim// Same as I except it can optionally modify CPSR. Note it's modeled as an input
437212904Sdim// operand since by default it's a zero register. It will become an implicit def
438212904Sdim// once it's "flipped".
439224145Sdimclass sI<dag oops, dag iops, AddrMode am, int sz,
440198090Srdivacky         IndexMode im, Format f, InstrItinClass itin,
441198090Srdivacky         string opc, string asm, string cstr,
442193323Sed         list<dag> pattern>
443198892Srdivacky  : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
444218893Sdim  bits<4> p; // Predicate operand
445218893Sdim  bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
446218893Sdim  let Inst{31-28} = p;
447218893Sdim  let Inst{20} = s;
448218893Sdim
449193323Sed  let OutOperandList = oops;
450205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
451218893Sdim  let AsmString = !strconcat(opc, "${s}${p}", asm);
452193323Sed  let Pattern = pattern;
453193323Sed  list<Predicate> Predicates = [IsARM];
454193323Sed}
455193323Sed
456193323Sed// Special cases
457224145Sdimclass XI<dag oops, dag iops, AddrMode am, int sz,
458198090Srdivacky         IndexMode im, Format f, InstrItinClass itin,
459198090Srdivacky         string asm, string cstr, list<dag> pattern>
460198892Srdivacky  : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
461193323Sed  let OutOperandList = oops;
462193323Sed  let InOperandList = iops;
463208599Srdivacky  let AsmString = asm;
464193323Sed  let Pattern = pattern;
465193323Sed  list<Predicate> Predicates = [IsARM];
466193323Sed}
467193323Sed
468198090Srdivackyclass AI<dag oops, dag iops, Format f, InstrItinClass itin,
469198090Srdivacky         string opc, string asm, list<dag> pattern>
470224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
471198090Srdivacky      opc, asm, "", pattern>;
472198090Srdivackyclass AsI<dag oops, dag iops, Format f, InstrItinClass itin,
473198090Srdivacky          string opc, string asm, list<dag> pattern>
474224145Sdim  : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
475198090Srdivacky       opc, asm, "", pattern>;
476198090Srdivackyclass AXI<dag oops, dag iops, Format f, InstrItinClass itin,
477193323Sed          string asm, list<dag> pattern>
478224145Sdim  : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
479193323Sed       asm, "", pattern>;
480200581Srdivackyclass AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
481206083Srdivacky            string opc, string asm, list<dag> pattern>
482224145Sdim  : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
483206083Srdivacky         opc, asm, "", pattern>;
484193323Sed
485193323Sed// Ctrl flow instructions
486198090Srdivackyclass ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
487198090Srdivacky          string opc, string asm, list<dag> pattern>
488224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
489198090Srdivacky      opc, asm, "", pattern> {
490193323Sed  let Inst{27-24} = opcod;
491193323Sed}
492198090Srdivackyclass ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
493198090Srdivacky           string asm, list<dag> pattern>
494224145Sdim  : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
495198090Srdivacky       asm, "", pattern> {
496193323Sed  let Inst{27-24} = opcod;
497193323Sed}
498193323Sed
499193323Sed// BR_JT instructions
500198090Srdivackyclass JTI<dag oops, dag iops, InstrItinClass itin,
501198090Srdivacky          string asm, list<dag> pattern>
502224145Sdim  : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
503193323Sed       asm, "", pattern>;
504193323Sed
505261991Sdimclass AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
506200581Srdivacky              string opc, string asm, list<dag> pattern>
507224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
508200581Srdivacky      opc, asm, "", pattern> {
509218893Sdim  bits<4> Rt;
510226633Sdim  bits<4> addr;
511200581Srdivacky  let Inst{27-23} = 0b00011;
512200581Srdivacky  let Inst{22-21} = opcod;
513212904Sdim  let Inst{20}    = 1;
514226633Sdim  let Inst{19-16} = addr;
515218893Sdim  let Inst{15-12} = Rt;
516261991Sdim  let Inst{11-10} = 0b11;
517261991Sdim  let Inst{9-8}   = opcod2;
518261991Sdim  let Inst{7-0}   = 0b10011111;
519200581Srdivacky}
520261991Sdimclass AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
521200581Srdivacky              string opc, string asm, list<dag> pattern>
522224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
523200581Srdivacky      opc, asm, "", pattern> {
524218893Sdim  bits<4> Rt;
525221345Sdim  bits<4> addr;
526200581Srdivacky  let Inst{27-23} = 0b00011;
527200581Srdivacky  let Inst{22-21} = opcod;
528212904Sdim  let Inst{20}    = 0;
529221345Sdim  let Inst{19-16} = addr;
530261991Sdim  let Inst{11-10} = 0b11;
531261991Sdim  let Inst{9-8}   = opcod2;
532261991Sdim  let Inst{7-4}   = 0b1001;
533218893Sdim  let Inst{3-0}   = Rt;
534200581Srdivacky}
535261991Sdim// Atomic load/store instructions
536261991Sdimclass AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
537261991Sdim              string opc, string asm, list<dag> pattern>
538261991Sdim  : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>;
539261991Sdim
540261991Sdimclass AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
541261991Sdim              string opc, string asm, list<dag> pattern>
542261991Sdim  : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> {
543261991Sdim  bits<4> Rd;
544261991Sdim  let Inst{15-12} = Rd;
545261991Sdim}
546261991Sdim
547261991Sdim// Exclusive load/store instructions
548261991Sdim
549261991Sdimclass AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
550261991Sdim              string opc, string asm, list<dag> pattern>
551261991Sdim  : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
552261991Sdim    Requires<[IsARM, HasV8]>;
553261991Sdim
554261991Sdimclass AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
555261991Sdim              string opc, string asm, list<dag> pattern>
556261991Sdim  : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
557261991Sdim    Requires<[IsARM, HasV8]> {
558261991Sdim  bits<4> Rd;
559261991Sdim  let Inst{15-12} = Rd;
560261991Sdim}
561261991Sdim
562218893Sdimclass AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
563226633Sdim  : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
564218893Sdim  bits<4> Rt;
565218893Sdim  bits<4> Rt2;
566226633Sdim  bits<4> addr;
567218893Sdim  let Inst{27-23} = 0b00010;
568218893Sdim  let Inst{22} = b;
569218893Sdim  let Inst{21-20} = 0b00;
570226633Sdim  let Inst{19-16} = addr;
571218893Sdim  let Inst{15-12} = Rt;
572218893Sdim  let Inst{11-4} = 0b00001001;
573218893Sdim  let Inst{3-0} = Rt2;
574234353Sdim
575234982Sdim  let Unpredictable{11-8} = 0b1111;
576234353Sdim  let DecoderMethod = "DecodeSwap";
577218893Sdim}
578261991Sdim// Acquire/Release load/store instructions
579261991Sdimclass AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
580261991Sdim              string opc, string asm, list<dag> pattern>
581261991Sdim  : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
582261991Sdim    Requires<[IsARM, HasV8]>;
583200581Srdivacky
584261991Sdimclass AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
585261991Sdim              string opc, string asm, list<dag> pattern>
586261991Sdim  : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
587261991Sdim    Requires<[IsARM, HasV8]> {
588261991Sdim  let Inst{15-12}   = 0b1111;
589261991Sdim}
590261991Sdim
591193323Sed// addrmode1 instructions
592198090Srdivackyclass AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
593198090Srdivacky          string opc, string asm, list<dag> pattern>
594224145Sdim  : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
595198090Srdivacky      opc, asm, "", pattern> {
596193323Sed  let Inst{24-21} = opcod;
597212904Sdim  let Inst{27-26} = 0b00;
598193323Sed}
599198090Srdivackyclass AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
600198090Srdivacky           string opc, string asm, list<dag> pattern>
601224145Sdim  : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
602198090Srdivacky       opc, asm, "", pattern> {
603193323Sed  let Inst{24-21} = opcod;
604212904Sdim  let Inst{27-26} = 0b00;
605193323Sed}
606198090Srdivackyclass AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
607198090Srdivacky           string asm, list<dag> pattern>
608224145Sdim  : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
609198090Srdivacky       asm, "", pattern> {
610193323Sed  let Inst{24-21} = opcod;
611212904Sdim  let Inst{27-26} = 0b00;
612193323Sed}
613193323Sed
614193323Sed// loads
615193323Sed
616218893Sdim// LDR/LDRB/STR/STRB/...
617218893Sdimclass AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
618218893Sdim             Format f, InstrItinClass itin, string opc, string asm,
619218893Sdim             list<dag> pattern>
620224145Sdim  : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
621218893Sdim      "", pattern> {
622218893Sdim  let Inst{27-25} = op;
623218893Sdim  let Inst{24} = 1;  // 24 == P
624218893Sdim  // 23 == U
625218893Sdim  let Inst{22} = isByte;
626218893Sdim  let Inst{21} = 0;  // 21 == W
627218893Sdim  let Inst{20} = isLd;
628193323Sed}
629218893Sdim// Indexed load/stores
630218893Sdimclass AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
631218893Sdim                IndexMode im, Format f, InstrItinClass itin, string opc,
632218893Sdim                string asm, string cstr, list<dag> pattern>
633224145Sdim  : I<oops, iops, AddrMode2, 4, im, f, itin,
634198090Srdivacky      opc, asm, cstr, pattern> {
635218893Sdim  bits<4> Rt;
636212904Sdim  let Inst{27-26} = 0b01;
637218893Sdim  let Inst{24}    = isPre; // P bit
638218893Sdim  let Inst{22}    = isByte; // B bit
639218893Sdim  let Inst{21}    = isPre; // W bit
640218893Sdim  let Inst{20}    = isLd; // L bit
641218893Sdim  let Inst{15-12} = Rt;
642193323Sed}
643226633Sdimclass AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
644218893Sdim                IndexMode im, Format f, InstrItinClass itin, string opc,
645218893Sdim                string asm, string cstr, list<dag> pattern>
646218893Sdim  : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
647218893Sdim               pattern> {
648218893Sdim  // AM2 store w/ two operands: (GPR, am2offset)
649218893Sdim  // {12}     isAdd
650218893Sdim  // {11-0}   imm12/Rm
651218893Sdim  bits<14> offset;
652218893Sdim  bits<4> Rn;
653226633Sdim  let Inst{25} = 1;
654218893Sdim  let Inst{23} = offset{12};
655218893Sdim  let Inst{19-16} = Rn;
656226633Sdim  let Inst{11-5} = offset{11-5};
657226633Sdim  let Inst{4} = 0;
658226633Sdim  let Inst{3-0} = offset{3-0};
659226633Sdim}
660226633Sdim
661226633Sdimclass AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
662226633Sdim                IndexMode im, Format f, InstrItinClass itin, string opc,
663226633Sdim                string asm, string cstr, list<dag> pattern>
664226633Sdim  : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
665226633Sdim               pattern> {
666226633Sdim  // AM2 store w/ two operands: (GPR, am2offset)
667226633Sdim  // {12}     isAdd
668226633Sdim  // {11-0}   imm12/Rm
669226633Sdim  bits<14> offset;
670226633Sdim  bits<4> Rn;
671226633Sdim  let Inst{25} = 0;
672226633Sdim  let Inst{23} = offset{12};
673226633Sdim  let Inst{19-16} = Rn;
674218893Sdim  let Inst{11-0} = offset{11-0};
675193323Sed}
676226633Sdim
677226633Sdim
678221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
679221345Sdim// but for now use this class for STRT and STRBT.
680221345Sdimclass AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
681221345Sdim                IndexMode im, Format f, InstrItinClass itin, string opc,
682221345Sdim                string asm, string cstr, list<dag> pattern>
683221345Sdim  : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
684221345Sdim               pattern> {
685221345Sdim  // AM2 store w/ two operands: (GPR, am2offset)
686221345Sdim  // {17-14}  Rn
687221345Sdim  // {13}     1 == Rm, 0 == imm12
688221345Sdim  // {12}     isAdd
689221345Sdim  // {11-0}   imm12/Rm
690221345Sdim  bits<18> addr;
691221345Sdim  let Inst{25} = addr{13};
692221345Sdim  let Inst{23} = addr{12};
693221345Sdim  let Inst{19-16} = addr{17-14};
694221345Sdim  let Inst{11-0} = addr{11-0};
695221345Sdim}
696193323Sed
697193323Sed// addrmode3 instructions
698218893Sdimclass AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
699218893Sdim            InstrItinClass itin, string opc, string asm, list<dag> pattern>
700224145Sdim  : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
701198090Srdivacky      opc, asm, "", pattern> {
702218893Sdim  bits<14> addr;
703218893Sdim  bits<4> Rt;
704198090Srdivacky  let Inst{27-25} = 0b000;
705218893Sdim  let Inst{24}    = 1;            // P bit
706218893Sdim  let Inst{23}    = addr{8};      // U bit
707218893Sdim  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
708218893Sdim  let Inst{21}    = 0;            // W bit
709218893Sdim  let Inst{20}    = op20;         // L bit
710218893Sdim  let Inst{19-16} = addr{12-9};   // Rn
711218893Sdim  let Inst{15-12} = Rt;           // Rt
712218893Sdim  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
713218893Sdim  let Inst{7-4}   = op;
714218893Sdim  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
715226633Sdim
716226633Sdim  let DecoderMethod = "DecodeAddrMode3Instruction";
717193323Sed}
718218893Sdim
719226633Sdimclass AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
720218893Sdim                IndexMode im, Format f, InstrItinClass itin, string opc,
721218893Sdim                string asm, string cstr, list<dag> pattern>
722224145Sdim  : I<oops, iops, AddrMode3, 4, im, f, itin,
723218893Sdim      opc, asm, cstr, pattern> {
724218893Sdim  bits<4> Rt;
725198090Srdivacky  let Inst{27-25} = 0b000;
726218893Sdim  let Inst{24}    = isPre;        // P bit
727218893Sdim  let Inst{21}    = isPre;        // W bit
728218893Sdim  let Inst{20}    = op20;         // L bit
729218893Sdim  let Inst{15-12} = Rt;           // Rt
730218893Sdim  let Inst{7-4}   = op;
731193323Sed}
732221345Sdim
733221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
734221345Sdim// but for now use this class for LDRSBT, LDRHT, LDSHT.
735226633Sdimclass AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
736221345Sdim                  IndexMode im, Format f, InstrItinClass itin, string opc,
737221345Sdim                  string asm, string cstr, list<dag> pattern>
738226633Sdim  : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
739221345Sdim  // {13}     1 == imm8, 0 == Rm
740221345Sdim  // {12-9}   Rn
741221345Sdim  // {8}      isAdd
742221345Sdim  // {7-4}    imm7_4/zero
743221345Sdim  // {3-0}    imm3_0/Rm
744226633Sdim  bits<4> addr;
745221345Sdim  bits<4> Rt;
746221345Sdim  let Inst{27-25} = 0b000;
747226633Sdim  let Inst{24}    = 0;            // P bit
748226633Sdim  let Inst{21}    = 1;
749226633Sdim  let Inst{20}    = isLoad;       // L bit
750226633Sdim  let Inst{19-16} = addr;         // Rn
751221345Sdim  let Inst{15-12} = Rt;           // Rt
752221345Sdim  let Inst{7-4}   = op;
753221345Sdim}
754221345Sdim
755193323Sed// stores
756218893Sdimclass AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
757198090Srdivacky             string opc, string asm, list<dag> pattern>
758224145Sdim  : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
759198090Srdivacky      opc, asm, "", pattern> {
760218893Sdim  bits<14> addr;
761218893Sdim  bits<4> Rt;
762198090Srdivacky  let Inst{27-25} = 0b000;
763218893Sdim  let Inst{24}    = 1;            // P bit
764218893Sdim  let Inst{23}    = addr{8};      // U bit
765218893Sdim  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
766218893Sdim  let Inst{21}    = 0;            // W bit
767218893Sdim  let Inst{20}    = 0;            // L bit
768218893Sdim  let Inst{19-16} = addr{12-9};   // Rn
769218893Sdim  let Inst{15-12} = Rt;           // Rt
770218893Sdim  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
771218893Sdim  let Inst{7-4}   = op;
772218893Sdim  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
773226633Sdim  let DecoderMethod = "DecodeAddrMode3Instruction";
774193323Sed}
775193323Sed
776193323Sed// addrmode4 instructions
777218893Sdimclass AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
778218893Sdim           string asm, string cstr, list<dag> pattern>
779224145Sdim  : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
780218893Sdim  bits<4>  p;
781218893Sdim  bits<16> regs;
782218893Sdim  bits<4>  Rn;
783218893Sdim  let Inst{31-28} = p;
784193323Sed  let Inst{27-25} = 0b100;
785193323Sed  let Inst{22}    = 0; // S bit
786218893Sdim  let Inst{19-16} = Rn;
787218893Sdim  let Inst{15-0}  = regs;
788193323Sed}
789193323Sed
790193323Sed// Unsigned multiply, multiply-accumulate instructions.
791198090Srdivackyclass AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
792198090Srdivacky             string opc, string asm, list<dag> pattern>
793224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
794198090Srdivacky      opc, asm, "", pattern> {
795193323Sed  let Inst{7-4}   = 0b1001;
796193323Sed  let Inst{20}    = 0; // S bit
797193323Sed  let Inst{27-21} = opcod;
798193323Sed}
799198090Srdivackyclass AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
800198090Srdivacky              string opc, string asm, list<dag> pattern>
801224145Sdim  : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
802198090Srdivacky       opc, asm, "", pattern> {
803193323Sed  let Inst{7-4}   = 0b1001;
804193323Sed  let Inst{27-21} = opcod;
805193323Sed}
806193323Sed
807193323Sed// Most significant word multiply
808218893Sdimclass AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
809218893Sdim             InstrItinClass itin, string opc, string asm, list<dag> pattern>
810224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
811198090Srdivacky      opc, asm, "", pattern> {
812218893Sdim  bits<4> Rd;
813218893Sdim  bits<4> Rn;
814218893Sdim  bits<4> Rm;
815218893Sdim  let Inst{7-4}   = opc7_4;
816193323Sed  let Inst{20}    = 1;
817193323Sed  let Inst{27-21} = opcod;
818218893Sdim  let Inst{19-16} = Rd;
819218893Sdim  let Inst{11-8}  = Rm;
820218893Sdim  let Inst{3-0}   = Rn;
821193323Sed}
822218893Sdim// MSW multiple w/ Ra operand
823218893Sdimclass AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
824218893Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
825218893Sdim  : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
826218893Sdim  bits<4> Ra;
827218893Sdim  let Inst{15-12} = Ra;
828218893Sdim}
829193323Sed
830193323Sed// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
831218893Sdimclass AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
832218893Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
833224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
834198090Srdivacky      opc, asm, "", pattern> {
835218893Sdim  bits<4> Rn;
836218893Sdim  bits<4> Rm;
837193323Sed  let Inst{4}     = 0;
838193323Sed  let Inst{7}     = 1;
839193323Sed  let Inst{20}    = 0;
840193323Sed  let Inst{27-21} = opcod;
841218893Sdim  let Inst{6-5}   = bit6_5;
842218893Sdim  let Inst{11-8}  = Rm;
843218893Sdim  let Inst{3-0}   = Rn;
844193323Sed}
845218893Sdimclass AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
846218893Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
847218893Sdim  : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
848218893Sdim  bits<4> Rd;
849218893Sdim  let Inst{19-16} = Rd;
850218893Sdim}
851193323Sed
852218893Sdim// AMulxyI with Ra operand
853218893Sdimclass AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
854218893Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
855218893Sdim  : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
856218893Sdim  bits<4> Ra;
857218893Sdim  let Inst{15-12} = Ra;
858218893Sdim}
859218893Sdim// SMLAL*
860218893Sdimclass AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
861218893Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
862218893Sdim  : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
863218893Sdim  bits<4> RdLo;
864218893Sdim  bits<4> RdHi;
865218893Sdim  let Inst{19-16} = RdHi;
866218893Sdim  let Inst{15-12} = RdLo;
867218893Sdim}
868218893Sdim
869193323Sed// Extend instructions.
870198090Srdivackyclass AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
871198090Srdivacky            string opc, string asm, list<dag> pattern>
872224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
873198090Srdivacky      opc, asm, "", pattern> {
874218893Sdim  // All AExtI instructions have Rd and Rm register operands.
875218893Sdim  bits<4> Rd;
876218893Sdim  bits<4> Rm;
877218893Sdim  let Inst{15-12} = Rd;
878218893Sdim  let Inst{3-0}   = Rm;
879193323Sed  let Inst{7-4}   = 0b0111;
880218893Sdim  let Inst{9-8}   = 0b00;
881193323Sed  let Inst{27-20} = opcod;
882239462Sdim
883239462Sdim  let Unpredictable{9-8} = 0b11;
884193323Sed}
885193323Sed
886193323Sed// Misc Arithmetic instructions.
887218893Sdimclass AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
888218893Sdim               InstrItinClass itin, string opc, string asm, list<dag> pattern>
889224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
890198090Srdivacky      opc, asm, "", pattern> {
891218893Sdim  bits<4> Rd;
892218893Sdim  bits<4> Rm;
893193323Sed  let Inst{27-20} = opcod;
894218893Sdim  let Inst{19-16} = 0b1111;
895218893Sdim  let Inst{15-12} = Rd;
896218893Sdim  let Inst{11-8}  = 0b1111;
897218893Sdim  let Inst{7-4}   = opc7_4;
898218893Sdim  let Inst{3-0}   = Rm;
899193323Sed}
900193323Sed
901243830Sdim// Division instructions.
902243830Sdimclass ADivA1I<bits<3> opcod, dag oops, dag iops,
903243830Sdim              InstrItinClass itin, string opc, string asm, list<dag> pattern>
904243830Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
905243830Sdim      opc, asm, "", pattern> {
906243830Sdim  bits<4> Rd;
907243830Sdim  bits<4> Rn;
908243830Sdim  bits<4> Rm;
909243830Sdim  let Inst{27-23} = 0b01110;
910243830Sdim  let Inst{22-20} = opcod;
911243830Sdim  let Inst{19-16} = Rd;
912243830Sdim  let Inst{15-12} = 0b1111;
913243830Sdim  let Inst{11-8}  = Rm;
914243830Sdim  let Inst{7-4}   = 0b0001;
915243830Sdim  let Inst{3-0}   = Rn;
916243830Sdim}
917243830Sdim
918218893Sdim// PKH instructions
919234353Sdimdef PKHLSLAsmOperand : ImmAsmOperand {
920226633Sdim  let Name = "PKHLSLImm";
921226633Sdim  let ParserMethod = "parsePKHLSLImm";
922226633Sdim}
923226633Sdimdef pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
924226633Sdim  let PrintMethod = "printPKHLSLShiftImm";
925226633Sdim  let ParserMatchClass = PKHLSLAsmOperand;
926226633Sdim}
927226633Sdimdef PKHASRAsmOperand : AsmOperandClass {
928226633Sdim  let Name = "PKHASRImm";
929226633Sdim  let ParserMethod = "parsePKHASRImm";
930226633Sdim}
931226633Sdimdef pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
932226633Sdim  let PrintMethod = "printPKHASRShiftImm";
933226633Sdim  let ParserMatchClass = PKHASRAsmOperand;
934226633Sdim}
935226633Sdim
936218893Sdimclass APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
937218893Sdim            string opc, string asm, list<dag> pattern>
938224145Sdim  : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
939218893Sdim      opc, asm, "", pattern> {
940218893Sdim  bits<4> Rd;
941218893Sdim  bits<4> Rn;
942218893Sdim  bits<4> Rm;
943226633Sdim  bits<5> sh;
944218893Sdim  let Inst{27-20} = opcod;
945218893Sdim  let Inst{19-16} = Rn;
946218893Sdim  let Inst{15-12} = Rd;
947226633Sdim  let Inst{11-7}  = sh;
948218893Sdim  let Inst{6}     = tb;
949218893Sdim  let Inst{5-4}   = 0b01;
950218893Sdim  let Inst{3-0}   = Rm;
951218893Sdim}
952218893Sdim
953193323Sed//===----------------------------------------------------------------------===//
954193323Sed
955193323Sed// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
956193323Sedclass ARMPat<dag pattern, dag result> : Pat<pattern, result> {
957193323Sed  list<Predicate> Predicates = [IsARM];
958193323Sed}
959223017Sdimclass ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
960223017Sdim  list<Predicate> Predicates = [IsARM, HasV5T];
961223017Sdim}
962193323Sedclass ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
963193323Sed  list<Predicate> Predicates = [IsARM, HasV5TE];
964193323Sed}
965243830Sdim// ARMV5MOPat - Same as ARMV5TEPat with UseMulOps.
966243830Sdimclass ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> {
967243830Sdim  list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps];
968243830Sdim}
969193323Sedclass ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
970193323Sed  list<Predicate> Predicates = [IsARM, HasV6];
971193323Sed}
972193323Sed
973193323Sed//===----------------------------------------------------------------------===//
974193323Sed// Thumb Instruction Format Definitions.
975193323Sed//
976193323Sed
977224145Sdimclass ThumbI<dag oops, dag iops, AddrMode am, int sz,
978198090Srdivacky             InstrItinClass itin, string asm, string cstr, list<dag> pattern>
979201360Srdivacky  : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
980198090Srdivacky  let OutOperandList = oops;
981198090Srdivacky  let InOperandList = iops;
982208599Srdivacky  let AsmString = asm;
983193323Sed  let Pattern = pattern;
984193323Sed  list<Predicate> Predicates = [IsThumb];
985193323Sed}
986193323Sed
987218893Sdim// TI - Thumb instruction.
988198090Srdivackyclass TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
989224145Sdim  : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
990193323Sed
991198090Srdivacky// Two-address instructions
992206083Srdivackyclass TIt<dag oops, dag iops, InstrItinClass itin, string asm,
993206083Srdivacky          list<dag> pattern>
994224145Sdim  : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
995206083Srdivacky           pattern>;
996193323Sed
997201360Srdivacky// tBL, tBX 32-bit instructions
998201360Srdivackyclass TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
999206083Srdivacky           dag oops, dag iops, InstrItinClass itin, string asm,
1000206083Srdivacky           list<dag> pattern>
1001224145Sdim    : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
1002206083Srdivacky      Encoding {
1003201360Srdivacky  let Inst{31-27} = opcod1;
1004201360Srdivacky  let Inst{15-14} = opcod2;
1005212904Sdim  let Inst{12}    = opcod3;
1006201360Srdivacky}
1007198090Srdivacky
1008193323Sed// BR_JT instructions
1009206083Srdivackyclass TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
1010206083Srdivacky           list<dag> pattern>
1011224145Sdim  : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1012193323Sed
1013198090Srdivacky// Thumb1 only
1014224145Sdimclass Thumb1I<dag oops, dag iops, AddrMode am, int sz,
1015198090Srdivacky              InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1016201360Srdivacky  : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1017198090Srdivacky  let OutOperandList = oops;
1018198090Srdivacky  let InOperandList = iops;
1019208599Srdivacky  let AsmString = asm;
1020198090Srdivacky  let Pattern = pattern;
1021218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1022194710Sed}
1023193323Sed
1024198090Srdivackyclass T1I<dag oops, dag iops, InstrItinClass itin,
1025198090Srdivacky          string asm, list<dag> pattern>
1026224145Sdim  : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1027198090Srdivackyclass T1Ix2<dag oops, dag iops, InstrItinClass itin,
1028198090Srdivacky            string asm, list<dag> pattern>
1029224145Sdim  : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1030194710Sed
1031198090Srdivacky// Two-address instructions
1032198090Srdivackyclass T1It<dag oops, dag iops, InstrItinClass itin,
1033205218Srdivacky           string asm, string cstr, list<dag> pattern>
1034224145Sdim  : Thumb1I<oops, iops, AddrModeNone, 2, itin,
1035205218Srdivacky            asm, cstr, pattern>;
1036198090Srdivacky
1037198090Srdivacky// Thumb1 instruction that can either be predicated or set CPSR.
1038224145Sdimclass Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
1039198090Srdivacky               InstrItinClass itin,
1040198090Srdivacky               string opc, string asm, string cstr, list<dag> pattern>
1041201360Srdivacky  : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1042205407Srdivacky  let OutOperandList = !con(oops, (outs s_cc_out:$s));
1043205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1044218893Sdim  let AsmString = !strconcat(opc, "${s}${p}", asm);
1045194754Sed  let Pattern = pattern;
1046226633Sdim  let thumbArithFlagSetting = 1;
1047218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1048226633Sdim  let DecoderNamespace = "ThumbSBit";
1049195098Sed}
1050195098Sed
1051198090Srdivackyclass T1sI<dag oops, dag iops, InstrItinClass itin,
1052198090Srdivacky           string opc, string asm, list<dag> pattern>
1053224145Sdim  : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1054195098Sed
1055195098Sed// Two-address instructions
1056198090Srdivackyclass T1sIt<dag oops, dag iops, InstrItinClass itin,
1057198090Srdivacky            string opc, string asm, list<dag> pattern>
1058224145Sdim  : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1059218893Sdim             "$Rn = $Rdn", pattern>;
1060195098Sed
1061198090Srdivacky// Thumb1 instruction that can be predicated.
1062224145Sdimclass Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
1063198090Srdivacky               InstrItinClass itin,
1064198090Srdivacky               string opc, string asm, string cstr, list<dag> pattern>
1065201360Srdivacky  : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1066198090Srdivacky  let OutOperandList = oops;
1067205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1068218893Sdim  let AsmString = !strconcat(opc, "${p}", asm);
1069198090Srdivacky  let Pattern = pattern;
1070218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1071195098Sed}
1072195098Sed
1073198090Srdivackyclass T1pI<dag oops, dag iops, InstrItinClass itin,
1074198090Srdivacky           string opc, string asm, list<dag> pattern>
1075224145Sdim  : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1076198090Srdivacky
1077198090Srdivacky// Two-address instructions
1078198090Srdivackyclass T1pIt<dag oops, dag iops, InstrItinClass itin,
1079198090Srdivacky            string opc, string asm, list<dag> pattern>
1080224145Sdim  : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1081218893Sdim             "$Rn = $Rdn", pattern>;
1082198090Srdivacky
1083206083Srdivackyclass T1pIs<dag oops, dag iops,
1084198090Srdivacky            InstrItinClass itin, string opc, string asm, list<dag> pattern>
1085224145Sdim  : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
1086198090Srdivacky
1087201360Srdivackyclass Encoding16 : Encoding {
1088201360Srdivacky  let Inst{31-16} = 0x0000;
1089201360Srdivacky}
1090201360Srdivacky
1091201360Srdivacky// A6.2 16-bit Thumb instruction encoding
1092201360Srdivackyclass T1Encoding<bits<6> opcode> : Encoding16 {
1093201360Srdivacky  let Inst{15-10} = opcode;
1094201360Srdivacky}
1095201360Srdivacky
1096201360Srdivacky// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1097201360Srdivackyclass T1General<bits<5> opcode> : Encoding16 {
1098201360Srdivacky  let Inst{15-14} = 0b00;
1099201360Srdivacky  let Inst{13-9} = opcode;
1100201360Srdivacky}
1101201360Srdivacky
1102201360Srdivacky// A6.2.2 Data-processing encoding.
1103201360Srdivackyclass T1DataProcessing<bits<4> opcode> : Encoding16 {
1104201360Srdivacky  let Inst{15-10} = 0b010000;
1105201360Srdivacky  let Inst{9-6} = opcode;
1106201360Srdivacky}
1107201360Srdivacky
1108201360Srdivacky// A6.2.3 Special data instructions and branch and exchange encoding.
1109201360Srdivackyclass T1Special<bits<4> opcode> : Encoding16 {
1110201360Srdivacky  let Inst{15-10} = 0b010001;
1111218893Sdim  let Inst{9-6}   = opcode;
1112201360Srdivacky}
1113201360Srdivacky
1114201360Srdivacky// A6.2.4 Load/store single data item encoding.
1115201360Srdivackyclass T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1116201360Srdivacky  let Inst{15-12} = opA;
1117212904Sdim  let Inst{11-9}  = opB;
1118201360Srdivacky}
1119212904Sdimclass T1LdStSP<bits<3> opB>   : T1LoadStore<0b1001, opB>; // SP relative
1120201360Srdivacky
1121223017Sdimclass T1BranchCond<bits<4> opcode> : Encoding16 {
1122223017Sdim  let Inst{15-12} = opcode;
1123223017Sdim}
1124223017Sdim
1125218893Sdim// Helper classes to encode Thumb1 loads and stores. For immediates, the
1126218893Sdim// following bits are used for "opA" (see A6.2.4):
1127218893Sdim//
1128218893Sdim//   0b0110 => Immediate, 4 bytes
1129218893Sdim//   0b1000 => Immediate, 2 bytes
1130218893Sdim//   0b0111 => Immediate, 1 byte
1131218893Sdimclass T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
1132218893Sdim                     InstrItinClass itin, string opc, string asm,
1133218893Sdim                     list<dag> pattern>
1134224145Sdim  : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1135218893Sdim    T1LoadStore<0b0101, opcode> {
1136218893Sdim  bits<3> Rt;
1137218893Sdim  bits<8> addr;
1138218893Sdim  let Inst{8-6} = addr{5-3};    // Rm
1139218893Sdim  let Inst{5-3} = addr{2-0};    // Rn
1140218893Sdim  let Inst{2-0} = Rt;
1141218893Sdim}
1142218893Sdimclass T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
1143218893Sdim                        InstrItinClass itin, string opc, string asm,
1144218893Sdim                        list<dag> pattern>
1145224145Sdim  : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1146218893Sdim    T1LoadStore<opA, {opB,?,?}> {
1147218893Sdim  bits<3> Rt;
1148218893Sdim  bits<8> addr;
1149218893Sdim  let Inst{10-6} = addr{7-3};   // imm5
1150218893Sdim  let Inst{5-3}  = addr{2-0};   // Rn
1151218893Sdim  let Inst{2-0}  = Rt;
1152218893Sdim}
1153218893Sdim
1154201360Srdivacky// A6.2.5 Miscellaneous 16-bit instructions encoding.
1155201360Srdivackyclass T1Misc<bits<7> opcode> : Encoding16 {
1156201360Srdivacky  let Inst{15-12} = 0b1011;
1157201360Srdivacky  let Inst{11-5} = opcode;
1158201360Srdivacky}
1159201360Srdivacky
1160195098Sed// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1161224145Sdimclass Thumb2I<dag oops, dag iops, AddrMode am, int sz,
1162198090Srdivacky              InstrItinClass itin,
1163195098Sed              string opc, string asm, string cstr, list<dag> pattern>
1164198892Srdivacky  : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1165195098Sed  let OutOperandList = oops;
1166205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1167218893Sdim  let AsmString = !strconcat(opc, "${p}", asm);
1168195098Sed  let Pattern = pattern;
1169195340Sed  list<Predicate> Predicates = [IsThumb2];
1170226633Sdim  let DecoderNamespace = "Thumb2";
1171194754Sed}
1172194754Sed
1173212904Sdim// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
1174212904Sdim// input operand since by default it's a zero register. It will become an
1175212904Sdim// implicit def once it's "flipped".
1176218893Sdim//
1177195098Sed// FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1178195098Sed// more consistent.
1179224145Sdimclass Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
1180198090Srdivacky               InstrItinClass itin,
1181195098Sed               string opc, string asm, string cstr, list<dag> pattern>
1182198892Srdivacky  : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1183218893Sdim  bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
1184218893Sdim  let Inst{20} = s;
1185218893Sdim
1186195098Sed  let OutOperandList = oops;
1187205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1188218893Sdim  let AsmString = !strconcat(opc, "${s}${p}", asm);
1189195098Sed  let Pattern = pattern;
1190195340Sed  list<Predicate> Predicates = [IsThumb2];
1191226633Sdim  let DecoderNamespace = "Thumb2";
1192195098Sed}
1193194754Sed
1194195098Sed// Special cases
1195224145Sdimclass Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
1196198090Srdivacky               InstrItinClass itin,
1197195098Sed               string asm, string cstr, list<dag> pattern>
1198198892Srdivacky  : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1199195098Sed  let OutOperandList = oops;
1200195098Sed  let InOperandList = iops;
1201208599Srdivacky  let AsmString = asm;
1202195098Sed  let Pattern = pattern;
1203195340Sed  list<Predicate> Predicates = [IsThumb2];
1204226633Sdim  let DecoderNamespace = "Thumb2";
1205194754Sed}
1206194754Sed
1207224145Sdimclass ThumbXI<dag oops, dag iops, AddrMode am, int sz,
1208206083Srdivacky              InstrItinClass itin,
1209206083Srdivacky              string asm, string cstr, list<dag> pattern>
1210200581Srdivacky  : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1211200581Srdivacky  let OutOperandList = oops;
1212200581Srdivacky  let InOperandList = iops;
1213208599Srdivacky  let AsmString = asm;
1214200581Srdivacky  let Pattern = pattern;
1215218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1216226633Sdim  let DecoderNamespace = "Thumb";
1217200581Srdivacky}
1218200581Srdivacky
1219198090Srdivackyclass T2I<dag oops, dag iops, InstrItinClass itin,
1220198090Srdivacky          string opc, string asm, list<dag> pattern>
1221224145Sdim  : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1222198090Srdivackyclass T2Ii12<dag oops, dag iops, InstrItinClass itin,
1223198090Srdivacky             string opc, string asm, list<dag> pattern>
1224224145Sdim  : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
1225198090Srdivackyclass T2Ii8<dag oops, dag iops, InstrItinClass itin,
1226198090Srdivacky            string opc, string asm, list<dag> pattern>
1227224145Sdim  : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>;
1228198090Srdivackyclass T2Iso<dag oops, dag iops, InstrItinClass itin,
1229198090Srdivacky            string opc, string asm, list<dag> pattern>
1230224145Sdim  : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
1231198090Srdivackyclass T2Ipc<dag oops, dag iops, InstrItinClass itin,
1232198090Srdivacky            string opc, string asm, list<dag> pattern>
1233224145Sdim  : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
1234218893Sdimclass T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
1235226633Sdim              string opc, string asm, string cstr, list<dag> pattern>
1236226633Sdim  : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1237201360Srdivacky            pattern> {
1238218893Sdim  bits<4> Rt;
1239218893Sdim  bits<4> Rt2;
1240218893Sdim  bits<13> addr;
1241218893Sdim  let Inst{31-25} = 0b1110100;
1242212904Sdim  let Inst{24}    = P;
1243218893Sdim  let Inst{23}    = addr{8};
1244212904Sdim  let Inst{22}    = 1;
1245212904Sdim  let Inst{21}    = W;
1246218893Sdim  let Inst{20}    = isLoad;
1247218893Sdim  let Inst{19-16} = addr{12-9};
1248218893Sdim  let Inst{15-12} = Rt{3-0};
1249218893Sdim  let Inst{11-8}  = Rt2{3-0};
1250218893Sdim  let Inst{7-0}   = addr{7-0};
1251201360Srdivacky}
1252226633Sdimclass T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
1253226633Sdim                  InstrItinClass itin, string opc, string asm, string cstr,
1254226633Sdim                  list<dag> pattern>
1255226633Sdim  : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1256226633Sdim            pattern> {
1257226633Sdim  bits<4> Rt;
1258226633Sdim  bits<4> Rt2;
1259226633Sdim  bits<4> addr;
1260226633Sdim  bits<9> imm;
1261226633Sdim  let Inst{31-25} = 0b1110100;
1262226633Sdim  let Inst{24}    = P;
1263226633Sdim  let Inst{23}    = imm{8};
1264226633Sdim  let Inst{22}    = 1;
1265226633Sdim  let Inst{21}    = W;
1266226633Sdim  let Inst{20}    = isLoad;
1267226633Sdim  let Inst{19-16} = addr;
1268226633Sdim  let Inst{15-12} = Rt{3-0};
1269226633Sdim  let Inst{11-8}  = Rt2{3-0};
1270226633Sdim  let Inst{7-0}   = imm{7-0};
1271226633Sdim}
1272195098Sed
1273198090Srdivackyclass T2sI<dag oops, dag iops, InstrItinClass itin,
1274198090Srdivacky           string opc, string asm, list<dag> pattern>
1275224145Sdim  : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1276195098Sed
1277198090Srdivackyclass T2XI<dag oops, dag iops, InstrItinClass itin,
1278198090Srdivacky           string asm, list<dag> pattern>
1279224145Sdim  : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1280198090Srdivackyclass T2JTI<dag oops, dag iops, InstrItinClass itin,
1281198090Srdivacky            string asm, list<dag> pattern>
1282224145Sdim  : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1283195098Sed
1284218893Sdim// Move to/from coprocessor instructions
1285261991Sdimclass T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
1286261991Sdim            list<dag> pattern>
1287261991Sdim  : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
1288224145Sdim  let Inst{31-28} = opc;
1289218893Sdim}
1290198090Srdivacky
1291205218Srdivacky// Two-address instructions
1292205218Srdivackyclass T2XIt<dag oops, dag iops, InstrItinClass itin,
1293205218Srdivacky            string asm, string cstr, list<dag> pattern>
1294224145Sdim  : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
1295198090Srdivacky
1296226633Sdim// T2Ipreldst - Thumb2 pre-indexed load / store instructions.
1297226633Sdimclass T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
1298201360Srdivacky                 dag oops, dag iops,
1299201360Srdivacky                 AddrMode am, IndexMode im, InstrItinClass itin,
1300195340Sed                 string opc, string asm, string cstr, list<dag> pattern>
1301224145Sdim  : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1302195340Sed  let OutOperandList = oops;
1303205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1304218893Sdim  let AsmString = !strconcat(opc, "${p}", asm);
1305195340Sed  let Pattern = pattern;
1306195340Sed  list<Predicate> Predicates = [IsThumb2];
1307226633Sdim  let DecoderNamespace = "Thumb2";
1308226633Sdim
1309226633Sdim  bits<4> Rt;
1310226633Sdim  bits<13> addr;
1311201360Srdivacky  let Inst{31-27} = 0b11111;
1312201360Srdivacky  let Inst{26-25} = 0b00;
1313212904Sdim  let Inst{24}    = signed;
1314212904Sdim  let Inst{23}    = 0;
1315201360Srdivacky  let Inst{22-21} = opcod;
1316212904Sdim  let Inst{20}    = load;
1317226633Sdim  let Inst{19-16} = addr{12-9};
1318226633Sdim  let Inst{15-12} = Rt{3-0};
1319212904Sdim  let Inst{11}    = 1;
1320201360Srdivacky  // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1321212904Sdim  let Inst{10}    = pre; // The P bit.
1322226633Sdim  let Inst{9}     = addr{8}; // Sign bit
1323212904Sdim  let Inst{8}     = 1; // The W bit.
1324226633Sdim  let Inst{7-0}   = addr{7-0};
1325195340Sed
1326226633Sdim  let DecoderMethod = "DecodeT2LdStPre";
1327226633Sdim}
1328218893Sdim
1329226633Sdim// T2Ipostldst - Thumb2 post-indexed load / store instructions.
1330226633Sdimclass T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
1331226633Sdim                 dag oops, dag iops,
1332226633Sdim                 AddrMode am, IndexMode im, InstrItinClass itin,
1333226633Sdim                 string opc, string asm, string cstr, list<dag> pattern>
1334226633Sdim  : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1335226633Sdim  let OutOperandList = oops;
1336226633Sdim  let InOperandList = !con(iops, (ins pred:$p));
1337226633Sdim  let AsmString = !strconcat(opc, "${p}", asm);
1338226633Sdim  let Pattern = pattern;
1339226633Sdim  list<Predicate> Predicates = [IsThumb2];
1340226633Sdim  let DecoderNamespace = "Thumb2";
1341226633Sdim
1342218893Sdim  bits<4> Rt;
1343218893Sdim  bits<4> Rn;
1344226633Sdim  bits<9> offset;
1345226633Sdim  let Inst{31-27} = 0b11111;
1346226633Sdim  let Inst{26-25} = 0b00;
1347226633Sdim  let Inst{24}    = signed;
1348226633Sdim  let Inst{23}    = 0;
1349226633Sdim  let Inst{22-21} = opcod;
1350226633Sdim  let Inst{20}    = load;
1351226633Sdim  let Inst{19-16} = Rn;
1352218893Sdim  let Inst{15-12} = Rt{3-0};
1353226633Sdim  let Inst{11}    = 1;
1354226633Sdim  // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1355226633Sdim  let Inst{10}    = pre; // The P bit.
1356226633Sdim  let Inst{9}     = offset{8}; // Sign bit
1357226633Sdim  let Inst{8}     = 1; // The W bit.
1358226633Sdim  let Inst{7-0}   = offset{7-0};
1359226633Sdim
1360226633Sdim  let DecoderMethod = "DecodeT2LdStPre";
1361204642Srdivacky}
1362204642Srdivacky
1363198090Srdivacky// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
1364198090Srdivackyclass Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
1365218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T];
1366198090Srdivacky}
1367195340Sed
1368198090Srdivacky// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1369198090Srdivackyclass T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1370218893Sdim  list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1371198090Srdivacky}
1372198090Srdivacky
1373223017Sdim// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
1374223017Sdimclass T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
1375223017Sdim  list<Predicate> Predicates = [IsThumb2, HasV6T2];
1376223017Sdim}
1377223017Sdim
1378195098Sed// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1379195098Sedclass T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1380195340Sed  list<Predicate> Predicates = [IsThumb2];
1381195098Sed}
1382195098Sed
1383193323Sed//===----------------------------------------------------------------------===//
1384193323Sed
1385193323Sed//===----------------------------------------------------------------------===//
1386193323Sed// ARM VFP Instruction templates.
1387193323Sed//
1388193323Sed
1389198090Srdivacky// Almost all VFP instructions are predicable.
1390224145Sdimclass VFPI<dag oops, dag iops, AddrMode am, int sz,
1391198090Srdivacky           IndexMode im, Format f, InstrItinClass itin,
1392198090Srdivacky           string opc, string asm, string cstr, list<dag> pattern>
1393198892Srdivacky  : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1394218893Sdim  bits<4> p;
1395218893Sdim  let Inst{31-28} = p;
1396198090Srdivacky  let OutOperandList = oops;
1397205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1398218893Sdim  let AsmString = !strconcat(opc, "${p}", asm);
1399198090Srdivacky  let Pattern = pattern;
1400218893Sdim  let PostEncoderMethod = "VFPThumb2PostEncoder";
1401226633Sdim  let DecoderNamespace = "VFP";
1402198090Srdivacky  list<Predicate> Predicates = [HasVFP2];
1403198090Srdivacky}
1404198090Srdivacky
1405198090Srdivacky// Special cases
1406224145Sdimclass VFPXI<dag oops, dag iops, AddrMode am, int sz,
1407198090Srdivacky            IndexMode im, Format f, InstrItinClass itin,
1408198090Srdivacky            string asm, string cstr, list<dag> pattern>
1409198892Srdivacky  : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1410218893Sdim  bits<4> p;
1411218893Sdim  let Inst{31-28} = p;
1412198090Srdivacky  let OutOperandList = oops;
1413198090Srdivacky  let InOperandList = iops;
1414208599Srdivacky  let AsmString = asm;
1415198090Srdivacky  let Pattern = pattern;
1416218893Sdim  let PostEncoderMethod = "VFPThumb2PostEncoder";
1417226633Sdim  let DecoderNamespace = "VFP";
1418198090Srdivacky  list<Predicate> Predicates = [HasVFP2];
1419198090Srdivacky}
1420198090Srdivacky
1421198090Srdivackyclass VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1422198090Srdivacky            string opc, string asm, list<dag> pattern>
1423224145Sdim  : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
1424218893Sdim         opc, asm, "", pattern> {
1425218893Sdim  let PostEncoderMethod = "VFPThumb2PostEncoder";
1426218893Sdim}
1427198090Srdivacky
1428193323Sed// ARM VFP addrmode5 loads and stores
1429193323Sedclass ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1430198090Srdivacky           InstrItinClass itin,
1431193323Sed           string opc, string asm, list<dag> pattern>
1432224145Sdim  : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1433206083Srdivacky         VFPLdStFrm, itin, opc, asm, "", pattern> {
1434218893Sdim  // Instruction operands.
1435218893Sdim  bits<5>  Dd;
1436218893Sdim  bits<13> addr;
1437218893Sdim
1438218893Sdim  // Encode instruction operands.
1439218893Sdim  let Inst{23}    = addr{8};      // U (add = (U == '1'))
1440218893Sdim  let Inst{22}    = Dd{4};
1441218893Sdim  let Inst{19-16} = addr{12-9};   // Rn
1442218893Sdim  let Inst{15-12} = Dd{3-0};
1443218893Sdim  let Inst{7-0}   = addr{7-0};    // imm8
1444218893Sdim
1445193323Sed  let Inst{27-24} = opcod1;
1446193323Sed  let Inst{21-20} = opcod2;
1447218893Sdim  let Inst{11-9}  = 0b101;
1448218893Sdim  let Inst{8}     = 1;          // Double precision
1449198892Srdivacky
1450218893Sdim  // Loads & stores operate on both NEON and VFP pipelines.
1451206274Srdivacky  let D = VFPNeonDomain;
1452193323Sed}
1453193323Sed
1454193323Sedclass ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1455198090Srdivacky           InstrItinClass itin,
1456193323Sed           string opc, string asm, list<dag> pattern>
1457224145Sdim  : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1458206083Srdivacky         VFPLdStFrm, itin, opc, asm, "", pattern> {
1459218893Sdim  // Instruction operands.
1460218893Sdim  bits<5>  Sd;
1461218893Sdim  bits<13> addr;
1462218893Sdim
1463218893Sdim  // Encode instruction operands.
1464218893Sdim  let Inst{23}    = addr{8};      // U (add = (U == '1'))
1465218893Sdim  let Inst{22}    = Sd{0};
1466218893Sdim  let Inst{19-16} = addr{12-9};   // Rn
1467218893Sdim  let Inst{15-12} = Sd{4-1};
1468218893Sdim  let Inst{7-0}   = addr{7-0};    // imm8
1469218893Sdim
1470193323Sed  let Inst{27-24} = opcod1;
1471193323Sed  let Inst{21-20} = opcod2;
1472218893Sdim  let Inst{11-9}  = 0b101;
1473218893Sdim  let Inst{8}     = 0;          // Single precision
1474218893Sdim
1475218893Sdim  // Loads & stores operate on both NEON and VFP pipelines.
1476218893Sdim  let D = VFPNeonDomain;
1477193323Sed}
1478193323Sed
1479218893Sdim// VFP Load / store multiple pseudo instructions.
1480218893Sdimclass PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
1481218893Sdim                     list<dag> pattern>
1482224145Sdim  : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
1483218893Sdim            cstr, itin> {
1484218893Sdim  let OutOperandList = oops;
1485218893Sdim  let InOperandList = !con(iops, (ins pred:$p));
1486218893Sdim  let Pattern = pattern;
1487218893Sdim  list<Predicate> Predicates = [HasVFP2];
1488218893Sdim}
1489218893Sdim
1490193323Sed// Load / store multiple
1491261991Sdim
1492261991Sdim// Unknown precision
1493261991Sdimclass AXXI4<dag oops, dag iops, IndexMode im,
1494261991Sdim            string asm, string cstr, list<dag> pattern>
1495261991Sdim  : VFPXI<oops, iops, AddrMode4, 4, im,
1496261991Sdim          VFPLdStFrm, NoItinerary, asm, cstr, pattern> {
1497261991Sdim  // Instruction operands.
1498261991Sdim  bits<4>  Rn;
1499261991Sdim  bits<13> regs;
1500261991Sdim
1501261991Sdim  // Encode instruction operands.
1502261991Sdim  let Inst{19-16} = Rn;
1503261991Sdim  let Inst{22}    = 0;
1504261991Sdim  let Inst{15-12} = regs{11-8};
1505261991Sdim  let Inst{7-1}   = regs{7-1};
1506261991Sdim
1507261991Sdim  let Inst{27-25} = 0b110;
1508261991Sdim  let Inst{11-8}  = 0b1011;
1509261991Sdim  let Inst{0}     = 1;
1510261991Sdim}
1511261991Sdim
1512261991Sdim// Double precision
1513212904Sdimclass AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1514205218Srdivacky            string asm, string cstr, list<dag> pattern>
1515224145Sdim  : VFPXI<oops, iops, AddrMode4, 4, im,
1516206083Srdivacky          VFPLdStMulFrm, itin, asm, cstr, pattern> {
1517218893Sdim  // Instruction operands.
1518218893Sdim  bits<4>  Rn;
1519218893Sdim  bits<13> regs;
1520218893Sdim
1521218893Sdim  // Encode instruction operands.
1522218893Sdim  let Inst{19-16} = Rn;
1523218893Sdim  let Inst{22}    = regs{12};
1524218893Sdim  let Inst{15-12} = regs{11-8};
1525261991Sdim  let Inst{7-1}   = regs{7-1};
1526218893Sdim
1527193323Sed  let Inst{27-25} = 0b110;
1528218893Sdim  let Inst{11-9}  = 0b101;
1529218893Sdim  let Inst{8}     = 1;          // Double precision
1530261991Sdim  let Inst{0}     = 0;
1531193323Sed}
1532193323Sed
1533261991Sdim// Single Precision
1534212904Sdimclass AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1535205218Srdivacky            string asm, string cstr, list<dag> pattern>
1536224145Sdim  : VFPXI<oops, iops, AddrMode4, 4, im,
1537206083Srdivacky          VFPLdStMulFrm, itin, asm, cstr, pattern> {
1538218893Sdim  // Instruction operands.
1539218893Sdim  bits<4> Rn;
1540218893Sdim  bits<13> regs;
1541218893Sdim
1542218893Sdim  // Encode instruction operands.
1543218893Sdim  let Inst{19-16} = Rn;
1544218893Sdim  let Inst{22}    = regs{8};
1545218893Sdim  let Inst{15-12} = regs{12-9};
1546218893Sdim  let Inst{7-0}   = regs{7-0};
1547218893Sdim
1548193323Sed  let Inst{27-25} = 0b110;
1549218893Sdim  let Inst{11-9}  = 0b101;
1550218893Sdim  let Inst{8}     = 0;          // Single precision
1551193323Sed}
1552193323Sed
1553193323Sed// Double precision, unary
1554203954Srdivackyclass ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1555203954Srdivacky           bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1556203954Srdivacky           string asm, list<dag> pattern>
1557198090Srdivacky  : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1558218893Sdim  // Instruction operands.
1559218893Sdim  bits<5> Dd;
1560218893Sdim  bits<5> Dm;
1561218893Sdim
1562218893Sdim  // Encode instruction operands.
1563218893Sdim  let Inst{3-0}   = Dm{3-0};
1564218893Sdim  let Inst{5}     = Dm{4};
1565218893Sdim  let Inst{15-12} = Dd{3-0};
1566218893Sdim  let Inst{22}    = Dd{4};
1567218893Sdim
1568203954Srdivacky  let Inst{27-23} = opcod1;
1569203954Srdivacky  let Inst{21-20} = opcod2;
1570203954Srdivacky  let Inst{19-16} = opcod3;
1571218893Sdim  let Inst{11-9}  = 0b101;
1572218893Sdim  let Inst{8}     = 1;          // Double precision
1573203954Srdivacky  let Inst{7-6}   = opcod4;
1574203954Srdivacky  let Inst{4}     = opcod5;
1575261991Sdim
1576261991Sdim  let Predicates = [HasVFP2, HasDPVFP];
1577193323Sed}
1578193323Sed
1579261991Sdim// Double precision, unary, not-predicated
1580261991Sdimclass ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1581261991Sdim           bit opcod5, dag oops, dag iops, InstrItinClass itin,
1582261991Sdim           string asm, list<dag> pattern>
1583261991Sdim  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> {
1584261991Sdim  // Instruction operands.
1585261991Sdim  bits<5> Dd;
1586261991Sdim  bits<5> Dm;
1587261991Sdim
1588261991Sdim  let Inst{31-28} = 0b1111;
1589261991Sdim
1590261991Sdim  // Encode instruction operands.
1591261991Sdim  let Inst{3-0}   = Dm{3-0};
1592261991Sdim  let Inst{5}     = Dm{4};
1593261991Sdim  let Inst{15-12} = Dd{3-0};
1594261991Sdim  let Inst{22}    = Dd{4};
1595261991Sdim
1596261991Sdim  let Inst{27-23} = opcod1;
1597261991Sdim  let Inst{21-20} = opcod2;
1598261991Sdim  let Inst{19-16} = opcod3;
1599261991Sdim  let Inst{11-9}  = 0b101;
1600261991Sdim  let Inst{8}     = 1;          // Double precision
1601261991Sdim  let Inst{7-6}   = opcod4;
1602261991Sdim  let Inst{4}     = opcod5;
1603261991Sdim}
1604261991Sdim
1605193323Sed// Double precision, binary
1606203954Srdivackyclass ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1607206083Srdivacky           dag iops, InstrItinClass itin, string opc, string asm,
1608206083Srdivacky           list<dag> pattern>
1609198090Srdivacky  : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1610218893Sdim  // Instruction operands.
1611218893Sdim  bits<5> Dd;
1612218893Sdim  bits<5> Dn;
1613218893Sdim  bits<5> Dm;
1614193323Sed
1615218893Sdim  // Encode instruction operands.
1616218893Sdim  let Inst{3-0}   = Dm{3-0};
1617218893Sdim  let Inst{5}     = Dm{4};
1618218893Sdim  let Inst{19-16} = Dn{3-0};
1619218893Sdim  let Inst{7}     = Dn{4};
1620218893Sdim  let Inst{15-12} = Dd{3-0};
1621218893Sdim  let Inst{22}    = Dd{4};
1622218893Sdim
1623206083Srdivacky  let Inst{27-23} = opcod1;
1624206083Srdivacky  let Inst{21-20} = opcod2;
1625218893Sdim  let Inst{11-9}  = 0b101;
1626218893Sdim  let Inst{8}     = 1;          // Double precision
1627212904Sdim  let Inst{6}     = op6;
1628212904Sdim  let Inst{4}     = op4;
1629261991Sdim
1630261991Sdim  let Predicates = [HasVFP2, HasDPVFP];
1631206083Srdivacky}
1632206083Srdivacky
1633261991Sdim// FP, binary, not predicated
1634261991Sdimclass ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1635261991Sdim           InstrItinClass itin, string asm, list<dag> pattern>
1636261991Sdim  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
1637261991Sdim          asm, "", pattern>
1638261991Sdim{
1639261991Sdim  // Instruction operands.
1640261991Sdim  bits<5> Dd;
1641261991Sdim  bits<5> Dn;
1642261991Sdim  bits<5> Dm;
1643261991Sdim
1644261991Sdim  let Inst{31-28} = 0b1111;
1645261991Sdim
1646261991Sdim  // Encode instruction operands.
1647261991Sdim  let Inst{3-0}   = Dm{3-0};
1648261991Sdim  let Inst{5}     = Dm{4};
1649261991Sdim  let Inst{19-16} = Dn{3-0};
1650261991Sdim  let Inst{7}     = Dn{4};
1651261991Sdim  let Inst{15-12} = Dd{3-0};
1652261991Sdim  let Inst{22}    = Dd{4};
1653261991Sdim
1654261991Sdim  let Inst{27-23} = opcod1;
1655261991Sdim  let Inst{21-20} = opcod2;
1656261991Sdim  let Inst{11-9}  = 0b101;
1657261991Sdim  let Inst{8}     = 1; // double precision
1658261991Sdim  let Inst{6}     = opcod3;
1659261991Sdim  let Inst{4}     = 0;
1660261991Sdim
1661261991Sdim  let Predicates = [HasVFP2, HasDPVFP];
1662261991Sdim}
1663261991Sdim
1664261991Sdim// Single precision, unary, predicated
1665203954Srdivackyclass ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1666203954Srdivacky           bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1667203954Srdivacky           string asm, list<dag> pattern>
1668198090Srdivacky  : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1669218893Sdim  // Instruction operands.
1670218893Sdim  bits<5> Sd;
1671218893Sdim  bits<5> Sm;
1672218893Sdim
1673218893Sdim  // Encode instruction operands.
1674218893Sdim  let Inst{3-0}   = Sm{4-1};
1675218893Sdim  let Inst{5}     = Sm{0};
1676218893Sdim  let Inst{15-12} = Sd{4-1};
1677218893Sdim  let Inst{22}    = Sd{0};
1678218893Sdim
1679203954Srdivacky  let Inst{27-23} = opcod1;
1680203954Srdivacky  let Inst{21-20} = opcod2;
1681203954Srdivacky  let Inst{19-16} = opcod3;
1682218893Sdim  let Inst{11-9}  = 0b101;
1683218893Sdim  let Inst{8}     = 0;          // Single precision
1684203954Srdivacky  let Inst{7-6}   = opcod4;
1685203954Srdivacky  let Inst{4}     = opcod5;
1686193323Sed}
1687193323Sed
1688261991Sdim// Single precision, unary, non-predicated
1689261991Sdimclass ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1690261991Sdim             bit opcod5, dag oops, dag iops, InstrItinClass itin,
1691261991Sdim             string asm, list<dag> pattern>
1692261991Sdim  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1693261991Sdim          VFPUnaryFrm, itin, asm, "", pattern> {
1694261991Sdim  // Instruction operands.
1695261991Sdim  bits<5> Sd;
1696261991Sdim  bits<5> Sm;
1697261991Sdim
1698261991Sdim  let Inst{31-28} = 0b1111;
1699261991Sdim
1700261991Sdim  // Encode instruction operands.
1701261991Sdim  let Inst{3-0}   = Sm{4-1};
1702261991Sdim  let Inst{5}     = Sm{0};
1703261991Sdim  let Inst{15-12} = Sd{4-1};
1704261991Sdim  let Inst{22}    = Sd{0};
1705261991Sdim
1706261991Sdim  let Inst{27-23} = opcod1;
1707261991Sdim  let Inst{21-20} = opcod2;
1708261991Sdim  let Inst{19-16} = opcod3;
1709261991Sdim  let Inst{11-9}  = 0b101;
1710261991Sdim  let Inst{8}     = 0;          // Single precision
1711261991Sdim  let Inst{7-6}   = opcod4;
1712261991Sdim  let Inst{4}     = opcod5;
1713261991Sdim}
1714261991Sdim
1715218893Sdim// Single precision unary, if no NEON. Same as ASuI except not available if
1716218893Sdim// NEON is enabled.
1717203954Srdivackyclass ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1718203954Srdivacky            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1719203954Srdivacky            string asm, list<dag> pattern>
1720203954Srdivacky  : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1721203954Srdivacky         pattern> {
1722198090Srdivacky  list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1723198090Srdivacky}
1724198090Srdivacky
1725193323Sed// Single precision, binary
1726203954Srdivackyclass ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1727203954Srdivacky           InstrItinClass itin, string opc, string asm, list<dag> pattern>
1728198090Srdivacky  : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1729218893Sdim  // Instruction operands.
1730218893Sdim  bits<5> Sd;
1731218893Sdim  bits<5> Sn;
1732218893Sdim  bits<5> Sm;
1733218893Sdim
1734218893Sdim  // Encode instruction operands.
1735218893Sdim  let Inst{3-0}   = Sm{4-1};
1736218893Sdim  let Inst{5}     = Sm{0};
1737218893Sdim  let Inst{19-16} = Sn{4-1};
1738218893Sdim  let Inst{7}     = Sn{0};
1739218893Sdim  let Inst{15-12} = Sd{4-1};
1740218893Sdim  let Inst{22}    = Sd{0};
1741218893Sdim
1742203954Srdivacky  let Inst{27-23} = opcod1;
1743203954Srdivacky  let Inst{21-20} = opcod2;
1744218893Sdim  let Inst{11-9}  = 0b101;
1745218893Sdim  let Inst{8}     = 0;          // Single precision
1746212904Sdim  let Inst{6}     = op6;
1747212904Sdim  let Inst{4}     = op4;
1748193323Sed}
1749193323Sed
1750261991Sdim// Single precision, binary, not predicated
1751261991Sdimclass ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1752261991Sdim           InstrItinClass itin, string asm, list<dag> pattern>
1753261991Sdim  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1754261991Sdim          VFPBinaryFrm, itin, asm, "", pattern>
1755261991Sdim{
1756261991Sdim  // Instruction operands.
1757261991Sdim  bits<5> Sd;
1758261991Sdim  bits<5> Sn;
1759261991Sdim  bits<5> Sm;
1760261991Sdim
1761261991Sdim  let Inst{31-28} = 0b1111;
1762261991Sdim
1763261991Sdim  // Encode instruction operands.
1764261991Sdim  let Inst{3-0}   = Sm{4-1};
1765261991Sdim  let Inst{5}     = Sm{0};
1766261991Sdim  let Inst{19-16} = Sn{4-1};
1767261991Sdim  let Inst{7}     = Sn{0};
1768261991Sdim  let Inst{15-12} = Sd{4-1};
1769261991Sdim  let Inst{22}    = Sd{0};
1770261991Sdim
1771261991Sdim  let Inst{27-23} = opcod1;
1772261991Sdim  let Inst{21-20} = opcod2;
1773261991Sdim  let Inst{11-9}  = 0b101;
1774261991Sdim  let Inst{8}     = 0; // Single precision
1775261991Sdim  let Inst{6}     = opcod3;
1776261991Sdim  let Inst{4}     = 0;
1777261991Sdim}
1778261991Sdim
1779218893Sdim// Single precision binary, if no NEON. Same as ASbI except not available if
1780218893Sdim// NEON is enabled.
1781203954Srdivackyclass ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1782206083Srdivacky            dag iops, InstrItinClass itin, string opc, string asm,
1783206083Srdivacky            list<dag> pattern>
1784203954Srdivacky  : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1785198090Srdivacky  list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1786218893Sdim
1787218893Sdim  // Instruction operands.
1788218893Sdim  bits<5> Sd;
1789218893Sdim  bits<5> Sn;
1790218893Sdim  bits<5> Sm;
1791218893Sdim
1792218893Sdim  // Encode instruction operands.
1793218893Sdim  let Inst{3-0}   = Sm{4-1};
1794218893Sdim  let Inst{5}     = Sm{0};
1795218893Sdim  let Inst{19-16} = Sn{4-1};
1796218893Sdim  let Inst{7}     = Sn{0};
1797218893Sdim  let Inst{15-12} = Sd{4-1};
1798218893Sdim  let Inst{22}    = Sd{0};
1799198090Srdivacky}
1800198090Srdivacky
1801193323Sed// VFP conversion instructions
1802203954Srdivackyclass AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1803203954Srdivacky               dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1804203954Srdivacky               list<dag> pattern>
1805198090Srdivacky  : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1806203954Srdivacky  let Inst{27-23} = opcod1;
1807203954Srdivacky  let Inst{21-20} = opcod2;
1808203954Srdivacky  let Inst{19-16} = opcod3;
1809203954Srdivacky  let Inst{11-8}  = opcod4;
1810193323Sed  let Inst{6}     = 1;
1811203954Srdivacky  let Inst{4}     = 0;
1812193323Sed}
1813193323Sed
1814203954Srdivacky// VFP conversion between floating-point and fixed-point
1815203954Srdivackyclass AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
1816206083Srdivacky                dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1817206083Srdivacky                list<dag> pattern>
1818203954Srdivacky  : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
1819234353Sdim  bits<5> fbits;
1820203954Srdivacky  // size (fixed-point number): sx == 0 ? 16 : 32
1821203954Srdivacky  let Inst{7} = op5; // sx
1822234353Sdim  let Inst{5} = fbits{0};
1823234353Sdim  let Inst{3-0} = fbits{4-1};
1824203954Srdivacky}
1825203954Srdivacky
1826198090Srdivacky// VFP conversion instructions, if no NEON
1827203954Srdivackyclass AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1828198090Srdivacky                dag oops, dag iops, InstrItinClass itin,
1829198090Srdivacky                string opc, string asm, list<dag> pattern>
1830203954Srdivacky  : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1831203954Srdivacky             pattern> {
1832198090Srdivacky  list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1833198090Srdivacky}
1834198090Srdivacky
1835193323Sedclass AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
1836198090Srdivacky               InstrItinClass itin,
1837198090Srdivacky               string opc, string asm, list<dag> pattern>
1838198090Srdivacky  : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
1839193323Sed  let Inst{27-20} = opcod1;
1840193323Sed  let Inst{11-8}  = opcod2;
1841193323Sed  let Inst{4}     = 1;
1842193323Sed}
1843193323Sed
1844198090Srdivackyclass AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1845198090Srdivacky               InstrItinClass itin, string opc, string asm, list<dag> pattern>
1846198090Srdivacky  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
1847193323Sed
1848206083Srdivackyclass AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1849198090Srdivacky               InstrItinClass itin, string opc, string asm, list<dag> pattern>
1850198090Srdivacky  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
1851193323Sed
1852198090Srdivackyclass AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1853198090Srdivacky               InstrItinClass itin, string opc, string asm, list<dag> pattern>
1854198090Srdivacky  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
1855193323Sed
1856198090Srdivackyclass AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1857198090Srdivacky               InstrItinClass itin, string opc, string asm, list<dag> pattern>
1858198090Srdivacky  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
1859193323Sed
1860193323Sed//===----------------------------------------------------------------------===//
1861193323Sed
1862194710Sed//===----------------------------------------------------------------------===//
1863194710Sed// ARM NEON Instruction templates.
1864194710Sed//
1865193323Sed
1866205407Srdivackyclass NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1867205407Srdivacky            InstrItinClass itin, string opc, string dt, string asm, string cstr,
1868205407Srdivacky            list<dag> pattern>
1869224145Sdim  : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1870194710Sed  let OutOperandList = oops;
1871205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1872218893Sdim  let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
1873194710Sed  let Pattern = pattern;
1874194710Sed  list<Predicate> Predicates = [HasNEON];
1875226633Sdim  let DecoderNamespace = "NEON";
1876193323Sed}
1877193323Sed
1878199989Srdivacky// Same as NeonI except it does not have a "data type" specifier.
1879206083Srdivackyclass NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1880206083Srdivacky             InstrItinClass itin, string opc, string asm, string cstr,
1881206083Srdivacky             list<dag> pattern>
1882224145Sdim  : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1883199989Srdivacky  let OutOperandList = oops;
1884205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
1885218893Sdim  let AsmString = !strconcat(opc, "${p}", "\t", asm);
1886199989Srdivacky  let Pattern = pattern;
1887199989Srdivacky  list<Predicate> Predicates = [HasNEON];
1888226633Sdim  let DecoderNamespace = "NEON";
1889193323Sed}
1890194710Sed
1891261991Sdim// Same as NeonI except it is not predicated
1892261991Sdimclass NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1893261991Sdim            InstrItinClass itin, string opc, string dt, string asm, string cstr,
1894261991Sdim            list<dag> pattern>
1895261991Sdim  : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1896261991Sdim  let OutOperandList = oops;
1897261991Sdim  let InOperandList = iops;
1898261991Sdim  let AsmString = !strconcat(opc, ".", dt, "\t", asm);
1899261991Sdim  let Pattern = pattern;
1900261991Sdim  list<Predicate> Predicates = [HasNEON];
1901261991Sdim  let DecoderNamespace = "NEON";
1902261991Sdim
1903261991Sdim  let Inst{31-28} = 0b1111;
1904261991Sdim}
1905261991Sdim
1906198090Srdivackyclass NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1907198090Srdivacky            dag oops, dag iops, InstrItinClass itin,
1908199989Srdivacky            string opc, string dt, string asm, string cstr, list<dag> pattern>
1909205407Srdivacky  : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
1910205407Srdivacky          cstr, pattern> {
1911198090Srdivacky  let Inst{31-24} = 0b11110100;
1912212904Sdim  let Inst{23}    = op23;
1913198396Srdivacky  let Inst{21-20} = op21_20;
1914212904Sdim  let Inst{11-8}  = op11_8;
1915212904Sdim  let Inst{7-4}   = op7_4;
1916218893Sdim
1917218893Sdim  let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
1918226633Sdim  let DecoderNamespace = "NEONLoadStore";
1919218893Sdim
1920218893Sdim  bits<5> Vd;
1921218893Sdim  bits<6> Rn;
1922218893Sdim  bits<4> Rm;
1923218893Sdim
1924218893Sdim  let Inst{22}    = Vd{4};
1925218893Sdim  let Inst{15-12} = Vd{3-0};
1926218893Sdim  let Inst{19-16} = Rn{3-0};
1927218893Sdim  let Inst{3-0}   = Rm{3-0};
1928198090Srdivacky}
1929198090Srdivacky
1930218893Sdimclass NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1931218893Sdim            dag oops, dag iops, InstrItinClass itin,
1932218893Sdim            string opc, string dt, string asm, string cstr, list<dag> pattern>
1933218893Sdim  : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
1934218893Sdim          dt, asm, cstr, pattern> {
1935218893Sdim  bits<3> lane;
1936218893Sdim}
1937218893Sdim
1938212904Sdimclass PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
1939224145Sdim  : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
1940212904Sdim            itin> {
1941212904Sdim  let OutOperandList = oops;
1942212904Sdim  let InOperandList = !con(iops, (ins pred:$p));
1943212904Sdim  list<Predicate> Predicates = [HasNEON];
1944212904Sdim}
1945212904Sdim
1946218893Sdimclass PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
1947218893Sdim                  list<dag> pattern>
1948224145Sdim  : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
1949218893Sdim            itin> {
1950218893Sdim  let OutOperandList = oops;
1951218893Sdim  let InOperandList = !con(iops, (ins pred:$p));
1952218893Sdim  let Pattern = pattern;
1953218893Sdim  list<Predicate> Predicates = [HasNEON];
1954218893Sdim}
1955218893Sdim
1956206083Srdivackyclass NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
1957199989Srdivacky             string opc, string dt, string asm, string cstr, list<dag> pattern>
1958206083Srdivacky  : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
1959206083Srdivacky          pattern> {
1960194710Sed  let Inst{31-25} = 0b1111001;
1961218893Sdim  let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
1962226633Sdim  let DecoderNamespace = "NEONData";
1963194710Sed}
1964194710Sed
1965206083Srdivackyclass NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
1966206083Srdivacky              string opc, string asm, string cstr, list<dag> pattern>
1967206083Srdivacky  : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
1968206083Srdivacky           cstr, pattern> {
1969199989Srdivacky  let Inst{31-25} = 0b1111001;
1970218893Sdim  let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
1971226633Sdim  let DecoderNamespace = "NEONData";
1972199989Srdivacky}
1973199989Srdivacky
1974194710Sed// NEON "one register and a modified immediate" format.
1975194710Sedclass N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1976194710Sed               bit op5, bit op4,
1977198090Srdivacky               dag oops, dag iops, InstrItinClass itin,
1978206083Srdivacky               string opc, string dt, string asm, string cstr,
1979206083Srdivacky               list<dag> pattern>
1980206083Srdivacky  : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
1981212904Sdim  let Inst{23}    = op23;
1982194710Sed  let Inst{21-19} = op21_19;
1983212904Sdim  let Inst{11-8}  = op11_8;
1984212904Sdim  let Inst{7}     = op7;
1985212904Sdim  let Inst{6}     = op6;
1986212904Sdim  let Inst{5}     = op5;
1987212904Sdim  let Inst{4}     = op4;
1988218893Sdim
1989218893Sdim  // Instruction operands.
1990218893Sdim  bits<5> Vd;
1991218893Sdim  bits<13> SIMM;
1992218893Sdim
1993218893Sdim  let Inst{15-12} = Vd{3-0};
1994218893Sdim  let Inst{22}    = Vd{4};
1995218893Sdim  let Inst{24}    = SIMM{7};
1996218893Sdim  let Inst{18-16} = SIMM{6-4};
1997218893Sdim  let Inst{3-0}   = SIMM{3-0};
1998226633Sdim  let DecoderMethod = "DecodeNEONModImmInstruction";
1999194710Sed}
2000194710Sed
2001194710Sed// NEON 2 vector register format.
2002194710Sedclass N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2003194710Sed          bits<5> op11_7, bit op6, bit op4,
2004198090Srdivacky          dag oops, dag iops, InstrItinClass itin,
2005199989Srdivacky          string opc, string dt, string asm, string cstr, list<dag> pattern>
2006206083Srdivacky  : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
2007194710Sed  let Inst{24-23} = op24_23;
2008194710Sed  let Inst{21-20} = op21_20;
2009194710Sed  let Inst{19-18} = op19_18;
2010194710Sed  let Inst{17-16} = op17_16;
2011212904Sdim  let Inst{11-7}  = op11_7;
2012212904Sdim  let Inst{6}     = op6;
2013212904Sdim  let Inst{4}     = op4;
2014218893Sdim
2015218893Sdim  // Instruction operands.
2016218893Sdim  bits<5> Vd;
2017218893Sdim  bits<5> Vm;
2018218893Sdim
2019218893Sdim  let Inst{15-12} = Vd{3-0};
2020218893Sdim  let Inst{22}    = Vd{4};
2021218893Sdim  let Inst{3-0}   = Vm{3-0};
2022218893Sdim  let Inst{5}     = Vm{4};
2023194710Sed}
2024194710Sed
2025261991Sdim// Same as N2V but not predicated.
2026261991Sdimclass N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
2027261991Sdim            dag oops, dag iops, InstrItinClass itin, string OpcodeStr,
2028261991Sdim            string Dt, ValueType ResTy, ValueType OpTy, list<dag> pattern>
2029261991Sdim   : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin,
2030261991Sdim             OpcodeStr, Dt, "$Vd, $Vm", "", pattern> {
2031261991Sdim  bits<5> Vd;
2032261991Sdim  bits<5> Vm;
2033261991Sdim
2034261991Sdim  // Encode instruction operands
2035261991Sdim  let Inst{22}    = Vd{4};
2036261991Sdim  let Inst{15-12} = Vd{3-0};
2037261991Sdim  let Inst{5}     = Vm{4};
2038261991Sdim  let Inst{3-0}   = Vm{3-0};
2039261991Sdim
2040261991Sdim  // Encode constant bits
2041261991Sdim  let Inst{27-23} = 0b00111;
2042261991Sdim  let Inst{21-20} = 0b11;
2043261991Sdim  let Inst{19-18} = op19_18;
2044261991Sdim  let Inst{17-16} = op17_16;
2045261991Sdim  let Inst{11} = 0;
2046261991Sdim  let Inst{10-8} = op10_8;
2047261991Sdim  let Inst{7} = op7;
2048261991Sdim  let Inst{6} = op6;
2049261991Sdim  let Inst{4} = 0;
2050261991Sdim
2051261991Sdim  let DecoderNamespace = "NEON";
2052261991Sdim}
2053261991Sdim
2054199989Srdivacky// Same as N2V except it doesn't have a datatype suffix.
2055199989Srdivackyclass N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2056206083Srdivacky           bits<5> op11_7, bit op6, bit op4,
2057206083Srdivacky           dag oops, dag iops, InstrItinClass itin,
2058206083Srdivacky           string opc, string asm, string cstr, list<dag> pattern>
2059206083Srdivacky  : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
2060198396Srdivacky  let Inst{24-23} = op24_23;
2061198396Srdivacky  let Inst{21-20} = op21_20;
2062199989Srdivacky  let Inst{19-18} = op19_18;
2063199989Srdivacky  let Inst{17-16} = op17_16;
2064212904Sdim  let Inst{11-7}  = op11_7;
2065212904Sdim  let Inst{6}     = op6;
2066212904Sdim  let Inst{4}     = op4;
2067218893Sdim
2068218893Sdim  // Instruction operands.
2069218893Sdim  bits<5> Vd;
2070218893Sdim  bits<5> Vm;
2071218893Sdim
2072218893Sdim  let Inst{15-12} = Vd{3-0};
2073218893Sdim  let Inst{22}    = Vd{4};
2074218893Sdim  let Inst{3-0}   = Vm{3-0};
2075218893Sdim  let Inst{5}     = Vm{4};
2076198396Srdivacky}
2077198396Srdivacky
2078194710Sed// NEON 2 vector register with immediate.
2079198396Srdivackyclass N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
2080206083Srdivacky             dag oops, dag iops, Format f, InstrItinClass itin,
2081199989Srdivacky             string opc, string dt, string asm, string cstr, list<dag> pattern>
2082206083Srdivacky  : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2083212904Sdim  let Inst{24}   = op24;
2084212904Sdim  let Inst{23}   = op23;
2085194710Sed  let Inst{11-8} = op11_8;
2086212904Sdim  let Inst{7}    = op7;
2087212904Sdim  let Inst{6}    = op6;
2088212904Sdim  let Inst{4}    = op4;
2089218893Sdim
2090218893Sdim  // Instruction operands.
2091218893Sdim  bits<5> Vd;
2092218893Sdim  bits<5> Vm;
2093218893Sdim  bits<6> SIMM;
2094218893Sdim
2095218893Sdim  let Inst{15-12} = Vd{3-0};
2096218893Sdim  let Inst{22}    = Vd{4};
2097218893Sdim  let Inst{3-0}   = Vm{3-0};
2098218893Sdim  let Inst{5}     = Vm{4};
2099218893Sdim  let Inst{21-16} = SIMM{5-0};
2100194710Sed}
2101194710Sed
2102194710Sed// NEON 3 vector register format.
2103221345Sdim
2104223017Sdimclass N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2105223017Sdim                bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2106223017Sdim                string opc, string dt, string asm, string cstr,
2107223017Sdim                list<dag> pattern>
2108206083Srdivacky  : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2109212904Sdim  let Inst{24}    = op24;
2110212904Sdim  let Inst{23}    = op23;
2111194710Sed  let Inst{21-20} = op21_20;
2112212904Sdim  let Inst{11-8}  = op11_8;
2113212904Sdim  let Inst{6}     = op6;
2114212904Sdim  let Inst{4}     = op4;
2115221345Sdim}
2116218893Sdim
2117221345Sdimclass N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
2118221345Sdim          dag oops, dag iops, Format f, InstrItinClass itin,
2119221345Sdim          string opc, string dt, string asm, string cstr, list<dag> pattern>
2120221345Sdim  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2121221345Sdim              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2122218893Sdim  // Instruction operands.
2123218893Sdim  bits<5> Vd;
2124218893Sdim  bits<5> Vn;
2125218893Sdim  bits<5> Vm;
2126218893Sdim
2127218893Sdim  let Inst{15-12} = Vd{3-0};
2128218893Sdim  let Inst{22}    = Vd{4};
2129218893Sdim  let Inst{19-16} = Vn{3-0};
2130218893Sdim  let Inst{7}     = Vn{4};
2131218893Sdim  let Inst{3-0}   = Vm{3-0};
2132218893Sdim  let Inst{5}     = Vm{4};
2133194710Sed}
2134194710Sed
2135261991Sdimclass N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2136261991Sdim                bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2137261991Sdim                string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
2138261991Sdim                SDPatternOperator IntOp, bit Commutable, list<dag> pattern>
2139261991Sdim  : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
2140261991Sdim            Dt, "$Vd, $Vn, $Vm", "", pattern> {
2141261991Sdim  bits<5> Vd;
2142261991Sdim  bits<5> Vn;
2143261991Sdim  bits<5> Vm;
2144261991Sdim
2145261991Sdim  // Encode instruction operands
2146261991Sdim  let Inst{22} = Vd{4};
2147261991Sdim  let Inst{15-12} = Vd{3-0};
2148261991Sdim  let Inst{19-16} = Vn{3-0};
2149261991Sdim  let Inst{7} = Vn{4};
2150261991Sdim  let Inst{5} = Vm{4};
2151261991Sdim  let Inst{3-0} = Vm{3-0};
2152261991Sdim
2153261991Sdim  // Encode constant bits
2154261991Sdim  let Inst{27-23} = op27_23;
2155261991Sdim  let Inst{21-20} = op21_20;
2156261991Sdim  let Inst{11-8}  = op11_8;
2157261991Sdim  let Inst{6}     = op6;
2158261991Sdim  let Inst{4}     = op4;
2159261991Sdim}
2160261991Sdim
2161223017Sdimclass N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2162223017Sdim                bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2163223017Sdim                string opc, string dt, string asm, string cstr,
2164223017Sdim                list<dag> pattern>
2165221345Sdim  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2166221345Sdim              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2167221345Sdim
2168221345Sdim  // Instruction operands.
2169221345Sdim  bits<5> Vd;
2170221345Sdim  bits<5> Vn;
2171221345Sdim  bits<5> Vm;
2172221345Sdim  bit lane;
2173221345Sdim
2174221345Sdim  let Inst{15-12} = Vd{3-0};
2175221345Sdim  let Inst{22}    = Vd{4};
2176221345Sdim  let Inst{19-16} = Vn{3-0};
2177221345Sdim  let Inst{7}     = Vn{4};
2178221345Sdim  let Inst{3-0}   = Vm{3-0};
2179221345Sdim  let Inst{5}     = lane;
2180221345Sdim}
2181221345Sdim
2182223017Sdimclass N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2183223017Sdim                bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2184223017Sdim                string opc, string dt, string asm, string cstr,
2185223017Sdim                list<dag> pattern>
2186221345Sdim  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2187221345Sdim              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2188221345Sdim
2189221345Sdim  // Instruction operands.
2190221345Sdim  bits<5> Vd;
2191221345Sdim  bits<5> Vn;
2192221345Sdim  bits<5> Vm;
2193221345Sdim  bits<2> lane;
2194221345Sdim
2195221345Sdim  let Inst{15-12} = Vd{3-0};
2196221345Sdim  let Inst{22}    = Vd{4};
2197221345Sdim  let Inst{19-16} = Vn{3-0};
2198221345Sdim  let Inst{7}     = Vn{4};
2199221345Sdim  let Inst{2-0}   = Vm{2-0};
2200221345Sdim  let Inst{5}     = lane{1};
2201221345Sdim  let Inst{3}     = lane{0};
2202221345Sdim}
2203221345Sdim
2204206083Srdivacky// Same as N3V except it doesn't have a data type suffix.
2205206083Srdivackyclass N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2206206083Srdivacky           bit op4,
2207206083Srdivacky           dag oops, dag iops, Format f, InstrItinClass itin,
2208206083Srdivacky           string opc, string asm, string cstr, list<dag> pattern>
2209206083Srdivacky  : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
2210212904Sdim  let Inst{24}    = op24;
2211212904Sdim  let Inst{23}    = op23;
2212198396Srdivacky  let Inst{21-20} = op21_20;
2213212904Sdim  let Inst{11-8}  = op11_8;
2214212904Sdim  let Inst{6}     = op6;
2215212904Sdim  let Inst{4}     = op4;
2216218893Sdim
2217218893Sdim  // Instruction operands.
2218218893Sdim  bits<5> Vd;
2219218893Sdim  bits<5> Vn;
2220218893Sdim  bits<5> Vm;
2221218893Sdim
2222218893Sdim  let Inst{15-12} = Vd{3-0};
2223218893Sdim  let Inst{22}    = Vd{4};
2224218893Sdim  let Inst{19-16} = Vn{3-0};
2225218893Sdim  let Inst{7}     = Vn{4};
2226218893Sdim  let Inst{3-0}   = Vm{3-0};
2227218893Sdim  let Inst{5}     = Vm{4};
2228198396Srdivacky}
2229198396Srdivacky
2230194710Sed// NEON VMOVs between scalar and core registers.
2231194710Sedclass NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2232198090Srdivacky               dag oops, dag iops, Format f, InstrItinClass itin,
2233199989Srdivacky               string opc, string dt, string asm, list<dag> pattern>
2234224145Sdim  : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
2235206083Srdivacky            "", itin> {
2236194710Sed  let Inst{27-20} = opcod1;
2237212904Sdim  let Inst{11-8}  = opcod2;
2238212904Sdim  let Inst{6-5}   = opcod3;
2239212904Sdim  let Inst{4}     = 1;
2240221345Sdim  // A8.6.303, A8.6.328, A8.6.329
2241221345Sdim  let Inst{3-0}   = 0b0000;
2242199989Srdivacky
2243199989Srdivacky  let OutOperandList = oops;
2244205407Srdivacky  let InOperandList = !con(iops, (ins pred:$p));
2245218893Sdim  let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2246199989Srdivacky  let Pattern = pattern;
2247194710Sed  list<Predicate> Predicates = [HasNEON];
2248218893Sdim
2249218893Sdim  let PostEncoderMethod = "NEONThumb2DupPostEncoder";
2250226633Sdim  let DecoderNamespace = "NEONDup";
2251218893Sdim
2252218893Sdim  bits<5> V;
2253218893Sdim  bits<4> R;
2254218893Sdim  bits<4> p;
2255218893Sdim  bits<4> lane;
2256218893Sdim
2257218893Sdim  let Inst{31-28} = p{3-0};
2258218893Sdim  let Inst{7}     = V{4};
2259218893Sdim  let Inst{19-16} = V{3-0};
2260218893Sdim  let Inst{15-12} = R{3-0};
2261194710Sed}
2262194710Sedclass NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2263198090Srdivacky                dag oops, dag iops, InstrItinClass itin,
2264199989Srdivacky                string opc, string dt, string asm, list<dag> pattern>
2265210299Sed  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
2266199989Srdivacky             opc, dt, asm, pattern>;
2267194710Sedclass NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2268198090Srdivacky                dag oops, dag iops, InstrItinClass itin,
2269199989Srdivacky                string opc, string dt, string asm, list<dag> pattern>
2270210299Sed  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
2271199989Srdivacky             opc, dt, asm, pattern>;
2272194710Sedclass NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2273198090Srdivacky            dag oops, dag iops, InstrItinClass itin,
2274199989Srdivacky            string opc, string dt, string asm, list<dag> pattern>
2275210299Sed  : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
2276199989Srdivacky             opc, dt, asm, pattern>;
2277198090Srdivacky
2278206083Srdivacky// Vector Duplicate Lane (from scalar to all elements)
2279206083Srdivackyclass NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
2280206083Srdivacky                InstrItinClass itin, string opc, string dt, string asm,
2281206083Srdivacky                list<dag> pattern>
2282206083Srdivacky  : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
2283206083Srdivacky  let Inst{24-23} = 0b11;
2284206083Srdivacky  let Inst{21-20} = 0b11;
2285206083Srdivacky  let Inst{19-16} = op19_16;
2286212904Sdim  let Inst{11-7}  = 0b11000;
2287212904Sdim  let Inst{6}     = op6;
2288212904Sdim  let Inst{4}     = 0;
2289218893Sdim
2290218893Sdim  bits<5> Vd;
2291218893Sdim  bits<5> Vm;
2292218893Sdim
2293218893Sdim  let Inst{22}     = Vd{4};
2294218893Sdim  let Inst{15-12} = Vd{3-0};
2295218893Sdim  let Inst{5}     = Vm{4};
2296218893Sdim  let Inst{3-0} = Vm{3-0};
2297206083Srdivacky}
2298206083Srdivacky
2299198090Srdivacky// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
2300198090Srdivacky// for single-precision FP.
2301198090Srdivackyclass NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
2302198090Srdivacky  list<Predicate> Predicates = [HasNEON,UseNEONForFP];
2303198090Srdivacky}
2304234353Sdim
2305234353Sdim// VFP/NEON Instruction aliases for type suffices.
2306234353Sdimclass VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result> :
2307234353Sdim  InstAlias<!strconcat(opc, dt, "\t", asm), Result>, Requires<[HasVFP2]>;
2308234353Sdim
2309234353Sdimmulticlass VFPDTAnyInstAlias<string opc, string asm, dag Result> {
2310234353Sdim  def : VFPDataTypeInstAlias<opc, ".8", asm, Result>;
2311234353Sdim  def : VFPDataTypeInstAlias<opc, ".16", asm, Result>;
2312234353Sdim  def : VFPDataTypeInstAlias<opc, ".32", asm, Result>;
2313234353Sdim  def : VFPDataTypeInstAlias<opc, ".64", asm, Result>;
2314234353Sdim}
2315234353Sdim
2316234353Sdimmulticlass NEONDTAnyInstAlias<string opc, string asm, dag Result> {
2317234353Sdim  let Predicates = [HasNEON] in {
2318234353Sdim  def : VFPDataTypeInstAlias<opc, ".8", asm, Result>;
2319234353Sdim  def : VFPDataTypeInstAlias<opc, ".16", asm, Result>;
2320234353Sdim  def : VFPDataTypeInstAlias<opc, ".32", asm, Result>;
2321234353Sdim  def : VFPDataTypeInstAlias<opc, ".64", asm, Result>;
2322234353Sdim}
2323234353Sdim}
2324234353Sdim
2325234353Sdim// The same alias classes using AsmPseudo instead, for the more complex
2326234353Sdim// stuff in NEON that InstAlias can't quite handle.
2327234353Sdim// Note that we can't use anonymous defm references here like we can
2328234353Sdim// above, as we care about the ultimate instruction enum names generated, unlike
2329234353Sdim// for instalias defs.
2330234353Sdimclass NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> :
2331234353Sdim  AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>;
2332234353Sdim
2333234353Sdim// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
2334234353Sdimdef : TokenAlias<".s8", ".i8">;
2335234353Sdimdef : TokenAlias<".u8", ".i8">;
2336234353Sdimdef : TokenAlias<".s16", ".i16">;
2337234353Sdimdef : TokenAlias<".u16", ".i16">;
2338234353Sdimdef : TokenAlias<".s32", ".i32">;
2339234353Sdimdef : TokenAlias<".u32", ".i32">;
2340234353Sdimdef : TokenAlias<".s64", ".i64">;
2341234353Sdimdef : TokenAlias<".u64", ".i64">;
2342234353Sdim
2343234353Sdimdef : TokenAlias<".i8", ".8">;
2344234353Sdimdef : TokenAlias<".i16", ".16">;
2345234353Sdimdef : TokenAlias<".i32", ".32">;
2346234353Sdimdef : TokenAlias<".i64", ".64">;
2347234353Sdim
2348234353Sdimdef : TokenAlias<".p8", ".8">;
2349234353Sdimdef : TokenAlias<".p16", ".16">;
2350234353Sdim
2351234353Sdimdef : TokenAlias<".f32", ".32">;
2352234353Sdimdef : TokenAlias<".f64", ".64">;
2353234353Sdimdef : TokenAlias<".f", ".f32">;
2354234353Sdimdef : TokenAlias<".d", ".f64">;
2355