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>;
85 class SizeFlagVal<bits<3> val> {
88 def SizeInvalid : SizeFlagVal<0>; // Unset.
89 def SizeSpecial : SizeFlagVal<1>; // Pseudo or special.
90 def Size8Bytes : SizeFlagVal<2>;
91 def Size4Bytes : SizeFlagVal<3>;
92 def Size2Bytes : SizeFlagVal<4>;
94 // Load / store index mode.
95 class IndexMode<bits<2> val> {
98 def IndexModeNone : IndexMode<0>;
99 def IndexModePre : IndexMode<1>;
100 def IndexModePost : IndexMode<2>;
102 //===----------------------------------------------------------------------===//
104 // ARM Instruction templates.
107 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
108 Format f, string cstr>
112 let Namespace = "ARM";
116 bits<4> AddrModeBits = AM.Value;
119 bits<3> SizeFlag = SZ.Value;
122 bits<2> IndexModeBits = IM.Value;
125 bits<5> Form = F.Value;
128 // Attributes specific to ARM instructions...
130 bit isUnaryDataProc = 0;
132 let Constraints = cstr;
135 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
136 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
137 let OutOperandList = oops;
138 let InOperandList = iops;
140 let Pattern = pattern;
143 // Almost all ARM instructions are predicable.
144 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
145 IndexMode im, Format f, string opc, string asm, string cstr,
147 : InstARM<am, sz, im, f, cstr> {
148 let OutOperandList = oops;
149 let InOperandList = !con(iops, (ops pred:$p));
150 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
151 let Pattern = pattern;
152 list<Predicate> Predicates = [IsARM];
155 // Same as I except it can optionally modify CPSR. Note it's modeled as
156 // an input operand since by default it's a zero register. It will
157 // become an implicit def once it's "flipped".
158 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
159 IndexMode im, Format f, string opc, string asm, string cstr,
161 : InstARM<am, sz, im, f, cstr> {
162 let OutOperandList = oops;
163 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
164 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
165 let Pattern = pattern;
166 list<Predicate> Predicates = [IsARM];
170 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
171 IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
172 : InstARM<am, sz, im, f, cstr> {
173 let OutOperandList = oops;
174 let InOperandList = iops;
176 let Pattern = pattern;
177 list<Predicate> Predicates = [IsARM];
180 class AI<dag oops, dag iops, Format f, string opc,
181 string asm, list<dag> pattern>
182 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
184 class AsI<dag oops, dag iops, Format f, string opc,
185 string asm, list<dag> pattern>
186 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
188 class AXI<dag oops, dag iops, Format f, string asm,
190 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
193 // Ctrl flow instructions
194 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
195 string asm, list<dag> pattern>
196 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
198 let Inst{27-24} = opcod;
200 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
201 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
203 let Inst{27-24} = opcod;
205 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
206 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
209 // BR_JT instructions
210 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
211 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
214 // addrmode1 instructions
215 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
216 string asm, list<dag> pattern>
217 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
219 let Inst{24-21} = opcod;
220 let Inst{27-26} = {0,0};
222 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
223 string asm, list<dag> pattern>
224 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
226 let Inst{24-21} = opcod;
227 let Inst{27-26} = {0,0};
229 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
231 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
233 let Inst{24-21} = opcod;
234 let Inst{27-26} = {0,0};
236 class AI1x2<dag oops, dag iops, Format f, string opc,
237 string asm, list<dag> pattern>
238 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
242 // addrmode2 loads and stores
243 class AI2<dag oops, dag iops, Format f, string opc,
244 string asm, list<dag> pattern>
245 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
247 let Inst{27-26} = {0,1};
251 class AI2ldw<dag oops, dag iops, Format f, string opc,
252 string asm, list<dag> pattern>
253 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
255 let Inst{20} = 1; // L bit
256 let Inst{21} = 0; // W bit
257 let Inst{22} = 0; // B bit
258 let Inst{24} = 1; // P bit
259 let Inst{27-26} = {0,1};
261 class AXI2ldw<dag oops, dag iops, Format f, string asm,
263 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
265 let Inst{20} = 1; // L bit
266 let Inst{21} = 0; // W bit
267 let Inst{22} = 0; // B bit
268 let Inst{24} = 1; // P bit
269 let Inst{27-26} = {0,1};
271 class AI2ldb<dag oops, dag iops, Format f, string opc,
272 string asm, list<dag> pattern>
273 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
275 let Inst{20} = 1; // L bit
276 let Inst{21} = 0; // W bit
277 let Inst{22} = 1; // B bit
278 let Inst{24} = 1; // P bit
279 let Inst{27-26} = {0,1};
281 class AXI2ldb<dag oops, dag iops, Format f, string asm,
283 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
285 let Inst{20} = 1; // L bit
286 let Inst{21} = 0; // W bit
287 let Inst{22} = 1; // B bit
288 let Inst{24} = 1; // P bit
289 let Inst{27-26} = {0,1};
293 class AI2stw<dag oops, dag iops, Format f, string opc,
294 string asm, list<dag> pattern>
295 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
297 let Inst{20} = 0; // L bit
298 let Inst{21} = 0; // W bit
299 let Inst{22} = 0; // B bit
300 let Inst{24} = 1; // P bit
301 let Inst{27-26} = {0,1};
303 class AXI2stw<dag oops, dag iops, Format f, string asm,
305 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
307 let Inst{20} = 0; // L bit
308 let Inst{21} = 0; // W bit
309 let Inst{22} = 0; // B bit
310 let Inst{24} = 1; // P bit
311 let Inst{27-26} = {0,1};
313 class AI2stb<dag oops, dag iops, Format f, string opc,
314 string asm, list<dag> pattern>
315 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
317 let Inst{20} = 0; // L bit
318 let Inst{21} = 0; // W bit
319 let Inst{22} = 1; // B bit
320 let Inst{24} = 1; // P bit
321 let Inst{27-26} = {0,1};
323 class AXI2stb<dag oops, dag iops, Format f, string asm,
325 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
327 let Inst{20} = 0; // L bit
328 let Inst{21} = 0; // W bit
329 let Inst{22} = 1; // B bit
330 let Inst{24} = 1; // P bit
331 let Inst{27-26} = {0,1};
335 class AI2ldwpr<dag oops, dag iops, Format f, string opc,
336 string asm, string cstr, list<dag> pattern>
337 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
338 asm, cstr, pattern> {
339 let Inst{20} = 1; // L bit
340 let Inst{21} = 1; // W bit
341 let Inst{22} = 0; // B bit
342 let Inst{24} = 1; // P bit
343 let Inst{27-26} = {0,1};
345 class AI2ldbpr<dag oops, dag iops, Format f, string opc,
346 string asm, string cstr, list<dag> pattern>
347 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
348 asm, cstr, pattern> {
349 let Inst{20} = 1; // L bit
350 let Inst{21} = 1; // W bit
351 let Inst{22} = 1; // B bit
352 let Inst{24} = 1; // P bit
353 let Inst{27-26} = {0,1};
356 // Pre-indexed stores
357 class AI2stwpr<dag oops, dag iops, Format f, string opc,
358 string asm, string cstr, list<dag> pattern>
359 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
360 asm, cstr, pattern> {
361 let Inst{20} = 0; // L bit
362 let Inst{21} = 1; // W bit
363 let Inst{22} = 0; // B bit
364 let Inst{24} = 1; // P bit
365 let Inst{27-26} = {0,1};
367 class AI2stbpr<dag oops, dag iops, Format f, string opc,
368 string asm, string cstr, list<dag> pattern>
369 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
370 asm, cstr, pattern> {
371 let Inst{20} = 0; // L bit
372 let Inst{21} = 1; // W bit
373 let Inst{22} = 1; // B bit
374 let Inst{24} = 1; // P bit
375 let Inst{27-26} = {0,1};
378 // Post-indexed loads
379 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
380 string asm, string cstr, list<dag> pattern>
381 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
383 let Inst{20} = 1; // L bit
384 let Inst{21} = 0; // W bit
385 let Inst{22} = 0; // B bit
386 let Inst{24} = 0; // P bit
387 let Inst{27-26} = {0,1};
389 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
390 string asm, string cstr, list<dag> pattern>
391 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
393 let Inst{20} = 1; // L bit
394 let Inst{21} = 0; // W bit
395 let Inst{22} = 1; // B bit
396 let Inst{24} = 0; // P bit
397 let Inst{27-26} = {0,1};
400 // Post-indexed stores
401 class AI2stwpo<dag oops, dag iops, Format f, string opc,
402 string asm, string cstr, list<dag> pattern>
403 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
405 let Inst{20} = 0; // L bit
406 let Inst{21} = 0; // W bit
407 let Inst{22} = 0; // B bit
408 let Inst{24} = 0; // P bit
409 let Inst{27-26} = {0,1};
411 class AI2stbpo<dag oops, dag iops, Format f, string opc,
412 string asm, string cstr, list<dag> pattern>
413 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
415 let Inst{20} = 0; // L bit
416 let Inst{21} = 0; // W bit
417 let Inst{22} = 1; // B bit
418 let Inst{24} = 0; // P bit
419 let Inst{27-26} = {0,1};
422 // addrmode3 instructions
423 class AI3<dag oops, dag iops, Format f, string opc,
424 string asm, list<dag> pattern>
425 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
427 class AXI3<dag oops, dag iops, Format f, string asm,
429 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
433 class AI3ldh<dag oops, dag iops, Format f, string opc,
434 string asm, list<dag> pattern>
435 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
438 let Inst{5} = 1; // H bit
439 let Inst{6} = 0; // S bit
441 let Inst{20} = 1; // L bit
442 let Inst{21} = 0; // W bit
443 let Inst{24} = 1; // P bit
445 class AXI3ldh<dag oops, dag iops, Format f, string asm,
447 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
450 let Inst{5} = 1; // H bit
451 let Inst{6} = 0; // S bit
453 let Inst{20} = 1; // L bit
454 let Inst{21} = 0; // W bit
455 let Inst{24} = 1; // P bit
457 class AI3ldsh<dag oops, dag iops, Format f, string opc,
458 string asm, list<dag> pattern>
459 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
462 let Inst{5} = 1; // H bit
463 let Inst{6} = 1; // S bit
465 let Inst{20} = 1; // L bit
466 let Inst{21} = 0; // W bit
467 let Inst{24} = 1; // P bit
469 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
471 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
474 let Inst{5} = 1; // H bit
475 let Inst{6} = 1; // S bit
477 let Inst{20} = 1; // L bit
478 let Inst{21} = 0; // W bit
479 let Inst{24} = 1; // P bit
481 class AI3ldsb<dag oops, dag iops, Format f, string opc,
482 string asm, list<dag> pattern>
483 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
486 let Inst{5} = 0; // H bit
487 let Inst{6} = 1; // S bit
489 let Inst{20} = 1; // L bit
490 let Inst{21} = 0; // W bit
491 let Inst{24} = 1; // P bit
493 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
495 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
498 let Inst{5} = 0; // H bit
499 let Inst{6} = 1; // S bit
501 let Inst{20} = 1; // L bit
502 let Inst{21} = 0; // W bit
503 let Inst{24} = 1; // P bit
505 class AI3ldd<dag oops, dag iops, Format f, string opc,
506 string asm, list<dag> pattern>
507 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
510 let Inst{5} = 0; // H bit
511 let Inst{6} = 1; // S bit
513 let Inst{20} = 0; // L bit
514 let Inst{21} = 0; // W bit
515 let Inst{24} = 1; // P bit
519 class AI3sth<dag oops, dag iops, Format f, string opc,
520 string asm, list<dag> pattern>
521 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
524 let Inst{5} = 1; // H bit
525 let Inst{6} = 0; // S bit
527 let Inst{20} = 0; // L bit
528 let Inst{21} = 0; // W bit
529 let Inst{24} = 1; // P bit
531 class AXI3sth<dag oops, dag iops, Format f, string asm,
533 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
536 let Inst{5} = 1; // H bit
537 let Inst{6} = 0; // S bit
539 let Inst{20} = 0; // L bit
540 let Inst{21} = 0; // W bit
541 let Inst{24} = 1; // P bit
543 class AI3std<dag oops, dag iops, Format f, string opc,
544 string asm, list<dag> pattern>
545 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
548 let Inst{5} = 1; // H bit
549 let Inst{6} = 1; // S bit
551 let Inst{20} = 0; // L bit
552 let Inst{21} = 0; // W bit
553 let Inst{24} = 1; // P bit
557 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
558 string asm, string cstr, list<dag> pattern>
559 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
560 asm, cstr, pattern> {
562 let Inst{5} = 1; // H bit
563 let Inst{6} = 0; // S bit
565 let Inst{20} = 1; // L bit
566 let Inst{21} = 1; // W bit
567 let Inst{24} = 1; // P bit
569 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
570 string asm, string cstr, list<dag> pattern>
571 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
572 asm, cstr, pattern> {
574 let Inst{5} = 1; // H bit
575 let Inst{6} = 1; // S bit
577 let Inst{20} = 1; // L bit
578 let Inst{21} = 1; // W bit
579 let Inst{24} = 1; // P bit
581 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
582 string asm, string cstr, list<dag> pattern>
583 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
584 asm, cstr, pattern> {
586 let Inst{5} = 0; // H bit
587 let Inst{6} = 1; // S bit
589 let Inst{20} = 1; // L bit
590 let Inst{21} = 1; // W bit
591 let Inst{24} = 1; // P bit
594 // Pre-indexed stores
595 class AI3sthpr<dag oops, dag iops, Format f, string opc,
596 string asm, string cstr, list<dag> pattern>
597 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
598 asm, cstr, pattern> {
600 let Inst{5} = 1; // H bit
601 let Inst{6} = 0; // S bit
603 let Inst{20} = 0; // L bit
604 let Inst{21} = 1; // W bit
605 let Inst{24} = 1; // P bit
608 // Post-indexed loads
609 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
610 string asm, string cstr, list<dag> pattern>
611 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
614 let Inst{5} = 1; // H bit
615 let Inst{6} = 0; // S bit
617 let Inst{20} = 1; // L bit
618 let Inst{21} = 1; // W bit
619 let Inst{24} = 0; // P bit
621 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
622 string asm, string cstr, list<dag> pattern>
623 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
626 let Inst{5} = 1; // H bit
627 let Inst{6} = 1; // S bit
629 let Inst{20} = 1; // L bit
630 let Inst{21} = 1; // W bit
631 let Inst{24} = 0; // P bit
633 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
634 string asm, string cstr, list<dag> pattern>
635 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
638 let Inst{5} = 0; // H bit
639 let Inst{6} = 1; // S bit
641 let Inst{20} = 1; // L bit
642 let Inst{21} = 1; // W bit
643 let Inst{24} = 0; // P bit
646 // Post-indexed stores
647 class AI3sthpo<dag oops, dag iops, Format f, string opc,
648 string asm, string cstr, list<dag> pattern>
649 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
652 let Inst{5} = 1; // H bit
653 let Inst{6} = 0; // S bit
655 let Inst{20} = 0; // L bit
656 let Inst{21} = 1; // W bit
657 let Inst{24} = 0; // P bit
661 // addrmode4 instructions
662 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
663 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
665 let Inst{20} = 1; // L bit
666 let Inst{22} = 0; // S bit
667 let Inst{27-25} = 0b100;
669 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
670 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
672 let Inst{20} = 0; // L bit
673 let Inst{22} = 0; // S bit
674 let Inst{27-25} = 0b100;
677 // Unsigned multiply, multiply-accumulate instructions.
678 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
679 string asm, list<dag> pattern>
680 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
682 let Inst{7-4} = 0b1001;
683 let Inst{20} = 0; // S bit
684 let Inst{27-21} = opcod;
686 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
687 string asm, list<dag> pattern>
688 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
690 let Inst{7-4} = 0b1001;
691 let Inst{27-21} = opcod;
694 // Most significant word multiply
695 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
696 string asm, list<dag> pattern>
697 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
699 let Inst{7-4} = 0b1001;
701 let Inst{27-21} = opcod;
704 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
705 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
706 string asm, list<dag> pattern>
707 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
712 let Inst{27-21} = opcod;
715 // Extend instructions.
716 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
717 string asm, list<dag> pattern>
718 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
720 let Inst{7-4} = 0b0111;
721 let Inst{27-20} = opcod;
724 // Misc Arithmetic instructions.
725 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
726 string asm, list<dag> pattern>
727 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
729 let Inst{27-20} = opcod;
732 //===----------------------------------------------------------------------===//
734 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
735 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
736 list<Predicate> Predicates = [IsARM];
738 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
739 list<Predicate> Predicates = [IsARM, HasV5TE];
741 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
742 list<Predicate> Predicates = [IsARM, HasV6];
745 //===----------------------------------------------------------------------===//
747 // Thumb Instruction Format Definitions.
750 // TI - Thumb instruction.
752 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
753 string asm, string cstr, list<dag> pattern>
754 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
755 let OutOperandList = outs;
756 let InOperandList = ins;
758 let Pattern = pattern;
759 list<Predicate> Predicates = [IsThumb];
762 class TI<dag outs, dag ins, string asm, list<dag> pattern>
763 : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
765 // BL, BLX(1) are translated by assembler into two instructions
766 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
767 : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
769 // BR_JT instructions
770 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
771 : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
773 // TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
774 class TPat<dag pattern, dag result> : Pat<pattern, result> {
775 list<Predicate> Predicates = [IsThumb];
778 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
779 list<Predicate> Predicates = [IsThumb, HasV5T];
783 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
784 string asm, string cstr, list<dag> pattern>
785 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
786 let OutOperandList = outs;
787 let InOperandList = ins;
789 let Pattern = pattern;
790 list<Predicate> Predicates = [IsThumb1Only];
793 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
794 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
795 class T1I1<dag outs, dag ins, string asm, list<dag> pattern>
796 : Thumb1I<outs, ins, AddrModeT1_1, Size2Bytes, asm, "", pattern>;
797 class T1I2<dag outs, dag ins, string asm, list<dag> pattern>
798 : Thumb1I<outs, ins, AddrModeT1_2, Size2Bytes, asm, "", pattern>;
799 class T1I4<dag outs, dag ins, string asm, list<dag> pattern>
800 : Thumb1I<outs, ins, AddrModeT1_4, Size2Bytes, asm, "", pattern>;
801 class T1Is<dag outs, dag ins, string asm, list<dag> pattern>
802 : Thumb1I<outs, ins, AddrModeT1_s, Size2Bytes, asm, "", pattern>;
804 // Two-address instructions
805 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
806 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
808 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
809 list<Predicate> Predicates = [IsThumb1Only];
812 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
813 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
814 string opc, string asm, string cstr, list<dag> pattern>
815 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
816 let OutOperandList = oops;
817 let InOperandList = !con(iops, (ops pred:$p));
818 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
819 let Pattern = pattern;
820 list<Predicate> Predicates = [IsThumb, HasThumb2];
823 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
824 // an input operand since by default it's a zero register. It will
825 // become an implicit def once it's "flipped".
826 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
828 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
829 string opc, string asm, string cstr, list<dag> pattern>
830 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
831 let OutOperandList = oops;
832 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
833 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
834 let Pattern = pattern;
835 list<Predicate> Predicates = [IsThumb, HasThumb2];
839 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
840 string asm, string cstr, list<dag> pattern>
841 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
842 let OutOperandList = oops;
843 let InOperandList = iops;
845 let Pattern = pattern;
846 list<Predicate> Predicates = [IsThumb, HasThumb2];
849 class T2I<dag oops, dag iops, string opc, string asm, list<dag> pattern>
850 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
851 class T2Ii12<dag oops, dag iops, string opc, string asm, list<dag> pattern>
852 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, opc, asm, "", pattern>;
853 class T2Ii8<dag oops, dag iops, string opc, string asm, list<dag> pattern>
854 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, opc, asm, "", pattern>;
855 class T2Iso<dag oops, dag iops, string opc, string asm, list<dag> pattern>
856 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, opc, asm, "", pattern>;
857 class T2Ipc<dag oops, dag iops, string opc, string asm, list<dag> pattern>
858 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, opc, asm, "", pattern>;
860 class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
861 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
863 class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
864 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
866 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
867 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
868 list<Predicate> Predicates = [IsThumb, HasThumb2];
871 //===----------------------------------------------------------------------===//
873 //===----------------------------------------------------------------------===//
874 // ARM VFP Instruction templates.
877 // ARM VFP addrmode5 loads and stores
878 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
879 string opc, string asm, list<dag> pattern>
880 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
881 VFPLdStFrm, opc, asm, "", pattern> {
882 // TODO: Mark the instructions with the appropriate subtarget info.
883 let Inst{27-24} = opcod1;
884 let Inst{21-20} = opcod2;
885 let Inst{11-8} = 0b1011;
888 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
889 string opc, string asm, list<dag> pattern>
890 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
891 VFPLdStFrm, opc, asm, "", pattern> {
892 // TODO: Mark the instructions with the appropriate subtarget info.
893 let Inst{27-24} = opcod1;
894 let Inst{21-20} = opcod2;
895 let Inst{11-8} = 0b1010;
898 // Load / store multiple
899 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
900 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
901 VFPLdStMulFrm, asm, "", pattern> {
902 // TODO: Mark the instructions with the appropriate subtarget info.
903 let Inst{27-25} = 0b110;
904 let Inst{11-8} = 0b1011;
907 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
908 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
909 VFPLdStMulFrm, asm, "", pattern> {
910 // TODO: Mark the instructions with the appropriate subtarget info.
911 let Inst{27-25} = 0b110;
912 let Inst{11-8} = 0b1010;
916 // Double precision, unary
917 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
918 string opc, string asm, list<dag> pattern>
919 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
920 let Inst{27-20} = opcod1;
921 let Inst{19-16} = opcod2;
922 let Inst{11-8} = 0b1011;
923 let Inst{7-4} = opcod3;
926 // Double precision, binary
927 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
928 string asm, list<dag> pattern>
929 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
930 let Inst{27-20} = opcod;
931 let Inst{11-8} = 0b1011;
934 // Single precision, unary
935 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
936 string opc, string asm, list<dag> pattern>
937 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
938 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
939 let Inst{27-20} = opcod1;
940 let Inst{19-16} = opcod2;
941 let Inst{11-8} = 0b1010;
942 let Inst{7-4} = opcod3;
945 // Single precision, binary
946 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
947 string asm, list<dag> pattern>
948 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
949 // Bit 22 (D bit) can be changed during instruction encoding.
950 let Inst{27-20} = opcod;
951 let Inst{11-8} = 0b1010;
954 // VFP conversion instructions
955 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
956 dag oops, dag iops, string opc, string asm, list<dag> pattern>
957 : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
958 let Inst{27-20} = opcod1;
959 let Inst{19-16} = opcod2;
960 let Inst{11-8} = opcod3;
964 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
965 string opc, string asm, list<dag> pattern>
966 : AI<oops, iops, f, opc, asm, pattern> {
967 let Inst{27-20} = opcod1;
968 let Inst{11-8} = opcod2;
972 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
973 string asm, list<dag> pattern>
974 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
976 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
977 string asm, list<dag> pattern>
978 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
980 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
981 string asm, list<dag> pattern>
982 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
984 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
985 string asm, list<dag> pattern>
986 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
988 //===----------------------------------------------------------------------===//
990 //===----------------------------------------------------------------------===//
991 // ARM NEON Instruction templates.
994 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
995 string cstr, list<dag> pattern>
996 : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
997 let OutOperandList = oops;
998 let InOperandList = iops;
1000 let Pattern = pattern;
1001 list<Predicate> Predicates = [HasNEON];
1004 class NI<dag oops, dag iops, string asm, list<dag> pattern>
1005 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
1008 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1009 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
1010 let Inst{31-25} = 0b1111001;
1013 // NEON "one register and a modified immediate" format.
1014 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1016 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1017 : NDataI<oops, iops, asm, cstr, pattern> {
1018 let Inst{23} = op23;
1019 let Inst{21-19} = op21_19;
1020 let Inst{11-8} = op11_8;
1027 // NEON 2 vector register format.
1028 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1029 bits<5> op11_7, bit op6, bit op4,
1030 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1031 : NDataI<oops, iops, asm, cstr, pattern> {
1032 let Inst{24-23} = op24_23;
1033 let Inst{21-20} = op21_20;
1034 let Inst{19-18} = op19_18;
1035 let Inst{17-16} = op17_16;
1036 let Inst{11-7} = op11_7;
1041 // NEON 2 vector register with immediate.
1042 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
1044 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1045 : NDataI<oops, iops, asm, cstr, pattern> {
1046 let Inst{24} = op24;
1047 let Inst{23} = op23;
1048 let Inst{21-16} = op21_16;
1049 let Inst{11-8} = op11_8;
1055 // NEON 3 vector register format.
1056 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1057 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1058 : NDataI<oops, iops, asm, cstr, pattern> {
1059 let Inst{24} = op24;
1060 let Inst{23} = op23;
1061 let Inst{21-20} = op21_20;
1062 let Inst{11-8} = op11_8;
1067 // NEON VMOVs between scalar and core registers.
1068 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1069 dag oops, dag iops, Format f, string opc, string asm,
1071 : AI<oops, iops, f, opc, asm, pattern> {
1072 let Inst{27-20} = opcod1;
1073 let Inst{11-8} = opcod2;
1074 let Inst{6-5} = opcod3;
1076 list<Predicate> Predicates = [HasNEON];
1078 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1079 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1080 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1082 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1083 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1084 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1086 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1087 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1088 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;