1249259Sdim//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tablegen -*-=//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim// This file describes AArch64 instruction formats, down to the level of the
10249259Sdim// instruction's overall class.
11251662Sdim//===----------------------------------------------------------------------===//
12249259Sdim
13249259Sdim
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim// A64 Instruction Format Definitions.
16249259Sdim//===----------------------------------------------------------------------===//
17249259Sdim
18249259Sdim// A64 is currently the only instruction set supported by the AArch64
19249259Sdim// architecture.
20249259Sdimclass A64Inst<dag outs, dag ins, string asmstr, list<dag> patterns,
21249259Sdim              InstrItinClass itin>
22249259Sdim    : Instruction {
23249259Sdim  // All A64 instructions are 32-bit. This field will be filled in
24249259Sdim  // gradually going down the hierarchy.
25249259Sdim  field bits<32> Inst;
26249259Sdim
27249259Sdim  field bits<32> Unpredictable = 0;
28249259Sdim  // SoftFail is the generic name for this field, but we alias it so
29249259Sdim  // as to make it more obvious what it means in ARM-land.
30249259Sdim  field bits<32> SoftFail = Unpredictable;
31249259Sdim
32249259Sdim  // LLVM-level model of the AArch64/A64 distinction.
33249259Sdim  let Namespace = "AArch64";
34249259Sdim  let DecoderNamespace = "A64";
35249259Sdim  let Size = 4;
36249259Sdim
37249259Sdim  // Set the templated fields
38249259Sdim  let OutOperandList = outs;
39249259Sdim  let InOperandList = ins;
40249259Sdim  let AsmString = asmstr;
41249259Sdim  let Pattern = patterns;
42249259Sdim  let Itinerary = itin;
43249259Sdim}
44249259Sdim
45249259Sdimclass PseudoInst<dag outs, dag ins, list<dag> patterns> : Instruction {
46249259Sdim  let Namespace = "AArch64";
47249259Sdim
48249259Sdim  let OutOperandList = outs;
49249259Sdim  let InOperandList= ins;
50249259Sdim  let Pattern = patterns;
51249259Sdim  let isCodeGenOnly = 1;
52249259Sdim  let isPseudo = 1;
53249259Sdim}
54249259Sdim
55249259Sdim// Represents a pseudo-instruction that represents a single A64 instruction for
56249259Sdim// whatever reason, the eventual result will be a 32-bit real instruction.
57249259Sdimclass A64PseudoInst<dag outs, dag ins, list<dag> patterns>
58249259Sdim  : PseudoInst<outs, ins, patterns> {
59249259Sdim  let Size = 4;
60249259Sdim}
61249259Sdim
62249259Sdim// As above, this will be a single A64 instruction, but we can actually give the
63249259Sdim// expansion in TableGen.
64249259Sdimclass A64PseudoExpand<dag outs, dag ins, list<dag> patterns, dag Result>
65249259Sdim  : A64PseudoInst<outs, ins, patterns>,
66249259Sdim    PseudoInstExpansion<Result>;
67249259Sdim
68249259Sdim
69249259Sdim// First, some common cross-hierarchy register formats.
70249259Sdim
71249259Sdimclass A64InstRd<dag outs, dag ins, string asmstr,
72249259Sdim                list<dag> patterns, InstrItinClass itin>
73249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
74249259Sdim  bits<5> Rd;
75249259Sdim
76249259Sdim  let Inst{4-0} = Rd;
77249259Sdim}
78249259Sdim
79249259Sdimclass A64InstRt<dag outs, dag ins, string asmstr,
80249259Sdim                list<dag> patterns, InstrItinClass itin>
81249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
82249259Sdim  bits<5> Rt;
83249259Sdim
84249259Sdim  let Inst{4-0} = Rt;
85249259Sdim}
86249259Sdim
87249259Sdim
88249259Sdimclass A64InstRdn<dag outs, dag ins, string asmstr,
89249259Sdim                 list<dag> patterns, InstrItinClass itin>
90249259Sdim    : A64InstRd<outs, ins, asmstr, patterns, itin> {
91249259Sdim  // Inherit rdt
92249259Sdim  bits<5> Rn;
93249259Sdim
94249259Sdim  let Inst{9-5} = Rn;
95249259Sdim}
96249259Sdim
97249259Sdimclass A64InstRtn<dag outs, dag ins, string asmstr,
98249259Sdim                list<dag> patterns, InstrItinClass itin>
99249259Sdim    : A64InstRt<outs, ins, asmstr, patterns, itin> {
100249259Sdim  // Inherit rdt
101249259Sdim  bits<5> Rn;
102249259Sdim
103249259Sdim  let Inst{9-5} = Rn;
104249259Sdim}
105249259Sdim
106249259Sdim// Instructions taking Rt,Rt2,Rn
107249259Sdimclass A64InstRtt2n<dag outs, dag ins, string asmstr,
108249259Sdim                   list<dag> patterns, InstrItinClass itin>
109249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
110249259Sdim  bits<5> Rt2;
111249259Sdim
112249259Sdim  let Inst{14-10} = Rt2;
113249259Sdim}
114249259Sdim
115249259Sdimclass A64InstRdnm<dag outs, dag ins, string asmstr,
116249259Sdim                  list<dag> patterns, InstrItinClass itin>
117249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
118249259Sdim  bits<5> Rm;
119249259Sdim
120249259Sdim  let Inst{20-16} = Rm;
121249259Sdim}
122249259Sdim
123263508Sdimclass A64InstRtnm<dag outs, dag ins, string asmstr,
124263508Sdim                  list<dag> patterns, InstrItinClass itin>
125263508Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
126263508Sdim  bits<5> Rm;
127263508Sdim
128263508Sdim  let Inst{20-16} = Rm;
129263508Sdim}
130263508Sdim
131249259Sdim//===----------------------------------------------------------------------===//
132249259Sdim//
133249259Sdim// Actual A64 Instruction Formats
134249259Sdim//
135249259Sdim
136249259Sdim// Format for Add-subtract (extended register) instructions.
137249259Sdimclass A64I_addsubext<bit sf, bit op, bit S, bits<2> opt, bits<3> option,
138249259Sdim                     dag outs, dag ins, string asmstr, list<dag> patterns,
139249259Sdim                     InstrItinClass itin>
140249259Sdim    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
141249259Sdim    bits<3> Imm3;
142249259Sdim
143249259Sdim    let Inst{31} = sf;
144249259Sdim    let Inst{30} = op;
145249259Sdim    let Inst{29} = S;
146249259Sdim    let Inst{28-24} = 0b01011;
147249259Sdim    let Inst{23-22} = opt;
148249259Sdim    let Inst{21} = 0b1;
149249259Sdim    // Rm inherited in 20-16
150249259Sdim    let Inst{15-13} = option;
151249259Sdim    let Inst{12-10} = Imm3;
152249259Sdim    // Rn inherited in 9-5
153249259Sdim    // Rd inherited in 4-0
154249259Sdim}
155249259Sdim
156249259Sdim// Format for Add-subtract (immediate) instructions.
157249259Sdimclass A64I_addsubimm<bit sf, bit op, bit S, bits<2> shift,
158249259Sdim                     dag outs, dag ins, string asmstr,
159249259Sdim                     list<dag> patterns, InstrItinClass itin>
160249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
161249259Sdim  bits<12> Imm12;
162249259Sdim
163249259Sdim  let Inst{31} = sf;
164249259Sdim  let Inst{30} = op;
165249259Sdim  let Inst{29} = S;
166249259Sdim  let Inst{28-24} = 0b10001;
167249259Sdim  let Inst{23-22} = shift;
168249259Sdim  let Inst{21-10} = Imm12;
169249259Sdim}
170249259Sdim
171249259Sdim// Format for Add-subtract (shifted register) instructions.
172249259Sdimclass A64I_addsubshift<bit sf, bit op, bit S, bits<2> shift,
173249259Sdim                       dag outs, dag ins, string asmstr, list<dag> patterns,
174249259Sdim                       InstrItinClass itin>
175249259Sdim    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
176249259Sdim    bits<6> Imm6;
177249259Sdim
178249259Sdim    let Inst{31} = sf;
179249259Sdim    let Inst{30} = op;
180249259Sdim    let Inst{29} = S;
181249259Sdim    let Inst{28-24} = 0b01011;
182249259Sdim    let Inst{23-22} = shift;
183249259Sdim    let Inst{21} = 0b0;
184249259Sdim    // Rm inherited in 20-16
185249259Sdim    let Inst{15-10} = Imm6;
186249259Sdim    // Rn inherited in 9-5
187249259Sdim    // Rd inherited in 4-0
188249259Sdim}
189249259Sdim
190249259Sdim// Format for Add-subtract (with carry) instructions.
191249259Sdimclass A64I_addsubcarry<bit sf, bit op, bit S, bits<6> opcode2,
192249259Sdim                       dag outs, dag ins, string asmstr, list<dag> patterns,
193249259Sdim                       InstrItinClass itin>
194249259Sdim    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
195249259Sdim    let Inst{31} = sf;
196249259Sdim    let Inst{30} = op;
197249259Sdim    let Inst{29} = S;
198249259Sdim    let Inst{28-21} = 0b11010000;
199249259Sdim    // Rm inherited in 20-16
200249259Sdim    let Inst{15-10} = opcode2;
201249259Sdim    // Rn inherited in 9-5
202249259Sdim    // Rd inherited in 4-0
203249259Sdim}
204249259Sdim
205249259Sdim
206249259Sdim// Format for Bitfield instructions
207249259Sdimclass A64I_bitfield<bit sf, bits<2> opc, bit n,
208249259Sdim                    dag outs, dag ins, string asmstr,
209249259Sdim                    list<dag> patterns, InstrItinClass itin>
210249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
211249259Sdim  bits<6> ImmR;
212249259Sdim  bits<6> ImmS;
213249259Sdim
214249259Sdim  let Inst{31} = sf;
215249259Sdim  let Inst{30-29} = opc;
216249259Sdim  let Inst{28-23} = 0b100110;
217249259Sdim  let Inst{22} = n;
218249259Sdim  let Inst{21-16} = ImmR;
219249259Sdim  let Inst{15-10} = ImmS;
220249259Sdim  // Inherit Rn in 9-5
221249259Sdim  // Inherit Rd in 4-0
222249259Sdim}
223249259Sdim
224249259Sdim// Format for compare and branch (immediate) instructions.
225249259Sdimclass A64I_cmpbr<bit sf, bit op,
226249259Sdim                  dag outs, dag ins, string asmstr,
227249259Sdim                  list<dag> patterns, InstrItinClass itin>
228249259Sdim  : A64InstRt<outs, ins, asmstr, patterns, itin> {
229249259Sdim  bits<19> Label;
230249259Sdim
231249259Sdim  let Inst{31} = sf;
232249259Sdim  let Inst{30-25} = 0b011010;
233249259Sdim  let Inst{24} = op;
234249259Sdim  let Inst{23-5} = Label;
235249259Sdim  // Inherit Rt in 4-0
236249259Sdim}
237249259Sdim
238249259Sdim// Format for conditional branch (immediate) instructions.
239249259Sdimclass A64I_condbr<bit o1, bit o0,
240249259Sdim                  dag outs, dag ins, string asmstr,
241249259Sdim                  list<dag> patterns, InstrItinClass itin>
242249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
243249259Sdim  bits<19> Label;
244249259Sdim  bits<4> Cond;
245249259Sdim
246249259Sdim  let Inst{31-25} = 0b0101010;
247249259Sdim  let Inst{24} = o1;
248249259Sdim  let Inst{23-5} = Label;
249249259Sdim  let Inst{4} = o0;
250249259Sdim  let Inst{3-0} = Cond;
251249259Sdim}
252249259Sdim
253249259Sdim// Format for conditional compare (immediate) instructions.
254249259Sdimclass A64I_condcmpimm<bit sf, bit op, bit o2, bit o3, bit s,
255249259Sdim                      dag outs, dag ins, string asmstr,
256249259Sdim                      list<dag> patterns, InstrItinClass itin>
257249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
258249259Sdim  bits<5> Rn;
259249259Sdim  bits<5> UImm5;
260249259Sdim  bits<4> NZCVImm;
261249259Sdim  bits<4> Cond;
262249259Sdim
263249259Sdim  let Inst{31} = sf;
264249259Sdim  let Inst{30} = op;
265249259Sdim  let Inst{29} = s;
266249259Sdim  let Inst{28-21} = 0b11010010;
267249259Sdim  let Inst{20-16} = UImm5;
268249259Sdim  let Inst{15-12} = Cond;
269249259Sdim  let Inst{11} = 0b1;
270249259Sdim  let Inst{10} = o2;
271249259Sdim  let Inst{9-5} = Rn;
272249259Sdim  let Inst{4} = o3;
273249259Sdim  let Inst{3-0} = NZCVImm;
274249259Sdim}
275249259Sdim
276249259Sdim// Format for conditional compare (register) instructions.
277249259Sdimclass A64I_condcmpreg<bit sf, bit op, bit o2, bit o3, bit s,
278249259Sdim                      dag outs, dag ins, string asmstr,
279249259Sdim                      list<dag> patterns, InstrItinClass itin>
280249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
281249259Sdim  bits<5> Rn;
282249259Sdim  bits<5> Rm;
283249259Sdim  bits<4> NZCVImm;
284249259Sdim  bits<4> Cond;
285249259Sdim
286249259Sdim
287249259Sdim  let Inst{31} = sf;
288249259Sdim  let Inst{30} = op;
289249259Sdim  let Inst{29} = s;
290249259Sdim  let Inst{28-21} = 0b11010010;
291249259Sdim  let Inst{20-16} = Rm;
292249259Sdim  let Inst{15-12} = Cond;
293249259Sdim  let Inst{11} = 0b0;
294249259Sdim  let Inst{10} = o2;
295249259Sdim  let Inst{9-5} = Rn;
296249259Sdim  let Inst{4} = o3;
297249259Sdim  let Inst{3-0} = NZCVImm;
298249259Sdim}
299249259Sdim
300249259Sdim// Format for conditional select instructions.
301249259Sdimclass A64I_condsel<bit sf, bit op, bit s, bits<2> op2,
302249259Sdim                   dag outs, dag ins, string asmstr,
303249259Sdim                   list<dag> patterns, InstrItinClass itin>
304249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
305249259Sdim  bits<4> Cond;
306249259Sdim
307249259Sdim  let Inst{31} = sf;
308249259Sdim  let Inst{30} = op;
309249259Sdim  let Inst{29} = s;
310249259Sdim  let Inst{28-21} = 0b11010100;
311249259Sdim  // Inherit Rm in 20-16
312249259Sdim  let Inst{15-12} = Cond;
313249259Sdim  let Inst{11-10} = op2;
314249259Sdim  // Inherit Rn in 9-5
315249259Sdim  // Inherit Rd in 4-0
316249259Sdim}
317249259Sdim
318249259Sdim// Format for data processing (1 source) instructions
319249259Sdimclass A64I_dp_1src<bit sf, bit S, bits<5> opcode2, bits<6> opcode,
320249259Sdim                string asmstr, dag outs, dag ins,
321249259Sdim                list<dag> patterns, InstrItinClass itin>
322249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
323249259Sdim  let Inst{31} = sf;
324249259Sdim  let Inst{30} = 0b1;
325249259Sdim  let Inst{29} = S;
326249259Sdim  let Inst{28-21} = 0b11010110;
327249259Sdim  let Inst{20-16} = opcode2;
328249259Sdim  let Inst{15-10} = opcode;
329249259Sdim}
330249259Sdim
331249259Sdim// Format for data processing (2 source) instructions
332249259Sdimclass A64I_dp_2src<bit sf, bits<6> opcode, bit S,
333249259Sdim                string asmstr, dag outs, dag ins,
334249259Sdim                list<dag> patterns, InstrItinClass itin>
335249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
336249259Sdim  let Inst{31} = sf;
337249259Sdim  let Inst{30} = 0b0;
338249259Sdim  let Inst{29} = S;
339249259Sdim  let Inst{28-21} = 0b11010110;
340249259Sdim  let Inst{15-10} = opcode;
341249259Sdim}
342249259Sdim
343249259Sdim// Format for data-processing (3 source) instructions
344249259Sdim
345249259Sdimclass A64I_dp3<bit sf, bits<6> opcode,
346249259Sdim               dag outs, dag ins, string asmstr,
347249259Sdim               list<dag> patterns, InstrItinClass itin>
348249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
349249259Sdim  bits<5> Ra;
350249259Sdim
351249259Sdim  let Inst{31} = sf;
352249259Sdim  let Inst{30-29} = opcode{5-4};
353249259Sdim  let Inst{28-24} = 0b11011;
354249259Sdim  let Inst{23-21} = opcode{3-1};
355249259Sdim  // Inherits Rm in 20-16
356249259Sdim  let Inst{15} = opcode{0};
357249259Sdim  let Inst{14-10} = Ra;
358249259Sdim  // Inherits Rn in 9-5
359249259Sdim  // Inherits Rd in 4-0
360249259Sdim}
361249259Sdim
362249259Sdim// Format for exception generation instructions
363249259Sdimclass A64I_exception<bits<3> opc, bits<3> op2, bits<2> ll,
364249259Sdim                     dag outs, dag ins, string asmstr,
365249259Sdim                     list<dag> patterns, InstrItinClass itin>
366249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
367249259Sdim  bits<16> UImm16;
368249259Sdim
369249259Sdim  let Inst{31-24} = 0b11010100;
370249259Sdim  let Inst{23-21} = opc;
371249259Sdim  let Inst{20-5} = UImm16;
372249259Sdim  let Inst{4-2} = op2;
373249259Sdim  let Inst{1-0} = ll;
374249259Sdim}
375249259Sdim
376249259Sdim// Format for extract (immediate) instructions
377249259Sdimclass A64I_extract<bit sf, bits<3> op, bit n,
378249259Sdim                   dag outs, dag ins, string asmstr,
379249259Sdim                   list<dag> patterns, InstrItinClass itin>
380249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
381249259Sdim  bits<6> LSB;
382249259Sdim
383249259Sdim  let Inst{31} = sf;
384249259Sdim  let Inst{30-29} = op{2-1};
385249259Sdim  let Inst{28-23} = 0b100111;
386249259Sdim  let Inst{22} = n;
387249259Sdim  let Inst{21} = op{0};
388249259Sdim  // Inherits Rm in bits 20-16
389249259Sdim  let Inst{15-10} = LSB;
390249259Sdim  // Inherits Rn in 9-5
391249259Sdim  // Inherits Rd in 4-0
392249259Sdim}
393249259Sdim
394263508Sdimlet Predicates = [HasFPARMv8] in {
395263508Sdim
396249259Sdim// Format for floating-point compare instructions.
397249259Sdimclass A64I_fpcmp<bit m, bit s, bits<2> type, bits<2> op, bits<5> opcode2,
398249259Sdim                dag outs, dag ins, string asmstr,
399249259Sdim                list<dag> patterns, InstrItinClass itin>
400249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
401249259Sdim  bits<5> Rn;
402249259Sdim  bits<5> Rm;
403249259Sdim
404249259Sdim  let Inst{31} = m;
405249259Sdim  let Inst{30} = 0b0;
406249259Sdim  let Inst{29} = s;
407249259Sdim  let Inst{28-24} = 0b11110;
408249259Sdim  let Inst{23-22} = type;
409249259Sdim  let Inst{21} = 0b1;
410249259Sdim  let Inst{20-16} = Rm;
411249259Sdim  let Inst{15-14} = op;
412249259Sdim  let Inst{13-10} = 0b1000;
413249259Sdim  let Inst{9-5} = Rn;
414249259Sdim  let Inst{4-0} = opcode2;
415249259Sdim}
416249259Sdim
417249259Sdim// Format for floating-point conditional compare instructions.
418249259Sdimclass A64I_fpccmp<bit m, bit s, bits<2> type, bit op,
419249259Sdim                 dag outs, dag ins, string asmstr,
420249259Sdim                 list<dag> patterns, InstrItinClass itin>
421249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
422249259Sdim  bits<5> Rn;
423249259Sdim  bits<5> Rm;
424249259Sdim  bits<4> NZCVImm;
425249259Sdim  bits<4> Cond;
426249259Sdim
427249259Sdim  let Inst{31} = m;
428249259Sdim  let Inst{30} = 0b0;
429249259Sdim  let Inst{29} = s;
430249259Sdim  let Inst{28-24} = 0b11110;
431249259Sdim  let Inst{23-22} = type;
432249259Sdim  let Inst{21} = 0b1;
433249259Sdim  let Inst{20-16} = Rm;
434249259Sdim  let Inst{15-12} = Cond;
435249259Sdim  let Inst{11-10} = 0b01;
436249259Sdim  let Inst{9-5} = Rn;
437249259Sdim  let Inst{4} = op;
438249259Sdim  let Inst{3-0} = NZCVImm;
439249259Sdim}
440249259Sdim
441249259Sdim// Format for floating-point conditional select instructions.
442249259Sdimclass A64I_fpcondsel<bit m, bit s, bits<2> type,
443249259Sdim                     dag outs, dag ins, string asmstr,
444249259Sdim                     list<dag> patterns, InstrItinClass itin>
445249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
446249259Sdim  bits<4> Cond;
447249259Sdim
448249259Sdim  let Inst{31} = m;
449249259Sdim  let Inst{30} = 0b0;
450249259Sdim  let Inst{29} = s;
451249259Sdim  let Inst{28-24} = 0b11110;
452249259Sdim  let Inst{23-22} = type;
453249259Sdim  let Inst{21} = 0b1;
454249259Sdim  // Inherit Rm in 20-16
455249259Sdim  let Inst{15-12} = Cond;
456249259Sdim  let Inst{11-10} = 0b11;
457249259Sdim  // Inherit Rn in 9-5
458249259Sdim  // Inherit Rd in 4-0
459249259Sdim}
460249259Sdim
461249259Sdim
462249259Sdim// Format for floating-point data-processing (1 source) instructions.
463249259Sdimclass A64I_fpdp1<bit m, bit s, bits<2> type, bits<6> opcode,
464249259Sdim                 dag outs, dag ins, string asmstr,
465249259Sdim                 list<dag> patterns, InstrItinClass itin>
466249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
467249259Sdim  let Inst{31} = m;
468249259Sdim  let Inst{30} = 0b0;
469249259Sdim  let Inst{29} = s;
470249259Sdim  let Inst{28-24} = 0b11110;
471249259Sdim  let Inst{23-22} = type;
472249259Sdim  let Inst{21} = 0b1;
473249259Sdim  let Inst{20-15} = opcode;
474249259Sdim  let Inst{14-10} = 0b10000;
475249259Sdim  // Inherit Rn in 9-5
476249259Sdim  // Inherit Rd in 4-0
477249259Sdim}
478249259Sdim
479249259Sdim// Format for floating-point data-processing (2 sources) instructions.
480249259Sdimclass A64I_fpdp2<bit m, bit s, bits<2> type, bits<4> opcode,
481249259Sdim                 dag outs, dag ins, string asmstr,
482249259Sdim                 list<dag> patterns, InstrItinClass itin>
483249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
484249259Sdim  let Inst{31} = m;
485249259Sdim  let Inst{30} = 0b0;
486249259Sdim  let Inst{29} = s;
487249259Sdim  let Inst{28-24} = 0b11110;
488249259Sdim  let Inst{23-22} = type;
489249259Sdim  let Inst{21} = 0b1;
490249259Sdim  // Inherit Rm in 20-16
491249259Sdim  let Inst{15-12} = opcode;
492249259Sdim  let Inst{11-10} = 0b10;
493249259Sdim  // Inherit Rn in 9-5
494249259Sdim  // Inherit Rd in 4-0
495249259Sdim}
496249259Sdim
497249259Sdim// Format for floating-point data-processing (3 sources) instructions.
498249259Sdimclass A64I_fpdp3<bit m, bit s, bits<2> type, bit o1, bit o0,
499249259Sdim                 dag outs, dag ins, string asmstr,
500249259Sdim                 list<dag> patterns, InstrItinClass itin>
501249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
502249259Sdim  bits<5> Ra;
503249259Sdim
504249259Sdim  let Inst{31} = m;
505249259Sdim  let Inst{30} = 0b0;
506249259Sdim  let Inst{29} = s;
507249259Sdim  let Inst{28-24} = 0b11111;
508249259Sdim  let Inst{23-22} = type;
509249259Sdim  let Inst{21} = o1;
510249259Sdim  // Inherit Rm in 20-16
511249259Sdim  let Inst{15} = o0;
512249259Sdim  let Inst{14-10} = Ra;
513249259Sdim  // Inherit Rn in 9-5
514249259Sdim  // Inherit Rd in 4-0
515249259Sdim}
516249259Sdim
517249259Sdim// Format for floating-point <-> fixed-point conversion instructions.
518249259Sdimclass A64I_fpfixed<bit sf, bit s, bits<2> type, bits<2> mode, bits<3> opcode,
519249259Sdim                 dag outs, dag ins, string asmstr,
520249259Sdim                 list<dag> patterns, InstrItinClass itin>
521249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
522249259Sdim  bits<6> Scale;
523249259Sdim
524249259Sdim  let Inst{31} = sf;
525249259Sdim  let Inst{30} = 0b0;
526249259Sdim  let Inst{29} = s;
527249259Sdim  let Inst{28-24} = 0b11110;
528249259Sdim  let Inst{23-22} = type;
529249259Sdim  let Inst{21} = 0b0;
530249259Sdim  let Inst{20-19} = mode;
531249259Sdim  let Inst{18-16} = opcode;
532249259Sdim  let Inst{15-10} = Scale;
533249259Sdim  // Inherit Rn in 9-5
534249259Sdim  // Inherit Rd in 4-0
535249259Sdim}
536249259Sdim
537249259Sdim// Format for floating-point <-> integer conversion instructions.
538249259Sdimclass A64I_fpint<bit sf, bit s, bits<2> type, bits<2> rmode, bits<3> opcode,
539249259Sdim                 dag outs, dag ins, string asmstr,
540249259Sdim                 list<dag> patterns, InstrItinClass itin>
541249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
542249259Sdim  let Inst{31} = sf;
543249259Sdim  let Inst{30} = 0b0;
544249259Sdim  let Inst{29} = s;
545249259Sdim  let Inst{28-24} = 0b11110;
546249259Sdim  let Inst{23-22} = type;
547249259Sdim  let Inst{21} = 0b1;
548249259Sdim  let Inst{20-19} = rmode;
549249259Sdim  let Inst{18-16} = opcode;
550249259Sdim  let Inst{15-10} = 0b000000;
551249259Sdim  // Inherit Rn in 9-5
552249259Sdim  // Inherit Rd in 4-0
553249259Sdim}
554249259Sdim
555249259Sdim
556249259Sdim// Format for floating-point immediate instructions.
557249259Sdimclass A64I_fpimm<bit m, bit s, bits<2> type, bits<5> imm5,
558249259Sdim                 dag outs, dag ins, string asmstr,
559249259Sdim                 list<dag> patterns, InstrItinClass itin>
560249259Sdim  : A64InstRd<outs, ins, asmstr, patterns, itin> {
561249259Sdim  bits<8> Imm8;
562249259Sdim
563249259Sdim  let Inst{31} = m;
564249259Sdim  let Inst{30} = 0b0;
565249259Sdim  let Inst{29} = s;
566249259Sdim  let Inst{28-24} = 0b11110;
567249259Sdim  let Inst{23-22} = type;
568249259Sdim  let Inst{21} = 0b1;
569249259Sdim  let Inst{20-13} = Imm8;
570249259Sdim  let Inst{12-10} = 0b100;
571249259Sdim  let Inst{9-5} = imm5;
572249259Sdim  // Inherit Rd in 4-0
573249259Sdim}
574249259Sdim
575263508Sdim}
576263508Sdim
577249259Sdim// Format for load-register (literal) instructions.
578249259Sdimclass A64I_LDRlit<bits<2> opc, bit v,
579249259Sdim                  dag outs, dag ins, string asmstr,
580249259Sdim                  list<dag> patterns, InstrItinClass itin>
581249259Sdim  : A64InstRt<outs, ins, asmstr, patterns, itin> {
582249259Sdim  bits<19> Imm19;
583249259Sdim
584249259Sdim  let Inst{31-30} = opc;
585249259Sdim  let Inst{29-27} = 0b011;
586249259Sdim  let Inst{26} = v;
587249259Sdim  let Inst{25-24} = 0b00;
588249259Sdim  let Inst{23-5} = Imm19;
589249259Sdim  // Inherit Rt in 4-0
590249259Sdim}
591249259Sdim
592249259Sdim// Format for load-store exclusive instructions.
593249259Sdimclass A64I_LDSTex_tn<bits<2> size, bit o2, bit L, bit o1, bit o0,
594249259Sdim                 dag outs, dag ins, string asmstr,
595249259Sdim                 list <dag> patterns, InstrItinClass itin>
596249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
597249259Sdim  let Inst{31-30} = size;
598249259Sdim  let Inst{29-24} = 0b001000;
599249259Sdim  let Inst{23} = o2;
600249259Sdim  let Inst{22} = L;
601249259Sdim  let Inst{21} = o1;
602249259Sdim  let Inst{15} = o0;
603249259Sdim}
604249259Sdim
605249259Sdimclass A64I_LDSTex_tt2n<bits<2> size, bit o2, bit L, bit o1, bit o0,
606249259Sdim                     dag outs, dag ins, string asmstr,
607249259Sdim                     list <dag> patterns, InstrItinClass itin>:
608249259Sdim      A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
609249259Sdim   bits<5> Rt2;
610249259Sdim   let Inst{14-10} = Rt2;
611249259Sdim}
612249259Sdim
613249259Sdimclass A64I_LDSTex_stn<bits<2> size, bit o2, bit L, bit o1, bit o0,
614249259Sdim                     dag outs, dag ins, string asmstr,
615249259Sdim                     list <dag> patterns, InstrItinClass itin>:
616249259Sdim      A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
617249259Sdim   bits<5> Rs;
618249259Sdim   let Inst{20-16} = Rs;
619249259Sdim}
620249259Sdim
621249259Sdimclass A64I_LDSTex_stt2n<bits<2> size, bit o2, bit L, bit o1, bit o0,
622249259Sdim                     dag outs, dag ins, string asmstr,
623249259Sdim                     list <dag> patterns, InstrItinClass itin>:
624249259Sdim      A64I_LDSTex_stn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
625249259Sdim   bits<5> Rt2;
626249259Sdim   let Inst{14-10} = Rt2;
627249259Sdim}
628249259Sdim
629249259Sdim// Format for load-store register (immediate post-indexed) instructions
630249259Sdimclass A64I_LSpostind<bits<2> size, bit v, bits<2> opc,
631249259Sdim                     dag outs, dag ins, string asmstr,
632249259Sdim                     list<dag> patterns, InstrItinClass itin>
633249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
634249259Sdim  bits<9> SImm9;
635249259Sdim
636249259Sdim  let Inst{31-30} = size;
637249259Sdim  let Inst{29-27} = 0b111;
638249259Sdim  let Inst{26} = v;
639249259Sdim  let Inst{25-24} = 0b00;
640249259Sdim  let Inst{23-22} = opc;
641249259Sdim  let Inst{21} = 0b0;
642249259Sdim  let Inst{20-12} = SImm9;
643249259Sdim  let Inst{11-10} = 0b01;
644249259Sdim  // Inherit Rn in 9-5
645249259Sdim  // Inherit Rt in 4-0
646249259Sdim}
647249259Sdim
648249259Sdim// Format for load-store register (immediate pre-indexed) instructions
649249259Sdimclass A64I_LSpreind<bits<2> size, bit v, bits<2> opc,
650249259Sdim                    dag outs, dag ins, string asmstr,
651249259Sdim                    list<dag> patterns, InstrItinClass itin>
652249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
653249259Sdim  bits<9> SImm9;
654249259Sdim
655249259Sdim
656249259Sdim  let Inst{31-30} = size;
657249259Sdim  let Inst{29-27} = 0b111;
658249259Sdim  let Inst{26} = v;
659249259Sdim  let Inst{25-24} = 0b00;
660249259Sdim  let Inst{23-22} = opc;
661249259Sdim  let Inst{21} = 0b0;
662249259Sdim  let Inst{20-12} = SImm9;
663249259Sdim  let Inst{11-10} = 0b11;
664249259Sdim  // Inherit Rn in 9-5
665249259Sdim  // Inherit Rt in 4-0
666249259Sdim}
667249259Sdim
668249259Sdim// Format for load-store register (unprivileged) instructions
669249259Sdimclass A64I_LSunpriv<bits<2> size, bit v, bits<2> opc,
670249259Sdim                    dag outs, dag ins, string asmstr,
671249259Sdim                    list<dag> patterns, InstrItinClass itin>
672249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
673249259Sdim  bits<9> SImm9;
674249259Sdim
675249259Sdim
676249259Sdim  let Inst{31-30} = size;
677249259Sdim  let Inst{29-27} = 0b111;
678249259Sdim  let Inst{26} = v;
679249259Sdim  let Inst{25-24} = 0b00;
680249259Sdim  let Inst{23-22} = opc;
681249259Sdim  let Inst{21} = 0b0;
682249259Sdim  let Inst{20-12} = SImm9;
683249259Sdim  let Inst{11-10} = 0b10;
684249259Sdim  // Inherit Rn in 9-5
685249259Sdim  // Inherit Rt in 4-0
686249259Sdim}
687249259Sdim
688249259Sdim// Format for load-store (unscaled immediate) instructions.
689249259Sdimclass A64I_LSunalimm<bits<2> size, bit v, bits<2> opc,
690249259Sdim                     dag outs, dag ins, string asmstr,
691249259Sdim                     list<dag> patterns, InstrItinClass itin>
692249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
693249259Sdim  bits<9> SImm9;
694249259Sdim
695249259Sdim  let Inst{31-30} = size;
696249259Sdim  let Inst{29-27} = 0b111;
697249259Sdim  let Inst{26} = v;
698249259Sdim  let Inst{25-24} = 0b00;
699249259Sdim  let Inst{23-22} = opc;
700249259Sdim  let Inst{21} = 0b0;
701249259Sdim  let Inst{20-12} = SImm9;
702249259Sdim  let Inst{11-10} = 0b00;
703249259Sdim  // Inherit Rn in 9-5
704249259Sdim  // Inherit Rt in 4-0
705249259Sdim}
706249259Sdim
707249259Sdim
708249259Sdim// Format for load-store (unsigned immediate) instructions.
709249259Sdimclass A64I_LSunsigimm<bits<2> size, bit v, bits<2> opc,
710249259Sdim                      dag outs, dag ins, string asmstr,
711249259Sdim                      list<dag> patterns, InstrItinClass itin>
712249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
713249259Sdim  bits<12> UImm12;
714249259Sdim
715249259Sdim  let Inst{31-30} = size;
716249259Sdim  let Inst{29-27} = 0b111;
717249259Sdim  let Inst{26} = v;
718249259Sdim  let Inst{25-24} = 0b01;
719249259Sdim  let Inst{23-22} = opc;
720249259Sdim  let Inst{21-10} = UImm12;
721249259Sdim}
722249259Sdim
723249259Sdim// Format for load-store register (register offset) instructions.
724249259Sdimclass A64I_LSregoff<bits<2> size, bit v, bits<2> opc, bit optionlo,
725249259Sdim                    dag outs, dag ins, string asmstr,
726249259Sdim                    list<dag> patterns, InstrItinClass itin>
727249259Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
728249259Sdim  bits<5> Rm;
729249259Sdim
730249259Sdim  // Complex operand selection needed for these instructions, so they
731249259Sdim  // need an "addr" field for encoding/decoding to be generated.
732249259Sdim  bits<3> Ext;
733249259Sdim  // OptionHi = Ext{2-1}
734249259Sdim  // S = Ext{0}
735249259Sdim
736249259Sdim  let Inst{31-30} = size;
737249259Sdim  let Inst{29-27} = 0b111;
738249259Sdim  let Inst{26} = v;
739249259Sdim  let Inst{25-24} = 0b00;
740249259Sdim  let Inst{23-22} = opc;
741249259Sdim  let Inst{21} = 0b1;
742249259Sdim  let Inst{20-16} = Rm;
743249259Sdim  let Inst{15-14} = Ext{2-1};
744249259Sdim  let Inst{13} = optionlo;
745249259Sdim  let Inst{12} = Ext{0};
746249259Sdim  let Inst{11-10} = 0b10;
747249259Sdim  // Inherits Rn in 9-5
748249259Sdim  // Inherits Rt in 4-0
749249259Sdim
750249259Sdim  let AddedComplexity = 50;
751249259Sdim}
752249259Sdim
753249259Sdim// Format for Load-store register pair (offset) instructions
754249259Sdimclass A64I_LSPoffset<bits<2> opc, bit v, bit l,
755249259Sdim                      dag outs, dag ins, string asmstr,
756249259Sdim                      list<dag> patterns, InstrItinClass itin>
757249259Sdim  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
758249259Sdim  bits<7> SImm7;
759249259Sdim
760249259Sdim  let Inst{31-30} = opc;
761249259Sdim  let Inst{29-27} = 0b101;
762249259Sdim  let Inst{26} = v;
763249259Sdim  let Inst{25-23} = 0b010;
764249259Sdim  let Inst{22} = l;
765249259Sdim  let Inst{21-15} = SImm7;
766249259Sdim  // Inherit Rt2 in 14-10
767249259Sdim  // Inherit Rn in 9-5
768249259Sdim  // Inherit Rt in 4-0
769249259Sdim}
770249259Sdim
771249259Sdim// Format for Load-store register pair (post-indexed) instructions
772249259Sdimclass A64I_LSPpostind<bits<2> opc, bit v, bit l,
773249259Sdim                      dag outs, dag ins, string asmstr,
774249259Sdim                      list<dag> patterns, InstrItinClass itin>
775249259Sdim  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
776249259Sdim  bits<7> SImm7;
777249259Sdim
778249259Sdim  let Inst{31-30} = opc;
779249259Sdim  let Inst{29-27} = 0b101;
780249259Sdim  let Inst{26} = v;
781249259Sdim  let Inst{25-23} = 0b001;
782249259Sdim  let Inst{22} = l;
783249259Sdim  let Inst{21-15} = SImm7;
784249259Sdim  // Inherit Rt2 in 14-10
785249259Sdim  // Inherit Rn in 9-5
786249259Sdim  // Inherit Rt in 4-0
787249259Sdim}
788249259Sdim
789249259Sdim// Format for Load-store register pair (pre-indexed) instructions
790249259Sdimclass A64I_LSPpreind<bits<2> opc, bit v, bit l,
791249259Sdim                      dag outs, dag ins, string asmstr,
792249259Sdim                      list<dag> patterns, InstrItinClass itin>
793249259Sdim  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
794249259Sdim  bits<7> SImm7;
795249259Sdim
796249259Sdim  let Inst{31-30} = opc;
797249259Sdim  let Inst{29-27} = 0b101;
798249259Sdim  let Inst{26} = v;
799249259Sdim  let Inst{25-23} = 0b011;
800249259Sdim  let Inst{22} = l;
801249259Sdim  let Inst{21-15} = SImm7;
802249259Sdim  // Inherit Rt2 in 14-10
803249259Sdim  // Inherit Rn in 9-5
804249259Sdim  // Inherit Rt in 4-0
805249259Sdim}
806249259Sdim
807249259Sdim// Format for Load-store non-temporal register pair (offset) instructions
808249259Sdimclass A64I_LSPnontemp<bits<2> opc, bit v, bit l,
809249259Sdim                      dag outs, dag ins, string asmstr,
810249259Sdim                      list<dag> patterns, InstrItinClass itin>
811249259Sdim  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
812249259Sdim  bits<7> SImm7;
813249259Sdim
814249259Sdim  let Inst{31-30} = opc;
815249259Sdim  let Inst{29-27} = 0b101;
816249259Sdim  let Inst{26} = v;
817249259Sdim  let Inst{25-23} = 0b000;
818249259Sdim  let Inst{22} = l;
819249259Sdim  let Inst{21-15} = SImm7;
820249259Sdim  // Inherit Rt2 in 14-10
821249259Sdim  // Inherit Rn in 9-5
822249259Sdim  // Inherit Rt in 4-0
823249259Sdim}
824249259Sdim
825249259Sdim// Format for Logical (immediate) instructions
826249259Sdimclass A64I_logicalimm<bit sf, bits<2> opc,
827249259Sdim                      dag outs, dag ins, string asmstr,
828249259Sdim                      list<dag> patterns, InstrItinClass itin>
829249259Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
830249259Sdim  bit N;
831249259Sdim  bits<6> ImmR;
832249259Sdim  bits<6> ImmS;
833249259Sdim
834249259Sdim  // N, ImmR and ImmS have no separate existence in any assembly syntax (or for
835249259Sdim  // selection), so we'll combine them into a single field here.
836249259Sdim  bits<13> Imm;
837249259Sdim  // N = Imm{12};
838249259Sdim  // ImmR = Imm{11-6};
839249259Sdim  // ImmS = Imm{5-0};
840249259Sdim
841249259Sdim  let Inst{31} = sf;
842249259Sdim  let Inst{30-29} = opc;
843249259Sdim  let Inst{28-23} = 0b100100;
844249259Sdim  let Inst{22} = Imm{12};
845249259Sdim  let Inst{21-16} = Imm{11-6};
846249259Sdim  let Inst{15-10} = Imm{5-0};
847249259Sdim  // Rn inherited in 9-5
848249259Sdim  // Rd inherited in 4-0
849249259Sdim}
850249259Sdim
851249259Sdim// Format for Logical (shifted register) instructions
852249259Sdimclass A64I_logicalshift<bit sf, bits<2> opc, bits<2> shift, bit N,
853249259Sdim                        dag outs, dag ins, string asmstr,
854249259Sdim                        list<dag> patterns, InstrItinClass itin>
855249259Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
856249259Sdim  bits<6> Imm6;
857249259Sdim
858249259Sdim  let Inst{31} = sf;
859249259Sdim  let Inst{30-29} = opc;
860249259Sdim  let Inst{28-24} = 0b01010;
861249259Sdim  let Inst{23-22} = shift;
862249259Sdim  let Inst{21} = N;
863249259Sdim  // Rm inherited
864249259Sdim  let Inst{15-10} = Imm6;
865249259Sdim  // Rn inherited
866249259Sdim  // Rd inherited
867249259Sdim}
868249259Sdim
869249259Sdim// Format for Move wide (immediate)
870249259Sdimclass A64I_movw<bit sf, bits<2> opc,
871249259Sdim                dag outs, dag ins, string asmstr,
872249259Sdim                list<dag> patterns, InstrItinClass itin>
873249259Sdim  : A64InstRd<outs, ins, asmstr, patterns, itin> {
874249259Sdim  bits<16> UImm16;
875249259Sdim  bits<2> Shift; // Called "hw" officially
876249259Sdim
877249259Sdim  let Inst{31} = sf;
878249259Sdim  let Inst{30-29} = opc;
879249259Sdim  let Inst{28-23} = 0b100101;
880249259Sdim  let Inst{22-21} = Shift;
881249259Sdim  let Inst{20-5} = UImm16;
882249259Sdim  // Inherits Rd in 4-0
883249259Sdim}
884249259Sdim
885249259Sdim// Format for PC-relative addressing instructions, ADR and ADRP.
886249259Sdimclass A64I_PCADR<bit op,
887249259Sdim                 dag outs, dag ins, string asmstr,
888249259Sdim                 list<dag> patterns, InstrItinClass itin>
889249259Sdim  : A64InstRd<outs, ins, asmstr, patterns, itin> {
890249259Sdim  bits<21> Label;
891249259Sdim
892249259Sdim  let Inst{31} = op;
893249259Sdim  let Inst{30-29} = Label{1-0};
894249259Sdim  let Inst{28-24} = 0b10000;
895249259Sdim  let Inst{23-5} = Label{20-2};
896249259Sdim}
897249259Sdim
898249259Sdim// Format for system instructions
899249259Sdimclass A64I_system<bit l,
900249259Sdim                  dag outs, dag ins, string asmstr,
901249259Sdim                  list<dag> patterns, InstrItinClass itin>
902249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
903249259Sdim  bits<2> Op0;
904249259Sdim  bits<3> Op1;
905249259Sdim  bits<4> CRn;
906249259Sdim  bits<4> CRm;
907249259Sdim  bits<3> Op2;
908249259Sdim  bits<5> Rt;
909249259Sdim
910249259Sdim  let Inst{31-22} = 0b1101010100;
911249259Sdim  let Inst{21} = l;
912249259Sdim  let Inst{20-19} = Op0;
913249259Sdim  let Inst{18-16} = Op1;
914249259Sdim  let Inst{15-12} = CRn;
915249259Sdim  let Inst{11-8} = CRm;
916249259Sdim  let Inst{7-5} = Op2;
917249259Sdim  let Inst{4-0} = Rt;
918249259Sdim
919249259Sdim  // These instructions can do horrible things.
920249259Sdim  let hasSideEffects = 1;
921249259Sdim}
922249259Sdim
923249259Sdim// Format for unconditional branch (immediate) instructions
924249259Sdimclass A64I_Bimm<bit op,
925249259Sdim                dag outs, dag ins, string asmstr,
926249259Sdim                list<dag> patterns, InstrItinClass itin>
927249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
928249259Sdim  // Doubly special in not even sharing register fields with other
929249259Sdim  // instructions, so we create our own Rn here.
930249259Sdim  bits<26> Label;
931249259Sdim
932249259Sdim  let Inst{31} = op;
933249259Sdim  let Inst{30-26} = 0b00101;
934249259Sdim  let Inst{25-0} = Label;
935249259Sdim}
936249259Sdim
937249259Sdim// Format for Test & branch (immediate) instructions
938249259Sdimclass A64I_TBimm<bit op,
939249259Sdim                dag outs, dag ins, string asmstr,
940249259Sdim                list<dag> patterns, InstrItinClass itin>
941249259Sdim  : A64InstRt<outs, ins, asmstr, patterns, itin> {
942249259Sdim  // Doubly special in not even sharing register fields with other
943249259Sdim  // instructions, so we create our own Rn here.
944249259Sdim  bits<6> Imm;
945249259Sdim  bits<14> Label;
946249259Sdim
947249259Sdim  let Inst{31} = Imm{5};
948249259Sdim  let Inst{30-25} = 0b011011;
949249259Sdim  let Inst{24} = op;
950249259Sdim  let Inst{23-19} = Imm{4-0};
951249259Sdim  let Inst{18-5} = Label;
952249259Sdim  // Inherit Rt in 4-0
953249259Sdim}
954249259Sdim
955249259Sdim// Format for Unconditional branch (register) instructions, including
956249259Sdim// RET.  Shares no fields with instructions further up the hierarchy
957249259Sdim// so top-level.
958249259Sdimclass A64I_Breg<bits<4> opc, bits<5> op2, bits<6> op3, bits<5> op4,
959249259Sdim                dag outs, dag ins, string asmstr,
960249259Sdim                list<dag> patterns, InstrItinClass itin>
961249259Sdim  : A64Inst<outs, ins, asmstr, patterns, itin> {
962249259Sdim  // Doubly special in not even sharing register fields with other
963249259Sdim  // instructions, so we create our own Rn here.
964249259Sdim  bits<5> Rn;
965249259Sdim
966249259Sdim  let Inst{31-25} = 0b1101011;
967249259Sdim  let Inst{24-21} = opc;
968249259Sdim  let Inst{20-16} = op2;
969249259Sdim  let Inst{15-10} = op3;
970249259Sdim  let Inst{9-5}   = Rn;
971249259Sdim  let Inst{4-0}   = op4;
972249259Sdim}
973249259Sdim
974263508Sdim
975263508Sdim//===----------------------------------------------------------------------===//
976263508Sdim//
977263508Sdim// Neon Instruction Format Definitions.
978263508Sdim//
979263508Sdim
980263508Sdimlet Predicates = [HasNEON] in {
981263508Sdim
982263508Sdimclass NeonInstAlias<string Asm, dag Result, bit Emit = 0b1>
983263508Sdim  : InstAlias<Asm, Result, Emit> {
984263508Sdim}
985263508Sdim
986263508Sdim// Format AdvSIMD bitwise extract
987263508Sdimclass NeonI_BitExtract<bit q, bits<2> op2,
988263508Sdim                       dag outs, dag ins, string asmstr,
989263508Sdim                       list<dag> patterns, InstrItinClass itin>
990263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
991263508Sdim  let Inst{31} = 0b0;
992263508Sdim  let Inst{30} = q;
993263508Sdim  let Inst{29-24} = 0b101110;
994263508Sdim  let Inst{23-22} = op2;
995263508Sdim  let Inst{21} = 0b0;
996263508Sdim  // Inherit Rm in 20-16
997263508Sdim  let Inst{15} = 0b0;
998263508Sdim  // imm4 in 14-11
999263508Sdim  let Inst{10} = 0b0;
1000263508Sdim  // Inherit Rn in 9-5
1001263508Sdim  // Inherit Rd in 4-0
1002263508Sdim}
1003263508Sdim
1004263508Sdim// Format AdvSIMD perm
1005263508Sdimclass NeonI_Perm<bit q, bits<2> size, bits<3> opcode,
1006263508Sdim                 dag outs, dag ins, string asmstr,
1007263508Sdim                 list<dag> patterns, InstrItinClass itin>
1008263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1009263508Sdim  let Inst{31} = 0b0;
1010263508Sdim  let Inst{30} = q;
1011263508Sdim  let Inst{29-24} = 0b001110;
1012263508Sdim  let Inst{23-22} = size;
1013263508Sdim  let Inst{21} = 0b0;
1014263508Sdim  // Inherit Rm in 20-16
1015263508Sdim  let Inst{15} = 0b0;
1016263508Sdim  let Inst{14-12} = opcode;
1017263508Sdim  let Inst{11-10} = 0b10;
1018263508Sdim  // Inherit Rn in 9-5
1019263508Sdim  // Inherit Rd in 4-0
1020263508Sdim}
1021263508Sdim
1022263508Sdim// Format AdvSIMD table lookup
1023263508Sdimclass NeonI_TBL<bit q, bits<2> op2, bits<2> len, bit op,
1024263508Sdim                dag outs, dag ins, string asmstr,
1025263508Sdim                list<dag> patterns, InstrItinClass itin>
1026263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1027263508Sdim  let Inst{31} = 0b0;
1028263508Sdim  let Inst{30} = q;
1029263508Sdim  let Inst{29-24} = 0b001110;
1030263508Sdim  let Inst{23-22} = op2;
1031263508Sdim  let Inst{21} = 0b0;
1032263508Sdim  // Inherit Rm in 20-16
1033263508Sdim  let Inst{15} = 0b0;
1034263508Sdim  let Inst{14-13} = len;
1035263508Sdim  let Inst{12} = op;
1036263508Sdim  let Inst{11-10} = 0b00;
1037263508Sdim  // Inherit Rn in 9-5
1038263508Sdim  // Inherit Rd in 4-0
1039263508Sdim}
1040263508Sdim
1041263508Sdim// Format AdvSIMD 3 vector registers with same vector type
1042263508Sdimclass NeonI_3VSame<bit q, bit u, bits<2> size, bits<5> opcode,
1043263508Sdim                   dag outs, dag ins, string asmstr,
1044263508Sdim                   list<dag> patterns, InstrItinClass itin>
1045263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1046263508Sdim  let Inst{31} = 0b0;
1047263508Sdim  let Inst{30} = q;
1048263508Sdim  let Inst{29} = u;
1049263508Sdim  let Inst{28-24} = 0b01110;
1050263508Sdim  let Inst{23-22} = size;
1051263508Sdim  let Inst{21} = 0b1;
1052263508Sdim  // Inherit Rm in 20-16
1053263508Sdim  let Inst{15-11} = opcode;
1054263508Sdim  let Inst{10} = 0b1;
1055263508Sdim  // Inherit Rn in 9-5
1056263508Sdim  // Inherit Rd in 4-0
1057263508Sdim}
1058263508Sdim
1059263508Sdim// Format AdvSIMD 3 vector registers with different vector type
1060263508Sdimclass NeonI_3VDiff<bit q, bit u, bits<2> size, bits<4> opcode,
1061263508Sdim                   dag outs, dag ins, string asmstr,
1062263508Sdim                   list<dag> patterns, InstrItinClass itin>
1063263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1064263508Sdim  let Inst{31} = 0b0;
1065263508Sdim  let Inst{30} = q;
1066263508Sdim  let Inst{29} = u;
1067263508Sdim  let Inst{28-24} = 0b01110;
1068263508Sdim  let Inst{23-22} = size;
1069263508Sdim  let Inst{21} = 0b1;
1070263508Sdim  // Inherit Rm in 20-16
1071263508Sdim  let Inst{15-12} = opcode;
1072263508Sdim  let Inst{11} = 0b0;
1073263508Sdim  let Inst{10} = 0b0;
1074263508Sdim  // Inherit Rn in 9-5
1075263508Sdim  // Inherit Rd in 4-0
1076263508Sdim}
1077263508Sdim
1078263508Sdim// Format AdvSIMD two registers and an element
1079263508Sdimclass NeonI_2VElem<bit q, bit u, bits<2> size, bits<4> opcode,
1080263508Sdim                   dag outs, dag ins, string asmstr,
1081263508Sdim                   list<dag> patterns, InstrItinClass itin>
1082263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1083263508Sdim  let Inst{31} = 0b0;
1084263508Sdim  let Inst{30} = q;
1085263508Sdim  let Inst{29} = u;
1086263508Sdim  let Inst{28-24} = 0b01111;
1087263508Sdim  let Inst{23-22} = size;
1088263508Sdim  // l in Inst{21}
1089263508Sdim  // m in Inst{20}
1090263508Sdim  // Inherit Rm in 19-16
1091263508Sdim  let Inst{15-12} = opcode;
1092263508Sdim  // h in Inst{11}
1093263508Sdim  let Inst{10} = 0b0;
1094263508Sdim  // Inherit Rn in 9-5
1095263508Sdim  // Inherit Rd in 4-0
1096263508Sdim}
1097263508Sdim
1098263508Sdim// Format AdvSIMD 1 vector register with modified immediate
1099263508Sdimclass NeonI_1VModImm<bit q, bit op,
1100263508Sdim                     dag outs, dag ins, string asmstr,
1101263508Sdim                     list<dag> patterns, InstrItinClass itin>
1102263508Sdim  : A64InstRd<outs,ins, asmstr, patterns, itin> {
1103263508Sdim  bits<8> Imm;
1104263508Sdim  bits<4> cmode;
1105263508Sdim  let Inst{31} = 0b0;
1106263508Sdim  let Inst{30} = q;
1107263508Sdim  let Inst{29} = op;
1108263508Sdim  let Inst{28-19} = 0b0111100000;
1109263508Sdim  let Inst{15-12} = cmode;
1110263508Sdim  let Inst{11} = 0b0; // o2
1111263508Sdim  let Inst{10} = 1;
1112263508Sdim  // Inherit Rd in 4-0
1113263508Sdim  let Inst{18-16} = Imm{7-5}; // imm a:b:c
1114263508Sdim  let Inst{9-5} = Imm{4-0};   // imm d:e:f:g:h
1115263508Sdim}
1116263508Sdim
1117263508Sdim// Format AdvSIMD 3 scalar registers with same type
1118263508Sdim
1119263508Sdimclass NeonI_Scalar3Same<bit u, bits<2> size, bits<5> opcode,
1120263508Sdim                          dag outs, dag ins, string asmstr,
1121263508Sdim                          list<dag> patterns, InstrItinClass itin>
1122263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1123263508Sdim  let Inst{31} = 0b0;
1124263508Sdim  let Inst{30} = 0b1;
1125263508Sdim  let Inst{29} = u;
1126263508Sdim  let Inst{28-24} = 0b11110;
1127263508Sdim  let Inst{23-22} = size;
1128263508Sdim  let Inst{21} = 0b1;
1129263508Sdim  // Inherit Rm in 20-16
1130263508Sdim  let Inst{15-11} = opcode;
1131263508Sdim  let Inst{10} = 0b1;
1132263508Sdim  // Inherit Rn in 9-5
1133263508Sdim  // Inherit Rd in 4-0
1134263508Sdim}
1135263508Sdim
1136263508Sdim
1137263508Sdim// Format AdvSIMD 2 vector registers miscellaneous
1138263508Sdimclass NeonI_2VMisc<bit q, bit u, bits<2> size, bits<5> opcode,
1139263508Sdim                   dag outs, dag ins, string asmstr,
1140263508Sdim                   list<dag> patterns, InstrItinClass itin>
1141263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1142263508Sdim  let Inst{31} = 0b0;
1143263508Sdim  let Inst{30} = q;
1144263508Sdim  let Inst{29} = u;
1145263508Sdim  let Inst{28-24} = 0b01110;
1146263508Sdim  let Inst{23-22} = size;
1147263508Sdim  let Inst{21-17} = 0b10000;
1148263508Sdim  let Inst{16-12} = opcode;
1149263508Sdim  let Inst{11-10} = 0b10;
1150263508Sdim
1151263508Sdim  // Inherit Rn in 9-5
1152263508Sdim  // Inherit Rd in 4-0
1153263508Sdim}
1154263508Sdim
1155263508Sdim// Format AdvSIMD 2 vector 1 immediate shift
1156263508Sdimclass NeonI_2VShiftImm<bit q, bit u, bits<5> opcode,
1157263508Sdim                       dag outs, dag ins, string asmstr,
1158263508Sdim                       list<dag> patterns, InstrItinClass itin>
1159263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1160263508Sdim  bits<7> Imm;
1161263508Sdim  let Inst{31} = 0b0;
1162263508Sdim  let Inst{30} = q;
1163263508Sdim  let Inst{29} = u;
1164263508Sdim  let Inst{28-23} = 0b011110;
1165263508Sdim  let Inst{22-16} = Imm;
1166263508Sdim  let Inst{15-11} = opcode;
1167263508Sdim  let Inst{10} = 0b1;
1168263508Sdim  
1169263508Sdim  // Inherit Rn in 9-5
1170263508Sdim  // Inherit Rd in 4-0
1171263508Sdim}
1172263508Sdim
1173263508Sdim// Format AdvSIMD duplicate and insert
1174263508Sdimclass NeonI_copy<bit q, bit op, bits<4> imm4,
1175263508Sdim                 dag outs, dag ins, string asmstr,
1176263508Sdim                 list<dag> patterns, InstrItinClass itin>
1177263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1178263508Sdim  bits<5> Imm5;
1179263508Sdim  let Inst{31} = 0b0;
1180263508Sdim  let Inst{30} = q;
1181263508Sdim  let Inst{29} = op;
1182263508Sdim  let Inst{28-21} = 0b01110000;
1183263508Sdim  let Inst{20-16} = Imm5;
1184263508Sdim  let Inst{15} = 0b0;
1185263508Sdim  let Inst{14-11} = imm4;
1186263508Sdim  let Inst{10} = 0b1;
1187263508Sdim  
1188263508Sdim  // Inherit Rn in 9-5
1189263508Sdim  // Inherit Rd in 4-0
1190263508Sdim}
1191263508Sdim// Format AdvSIMD insert from element to vector
1192263508Sdimclass NeonI_insert<bit q, bit op,
1193263508Sdim                  dag outs, dag ins, string asmstr,
1194263508Sdim                  list<dag> patterns, InstrItinClass itin>
1195263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1196263508Sdim  bits<5> Imm5;
1197263508Sdim  bits<4> Imm4;
1198263508Sdim  let Inst{31} = 0b0;
1199263508Sdim  let Inst{30} = q;
1200263508Sdim  let Inst{29} = op;
1201263508Sdim  let Inst{28-21} = 0b01110000;
1202263508Sdim  let Inst{20-16} = Imm5;
1203263508Sdim  let Inst{15} = 0b0;
1204263508Sdim  let Inst{14-11} = Imm4;
1205263508Sdim  let Inst{10} = 0b1;
1206263508Sdim  
1207263508Sdim  // Inherit Rn in 9-5
1208263508Sdim  // Inherit Rd in 4-0
1209263508Sdim}
1210263508Sdim
1211263508Sdim// Format AdvSIMD scalar pairwise
1212263508Sdimclass NeonI_ScalarPair<bit u, bits<2> size, bits<5> opcode,
1213263508Sdim                          dag outs, dag ins, string asmstr,
1214263508Sdim                          list<dag> patterns, InstrItinClass itin>
1215263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1216263508Sdim  let Inst{31} = 0b0;
1217263508Sdim  let Inst{30} = 0b1;
1218263508Sdim  let Inst{29} = u;
1219263508Sdim  let Inst{28-24} = 0b11110;
1220263508Sdim  let Inst{23-22} = size;
1221263508Sdim  let Inst{21-17} = 0b11000;
1222263508Sdim  let Inst{16-12} = opcode;
1223263508Sdim  let Inst{11-10} = 0b10;
1224263508Sdim
1225263508Sdim  // Inherit Rn in 9-5
1226263508Sdim  // Inherit Rd in 4-0
1227263508Sdim}
1228263508Sdim
1229263508Sdim// Format AdvSIMD 2 vector across lanes
1230263508Sdimclass NeonI_2VAcross<bit q, bit u, bits<2> size, bits<5> opcode,
1231263508Sdim                     dag outs, dag ins, string asmstr,
1232263508Sdim                     list<dag> patterns, InstrItinClass itin>
1233263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin>
1234263508Sdim{
1235263508Sdim  let Inst{31} = 0b0;
1236263508Sdim  let Inst{30} = q;
1237263508Sdim  let Inst{29} = u;
1238263508Sdim  let Inst{28-24} = 0b01110;
1239263508Sdim  let Inst{23-22} = size;
1240263508Sdim  let Inst{21-17} = 0b11000;
1241263508Sdim  let Inst{16-12} = opcode;
1242263508Sdim  let Inst{11-10} = 0b10;
1243263508Sdim
1244263508Sdim  // Inherit Rn in 9-5
1245263508Sdim  // Inherit Rd in 4-0
1246263508Sdim}
1247263508Sdim
1248263508Sdim// Format AdvSIMD scalar two registers miscellaneous
1249263508Sdimclass NeonI_Scalar2SameMisc<bit u, bits<2> size, bits<5> opcode, dag outs, dag ins,
1250263508Sdim                            string asmstr, list<dag> patterns, InstrItinClass itin>
1251263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1252263508Sdim  let Inst{31} = 0b0;
1253263508Sdim  let Inst{30} = 0b1;
1254263508Sdim  let Inst{29} = u;
1255263508Sdim  let Inst{28-24} = 0b11110;
1256263508Sdim  let Inst{23-22} = size;
1257263508Sdim  let Inst{21-17} = 0b10000;
1258263508Sdim  let Inst{16-12} = opcode;
1259263508Sdim  let Inst{11-10} = 0b10;
1260263508Sdim  // Inherit Rn in 9-5
1261263508Sdim  // Inherit Rd in 4-0
1262263508Sdim}
1263263508Sdim
1264263508Sdim// Format AdvSIMD vector load/store multiple N-element structure
1265263508Sdimclass NeonI_LdStMult<bit q, bit l, bits<4> opcode, bits<2> size,
1266263508Sdim                    dag outs, dag ins, string asmstr,
1267263508Sdim                    list<dag> patterns, InstrItinClass itin>
1268263508Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin>
1269263508Sdim{
1270263508Sdim  let Inst{31} = 0b0;
1271263508Sdim  let Inst{30} = q;
1272263508Sdim  let Inst{29-23} = 0b0011000;
1273263508Sdim  let Inst{22} = l;
1274263508Sdim  let Inst{21-16} = 0b000000;
1275263508Sdim  let Inst{15-12} = opcode;
1276263508Sdim  let Inst{11-10} = size;
1277263508Sdim  
1278263508Sdim  // Inherit Rn in 9-5
1279263508Sdim  // Inherit Rt in 4-0
1280263508Sdim}
1281263508Sdim
1282263508Sdim// Format AdvSIMD vector load/store multiple N-element structure (post-index)
1283263508Sdimclass NeonI_LdStMult_Post<bit q, bit l, bits<4> opcode, bits<2> size,
1284263508Sdim                         dag outs, dag ins, string asmstr,
1285263508Sdim                         list<dag> patterns, InstrItinClass itin>
1286263508Sdim  : A64InstRtnm<outs, ins, asmstr, patterns, itin>
1287263508Sdim{
1288263508Sdim  let Inst{31} = 0b0;
1289263508Sdim  let Inst{30} = q;
1290263508Sdim  let Inst{29-23} = 0b0011001;
1291263508Sdim  let Inst{22} = l;
1292263508Sdim  let Inst{21} = 0b0;
1293263508Sdim  // Inherit Rm in 20-16
1294263508Sdim  let Inst{15-12} = opcode;
1295263508Sdim  let Inst{11-10} = size;
1296263508Sdim  // Inherit Rn in 9-5
1297263508Sdim  // Inherit Rt in 4-0
1298263508Sdim}
1299263508Sdim
1300263508Sdim// Format AdvSIMD vector load Single N-element structure to all lanes
1301263508Sdimclass NeonI_LdOne_Dup<bit q, bit r, bits<3> opcode, bits<2> size, dag outs,
1302263508Sdim                      dag ins, string asmstr, list<dag> patterns,
1303263508Sdim                      InstrItinClass itin>
1304263508Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin>
1305263508Sdim{
1306263508Sdim  let Inst{31} = 0b0;
1307263508Sdim  let Inst{30} = q;
1308263508Sdim  let Inst{29-23} = 0b0011010;
1309263508Sdim  let Inst{22} = 0b1;
1310263508Sdim  let Inst{21} = r;
1311263508Sdim  let Inst{20-16} = 0b00000;
1312263508Sdim  let Inst{15-13} = opcode;
1313263508Sdim  let Inst{12} = 0b0;
1314263508Sdim  let Inst{11-10} = size;
1315263508Sdim
1316263508Sdim  // Inherit Rn in 9-5
1317263508Sdim  // Inherit Rt in 4-0
1318263508Sdim}
1319263508Sdim
1320263508Sdim// Format AdvSIMD vector load/store Single N-element structure to/from one lane
1321263508Sdimclass NeonI_LdStOne_Lane<bit l, bit r, bits<2> op2_1, bit op0, dag outs,
1322263508Sdim                         dag ins, string asmstr,
1323263508Sdim                         list<dag> patterns, InstrItinClass itin>
1324263508Sdim  : A64InstRtn<outs, ins, asmstr, patterns, itin>
1325263508Sdim{
1326263508Sdim  bits<4> lane;
1327263508Sdim  let Inst{31} = 0b0;
1328263508Sdim  let Inst{29-23} = 0b0011010;
1329263508Sdim  let Inst{22} = l;
1330263508Sdim  let Inst{21} = r;
1331263508Sdim  let Inst{20-16} = 0b00000;
1332263508Sdim  let Inst{15-14} = op2_1;
1333263508Sdim  let Inst{13} = op0;
1334263508Sdim  
1335263508Sdim  // Inherit Rn in 9-5
1336263508Sdim  // Inherit Rt in 4-0
1337263508Sdim}
1338263508Sdim
1339263508Sdim// Format AdvSIMD post-index vector load Single N-element structure to all lanes
1340263508Sdimclass NeonI_LdOne_Dup_Post<bit q, bit r, bits<3> opcode, bits<2> size, dag outs,
1341263508Sdim                           dag ins, string asmstr, list<dag> patterns,
1342263508Sdim                           InstrItinClass itin>
1343263508Sdim  : A64InstRtnm<outs, ins, asmstr, patterns, itin>
1344263508Sdim{
1345263508Sdim  let Inst{31} = 0b0;
1346263508Sdim  let Inst{30} = q;
1347263508Sdim  let Inst{29-23} = 0b0011011;
1348263508Sdim  let Inst{22} = 0b1;
1349263508Sdim  let Inst{21} = r;
1350263508Sdim  // Inherit Rm in 20-16
1351263508Sdim  let Inst{15-13} = opcode;
1352263508Sdim  let Inst{12} = 0b0;
1353263508Sdim  let Inst{11-10} = size;
1354263508Sdim
1355263508Sdim  // Inherit Rn in 9-5
1356263508Sdim  // Inherit Rt in 4-0
1357263508Sdim}
1358263508Sdim
1359263508Sdim// Format AdvSIMD post-index vector load/store Single N-element structure
1360263508Sdim// to/from one lane
1361263508Sdimclass NeonI_LdStOne_Lane_Post<bit l, bit r, bits<2> op2_1, bit op0, dag outs,
1362263508Sdim                         dag ins, string asmstr,
1363263508Sdim                         list<dag> patterns, InstrItinClass itin>
1364263508Sdim  : A64InstRtnm<outs, ins, asmstr, patterns, itin>
1365263508Sdim{
1366263508Sdim  bits<4> lane;
1367263508Sdim  let Inst{31} = 0b0;
1368263508Sdim  let Inst{29-23} = 0b0011011;
1369263508Sdim  let Inst{22} = l;
1370263508Sdim  let Inst{21} = r;
1371263508Sdim  // Inherit Rm in 20-16
1372263508Sdim  let Inst{15-14} = op2_1;
1373263508Sdim  let Inst{13} = op0;
1374263508Sdim  
1375263508Sdim  // Inherit Rn in 9-5
1376263508Sdim  // Inherit Rt in 4-0
1377263508Sdim}
1378263508Sdim
1379263508Sdim// Format AdvSIMD 3 scalar registers with different type
1380263508Sdim
1381263508Sdimclass NeonI_Scalar3Diff<bit u, bits<2> size, bits<4> opcode,
1382263508Sdim                          dag outs, dag ins, string asmstr,
1383263508Sdim                          list<dag> patterns, InstrItinClass itin>
1384263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1385263508Sdim  let Inst{31-30} = 0b01;
1386263508Sdim  let Inst{29} = u;
1387263508Sdim  let Inst{28-24} = 0b11110;
1388263508Sdim  let Inst{23-22} = size;
1389263508Sdim  let Inst{21} = 0b1;
1390263508Sdim  // Inherit Rm in 20-16
1391263508Sdim  let Inst{15-12} = opcode;
1392263508Sdim  let Inst{11-10} = 0b00;
1393263508Sdim  // Inherit Rn in 9-5
1394263508Sdim  // Inherit Rd in 4-0
1395263508Sdim}
1396263508Sdim
1397263508Sdim// Format AdvSIMD scalar shift by immediate
1398263508Sdim
1399263508Sdimclass NeonI_ScalarShiftImm<bit u, bits<5> opcode,
1400263508Sdim                           dag outs, dag ins, string asmstr,
1401263508Sdim                           list<dag> patterns, InstrItinClass itin>
1402263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1403263508Sdim  bits<4> Imm4;
1404263508Sdim  bits<3> Imm3;
1405263508Sdim  let Inst{31-30} = 0b01;
1406263508Sdim  let Inst{29} = u;
1407263508Sdim  let Inst{28-23} = 0b111110;
1408263508Sdim  let Inst{22-19} = Imm4;
1409263508Sdim  let Inst{18-16} = Imm3;
1410263508Sdim  let Inst{15-11} = opcode;
1411263508Sdim  let Inst{10} = 0b1;
1412263508Sdim  // Inherit Rn in 9-5
1413263508Sdim  // Inherit Rd in 4-0
1414263508Sdim}
1415263508Sdim
1416263508Sdim// Format AdvSIMD crypto AES
1417263508Sdimclass NeonI_Crypto_AES<bits<2> size, bits<5> opcode,
1418263508Sdim                       dag outs, dag ins, string asmstr,
1419263508Sdim                       list<dag> patterns, InstrItinClass itin>
1420263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1421263508Sdim  let Inst{31-24} = 0b01001110;
1422263508Sdim  let Inst{23-22} = size;
1423263508Sdim  let Inst{21-17} = 0b10100;
1424263508Sdim  let Inst{16-12} = opcode;
1425263508Sdim  let Inst{11-10} = 0b10;
1426263508Sdim  // Inherit Rn in 9-5
1427263508Sdim  // Inherit Rd in 4-0
1428263508Sdim}
1429263508Sdim
1430263508Sdim// Format AdvSIMD crypto SHA
1431263508Sdimclass NeonI_Crypto_SHA<bits<2> size, bits<5> opcode,
1432263508Sdim                       dag outs, dag ins, string asmstr,
1433263508Sdim                       list<dag> patterns, InstrItinClass itin>
1434263508Sdim  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
1435263508Sdim  let Inst{31-24} = 0b01011110;
1436263508Sdim  let Inst{23-22} = size;
1437263508Sdim  let Inst{21-17} = 0b10100;
1438263508Sdim  let Inst{16-12} = opcode;
1439263508Sdim  let Inst{11-10} = 0b10;
1440263508Sdim  // Inherit Rn in 9-5
1441263508Sdim  // Inherit Rd in 4-0
1442263508Sdim}
1443263508Sdim
1444263508Sdim// Format AdvSIMD crypto 3V SHA
1445263508Sdimclass NeonI_Crypto_3VSHA<bits<2> size, bits<3> opcode,
1446263508Sdim                         dag outs, dag ins, string asmstr,
1447263508Sdim                         list<dag> patterns, InstrItinClass itin>
1448263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
1449263508Sdim  let Inst{31-24} = 0b01011110;
1450263508Sdim  let Inst{23-22} = size;
1451263508Sdim  let Inst{21} = 0b0;
1452263508Sdim  // Inherit Rm in 20-16
1453263508Sdim  let Inst{15} = 0b0;
1454263508Sdim  let Inst{14-12} = opcode;
1455263508Sdim  let Inst{11-10} = 0b00;
1456263508Sdim  // Inherit Rn in 9-5
1457263508Sdim  // Inherit Rd in 4-0
1458263508Sdim}
1459263508Sdim
1460263508Sdim// Format AdvSIMD scalar x indexed element
1461263508Sdimclass NeonI_ScalarXIndexedElem<bit u, bit szhi, bit szlo,
1462263508Sdim                               bits<4> opcode, dag outs, dag ins,
1463263508Sdim                               string asmstr, list<dag> patterns,
1464263508Sdim                               InstrItinClass itin>
1465263508Sdim  : A64InstRdnm<outs, ins, asmstr, patterns, itin>
1466263508Sdim{
1467263508Sdim  let Inst{31} = 0b0;
1468263508Sdim  let Inst{30} = 0b1;
1469263508Sdim  let Inst{29} = u;
1470263508Sdim  let Inst{28-24} = 0b11111;
1471263508Sdim  let Inst{23} = szhi;
1472263508Sdim  let Inst{22} = szlo;
1473263508Sdim  // l in Inst{21}
1474263508Sdim  // m in Instr{20}
1475263508Sdim  // Inherit Rm in 19-16
1476263508Sdim  let Inst{15-12} = opcode;
1477263508Sdim  // h in Inst{11}
1478263508Sdim  let Inst{10} = 0b0;
1479263508Sdim  // Inherit Rn in 9-5
1480263508Sdim  // Inherit Rd in 4-0
1481263508Sdim}
1482263508Sdim// Format AdvSIMD scalar copy - insert from element to scalar
1483263508Sdimclass NeonI_ScalarCopy<dag outs, dag ins, string asmstr,
1484263508Sdim                       list<dag> patterns, InstrItinClass itin>
1485263508Sdim  : NeonI_copy<0b1, 0b0, 0b0000, outs, ins, asmstr, patterns, itin> {
1486263508Sdim  let Inst{28} = 0b1;
1487263508Sdim}
1488263508Sdim}
1489263508Sdim
1490