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