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 AddrMode6 : AddrMode<6>;
76 def AddrModeT1_1 : AddrMode<7>;
77 def AddrModeT1_2 : AddrMode<8>;
78 def AddrModeT1_4 : AddrMode<9>;
79 def AddrModeT1_s : AddrMode<10>;
80 def AddrModeT2_i12: AddrMode<12>;
81 def AddrModeT2_i8 : AddrMode<12>;
82 def AddrModeT2_so : AddrMode<13>;
83 def AddrModeT2_pc : AddrMode<14>;
84 def AddrModeT2_i8s4 : AddrMode<15>;
87 class SizeFlagVal<bits<3> val> {
90 def SizeInvalid : SizeFlagVal<0>; // Unset.
91 def SizeSpecial : SizeFlagVal<1>; // Pseudo or special.
92 def Size8Bytes : SizeFlagVal<2>;
93 def Size4Bytes : SizeFlagVal<3>;
94 def Size2Bytes : SizeFlagVal<4>;
96 // Load / store index mode.
97 class IndexMode<bits<2> val> {
100 def IndexModeNone : IndexMode<0>;
101 def IndexModePre : IndexMode<1>;
102 def IndexModePost : IndexMode<2>;
104 //===----------------------------------------------------------------------===//
106 // ARM Instruction templates.
109 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
110 Format f, string cstr>
114 let Namespace = "ARM";
118 bits<4> AddrModeBits = AM.Value;
121 bits<3> SizeFlag = SZ.Value;
124 bits<2> IndexModeBits = IM.Value;
127 bits<5> Form = F.Value;
130 // Attributes specific to ARM instructions...
132 bit isUnaryDataProc = 0;
134 let Constraints = cstr;
137 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
138 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
139 let OutOperandList = oops;
140 let InOperandList = iops;
142 let Pattern = pattern;
145 // Almost all ARM instructions are predicable.
146 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
147 IndexMode im, Format f, string opc, string asm, string cstr,
149 : InstARM<am, sz, im, f, cstr> {
150 let OutOperandList = oops;
151 let InOperandList = !con(iops, (ops pred:$p));
152 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
153 let Pattern = pattern;
154 list<Predicate> Predicates = [IsARM];
157 // Same as I except it can optionally modify CPSR. Note it's modeled as
158 // an input operand since by default it's a zero register. It will
159 // become an implicit def once it's "flipped".
160 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
161 IndexMode im, Format f, string opc, string asm, string cstr,
163 : InstARM<am, sz, im, f, cstr> {
164 let OutOperandList = oops;
165 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
166 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
167 let Pattern = pattern;
168 list<Predicate> Predicates = [IsARM];
172 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
173 IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
174 : InstARM<am, sz, im, f, cstr> {
175 let OutOperandList = oops;
176 let InOperandList = iops;
178 let Pattern = pattern;
179 list<Predicate> Predicates = [IsARM];
182 class AI<dag oops, dag iops, Format f, string opc,
183 string asm, list<dag> pattern>
184 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
186 class AsI<dag oops, dag iops, Format f, string opc,
187 string asm, list<dag> pattern>
188 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
190 class AXI<dag oops, dag iops, Format f, string asm,
192 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
195 // Ctrl flow instructions
196 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
197 string asm, list<dag> pattern>
198 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
200 let Inst{27-24} = opcod;
202 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
203 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
205 let Inst{27-24} = opcod;
207 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
208 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
211 // BR_JT instructions
212 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
213 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
216 // addrmode1 instructions
217 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
218 string asm, list<dag> pattern>
219 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
221 let Inst{24-21} = opcod;
222 let Inst{27-26} = {0,0};
224 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
225 string asm, list<dag> pattern>
226 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
228 let Inst{24-21} = opcod;
229 let Inst{27-26} = {0,0};
231 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
233 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
235 let Inst{24-21} = opcod;
236 let Inst{27-26} = {0,0};
238 class AI1x2<dag oops, dag iops, Format f, string opc,
239 string asm, list<dag> pattern>
240 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
244 // addrmode2 loads and stores
245 class AI2<dag oops, dag iops, Format f, string opc,
246 string asm, list<dag> pattern>
247 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
249 let Inst{27-26} = {0,1};
253 class AI2ldw<dag oops, dag iops, Format f, string opc,
254 string asm, list<dag> pattern>
255 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
257 let Inst{20} = 1; // L bit
258 let Inst{21} = 0; // W bit
259 let Inst{22} = 0; // B bit
260 let Inst{24} = 1; // P bit
261 let Inst{27-26} = {0,1};
263 class AXI2ldw<dag oops, dag iops, Format f, string asm,
265 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
267 let Inst{20} = 1; // L bit
268 let Inst{21} = 0; // W bit
269 let Inst{22} = 0; // B bit
270 let Inst{24} = 1; // P bit
271 let Inst{27-26} = {0,1};
273 class AI2ldb<dag oops, dag iops, Format f, string opc,
274 string asm, list<dag> pattern>
275 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
277 let Inst{20} = 1; // L bit
278 let Inst{21} = 0; // W bit
279 let Inst{22} = 1; // B bit
280 let Inst{24} = 1; // P bit
281 let Inst{27-26} = {0,1};
283 class AXI2ldb<dag oops, dag iops, Format f, string asm,
285 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
287 let Inst{20} = 1; // L bit
288 let Inst{21} = 0; // W bit
289 let Inst{22} = 1; // B bit
290 let Inst{24} = 1; // P bit
291 let Inst{27-26} = {0,1};
295 class AI2stw<dag oops, dag iops, Format f, string opc,
296 string asm, list<dag> pattern>
297 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
299 let Inst{20} = 0; // L bit
300 let Inst{21} = 0; // W bit
301 let Inst{22} = 0; // B bit
302 let Inst{24} = 1; // P bit
303 let Inst{27-26} = {0,1};
305 class AXI2stw<dag oops, dag iops, Format f, string asm,
307 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
309 let Inst{20} = 0; // L bit
310 let Inst{21} = 0; // W bit
311 let Inst{22} = 0; // B bit
312 let Inst{24} = 1; // P bit
313 let Inst{27-26} = {0,1};
315 class AI2stb<dag oops, dag iops, Format f, string opc,
316 string asm, list<dag> pattern>
317 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
319 let Inst{20} = 0; // L bit
320 let Inst{21} = 0; // W bit
321 let Inst{22} = 1; // B bit
322 let Inst{24} = 1; // P bit
323 let Inst{27-26} = {0,1};
325 class AXI2stb<dag oops, dag iops, Format f, string asm,
327 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
329 let Inst{20} = 0; // L bit
330 let Inst{21} = 0; // W bit
331 let Inst{22} = 1; // B bit
332 let Inst{24} = 1; // P bit
333 let Inst{27-26} = {0,1};
337 class AI2ldwpr<dag oops, dag iops, Format f, string opc,
338 string asm, string cstr, list<dag> pattern>
339 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
340 asm, cstr, pattern> {
341 let Inst{20} = 1; // L bit
342 let Inst{21} = 1; // W bit
343 let Inst{22} = 0; // B bit
344 let Inst{24} = 1; // P bit
345 let Inst{27-26} = {0,1};
347 class AI2ldbpr<dag oops, dag iops, Format f, string opc,
348 string asm, string cstr, list<dag> pattern>
349 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
350 asm, cstr, pattern> {
351 let Inst{20} = 1; // L bit
352 let Inst{21} = 1; // W bit
353 let Inst{22} = 1; // B bit
354 let Inst{24} = 1; // P bit
355 let Inst{27-26} = {0,1};
358 // Pre-indexed stores
359 class AI2stwpr<dag oops, dag iops, Format f, string opc,
360 string asm, string cstr, list<dag> pattern>
361 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
362 asm, cstr, pattern> {
363 let Inst{20} = 0; // L bit
364 let Inst{21} = 1; // W bit
365 let Inst{22} = 0; // B bit
366 let Inst{24} = 1; // P bit
367 let Inst{27-26} = {0,1};
369 class AI2stbpr<dag oops, dag iops, Format f, string opc,
370 string asm, string cstr, list<dag> pattern>
371 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
372 asm, cstr, pattern> {
373 let Inst{20} = 0; // L bit
374 let Inst{21} = 1; // W bit
375 let Inst{22} = 1; // B bit
376 let Inst{24} = 1; // P bit
377 let Inst{27-26} = {0,1};
380 // Post-indexed loads
381 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
382 string asm, string cstr, list<dag> pattern>
383 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
385 let Inst{20} = 1; // L bit
386 let Inst{21} = 0; // W bit
387 let Inst{22} = 0; // B bit
388 let Inst{24} = 0; // P bit
389 let Inst{27-26} = {0,1};
391 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
392 string asm, string cstr, list<dag> pattern>
393 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
395 let Inst{20} = 1; // L bit
396 let Inst{21} = 0; // W bit
397 let Inst{22} = 1; // B bit
398 let Inst{24} = 0; // P bit
399 let Inst{27-26} = {0,1};
402 // Post-indexed stores
403 class AI2stwpo<dag oops, dag iops, Format f, string opc,
404 string asm, string cstr, list<dag> pattern>
405 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
407 let Inst{20} = 0; // L bit
408 let Inst{21} = 0; // W bit
409 let Inst{22} = 0; // B bit
410 let Inst{24} = 0; // P bit
411 let Inst{27-26} = {0,1};
413 class AI2stbpo<dag oops, dag iops, Format f, string opc,
414 string asm, string cstr, list<dag> pattern>
415 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
417 let Inst{20} = 0; // L bit
418 let Inst{21} = 0; // W bit
419 let Inst{22} = 1; // B bit
420 let Inst{24} = 0; // P bit
421 let Inst{27-26} = {0,1};
424 // addrmode3 instructions
425 class AI3<dag oops, dag iops, Format f, string opc,
426 string asm, list<dag> pattern>
427 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
429 class AXI3<dag oops, dag iops, Format f, string asm,
431 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
435 class AI3ldh<dag oops, dag iops, Format f, string opc,
436 string asm, list<dag> pattern>
437 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
440 let Inst{5} = 1; // H bit
441 let Inst{6} = 0; // S bit
443 let Inst{20} = 1; // L bit
444 let Inst{21} = 0; // W bit
445 let Inst{24} = 1; // P bit
447 class AXI3ldh<dag oops, dag iops, Format f, string asm,
449 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
452 let Inst{5} = 1; // H bit
453 let Inst{6} = 0; // S bit
455 let Inst{20} = 1; // L bit
456 let Inst{21} = 0; // W bit
457 let Inst{24} = 1; // P bit
459 class AI3ldsh<dag oops, dag iops, Format f, string opc,
460 string asm, list<dag> pattern>
461 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
464 let Inst{5} = 1; // H bit
465 let Inst{6} = 1; // S bit
467 let Inst{20} = 1; // L bit
468 let Inst{21} = 0; // W bit
469 let Inst{24} = 1; // P bit
471 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
473 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
476 let Inst{5} = 1; // H bit
477 let Inst{6} = 1; // S bit
479 let Inst{20} = 1; // L bit
480 let Inst{21} = 0; // W bit
481 let Inst{24} = 1; // P bit
483 class AI3ldsb<dag oops, dag iops, Format f, string opc,
484 string asm, list<dag> pattern>
485 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
488 let Inst{5} = 0; // H bit
489 let Inst{6} = 1; // S bit
491 let Inst{20} = 1; // L bit
492 let Inst{21} = 0; // W bit
493 let Inst{24} = 1; // P bit
495 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
497 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
500 let Inst{5} = 0; // H bit
501 let Inst{6} = 1; // S bit
503 let Inst{20} = 1; // L bit
504 let Inst{21} = 0; // W bit
505 let Inst{24} = 1; // P bit
507 class AI3ldd<dag oops, dag iops, Format f, string opc,
508 string asm, list<dag> pattern>
509 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
512 let Inst{5} = 0; // H bit
513 let Inst{6} = 1; // S bit
515 let Inst{20} = 0; // L bit
516 let Inst{21} = 0; // W bit
517 let Inst{24} = 1; // P bit
521 class AI3sth<dag oops, dag iops, Format f, string opc,
522 string asm, list<dag> pattern>
523 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
526 let Inst{5} = 1; // H bit
527 let Inst{6} = 0; // S bit
529 let Inst{20} = 0; // L bit
530 let Inst{21} = 0; // W bit
531 let Inst{24} = 1; // P bit
533 class AXI3sth<dag oops, dag iops, Format f, string asm,
535 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
538 let Inst{5} = 1; // H bit
539 let Inst{6} = 0; // S bit
541 let Inst{20} = 0; // L bit
542 let Inst{21} = 0; // W bit
543 let Inst{24} = 1; // P bit
545 class AI3std<dag oops, dag iops, Format f, string opc,
546 string asm, list<dag> pattern>
547 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
550 let Inst{5} = 1; // H bit
551 let Inst{6} = 1; // S bit
553 let Inst{20} = 0; // L bit
554 let Inst{21} = 0; // W bit
555 let Inst{24} = 1; // P bit
559 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
560 string asm, string cstr, list<dag> pattern>
561 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
562 asm, cstr, pattern> {
564 let Inst{5} = 1; // H bit
565 let Inst{6} = 0; // S bit
567 let Inst{20} = 1; // L bit
568 let Inst{21} = 1; // W bit
569 let Inst{24} = 1; // P bit
571 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
572 string asm, string cstr, list<dag> pattern>
573 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
574 asm, cstr, pattern> {
576 let Inst{5} = 1; // H bit
577 let Inst{6} = 1; // S bit
579 let Inst{20} = 1; // L bit
580 let Inst{21} = 1; // W bit
581 let Inst{24} = 1; // P bit
583 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
584 string asm, string cstr, list<dag> pattern>
585 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
586 asm, cstr, pattern> {
588 let Inst{5} = 0; // H bit
589 let Inst{6} = 1; // S bit
591 let Inst{20} = 1; // L bit
592 let Inst{21} = 1; // W bit
593 let Inst{24} = 1; // P bit
596 // Pre-indexed stores
597 class AI3sthpr<dag oops, dag iops, Format f, string opc,
598 string asm, string cstr, list<dag> pattern>
599 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
600 asm, cstr, pattern> {
602 let Inst{5} = 1; // H bit
603 let Inst{6} = 0; // S bit
605 let Inst{20} = 0; // L bit
606 let Inst{21} = 1; // W bit
607 let Inst{24} = 1; // P bit
610 // Post-indexed loads
611 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
612 string asm, string cstr, list<dag> pattern>
613 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
616 let Inst{5} = 1; // H bit
617 let Inst{6} = 0; // S bit
619 let Inst{20} = 1; // L bit
620 let Inst{21} = 1; // W bit
621 let Inst{24} = 0; // P bit
623 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
624 string asm, string cstr, list<dag> pattern>
625 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
628 let Inst{5} = 1; // H bit
629 let Inst{6} = 1; // S bit
631 let Inst{20} = 1; // L bit
632 let Inst{21} = 1; // W bit
633 let Inst{24} = 0; // P bit
635 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
636 string asm, string cstr, list<dag> pattern>
637 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
640 let Inst{5} = 0; // H bit
641 let Inst{6} = 1; // S bit
643 let Inst{20} = 1; // L bit
644 let Inst{21} = 1; // W bit
645 let Inst{24} = 0; // P bit
648 // Post-indexed stores
649 class AI3sthpo<dag oops, dag iops, Format f, string opc,
650 string asm, string cstr, list<dag> pattern>
651 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
654 let Inst{5} = 1; // H bit
655 let Inst{6} = 0; // S bit
657 let Inst{20} = 0; // L bit
658 let Inst{21} = 1; // W bit
659 let Inst{24} = 0; // P bit
663 // addrmode4 instructions
664 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
665 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
667 let Inst{20} = 1; // L bit
668 let Inst{22} = 0; // S bit
669 let Inst{27-25} = 0b100;
671 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
672 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
674 let Inst{20} = 0; // L bit
675 let Inst{22} = 0; // S bit
676 let Inst{27-25} = 0b100;
679 // Unsigned multiply, multiply-accumulate instructions.
680 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
681 string asm, list<dag> pattern>
682 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
684 let Inst{7-4} = 0b1001;
685 let Inst{20} = 0; // S bit
686 let Inst{27-21} = opcod;
688 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
689 string asm, list<dag> pattern>
690 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
692 let Inst{7-4} = 0b1001;
693 let Inst{27-21} = opcod;
696 // Most significant word multiply
697 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
698 string asm, list<dag> pattern>
699 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
701 let Inst{7-4} = 0b1001;
703 let Inst{27-21} = opcod;
706 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
707 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
708 string asm, list<dag> pattern>
709 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
714 let Inst{27-21} = opcod;
717 // Extend instructions.
718 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
719 string asm, list<dag> pattern>
720 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
722 let Inst{7-4} = 0b0111;
723 let Inst{27-20} = opcod;
726 // Misc Arithmetic instructions.
727 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
728 string asm, list<dag> pattern>
729 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
731 let Inst{27-20} = opcod;
734 //===----------------------------------------------------------------------===//
736 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
737 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
738 list<Predicate> Predicates = [IsARM];
740 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
741 list<Predicate> Predicates = [IsARM, HasV5TE];
743 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
744 list<Predicate> Predicates = [IsARM, HasV6];
747 //===----------------------------------------------------------------------===//
749 // Thumb Instruction Format Definitions.
752 // TI - Thumb instruction.
754 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
755 string asm, string cstr, list<dag> pattern>
756 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
757 let OutOperandList = outs;
758 let InOperandList = ins;
760 let Pattern = pattern;
761 list<Predicate> Predicates = [IsThumb];
764 class TI<dag outs, dag ins, string asm, list<dag> pattern>
765 : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
767 // BL, BLX(1) are translated by assembler into two instructions
768 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
769 : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
771 // BR_JT instructions
772 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
773 : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
775 // TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
776 class TPat<dag pattern, dag result> : Pat<pattern, result> {
777 list<Predicate> Predicates = [IsThumb];
780 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
781 list<Predicate> Predicates = [IsThumb, HasV5T];
785 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
786 string asm, string cstr, list<dag> pattern>
787 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
788 let OutOperandList = outs;
789 let InOperandList = ins;
791 let Pattern = pattern;
792 list<Predicate> Predicates = [IsThumb1Only];
795 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
796 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
797 class T1I1<dag outs, dag ins, string asm, list<dag> pattern>
798 : Thumb1I<outs, ins, AddrModeT1_1, Size2Bytes, asm, "", pattern>;
799 class T1I2<dag outs, dag ins, string asm, list<dag> pattern>
800 : Thumb1I<outs, ins, AddrModeT1_2, Size2Bytes, asm, "", pattern>;
801 class T1I4<dag outs, dag ins, string asm, list<dag> pattern>
802 : Thumb1I<outs, ins, AddrModeT1_4, Size2Bytes, asm, "", pattern>;
803 class T1Is<dag outs, dag ins, string asm, list<dag> pattern>
804 : Thumb1I<outs, ins, AddrModeT1_s, Size2Bytes, asm, "", pattern>;
805 class T1Ix2<dag outs, dag ins, string asm, list<dag> pattern>
806 : Thumb1I<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
807 class T1JTI<dag outs, dag ins, string asm, list<dag> pattern>
808 : Thumb1I<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
810 // Two-address instructions
811 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
812 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
814 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
815 list<Predicate> Predicates = [IsThumb1Only];
818 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
819 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
820 string opc, string asm, string cstr, list<dag> pattern>
821 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
822 let OutOperandList = oops;
823 let InOperandList = !con(iops, (ops pred:$p));
824 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
825 let Pattern = pattern;
826 list<Predicate> Predicates = [IsThumb2];
829 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
830 // an input operand since by default it's a zero register. It will
831 // become an implicit def once it's "flipped".
832 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
834 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
835 string opc, string asm, string cstr, list<dag> pattern>
836 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
837 let OutOperandList = oops;
838 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
839 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
840 let Pattern = pattern;
841 list<Predicate> Predicates = [IsThumb2];
845 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
846 string asm, string cstr, list<dag> pattern>
847 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
848 let OutOperandList = oops;
849 let InOperandList = iops;
851 let Pattern = pattern;
852 list<Predicate> Predicates = [IsThumb2];
855 class T2I<dag oops, dag iops, string opc, string asm, list<dag> pattern>
856 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
857 class T2Ii12<dag oops, dag iops, string opc, string asm, list<dag> pattern>
858 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, opc, asm, "", pattern>;
859 class T2Ii8<dag oops, dag iops, string opc, string asm, list<dag> pattern>
860 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, opc, asm, "", pattern>;
861 class T2Iso<dag oops, dag iops, string opc, string asm, list<dag> pattern>
862 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, opc, asm, "", pattern>;
863 class T2Ipc<dag oops, dag iops, string opc, string asm, list<dag> pattern>
864 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, opc, asm, "", pattern>;
865 class T2Ii8s4<dag oops, dag iops, string opc, string asm, list<dag> pattern>
866 : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, opc, asm, "", pattern>;
868 class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
869 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
871 class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
872 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
873 class T2JTI<dag oops, dag iops, string asm, list<dag> pattern>
874 : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, asm, "", pattern>;
876 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
877 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
878 list<Predicate> Predicates = [IsThumb2];
881 //===----------------------------------------------------------------------===//
883 //===----------------------------------------------------------------------===//
884 // ARM VFP Instruction templates.
887 // ARM VFP addrmode5 loads and stores
888 class ADI5<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} = 0b1011;
898 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
899 string opc, string asm, list<dag> pattern>
900 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
901 VFPLdStFrm, opc, asm, "", pattern> {
902 // TODO: Mark the instructions with the appropriate subtarget info.
903 let Inst{27-24} = opcod1;
904 let Inst{21-20} = opcod2;
905 let Inst{11-8} = 0b1010;
908 // Load / store multiple
909 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
910 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
911 VFPLdStMulFrm, asm, "", pattern> {
912 // TODO: Mark the instructions with the appropriate subtarget info.
913 let Inst{27-25} = 0b110;
914 let Inst{11-8} = 0b1011;
917 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
918 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
919 VFPLdStMulFrm, asm, "", pattern> {
920 // TODO: Mark the instructions with the appropriate subtarget info.
921 let Inst{27-25} = 0b110;
922 let Inst{11-8} = 0b1010;
926 // Double precision, unary
927 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
928 string opc, string asm, list<dag> pattern>
929 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
930 let Inst{27-20} = opcod1;
931 let Inst{19-16} = opcod2;
932 let Inst{11-8} = 0b1011;
933 let Inst{7-4} = opcod3;
936 // Double precision, binary
937 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
938 string asm, list<dag> pattern>
939 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
940 let Inst{27-20} = opcod;
941 let Inst{11-8} = 0b1011;
944 // Single precision, unary
945 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
946 string opc, string asm, list<dag> pattern>
947 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
948 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
949 let Inst{27-20} = opcod1;
950 let Inst{19-16} = opcod2;
951 let Inst{11-8} = 0b1010;
952 let Inst{7-4} = opcod3;
955 // Single precision, binary
956 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
957 string asm, list<dag> pattern>
958 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
959 // Bit 22 (D bit) can be changed during instruction encoding.
960 let Inst{27-20} = opcod;
961 let Inst{11-8} = 0b1010;
964 // VFP conversion instructions
965 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
966 dag oops, dag iops, string opc, string asm, list<dag> pattern>
967 : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
968 let Inst{27-20} = opcod1;
969 let Inst{19-16} = opcod2;
970 let Inst{11-8} = opcod3;
974 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
975 string opc, string asm, list<dag> pattern>
976 : AI<oops, iops, f, opc, asm, pattern> {
977 let Inst{27-20} = opcod1;
978 let Inst{11-8} = opcod2;
982 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
983 string asm, list<dag> pattern>
984 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
986 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
987 string asm, list<dag> pattern>
988 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
990 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
991 string asm, list<dag> pattern>
992 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
994 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
995 string asm, list<dag> pattern>
996 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
998 //===----------------------------------------------------------------------===//
1000 //===----------------------------------------------------------------------===//
1001 // ARM NEON Instruction templates.
1004 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
1005 string cstr, list<dag> pattern>
1006 : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
1007 let OutOperandList = oops;
1008 let InOperandList = iops;
1009 let AsmString = asm;
1010 let Pattern = pattern;
1011 list<Predicate> Predicates = [HasNEON];
1014 class NI<dag oops, dag iops, string asm, list<dag> pattern>
1015 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
1018 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1019 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
1020 let Inst{31-25} = 0b1111001;
1023 // NEON "one register and a modified immediate" format.
1024 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1026 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1027 : NDataI<oops, iops, asm, cstr, pattern> {
1028 let Inst{23} = op23;
1029 let Inst{21-19} = op21_19;
1030 let Inst{11-8} = op11_8;
1037 // NEON 2 vector register format.
1038 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1039 bits<5> op11_7, bit op6, bit op4,
1040 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1041 : NDataI<oops, iops, asm, cstr, pattern> {
1042 let Inst{24-23} = op24_23;
1043 let Inst{21-20} = op21_20;
1044 let Inst{19-18} = op19_18;
1045 let Inst{17-16} = op17_16;
1046 let Inst{11-7} = op11_7;
1051 // NEON 2 vector register with immediate.
1052 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
1054 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1055 : NDataI<oops, iops, asm, cstr, pattern> {
1056 let Inst{24} = op24;
1057 let Inst{23} = op23;
1058 let Inst{21-16} = op21_16;
1059 let Inst{11-8} = op11_8;
1065 // NEON 3 vector register format.
1066 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1067 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1068 : NDataI<oops, iops, asm, cstr, pattern> {
1069 let Inst{24} = op24;
1070 let Inst{23} = op23;
1071 let Inst{21-20} = op21_20;
1072 let Inst{11-8} = op11_8;
1077 // NEON VMOVs between scalar and core registers.
1078 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1079 dag oops, dag iops, Format f, string opc, string asm,
1081 : AI<oops, iops, f, opc, asm, pattern> {
1082 let Inst{27-20} = opcod1;
1083 let Inst{11-8} = opcod2;
1084 let Inst{6-5} = opcod3;
1086 list<Predicate> Predicates = [HasNEON];
1088 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1089 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1090 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1092 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1093 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1094 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1096 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1097 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1098 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;