AArch64InstrFormats.td revision 251662
1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// This file describes AArch64 instruction formats, down to the level of the
10// instruction's overall class.
11//===----------------------------------------------------------------------===//
12
13
14//===----------------------------------------------------------------------===//
15// A64 Instruction Format Definitions.
16//===----------------------------------------------------------------------===//
17
18// A64 is currently the only instruction set supported by the AArch64
19// architecture.
20class A64Inst<dag outs, dag ins, string asmstr, list<dag> patterns,
21              InstrItinClass itin>
22    : Instruction {
23  // All A64 instructions are 32-bit. This field will be filled in
24  // gradually going down the hierarchy.
25  field bits<32> Inst;
26
27  field bits<32> Unpredictable = 0;
28  // SoftFail is the generic name for this field, but we alias it so
29  // as to make it more obvious what it means in ARM-land.
30  field bits<32> SoftFail = Unpredictable;
31
32  // LLVM-level model of the AArch64/A64 distinction.
33  let Namespace = "AArch64";
34  let DecoderNamespace = "A64";
35  let Size = 4;
36
37  // Set the templated fields
38  let OutOperandList = outs;
39  let InOperandList = ins;
40  let AsmString = asmstr;
41  let Pattern = patterns;
42  let Itinerary = itin;
43}
44
45class PseudoInst<dag outs, dag ins, list<dag> patterns> : Instruction {
46  let Namespace = "AArch64";
47
48  let OutOperandList = outs;
49  let InOperandList= ins;
50  let Pattern = patterns;
51  let isCodeGenOnly = 1;
52  let isPseudo = 1;
53}
54
55// Represents a pseudo-instruction that represents a single A64 instruction for
56// whatever reason, the eventual result will be a 32-bit real instruction.
57class A64PseudoInst<dag outs, dag ins, list<dag> patterns>
58  : PseudoInst<outs, ins, patterns> {
59  let Size = 4;
60}
61
62// As above, this will be a single A64 instruction, but we can actually give the
63// expansion in TableGen.
64class A64PseudoExpand<dag outs, dag ins, list<dag> patterns, dag Result>
65  : A64PseudoInst<outs, ins, patterns>,
66    PseudoInstExpansion<Result>;
67
68
69// First, some common cross-hierarchy register formats.
70
71class A64InstRd<dag outs, dag ins, string asmstr,
72                list<dag> patterns, InstrItinClass itin>
73  : A64Inst<outs, ins, asmstr, patterns, itin> {
74  bits<5> Rd;
75
76  let Inst{4-0} = Rd;
77}
78
79class A64InstRt<dag outs, dag ins, string asmstr,
80                list<dag> patterns, InstrItinClass itin>
81  : A64Inst<outs, ins, asmstr, patterns, itin> {
82  bits<5> Rt;
83
84  let Inst{4-0} = Rt;
85}
86
87
88class A64InstRdn<dag outs, dag ins, string asmstr,
89                 list<dag> patterns, InstrItinClass itin>
90    : A64InstRd<outs, ins, asmstr, patterns, itin> {
91  // Inherit rdt
92  bits<5> Rn;
93
94  let Inst{9-5} = Rn;
95}
96
97class A64InstRtn<dag outs, dag ins, string asmstr,
98                list<dag> patterns, InstrItinClass itin>
99    : A64InstRt<outs, ins, asmstr, patterns, itin> {
100  // Inherit rdt
101  bits<5> Rn;
102
103  let Inst{9-5} = Rn;
104}
105
106// Instructions taking Rt,Rt2,Rn
107class A64InstRtt2n<dag outs, dag ins, string asmstr,
108                   list<dag> patterns, InstrItinClass itin>
109  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
110  bits<5> Rt2;
111
112  let Inst{14-10} = Rt2;
113}
114
115class A64InstRdnm<dag outs, dag ins, string asmstr,
116                  list<dag> patterns, InstrItinClass itin>
117  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
118  bits<5> Rm;
119
120  let Inst{20-16} = Rm;
121}
122
123//===----------------------------------------------------------------------===//
124//
125// Actual A64 Instruction Formats
126//
127
128// Format for Add-subtract (extended register) instructions.
129class A64I_addsubext<bit sf, bit op, bit S, bits<2> opt, bits<3> option,
130                     dag outs, dag ins, string asmstr, list<dag> patterns,
131                     InstrItinClass itin>
132    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
133    bits<3> Imm3;
134
135    let Inst{31} = sf;
136    let Inst{30} = op;
137    let Inst{29} = S;
138    let Inst{28-24} = 0b01011;
139    let Inst{23-22} = opt;
140    let Inst{21} = 0b1;
141    // Rm inherited in 20-16
142    let Inst{15-13} = option;
143    let Inst{12-10} = Imm3;
144    // Rn inherited in 9-5
145    // Rd inherited in 4-0
146}
147
148// Format for Add-subtract (immediate) instructions.
149class A64I_addsubimm<bit sf, bit op, bit S, bits<2> shift,
150                     dag outs, dag ins, string asmstr,
151                     list<dag> patterns, InstrItinClass itin>
152  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
153  bits<12> Imm12;
154
155  let Inst{31} = sf;
156  let Inst{30} = op;
157  let Inst{29} = S;
158  let Inst{28-24} = 0b10001;
159  let Inst{23-22} = shift;
160  let Inst{21-10} = Imm12;
161}
162
163// Format for Add-subtract (shifted register) instructions.
164class A64I_addsubshift<bit sf, bit op, bit S, bits<2> shift,
165                       dag outs, dag ins, string asmstr, list<dag> patterns,
166                       InstrItinClass itin>
167    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
168    bits<6> Imm6;
169
170    let Inst{31} = sf;
171    let Inst{30} = op;
172    let Inst{29} = S;
173    let Inst{28-24} = 0b01011;
174    let Inst{23-22} = shift;
175    let Inst{21} = 0b0;
176    // Rm inherited in 20-16
177    let Inst{15-10} = Imm6;
178    // Rn inherited in 9-5
179    // Rd inherited in 4-0
180}
181
182// Format for Add-subtract (with carry) instructions.
183class A64I_addsubcarry<bit sf, bit op, bit S, bits<6> opcode2,
184                       dag outs, dag ins, string asmstr, list<dag> patterns,
185                       InstrItinClass itin>
186    : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
187    let Inst{31} = sf;
188    let Inst{30} = op;
189    let Inst{29} = S;
190    let Inst{28-21} = 0b11010000;
191    // Rm inherited in 20-16
192    let Inst{15-10} = opcode2;
193    // Rn inherited in 9-5
194    // Rd inherited in 4-0
195}
196
197
198// Format for Bitfield instructions
199class A64I_bitfield<bit sf, bits<2> opc, bit n,
200                    dag outs, dag ins, string asmstr,
201                    list<dag> patterns, InstrItinClass itin>
202  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
203  bits<6> ImmR;
204  bits<6> ImmS;
205
206  let Inst{31} = sf;
207  let Inst{30-29} = opc;
208  let Inst{28-23} = 0b100110;
209  let Inst{22} = n;
210  let Inst{21-16} = ImmR;
211  let Inst{15-10} = ImmS;
212  // Inherit Rn in 9-5
213  // Inherit Rd in 4-0
214}
215
216// Format for compare and branch (immediate) instructions.
217class A64I_cmpbr<bit sf, bit op,
218                  dag outs, dag ins, string asmstr,
219                  list<dag> patterns, InstrItinClass itin>
220  : A64InstRt<outs, ins, asmstr, patterns, itin> {
221  bits<19> Label;
222
223  let Inst{31} = sf;
224  let Inst{30-25} = 0b011010;
225  let Inst{24} = op;
226  let Inst{23-5} = Label;
227  // Inherit Rt in 4-0
228}
229
230// Format for conditional branch (immediate) instructions.
231class A64I_condbr<bit o1, bit o0,
232                  dag outs, dag ins, string asmstr,
233                  list<dag> patterns, InstrItinClass itin>
234  : A64Inst<outs, ins, asmstr, patterns, itin> {
235  bits<19> Label;
236  bits<4> Cond;
237
238  let Inst{31-25} = 0b0101010;
239  let Inst{24} = o1;
240  let Inst{23-5} = Label;
241  let Inst{4} = o0;
242  let Inst{3-0} = Cond;
243}
244
245// Format for conditional compare (immediate) instructions.
246class A64I_condcmpimm<bit sf, bit op, bit o2, bit o3, bit s,
247                      dag outs, dag ins, string asmstr,
248                      list<dag> patterns, InstrItinClass itin>
249  : A64Inst<outs, ins, asmstr, patterns, itin> {
250  bits<5> Rn;
251  bits<5> UImm5;
252  bits<4> NZCVImm;
253  bits<4> Cond;
254
255  let Inst{31} = sf;
256  let Inst{30} = op;
257  let Inst{29} = s;
258  let Inst{28-21} = 0b11010010;
259  let Inst{20-16} = UImm5;
260  let Inst{15-12} = Cond;
261  let Inst{11} = 0b1;
262  let Inst{10} = o2;
263  let Inst{9-5} = Rn;
264  let Inst{4} = o3;
265  let Inst{3-0} = NZCVImm;
266}
267
268// Format for conditional compare (register) instructions.
269class A64I_condcmpreg<bit sf, bit op, bit o2, bit o3, bit s,
270                      dag outs, dag ins, string asmstr,
271                      list<dag> patterns, InstrItinClass itin>
272  : A64Inst<outs, ins, asmstr, patterns, itin> {
273  bits<5> Rn;
274  bits<5> Rm;
275  bits<4> NZCVImm;
276  bits<4> Cond;
277
278
279  let Inst{31} = sf;
280  let Inst{30} = op;
281  let Inst{29} = s;
282  let Inst{28-21} = 0b11010010;
283  let Inst{20-16} = Rm;
284  let Inst{15-12} = Cond;
285  let Inst{11} = 0b0;
286  let Inst{10} = o2;
287  let Inst{9-5} = Rn;
288  let Inst{4} = o3;
289  let Inst{3-0} = NZCVImm;
290}
291
292// Format for conditional select instructions.
293class A64I_condsel<bit sf, bit op, bit s, bits<2> op2,
294                   dag outs, dag ins, string asmstr,
295                   list<dag> patterns, InstrItinClass itin>
296  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
297  bits<4> Cond;
298
299  let Inst{31} = sf;
300  let Inst{30} = op;
301  let Inst{29} = s;
302  let Inst{28-21} = 0b11010100;
303  // Inherit Rm in 20-16
304  let Inst{15-12} = Cond;
305  let Inst{11-10} = op2;
306  // Inherit Rn in 9-5
307  // Inherit Rd in 4-0
308}
309
310// Format for data processing (1 source) instructions
311class A64I_dp_1src<bit sf, bit S, bits<5> opcode2, bits<6> opcode,
312                string asmstr, dag outs, dag ins,
313                list<dag> patterns, InstrItinClass itin>
314  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
315  let Inst{31} = sf;
316  let Inst{30} = 0b1;
317  let Inst{29} = S;
318  let Inst{28-21} = 0b11010110;
319  let Inst{20-16} = opcode2;
320  let Inst{15-10} = opcode;
321}
322
323// Format for data processing (2 source) instructions
324class A64I_dp_2src<bit sf, bits<6> opcode, bit S,
325                string asmstr, dag outs, dag ins,
326                list<dag> patterns, InstrItinClass itin>
327  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
328  let Inst{31} = sf;
329  let Inst{30} = 0b0;
330  let Inst{29} = S;
331  let Inst{28-21} = 0b11010110;
332  let Inst{15-10} = opcode;
333}
334
335// Format for data-processing (3 source) instructions
336
337class A64I_dp3<bit sf, bits<6> opcode,
338               dag outs, dag ins, string asmstr,
339               list<dag> patterns, InstrItinClass itin>
340  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
341  bits<5> Ra;
342
343  let Inst{31} = sf;
344  let Inst{30-29} = opcode{5-4};
345  let Inst{28-24} = 0b11011;
346  let Inst{23-21} = opcode{3-1};
347  // Inherits Rm in 20-16
348  let Inst{15} = opcode{0};
349  let Inst{14-10} = Ra;
350  // Inherits Rn in 9-5
351  // Inherits Rd in 4-0
352}
353
354// Format for exception generation instructions
355class A64I_exception<bits<3> opc, bits<3> op2, bits<2> ll,
356                     dag outs, dag ins, string asmstr,
357                     list<dag> patterns, InstrItinClass itin>
358  : A64Inst<outs, ins, asmstr, patterns, itin> {
359  bits<16> UImm16;
360
361  let Inst{31-24} = 0b11010100;
362  let Inst{23-21} = opc;
363  let Inst{20-5} = UImm16;
364  let Inst{4-2} = op2;
365  let Inst{1-0} = ll;
366}
367
368// Format for extract (immediate) instructions
369class A64I_extract<bit sf, bits<3> op, bit n,
370                   dag outs, dag ins, string asmstr,
371                   list<dag> patterns, InstrItinClass itin>
372  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
373  bits<6> LSB;
374
375  let Inst{31} = sf;
376  let Inst{30-29} = op{2-1};
377  let Inst{28-23} = 0b100111;
378  let Inst{22} = n;
379  let Inst{21} = op{0};
380  // Inherits Rm in bits 20-16
381  let Inst{15-10} = LSB;
382  // Inherits Rn in 9-5
383  // Inherits Rd in 4-0
384}
385
386// Format for floating-point compare instructions.
387class A64I_fpcmp<bit m, bit s, bits<2> type, bits<2> op, bits<5> opcode2,
388                dag outs, dag ins, string asmstr,
389                list<dag> patterns, InstrItinClass itin>
390  : A64Inst<outs, ins, asmstr, patterns, itin> {
391  bits<5> Rn;
392  bits<5> Rm;
393
394  let Inst{31} = m;
395  let Inst{30} = 0b0;
396  let Inst{29} = s;
397  let Inst{28-24} = 0b11110;
398  let Inst{23-22} = type;
399  let Inst{21} = 0b1;
400  let Inst{20-16} = Rm;
401  let Inst{15-14} = op;
402  let Inst{13-10} = 0b1000;
403  let Inst{9-5} = Rn;
404  let Inst{4-0} = opcode2;
405}
406
407// Format for floating-point conditional compare instructions.
408class A64I_fpccmp<bit m, bit s, bits<2> type, bit op,
409                 dag outs, dag ins, string asmstr,
410                 list<dag> patterns, InstrItinClass itin>
411  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
412  bits<5> Rn;
413  bits<5> Rm;
414  bits<4> NZCVImm;
415  bits<4> Cond;
416
417  let Inst{31} = m;
418  let Inst{30} = 0b0;
419  let Inst{29} = s;
420  let Inst{28-24} = 0b11110;
421  let Inst{23-22} = type;
422  let Inst{21} = 0b1;
423  let Inst{20-16} = Rm;
424  let Inst{15-12} = Cond;
425  let Inst{11-10} = 0b01;
426  let Inst{9-5} = Rn;
427  let Inst{4} = op;
428  let Inst{3-0} = NZCVImm;
429}
430
431// Format for floating-point conditional select instructions.
432class A64I_fpcondsel<bit m, bit s, bits<2> type,
433                     dag outs, dag ins, string asmstr,
434                     list<dag> patterns, InstrItinClass itin>
435  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
436  bits<4> Cond;
437
438  let Inst{31} = m;
439  let Inst{30} = 0b0;
440  let Inst{29} = s;
441  let Inst{28-24} = 0b11110;
442  let Inst{23-22} = type;
443  let Inst{21} = 0b1;
444  // Inherit Rm in 20-16
445  let Inst{15-12} = Cond;
446  let Inst{11-10} = 0b11;
447  // Inherit Rn in 9-5
448  // Inherit Rd in 4-0
449}
450
451
452// Format for floating-point data-processing (1 source) instructions.
453class A64I_fpdp1<bit m, bit s, bits<2> type, bits<6> opcode,
454                 dag outs, dag ins, string asmstr,
455                 list<dag> patterns, InstrItinClass itin>
456  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
457  let Inst{31} = m;
458  let Inst{30} = 0b0;
459  let Inst{29} = s;
460  let Inst{28-24} = 0b11110;
461  let Inst{23-22} = type;
462  let Inst{21} = 0b1;
463  let Inst{20-15} = opcode;
464  let Inst{14-10} = 0b10000;
465  // Inherit Rn in 9-5
466  // Inherit Rd in 4-0
467}
468
469// Format for floating-point data-processing (2 sources) instructions.
470class A64I_fpdp2<bit m, bit s, bits<2> type, bits<4> opcode,
471                 dag outs, dag ins, string asmstr,
472                 list<dag> patterns, InstrItinClass itin>
473  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
474  let Inst{31} = m;
475  let Inst{30} = 0b0;
476  let Inst{29} = s;
477  let Inst{28-24} = 0b11110;
478  let Inst{23-22} = type;
479  let Inst{21} = 0b1;
480  // Inherit Rm in 20-16
481  let Inst{15-12} = opcode;
482  let Inst{11-10} = 0b10;
483  // Inherit Rn in 9-5
484  // Inherit Rd in 4-0
485}
486
487// Format for floating-point data-processing (3 sources) instructions.
488class A64I_fpdp3<bit m, bit s, bits<2> type, bit o1, bit o0,
489                 dag outs, dag ins, string asmstr,
490                 list<dag> patterns, InstrItinClass itin>
491  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
492  bits<5> Ra;
493
494  let Inst{31} = m;
495  let Inst{30} = 0b0;
496  let Inst{29} = s;
497  let Inst{28-24} = 0b11111;
498  let Inst{23-22} = type;
499  let Inst{21} = o1;
500  // Inherit Rm in 20-16
501  let Inst{15} = o0;
502  let Inst{14-10} = Ra;
503  // Inherit Rn in 9-5
504  // Inherit Rd in 4-0
505}
506
507// Format for floating-point <-> fixed-point conversion instructions.
508class A64I_fpfixed<bit sf, bit s, bits<2> type, bits<2> mode, bits<3> opcode,
509                 dag outs, dag ins, string asmstr,
510                 list<dag> patterns, InstrItinClass itin>
511  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
512  bits<6> Scale;
513
514  let Inst{31} = sf;
515  let Inst{30} = 0b0;
516  let Inst{29} = s;
517  let Inst{28-24} = 0b11110;
518  let Inst{23-22} = type;
519  let Inst{21} = 0b0;
520  let Inst{20-19} = mode;
521  let Inst{18-16} = opcode;
522  let Inst{15-10} = Scale;
523  // Inherit Rn in 9-5
524  // Inherit Rd in 4-0
525}
526
527// Format for floating-point <-> integer conversion instructions.
528class A64I_fpint<bit sf, bit s, bits<2> type, bits<2> rmode, bits<3> opcode,
529                 dag outs, dag ins, string asmstr,
530                 list<dag> patterns, InstrItinClass itin>
531  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
532  let Inst{31} = sf;
533  let Inst{30} = 0b0;
534  let Inst{29} = s;
535  let Inst{28-24} = 0b11110;
536  let Inst{23-22} = type;
537  let Inst{21} = 0b1;
538  let Inst{20-19} = rmode;
539  let Inst{18-16} = opcode;
540  let Inst{15-10} = 0b000000;
541  // Inherit Rn in 9-5
542  // Inherit Rd in 4-0
543}
544
545
546// Format for floating-point immediate instructions.
547class A64I_fpimm<bit m, bit s, bits<2> type, bits<5> imm5,
548                 dag outs, dag ins, string asmstr,
549                 list<dag> patterns, InstrItinClass itin>
550  : A64InstRd<outs, ins, asmstr, patterns, itin> {
551  bits<8> Imm8;
552
553  let Inst{31} = m;
554  let Inst{30} = 0b0;
555  let Inst{29} = s;
556  let Inst{28-24} = 0b11110;
557  let Inst{23-22} = type;
558  let Inst{21} = 0b1;
559  let Inst{20-13} = Imm8;
560  let Inst{12-10} = 0b100;
561  let Inst{9-5} = imm5;
562  // Inherit Rd in 4-0
563}
564
565// Format for load-register (literal) instructions.
566class A64I_LDRlit<bits<2> opc, bit v,
567                  dag outs, dag ins, string asmstr,
568                  list<dag> patterns, InstrItinClass itin>
569  : A64InstRt<outs, ins, asmstr, patterns, itin> {
570  bits<19> Imm19;
571
572  let Inst{31-30} = opc;
573  let Inst{29-27} = 0b011;
574  let Inst{26} = v;
575  let Inst{25-24} = 0b00;
576  let Inst{23-5} = Imm19;
577  // Inherit Rt in 4-0
578}
579
580// Format for load-store exclusive instructions.
581class A64I_LDSTex_tn<bits<2> size, bit o2, bit L, bit o1, bit o0,
582                 dag outs, dag ins, string asmstr,
583                 list <dag> patterns, InstrItinClass itin>
584  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
585  let Inst{31-30} = size;
586  let Inst{29-24} = 0b001000;
587  let Inst{23} = o2;
588  let Inst{22} = L;
589  let Inst{21} = o1;
590  let Inst{15} = o0;
591}
592
593class A64I_LDSTex_tt2n<bits<2> size, bit o2, bit L, bit o1, bit o0,
594                     dag outs, dag ins, string asmstr,
595                     list <dag> patterns, InstrItinClass itin>:
596      A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
597   bits<5> Rt2;
598   let Inst{14-10} = Rt2;
599}
600
601class A64I_LDSTex_stn<bits<2> size, bit o2, bit L, bit o1, bit o0,
602                     dag outs, dag ins, string asmstr,
603                     list <dag> patterns, InstrItinClass itin>:
604      A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
605   bits<5> Rs;
606   let Inst{20-16} = Rs;
607}
608
609class A64I_LDSTex_stt2n<bits<2> size, bit o2, bit L, bit o1, bit o0,
610                     dag outs, dag ins, string asmstr,
611                     list <dag> patterns, InstrItinClass itin>:
612      A64I_LDSTex_stn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{
613   bits<5> Rt2;
614   let Inst{14-10} = Rt2;
615}
616
617// Format for load-store register (immediate post-indexed) instructions
618class A64I_LSpostind<bits<2> size, bit v, bits<2> opc,
619                     dag outs, dag ins, string asmstr,
620                     list<dag> patterns, InstrItinClass itin>
621  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
622  bits<9> SImm9;
623
624  let Inst{31-30} = size;
625  let Inst{29-27} = 0b111;
626  let Inst{26} = v;
627  let Inst{25-24} = 0b00;
628  let Inst{23-22} = opc;
629  let Inst{21} = 0b0;
630  let Inst{20-12} = SImm9;
631  let Inst{11-10} = 0b01;
632  // Inherit Rn in 9-5
633  // Inherit Rt in 4-0
634}
635
636// Format for load-store register (immediate pre-indexed) instructions
637class A64I_LSpreind<bits<2> size, bit v, bits<2> opc,
638                    dag outs, dag ins, string asmstr,
639                    list<dag> patterns, InstrItinClass itin>
640  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
641  bits<9> SImm9;
642
643
644  let Inst{31-30} = size;
645  let Inst{29-27} = 0b111;
646  let Inst{26} = v;
647  let Inst{25-24} = 0b00;
648  let Inst{23-22} = opc;
649  let Inst{21} = 0b0;
650  let Inst{20-12} = SImm9;
651  let Inst{11-10} = 0b11;
652  // Inherit Rn in 9-5
653  // Inherit Rt in 4-0
654}
655
656// Format for load-store register (unprivileged) instructions
657class A64I_LSunpriv<bits<2> size, bit v, bits<2> opc,
658                    dag outs, dag ins, string asmstr,
659                    list<dag> patterns, InstrItinClass itin>
660  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
661  bits<9> SImm9;
662
663
664  let Inst{31-30} = size;
665  let Inst{29-27} = 0b111;
666  let Inst{26} = v;
667  let Inst{25-24} = 0b00;
668  let Inst{23-22} = opc;
669  let Inst{21} = 0b0;
670  let Inst{20-12} = SImm9;
671  let Inst{11-10} = 0b10;
672  // Inherit Rn in 9-5
673  // Inherit Rt in 4-0
674}
675
676// Format for load-store (unscaled immediate) instructions.
677class A64I_LSunalimm<bits<2> size, bit v, bits<2> opc,
678                     dag outs, dag ins, string asmstr,
679                     list<dag> patterns, InstrItinClass itin>
680  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
681  bits<9> SImm9;
682
683  let Inst{31-30} = size;
684  let Inst{29-27} = 0b111;
685  let Inst{26} = v;
686  let Inst{25-24} = 0b00;
687  let Inst{23-22} = opc;
688  let Inst{21} = 0b0;
689  let Inst{20-12} = SImm9;
690  let Inst{11-10} = 0b00;
691  // Inherit Rn in 9-5
692  // Inherit Rt in 4-0
693}
694
695
696// Format for load-store (unsigned immediate) instructions.
697class A64I_LSunsigimm<bits<2> size, bit v, bits<2> opc,
698                      dag outs, dag ins, string asmstr,
699                      list<dag> patterns, InstrItinClass itin>
700  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
701  bits<12> UImm12;
702
703  let Inst{31-30} = size;
704  let Inst{29-27} = 0b111;
705  let Inst{26} = v;
706  let Inst{25-24} = 0b01;
707  let Inst{23-22} = opc;
708  let Inst{21-10} = UImm12;
709}
710
711// Format for load-store register (register offset) instructions.
712class A64I_LSregoff<bits<2> size, bit v, bits<2> opc, bit optionlo,
713                    dag outs, dag ins, string asmstr,
714                    list<dag> patterns, InstrItinClass itin>
715  : A64InstRtn<outs, ins, asmstr, patterns, itin> {
716  bits<5> Rm;
717
718  // Complex operand selection needed for these instructions, so they
719  // need an "addr" field for encoding/decoding to be generated.
720  bits<3> Ext;
721  // OptionHi = Ext{2-1}
722  // S = Ext{0}
723
724  let Inst{31-30} = size;
725  let Inst{29-27} = 0b111;
726  let Inst{26} = v;
727  let Inst{25-24} = 0b00;
728  let Inst{23-22} = opc;
729  let Inst{21} = 0b1;
730  let Inst{20-16} = Rm;
731  let Inst{15-14} = Ext{2-1};
732  let Inst{13} = optionlo;
733  let Inst{12} = Ext{0};
734  let Inst{11-10} = 0b10;
735  // Inherits Rn in 9-5
736  // Inherits Rt in 4-0
737
738  let AddedComplexity = 50;
739}
740
741// Format for Load-store register pair (offset) instructions
742class A64I_LSPoffset<bits<2> opc, bit v, bit l,
743                      dag outs, dag ins, string asmstr,
744                      list<dag> patterns, InstrItinClass itin>
745  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
746  bits<7> SImm7;
747
748  let Inst{31-30} = opc;
749  let Inst{29-27} = 0b101;
750  let Inst{26} = v;
751  let Inst{25-23} = 0b010;
752  let Inst{22} = l;
753  let Inst{21-15} = SImm7;
754  // Inherit Rt2 in 14-10
755  // Inherit Rn in 9-5
756  // Inherit Rt in 4-0
757}
758
759// Format for Load-store register pair (post-indexed) instructions
760class A64I_LSPpostind<bits<2> opc, bit v, bit l,
761                      dag outs, dag ins, string asmstr,
762                      list<dag> patterns, InstrItinClass itin>
763  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
764  bits<7> SImm7;
765
766  let Inst{31-30} = opc;
767  let Inst{29-27} = 0b101;
768  let Inst{26} = v;
769  let Inst{25-23} = 0b001;
770  let Inst{22} = l;
771  let Inst{21-15} = SImm7;
772  // Inherit Rt2 in 14-10
773  // Inherit Rn in 9-5
774  // Inherit Rt in 4-0
775}
776
777// Format for Load-store register pair (pre-indexed) instructions
778class A64I_LSPpreind<bits<2> opc, bit v, bit l,
779                      dag outs, dag ins, string asmstr,
780                      list<dag> patterns, InstrItinClass itin>
781  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
782  bits<7> SImm7;
783
784  let Inst{31-30} = opc;
785  let Inst{29-27} = 0b101;
786  let Inst{26} = v;
787  let Inst{25-23} = 0b011;
788  let Inst{22} = l;
789  let Inst{21-15} = SImm7;
790  // Inherit Rt2 in 14-10
791  // Inherit Rn in 9-5
792  // Inherit Rt in 4-0
793}
794
795// Format for Load-store non-temporal register pair (offset) instructions
796class A64I_LSPnontemp<bits<2> opc, bit v, bit l,
797                      dag outs, dag ins, string asmstr,
798                      list<dag> patterns, InstrItinClass itin>
799  : A64InstRtt2n<outs, ins, asmstr, patterns, itin> {
800  bits<7> SImm7;
801
802  let Inst{31-30} = opc;
803  let Inst{29-27} = 0b101;
804  let Inst{26} = v;
805  let Inst{25-23} = 0b000;
806  let Inst{22} = l;
807  let Inst{21-15} = SImm7;
808  // Inherit Rt2 in 14-10
809  // Inherit Rn in 9-5
810  // Inherit Rt in 4-0
811}
812
813// Format for Logical (immediate) instructions
814class A64I_logicalimm<bit sf, bits<2> opc,
815                      dag outs, dag ins, string asmstr,
816                      list<dag> patterns, InstrItinClass itin>
817  : A64InstRdn<outs, ins, asmstr, patterns, itin> {
818  bit N;
819  bits<6> ImmR;
820  bits<6> ImmS;
821
822  // N, ImmR and ImmS have no separate existence in any assembly syntax (or for
823  // selection), so we'll combine them into a single field here.
824  bits<13> Imm;
825  // N = Imm{12};
826  // ImmR = Imm{11-6};
827  // ImmS = Imm{5-0};
828
829  let Inst{31} = sf;
830  let Inst{30-29} = opc;
831  let Inst{28-23} = 0b100100;
832  let Inst{22} = Imm{12};
833  let Inst{21-16} = Imm{11-6};
834  let Inst{15-10} = Imm{5-0};
835  // Rn inherited in 9-5
836  // Rd inherited in 4-0
837}
838
839// Format for Logical (shifted register) instructions
840class A64I_logicalshift<bit sf, bits<2> opc, bits<2> shift, bit N,
841                        dag outs, dag ins, string asmstr,
842                        list<dag> patterns, InstrItinClass itin>
843  : A64InstRdnm<outs, ins, asmstr, patterns, itin> {
844  bits<6> Imm6;
845
846  let Inst{31} = sf;
847  let Inst{30-29} = opc;
848  let Inst{28-24} = 0b01010;
849  let Inst{23-22} = shift;
850  let Inst{21} = N;
851  // Rm inherited
852  let Inst{15-10} = Imm6;
853  // Rn inherited
854  // Rd inherited
855}
856
857// Format for Move wide (immediate)
858class A64I_movw<bit sf, bits<2> opc,
859                dag outs, dag ins, string asmstr,
860                list<dag> patterns, InstrItinClass itin>
861  : A64InstRd<outs, ins, asmstr, patterns, itin> {
862  bits<16> UImm16;
863  bits<2> Shift; // Called "hw" officially
864
865  let Inst{31} = sf;
866  let Inst{30-29} = opc;
867  let Inst{28-23} = 0b100101;
868  let Inst{22-21} = Shift;
869  let Inst{20-5} = UImm16;
870  // Inherits Rd in 4-0
871}
872
873// Format for PC-relative addressing instructions, ADR and ADRP.
874class A64I_PCADR<bit op,
875                 dag outs, dag ins, string asmstr,
876                 list<dag> patterns, InstrItinClass itin>
877  : A64InstRd<outs, ins, asmstr, patterns, itin> {
878  bits<21> Label;
879
880  let Inst{31} = op;
881  let Inst{30-29} = Label{1-0};
882  let Inst{28-24} = 0b10000;
883  let Inst{23-5} = Label{20-2};
884}
885
886// Format for system instructions
887class A64I_system<bit l,
888                  dag outs, dag ins, string asmstr,
889                  list<dag> patterns, InstrItinClass itin>
890  : A64Inst<outs, ins, asmstr, patterns, itin> {
891  bits<2> Op0;
892  bits<3> Op1;
893  bits<4> CRn;
894  bits<4> CRm;
895  bits<3> Op2;
896  bits<5> Rt;
897
898  let Inst{31-22} = 0b1101010100;
899  let Inst{21} = l;
900  let Inst{20-19} = Op0;
901  let Inst{18-16} = Op1;
902  let Inst{15-12} = CRn;
903  let Inst{11-8} = CRm;
904  let Inst{7-5} = Op2;
905  let Inst{4-0} = Rt;
906
907  // These instructions can do horrible things.
908  let hasSideEffects = 1;
909}
910
911// Format for unconditional branch (immediate) instructions
912class A64I_Bimm<bit op,
913                dag outs, dag ins, string asmstr,
914                list<dag> patterns, InstrItinClass itin>
915  : A64Inst<outs, ins, asmstr, patterns, itin> {
916  // Doubly special in not even sharing register fields with other
917  // instructions, so we create our own Rn here.
918  bits<26> Label;
919
920  let Inst{31} = op;
921  let Inst{30-26} = 0b00101;
922  let Inst{25-0} = Label;
923}
924
925// Format for Test & branch (immediate) instructions
926class A64I_TBimm<bit op,
927                dag outs, dag ins, string asmstr,
928                list<dag> patterns, InstrItinClass itin>
929  : A64InstRt<outs, ins, asmstr, patterns, itin> {
930  // Doubly special in not even sharing register fields with other
931  // instructions, so we create our own Rn here.
932  bits<6> Imm;
933  bits<14> Label;
934
935  let Inst{31} = Imm{5};
936  let Inst{30-25} = 0b011011;
937  let Inst{24} = op;
938  let Inst{23-19} = Imm{4-0};
939  let Inst{18-5} = Label;
940  // Inherit Rt in 4-0
941}
942
943// Format for Unconditional branch (register) instructions, including
944// RET.  Shares no fields with instructions further up the hierarchy
945// so top-level.
946class A64I_Breg<bits<4> opc, bits<5> op2, bits<6> op3, bits<5> op4,
947                dag outs, dag ins, string asmstr,
948                list<dag> patterns, InstrItinClass itin>
949  : A64Inst<outs, ins, asmstr, patterns, itin> {
950  // Doubly special in not even sharing register fields with other
951  // instructions, so we create our own Rn here.
952  bits<5> Rn;
953
954  let Inst{31-25} = 0b1101011;
955  let Inst{24-21} = opc;
956  let Inst{20-16} = op2;
957  let Inst{15-10} = op3;
958  let Inst{9-5}   = Rn;
959  let Inst{4-0}   = op4;
960}
961
962