1 //===- ARMInstrFormats.td - ARM Instruction Formats --*- tablegen -*---------=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
12 // ARM Instruction Format Definitions.
15 // Format specifies the encoding used by the instruction. This is part of the
16 // ad-hoc solution used to emit machine instruction encodings by our machine
18 class Format<bits<5> val> {
22 def Pseudo : Format<0>;
23 def MulFrm : Format<1>;
24 def BrFrm : Format<2>;
25 def BrMiscFrm : Format<3>;
27 def DPFrm : Format<4>;
28 def DPSoRegFrm : Format<5>;
30 def LdFrm : Format<6>;
31 def StFrm : Format<7>;
32 def LdMiscFrm : Format<8>;
33 def StMiscFrm : Format<9>;
34 def LdStMulFrm : Format<10>;
36 def ArithMiscFrm : Format<11>;
37 def ExtFrm : Format<12>;
39 def VFPUnaryFrm : Format<13>;
40 def VFPBinaryFrm : Format<14>;
41 def VFPConv1Frm : Format<15>;
42 def VFPConv2Frm : Format<16>;
43 def VFPConv3Frm : Format<17>;
44 def VFPConv4Frm : Format<18>;
45 def VFPConv5Frm : Format<19>;
46 def VFPLdStFrm : Format<20>;
47 def VFPLdStMulFrm : Format<21>;
48 def VFPMiscFrm : Format<22>;
50 def ThumbFrm : Format<23>;
52 def NEONFrm : Format<24>;
53 def NEONGetLnFrm : Format<25>;
54 def NEONSetLnFrm : Format<26>;
55 def NEONDupFrm : Format<27>;
57 // Misc flag for data processing instructions that indicates whether
58 // the instruction has a Rn register operand.
59 class UnaryDP { bit isUnaryDataProc = 1; }
61 //===----------------------------------------------------------------------===//
62 // ARM Instruction flags. These need to match ARMInstrInfo.h.
66 class AddrMode<bits<4> val> {
69 def AddrModeNone : AddrMode<0>;
70 def AddrMode1 : AddrMode<1>;
71 def AddrMode2 : AddrMode<2>;
72 def AddrMode3 : AddrMode<3>;
73 def AddrMode4 : AddrMode<4>;
74 def AddrMode5 : AddrMode<5>;
75 def AddrModeT1_1 : AddrMode<6>;
76 def AddrModeT1_2 : AddrMode<7>;
77 def AddrModeT1_4 : AddrMode<8>;
78 def AddrModeT1_s : AddrMode<9>;
79 def AddrModeT2_i12: AddrMode<10>;
80 def AddrModeT2_i8 : AddrMode<11>;
81 def AddrModeT2_so : AddrMode<12>;
82 def AddrModeT2_pc : AddrMode<13>;
83 def AddrModeT2_i8s4 : AddrMode<14>;
86 class SizeFlagVal<bits<3> val> {
89 def SizeInvalid : SizeFlagVal<0>; // Unset.
90 def SizeSpecial : SizeFlagVal<1>; // Pseudo or special.
91 def Size8Bytes : SizeFlagVal<2>;
92 def Size4Bytes : SizeFlagVal<3>;
93 def Size2Bytes : SizeFlagVal<4>;
95 // Load / store index mode.
96 class IndexMode<bits<2> val> {
99 def IndexModeNone : IndexMode<0>;
100 def IndexModePre : IndexMode<1>;
101 def IndexModePost : IndexMode<2>;
103 //===----------------------------------------------------------------------===//
105 // ARM Instruction templates.
108 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
109 Format f, string cstr>
113 let Namespace = "ARM";
117 bits<4> AddrModeBits = AM.Value;
120 bits<3> SizeFlag = SZ.Value;
123 bits<2> IndexModeBits = IM.Value;
126 bits<5> Form = F.Value;
129 // Attributes specific to ARM instructions...
131 bit isUnaryDataProc = 0;
133 let Constraints = cstr;
136 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
137 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
138 let OutOperandList = oops;
139 let InOperandList = iops;
141 let Pattern = pattern;
144 // Almost all ARM instructions are predicable.
145 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
146 IndexMode im, Format f, string opc, string asm, string cstr,
148 : InstARM<am, sz, im, f, cstr> {
149 let OutOperandList = oops;
150 let InOperandList = !con(iops, (ops pred:$p));
151 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
152 let Pattern = pattern;
153 list<Predicate> Predicates = [IsARM];
156 // Same as I except it can optionally modify CPSR. Note it's modeled as
157 // an input operand since by default it's a zero register. It will
158 // become an implicit def once it's "flipped".
159 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
160 IndexMode im, Format f, string opc, string asm, string cstr,
162 : InstARM<am, sz, im, f, cstr> {
163 let OutOperandList = oops;
164 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
165 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
166 let Pattern = pattern;
167 list<Predicate> Predicates = [IsARM];
171 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
172 IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
173 : InstARM<am, sz, im, f, cstr> {
174 let OutOperandList = oops;
175 let InOperandList = iops;
177 let Pattern = pattern;
178 list<Predicate> Predicates = [IsARM];
181 class AI<dag oops, dag iops, Format f, string opc,
182 string asm, list<dag> pattern>
183 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
185 class AsI<dag oops, dag iops, Format f, string opc,
186 string asm, list<dag> pattern>
187 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
189 class AXI<dag oops, dag iops, Format f, string asm,
191 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
194 // Ctrl flow instructions
195 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
196 string asm, list<dag> pattern>
197 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
199 let Inst{27-24} = opcod;
201 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
202 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
204 let Inst{27-24} = opcod;
206 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
207 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
210 // BR_JT instructions
211 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
212 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
215 // addrmode1 instructions
216 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
217 string asm, list<dag> pattern>
218 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
220 let Inst{24-21} = opcod;
221 let Inst{27-26} = {0,0};
223 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
224 string asm, list<dag> pattern>
225 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
227 let Inst{24-21} = opcod;
228 let Inst{27-26} = {0,0};
230 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
232 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
234 let Inst{24-21} = opcod;
235 let Inst{27-26} = {0,0};
237 class AI1x2<dag oops, dag iops, Format f, string opc,
238 string asm, list<dag> pattern>
239 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
243 // addrmode2 loads and stores
244 class AI2<dag oops, dag iops, Format f, string opc,
245 string asm, list<dag> pattern>
246 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
248 let Inst{27-26} = {0,1};
252 class AI2ldw<dag oops, dag iops, Format f, string opc,
253 string asm, list<dag> pattern>
254 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
256 let Inst{20} = 1; // L bit
257 let Inst{21} = 0; // W bit
258 let Inst{22} = 0; // B bit
259 let Inst{24} = 1; // P bit
260 let Inst{27-26} = {0,1};
262 class AXI2ldw<dag oops, dag iops, Format f, string asm,
264 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
266 let Inst{20} = 1; // L bit
267 let Inst{21} = 0; // W bit
268 let Inst{22} = 0; // B bit
269 let Inst{24} = 1; // P bit
270 let Inst{27-26} = {0,1};
272 class AI2ldb<dag oops, dag iops, Format f, string opc,
273 string asm, list<dag> pattern>
274 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
276 let Inst{20} = 1; // L bit
277 let Inst{21} = 0; // W bit
278 let Inst{22} = 1; // B bit
279 let Inst{24} = 1; // P bit
280 let Inst{27-26} = {0,1};
282 class AXI2ldb<dag oops, dag iops, Format f, string asm,
284 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
286 let Inst{20} = 1; // L bit
287 let Inst{21} = 0; // W bit
288 let Inst{22} = 1; // B bit
289 let Inst{24} = 1; // P bit
290 let Inst{27-26} = {0,1};
294 class AI2stw<dag oops, dag iops, Format f, string opc,
295 string asm, list<dag> pattern>
296 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
298 let Inst{20} = 0; // L bit
299 let Inst{21} = 0; // W bit
300 let Inst{22} = 0; // B bit
301 let Inst{24} = 1; // P bit
302 let Inst{27-26} = {0,1};
304 class AXI2stw<dag oops, dag iops, Format f, string asm,
306 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
308 let Inst{20} = 0; // L bit
309 let Inst{21} = 0; // W bit
310 let Inst{22} = 0; // B bit
311 let Inst{24} = 1; // P bit
312 let Inst{27-26} = {0,1};
314 class AI2stb<dag oops, dag iops, Format f, string opc,
315 string asm, list<dag> pattern>
316 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
318 let Inst{20} = 0; // L bit
319 let Inst{21} = 0; // W bit
320 let Inst{22} = 1; // B bit
321 let Inst{24} = 1; // P bit
322 let Inst{27-26} = {0,1};
324 class AXI2stb<dag oops, dag iops, Format f, string asm,
326 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
328 let Inst{20} = 0; // L bit
329 let Inst{21} = 0; // W bit
330 let Inst{22} = 1; // B bit
331 let Inst{24} = 1; // P bit
332 let Inst{27-26} = {0,1};
336 class AI2ldwpr<dag oops, dag iops, Format f, string opc,
337 string asm, string cstr, list<dag> pattern>
338 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
339 asm, cstr, pattern> {
340 let Inst{20} = 1; // L bit
341 let Inst{21} = 1; // W bit
342 let Inst{22} = 0; // B bit
343 let Inst{24} = 1; // P bit
344 let Inst{27-26} = {0,1};
346 class AI2ldbpr<dag oops, dag iops, Format f, string opc,
347 string asm, string cstr, list<dag> pattern>
348 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
349 asm, cstr, pattern> {
350 let Inst{20} = 1; // L bit
351 let Inst{21} = 1; // W bit
352 let Inst{22} = 1; // B bit
353 let Inst{24} = 1; // P bit
354 let Inst{27-26} = {0,1};
357 // Pre-indexed stores
358 class AI2stwpr<dag oops, dag iops, Format f, string opc,
359 string asm, string cstr, list<dag> pattern>
360 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
361 asm, cstr, pattern> {
362 let Inst{20} = 0; // L bit
363 let Inst{21} = 1; // W bit
364 let Inst{22} = 0; // B bit
365 let Inst{24} = 1; // P bit
366 let Inst{27-26} = {0,1};
368 class AI2stbpr<dag oops, dag iops, Format f, string opc,
369 string asm, string cstr, list<dag> pattern>
370 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
371 asm, cstr, pattern> {
372 let Inst{20} = 0; // L bit
373 let Inst{21} = 1; // W bit
374 let Inst{22} = 1; // B bit
375 let Inst{24} = 1; // P bit
376 let Inst{27-26} = {0,1};
379 // Post-indexed loads
380 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
381 string asm, string cstr, list<dag> pattern>
382 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
384 let Inst{20} = 1; // L bit
385 let Inst{21} = 0; // W bit
386 let Inst{22} = 0; // B bit
387 let Inst{24} = 0; // P bit
388 let Inst{27-26} = {0,1};
390 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
391 string asm, string cstr, list<dag> pattern>
392 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
394 let Inst{20} = 1; // L bit
395 let Inst{21} = 0; // W bit
396 let Inst{22} = 1; // B bit
397 let Inst{24} = 0; // P bit
398 let Inst{27-26} = {0,1};
401 // Post-indexed stores
402 class AI2stwpo<dag oops, dag iops, Format f, string opc,
403 string asm, string cstr, list<dag> pattern>
404 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
406 let Inst{20} = 0; // L bit
407 let Inst{21} = 0; // W bit
408 let Inst{22} = 0; // B bit
409 let Inst{24} = 0; // P bit
410 let Inst{27-26} = {0,1};
412 class AI2stbpo<dag oops, dag iops, Format f, string opc,
413 string asm, string cstr, list<dag> pattern>
414 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
416 let Inst{20} = 0; // L bit
417 let Inst{21} = 0; // W bit
418 let Inst{22} = 1; // B bit
419 let Inst{24} = 0; // P bit
420 let Inst{27-26} = {0,1};
423 // addrmode3 instructions
424 class AI3<dag oops, dag iops, Format f, string opc,
425 string asm, list<dag> pattern>
426 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
428 class AXI3<dag oops, dag iops, Format f, string asm,
430 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
434 class AI3ldh<dag oops, dag iops, Format f, string opc,
435 string asm, list<dag> pattern>
436 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
439 let Inst{5} = 1; // H bit
440 let Inst{6} = 0; // S bit
442 let Inst{20} = 1; // L bit
443 let Inst{21} = 0; // W bit
444 let Inst{24} = 1; // P bit
446 class AXI3ldh<dag oops, dag iops, Format f, string asm,
448 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
451 let Inst{5} = 1; // H bit
452 let Inst{6} = 0; // S bit
454 let Inst{20} = 1; // L bit
455 let Inst{21} = 0; // W bit
456 let Inst{24} = 1; // P bit
458 class AI3ldsh<dag oops, dag iops, Format f, string opc,
459 string asm, list<dag> pattern>
460 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
463 let Inst{5} = 1; // H bit
464 let Inst{6} = 1; // S bit
466 let Inst{20} = 1; // L bit
467 let Inst{21} = 0; // W bit
468 let Inst{24} = 1; // P bit
470 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
472 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
475 let Inst{5} = 1; // H bit
476 let Inst{6} = 1; // S bit
478 let Inst{20} = 1; // L bit
479 let Inst{21} = 0; // W bit
480 let Inst{24} = 1; // P bit
482 class AI3ldsb<dag oops, dag iops, Format f, string opc,
483 string asm, list<dag> pattern>
484 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
487 let Inst{5} = 0; // H bit
488 let Inst{6} = 1; // S bit
490 let Inst{20} = 1; // L bit
491 let Inst{21} = 0; // W bit
492 let Inst{24} = 1; // P bit
494 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
496 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
499 let Inst{5} = 0; // H bit
500 let Inst{6} = 1; // S bit
502 let Inst{20} = 1; // L bit
503 let Inst{21} = 0; // W bit
504 let Inst{24} = 1; // P bit
506 class AI3ldd<dag oops, dag iops, Format f, string opc,
507 string asm, list<dag> pattern>
508 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
511 let Inst{5} = 0; // H bit
512 let Inst{6} = 1; // S bit
514 let Inst{20} = 0; // L bit
515 let Inst{21} = 0; // W bit
516 let Inst{24} = 1; // P bit
520 class AI3sth<dag oops, dag iops, Format f, string opc,
521 string asm, list<dag> pattern>
522 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
525 let Inst{5} = 1; // H bit
526 let Inst{6} = 0; // S bit
528 let Inst{20} = 0; // L bit
529 let Inst{21} = 0; // W bit
530 let Inst{24} = 1; // P bit
532 class AXI3sth<dag oops, dag iops, Format f, string asm,
534 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
537 let Inst{5} = 1; // H bit
538 let Inst{6} = 0; // S bit
540 let Inst{20} = 0; // L bit
541 let Inst{21} = 0; // W bit
542 let Inst{24} = 1; // P bit
544 class AI3std<dag oops, dag iops, Format f, string opc,
545 string asm, list<dag> pattern>
546 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
549 let Inst{5} = 1; // H bit
550 let Inst{6} = 1; // S bit
552 let Inst{20} = 0; // L bit
553 let Inst{21} = 0; // W bit
554 let Inst{24} = 1; // P bit
558 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
559 string asm, string cstr, list<dag> pattern>
560 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
561 asm, cstr, pattern> {
563 let Inst{5} = 1; // H bit
564 let Inst{6} = 0; // S bit
566 let Inst{20} = 1; // L bit
567 let Inst{21} = 1; // W bit
568 let Inst{24} = 1; // P bit
570 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
571 string asm, string cstr, list<dag> pattern>
572 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
573 asm, cstr, pattern> {
575 let Inst{5} = 1; // H bit
576 let Inst{6} = 1; // S bit
578 let Inst{20} = 1; // L bit
579 let Inst{21} = 1; // W bit
580 let Inst{24} = 1; // P bit
582 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
583 string asm, string cstr, list<dag> pattern>
584 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
585 asm, cstr, pattern> {
587 let Inst{5} = 0; // H bit
588 let Inst{6} = 1; // S bit
590 let Inst{20} = 1; // L bit
591 let Inst{21} = 1; // W bit
592 let Inst{24} = 1; // P bit
595 // Pre-indexed stores
596 class AI3sthpr<dag oops, dag iops, Format f, string opc,
597 string asm, string cstr, list<dag> pattern>
598 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
599 asm, cstr, pattern> {
601 let Inst{5} = 1; // H bit
602 let Inst{6} = 0; // S bit
604 let Inst{20} = 0; // L bit
605 let Inst{21} = 1; // W bit
606 let Inst{24} = 1; // P bit
609 // Post-indexed loads
610 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
611 string asm, string cstr, list<dag> pattern>
612 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
615 let Inst{5} = 1; // H bit
616 let Inst{6} = 0; // S bit
618 let Inst{20} = 1; // L bit
619 let Inst{21} = 1; // W bit
620 let Inst{24} = 0; // P bit
622 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
623 string asm, string cstr, list<dag> pattern>
624 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
627 let Inst{5} = 1; // H bit
628 let Inst{6} = 1; // S bit
630 let Inst{20} = 1; // L bit
631 let Inst{21} = 1; // W bit
632 let Inst{24} = 0; // P bit
634 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
635 string asm, string cstr, list<dag> pattern>
636 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
639 let Inst{5} = 0; // H bit
640 let Inst{6} = 1; // S bit
642 let Inst{20} = 1; // L bit
643 let Inst{21} = 1; // W bit
644 let Inst{24} = 0; // P bit
647 // Post-indexed stores
648 class AI3sthpo<dag oops, dag iops, Format f, string opc,
649 string asm, string cstr, list<dag> pattern>
650 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
653 let Inst{5} = 1; // H bit
654 let Inst{6} = 0; // S bit
656 let Inst{20} = 0; // L bit
657 let Inst{21} = 1; // W bit
658 let Inst{24} = 0; // P bit
662 // addrmode4 instructions
663 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
664 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
666 let Inst{20} = 1; // L bit
667 let Inst{22} = 0; // S bit
668 let Inst{27-25} = 0b100;
670 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
671 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
673 let Inst{20} = 0; // L bit
674 let Inst{22} = 0; // S bit
675 let Inst{27-25} = 0b100;
678 // Unsigned multiply, multiply-accumulate instructions.
679 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
680 string asm, list<dag> pattern>
681 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
683 let Inst{7-4} = 0b1001;
684 let Inst{20} = 0; // S bit
685 let Inst{27-21} = opcod;
687 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
688 string asm, list<dag> pattern>
689 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
691 let Inst{7-4} = 0b1001;
692 let Inst{27-21} = opcod;
695 // Most significant word multiply
696 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
697 string asm, list<dag> pattern>
698 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
700 let Inst{7-4} = 0b1001;
702 let Inst{27-21} = opcod;
705 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
706 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
707 string asm, list<dag> pattern>
708 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
713 let Inst{27-21} = opcod;
716 // Extend instructions.
717 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
718 string asm, list<dag> pattern>
719 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
721 let Inst{7-4} = 0b0111;
722 let Inst{27-20} = opcod;
725 // Misc Arithmetic instructions.
726 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
727 string asm, list<dag> pattern>
728 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
730 let Inst{27-20} = opcod;
733 //===----------------------------------------------------------------------===//
735 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
736 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
737 list<Predicate> Predicates = [IsARM];
739 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
740 list<Predicate> Predicates = [IsARM, HasV5TE];
742 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
743 list<Predicate> Predicates = [IsARM, HasV6];
746 //===----------------------------------------------------------------------===//
748 // Thumb Instruction Format Definitions.
751 // TI - Thumb instruction.
753 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
754 string asm, string cstr, list<dag> pattern>
755 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
756 let OutOperandList = outs;
757 let InOperandList = ins;
759 let Pattern = pattern;
760 list<Predicate> Predicates = [IsThumb];
763 class TI<dag outs, dag ins, string asm, list<dag> pattern>
764 : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
766 // BL, BLX(1) are translated by assembler into two instructions
767 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
768 : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
770 // BR_JT instructions
771 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
772 : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
774 // TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
775 class TPat<dag pattern, dag result> : Pat<pattern, result> {
776 list<Predicate> Predicates = [IsThumb];
779 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
780 list<Predicate> Predicates = [IsThumb, HasV5T];
784 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
785 string asm, string cstr, list<dag> pattern>
786 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
787 let OutOperandList = outs;
788 let InOperandList = ins;
790 let Pattern = pattern;
791 list<Predicate> Predicates = [IsThumb1Only];
794 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
795 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
796 class T1I1<dag outs, dag ins, string asm, list<dag> pattern>
797 : Thumb1I<outs, ins, AddrModeT1_1, Size2Bytes, asm, "", pattern>;
798 class T1I2<dag outs, dag ins, string asm, list<dag> pattern>
799 : Thumb1I<outs, ins, AddrModeT1_2, Size2Bytes, asm, "", pattern>;
800 class T1I4<dag outs, dag ins, string asm, list<dag> pattern>
801 : Thumb1I<outs, ins, AddrModeT1_4, Size2Bytes, asm, "", pattern>;
802 class T1Is<dag outs, dag ins, string asm, list<dag> pattern>
803 : Thumb1I<outs, ins, AddrModeT1_s, Size2Bytes, asm, "", pattern>;
804 class T1Ix2<dag outs, dag ins, string asm, list<dag> pattern>
805 : Thumb1I<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
806 class T1JTI<dag outs, dag ins, string asm, list<dag> pattern>
807 : Thumb1I<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
809 // Two-address instructions
810 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
811 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
813 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
814 list<Predicate> Predicates = [IsThumb1Only];
817 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
818 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
819 string opc, string asm, string cstr, list<dag> pattern>
820 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
821 let OutOperandList = oops;
822 let InOperandList = !con(iops, (ops pred:$p));
823 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
824 let Pattern = pattern;
825 list<Predicate> Predicates = [IsThumb, HasThumb2];
828 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
829 // an input operand since by default it's a zero register. It will
830 // become an implicit def once it's "flipped".
831 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
833 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
834 string opc, string asm, string cstr, list<dag> pattern>
835 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
836 let OutOperandList = oops;
837 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
838 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
839 let Pattern = pattern;
840 list<Predicate> Predicates = [IsThumb, HasThumb2];
844 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
845 string asm, string cstr, list<dag> pattern>
846 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
847 let OutOperandList = oops;
848 let InOperandList = iops;
850 let Pattern = pattern;
851 list<Predicate> Predicates = [IsThumb, HasThumb2];
854 class T2I<dag oops, dag iops, string opc, string asm, list<dag> pattern>
855 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
856 class T2Ii12<dag oops, dag iops, string opc, string asm, list<dag> pattern>
857 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, opc, asm, "", pattern>;
858 class T2Ii8<dag oops, dag iops, string opc, string asm, list<dag> pattern>
859 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, opc, asm, "", pattern>;
860 class T2Iso<dag oops, dag iops, string opc, string asm, list<dag> pattern>
861 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, opc, asm, "", pattern>;
862 class T2Ipc<dag oops, dag iops, string opc, string asm, list<dag> pattern>
863 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, opc, asm, "", pattern>;
864 class T2Ii8s4<dag oops, dag iops, string opc, string asm, list<dag> pattern>
865 : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, opc, asm, "", pattern>;
867 class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
868 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
870 class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
871 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
872 class T2JTI<dag oops, dag iops, string asm, list<dag> pattern>
873 : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, asm, "", pattern>;
875 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
876 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
877 list<Predicate> Predicates = [IsThumb, HasThumb2];
880 //===----------------------------------------------------------------------===//
882 //===----------------------------------------------------------------------===//
883 // ARM VFP Instruction templates.
886 // ARM VFP addrmode5 loads and stores
887 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
888 string opc, string asm, list<dag> pattern>
889 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
890 VFPLdStFrm, opc, asm, "", pattern> {
891 // TODO: Mark the instructions with the appropriate subtarget info.
892 let Inst{27-24} = opcod1;
893 let Inst{21-20} = opcod2;
894 let Inst{11-8} = 0b1011;
897 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
898 string opc, string asm, list<dag> pattern>
899 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
900 VFPLdStFrm, opc, asm, "", pattern> {
901 // TODO: Mark the instructions with the appropriate subtarget info.
902 let Inst{27-24} = opcod1;
903 let Inst{21-20} = opcod2;
904 let Inst{11-8} = 0b1010;
907 // Load / store multiple
908 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
909 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
910 VFPLdStMulFrm, asm, "", pattern> {
911 // TODO: Mark the instructions with the appropriate subtarget info.
912 let Inst{27-25} = 0b110;
913 let Inst{11-8} = 0b1011;
916 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
917 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
918 VFPLdStMulFrm, asm, "", pattern> {
919 // TODO: Mark the instructions with the appropriate subtarget info.
920 let Inst{27-25} = 0b110;
921 let Inst{11-8} = 0b1010;
925 // Double precision, unary
926 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
927 string opc, string asm, list<dag> pattern>
928 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
929 let Inst{27-20} = opcod1;
930 let Inst{19-16} = opcod2;
931 let Inst{11-8} = 0b1011;
932 let Inst{7-4} = opcod3;
935 // Double precision, binary
936 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
937 string asm, list<dag> pattern>
938 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
939 let Inst{27-20} = opcod;
940 let Inst{11-8} = 0b1011;
943 // Single precision, unary
944 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
945 string opc, string asm, list<dag> pattern>
946 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
947 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
948 let Inst{27-20} = opcod1;
949 let Inst{19-16} = opcod2;
950 let Inst{11-8} = 0b1010;
951 let Inst{7-4} = opcod3;
954 // Single precision, binary
955 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
956 string asm, list<dag> pattern>
957 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
958 // Bit 22 (D bit) can be changed during instruction encoding.
959 let Inst{27-20} = opcod;
960 let Inst{11-8} = 0b1010;
963 // VFP conversion instructions
964 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
965 dag oops, dag iops, string opc, string asm, list<dag> pattern>
966 : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
967 let Inst{27-20} = opcod1;
968 let Inst{19-16} = opcod2;
969 let Inst{11-8} = opcod3;
973 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
974 string opc, string asm, list<dag> pattern>
975 : AI<oops, iops, f, opc, asm, pattern> {
976 let Inst{27-20} = opcod1;
977 let Inst{11-8} = opcod2;
981 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
982 string asm, list<dag> pattern>
983 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
985 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
986 string asm, list<dag> pattern>
987 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
989 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
990 string asm, list<dag> pattern>
991 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
993 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
994 string asm, list<dag> pattern>
995 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
997 //===----------------------------------------------------------------------===//
999 //===----------------------------------------------------------------------===//
1000 // ARM NEON Instruction templates.
1003 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
1004 string cstr, list<dag> pattern>
1005 : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
1006 let OutOperandList = oops;
1007 let InOperandList = iops;
1008 let AsmString = asm;
1009 let Pattern = pattern;
1010 list<Predicate> Predicates = [HasNEON];
1013 class NI<dag oops, dag iops, string asm, list<dag> pattern>
1014 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
1017 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1018 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
1019 let Inst{31-25} = 0b1111001;
1022 // NEON "one register and a modified immediate" format.
1023 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1025 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1026 : NDataI<oops, iops, asm, cstr, pattern> {
1027 let Inst{23} = op23;
1028 let Inst{21-19} = op21_19;
1029 let Inst{11-8} = op11_8;
1036 // NEON 2 vector register format.
1037 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1038 bits<5> op11_7, bit op6, bit op4,
1039 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1040 : NDataI<oops, iops, asm, cstr, pattern> {
1041 let Inst{24-23} = op24_23;
1042 let Inst{21-20} = op21_20;
1043 let Inst{19-18} = op19_18;
1044 let Inst{17-16} = op17_16;
1045 let Inst{11-7} = op11_7;
1050 // NEON 2 vector register with immediate.
1051 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
1053 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1054 : NDataI<oops, iops, asm, cstr, pattern> {
1055 let Inst{24} = op24;
1056 let Inst{23} = op23;
1057 let Inst{21-16} = op21_16;
1058 let Inst{11-8} = op11_8;
1064 // NEON 3 vector register format.
1065 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1066 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1067 : NDataI<oops, iops, asm, cstr, pattern> {
1068 let Inst{24} = op24;
1069 let Inst{23} = op23;
1070 let Inst{21-20} = op21_20;
1071 let Inst{11-8} = op11_8;
1076 // NEON VMOVs between scalar and core registers.
1077 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1078 dag oops, dag iops, Format f, string opc, string asm,
1080 : AI<oops, iops, f, opc, asm, pattern> {
1081 let Inst{27-20} = opcod1;
1082 let Inst{11-8} = opcod2;
1083 let Inst{6-5} = opcod3;
1085 list<Predicate> Predicates = [HasNEON];
1087 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1088 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1089 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1091 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1092 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1093 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1095 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1096 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1097 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;