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 //===----------------------------------------------------------------------===//
63 // ARM Instruction templates.
66 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
67 Format f, string cstr>
71 let Namespace = "ARM";
75 bits<4> AddrModeBits = AM.Value;
78 bits<3> SizeFlag = SZ.Value;
81 bits<2> IndexModeBits = IM.Value;
84 bits<5> Form = F.Value;
87 // Attributes specific to ARM instructions...
89 bit isUnaryDataProc = 0;
91 let Constraints = cstr;
94 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
95 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
96 let OutOperandList = oops;
97 let InOperandList = iops;
99 let Pattern = pattern;
102 // Almost all ARM instructions are predicable.
103 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
104 IndexMode im, Format f, string opc, string asm, string cstr,
106 : InstARM<am, sz, im, f, cstr> {
107 let OutOperandList = oops;
108 let InOperandList = !con(iops, (ops pred:$p));
109 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
110 let Pattern = pattern;
111 list<Predicate> Predicates = [IsARM];
114 // Same as I except it can optionally modify CPSR. Note it's modeled as
115 // an input operand since by default it's a zero register. It will
116 // become an implicit def once it's "flipped".
117 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
118 IndexMode im, Format f, string opc, string asm, string cstr,
120 : InstARM<am, sz, im, f, cstr> {
121 let OutOperandList = oops;
122 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
123 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
124 let Pattern = pattern;
125 list<Predicate> Predicates = [IsARM];
129 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
130 IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
131 : InstARM<am, sz, im, f, cstr> {
132 let OutOperandList = oops;
133 let InOperandList = iops;
135 let Pattern = pattern;
136 list<Predicate> Predicates = [IsARM];
139 class AI<dag oops, dag iops, Format f, string opc,
140 string asm, list<dag> pattern>
141 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
143 class AsI<dag oops, dag iops, Format f, string opc,
144 string asm, list<dag> pattern>
145 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
147 class AXI<dag oops, dag iops, Format f, string asm,
149 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
152 // Ctrl flow instructions
153 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
154 string asm, list<dag> pattern>
155 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
157 let Inst{27-24} = opcod;
159 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
160 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
162 let Inst{27-24} = opcod;
164 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
165 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
168 // BR_JT instructions
169 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
170 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
173 // addrmode1 instructions
174 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
175 string asm, list<dag> pattern>
176 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
178 let Inst{24-21} = opcod;
179 let Inst{27-26} = {0,0};
181 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
182 string asm, list<dag> pattern>
183 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
185 let Inst{24-21} = opcod;
186 let Inst{27-26} = {0,0};
188 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
190 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
192 let Inst{24-21} = opcod;
193 let Inst{27-26} = {0,0};
195 class AI1x2<dag oops, dag iops, Format f, string opc,
196 string asm, list<dag> pattern>
197 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
201 // addrmode2 loads and stores
202 class AI2<dag oops, dag iops, Format f, string opc,
203 string asm, list<dag> pattern>
204 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
206 let Inst{27-26} = {0,1};
210 class AI2ldw<dag oops, dag iops, Format f, string opc,
211 string asm, list<dag> pattern>
212 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
214 let Inst{20} = 1; // L bit
215 let Inst{21} = 0; // W bit
216 let Inst{22} = 0; // B bit
217 let Inst{24} = 1; // P bit
218 let Inst{27-26} = {0,1};
220 class AXI2ldw<dag oops, dag iops, Format f, string asm,
222 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
224 let Inst{20} = 1; // L bit
225 let Inst{21} = 0; // W bit
226 let Inst{22} = 0; // B bit
227 let Inst{24} = 1; // P bit
228 let Inst{27-26} = {0,1};
230 class AI2ldb<dag oops, dag iops, Format f, string opc,
231 string asm, list<dag> pattern>
232 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
234 let Inst{20} = 1; // L bit
235 let Inst{21} = 0; // W bit
236 let Inst{22} = 1; // B bit
237 let Inst{24} = 1; // P bit
238 let Inst{27-26} = {0,1};
240 class AXI2ldb<dag oops, dag iops, Format f, string asm,
242 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
244 let Inst{20} = 1; // L bit
245 let Inst{21} = 0; // W bit
246 let Inst{22} = 1; // B bit
247 let Inst{24} = 1; // P bit
248 let Inst{27-26} = {0,1};
252 class AI2stw<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} = 0; // 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 AXI2stw<dag oops, dag iops, Format f, string asm,
264 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
266 let Inst{20} = 0; // 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 AI2stb<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} = 0; // 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 AXI2stb<dag oops, dag iops, Format f, string asm,
284 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
286 let Inst{20} = 0; // 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 AI2ldwpr<dag oops, dag iops, Format f, string opc,
295 string asm, string cstr, list<dag> pattern>
296 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
297 asm, cstr, pattern> {
298 let Inst{20} = 1; // L bit
299 let Inst{21} = 1; // 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 AI2ldbpr<dag oops, dag iops, Format f, string opc,
305 string asm, string cstr, list<dag> pattern>
306 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
307 asm, cstr, pattern> {
308 let Inst{20} = 1; // L bit
309 let Inst{21} = 1; // W bit
310 let Inst{22} = 1; // B bit
311 let Inst{24} = 1; // P bit
312 let Inst{27-26} = {0,1};
315 // Pre-indexed stores
316 class AI2stwpr<dag oops, dag iops, Format f, string opc,
317 string asm, string cstr, list<dag> pattern>
318 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
319 asm, cstr, pattern> {
320 let Inst{20} = 0; // L bit
321 let Inst{21} = 1; // W bit
322 let Inst{22} = 0; // B bit
323 let Inst{24} = 1; // P bit
324 let Inst{27-26} = {0,1};
326 class AI2stbpr<dag oops, dag iops, Format f, string opc,
327 string asm, string cstr, list<dag> pattern>
328 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
329 asm, cstr, pattern> {
330 let Inst{20} = 0; // L bit
331 let Inst{21} = 1; // W bit
332 let Inst{22} = 1; // B bit
333 let Inst{24} = 1; // P bit
334 let Inst{27-26} = {0,1};
337 // Post-indexed loads
338 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
339 string asm, string cstr, list<dag> pattern>
340 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
342 let Inst{20} = 1; // L bit
343 let Inst{21} = 0; // W bit
344 let Inst{22} = 0; // B bit
345 let Inst{24} = 0; // P bit
346 let Inst{27-26} = {0,1};
348 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
349 string asm, string cstr, list<dag> pattern>
350 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
352 let Inst{20} = 1; // L bit
353 let Inst{21} = 0; // W bit
354 let Inst{22} = 1; // B bit
355 let Inst{24} = 0; // P bit
356 let Inst{27-26} = {0,1};
359 // Post-indexed stores
360 class AI2stwpo<dag oops, dag iops, Format f, string opc,
361 string asm, string cstr, list<dag> pattern>
362 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
364 let Inst{20} = 0; // L bit
365 let Inst{21} = 0; // W bit
366 let Inst{22} = 0; // B bit
367 let Inst{24} = 0; // P bit
368 let Inst{27-26} = {0,1};
370 class AI2stbpo<dag oops, dag iops, Format f, string opc,
371 string asm, string cstr, list<dag> pattern>
372 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
374 let Inst{20} = 0; // L bit
375 let Inst{21} = 0; // W bit
376 let Inst{22} = 1; // B bit
377 let Inst{24} = 0; // P bit
378 let Inst{27-26} = {0,1};
381 // addrmode3 instructions
382 class AI3<dag oops, dag iops, Format f, string opc,
383 string asm, list<dag> pattern>
384 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
386 class AXI3<dag oops, dag iops, Format f, string asm,
388 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
392 class AI3ldh<dag oops, dag iops, Format f, string opc,
393 string asm, list<dag> pattern>
394 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
397 let Inst{5} = 1; // H bit
398 let Inst{6} = 0; // S bit
400 let Inst{20} = 1; // L bit
401 let Inst{21} = 0; // W bit
402 let Inst{24} = 1; // P bit
404 class AXI3ldh<dag oops, dag iops, Format f, string asm,
406 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
409 let Inst{5} = 1; // H bit
410 let Inst{6} = 0; // S bit
412 let Inst{20} = 1; // L bit
413 let Inst{21} = 0; // W bit
414 let Inst{24} = 1; // P bit
416 class AI3ldsh<dag oops, dag iops, Format f, string opc,
417 string asm, list<dag> pattern>
418 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
421 let Inst{5} = 1; // H bit
422 let Inst{6} = 1; // S bit
424 let Inst{20} = 1; // L bit
425 let Inst{21} = 0; // W bit
426 let Inst{24} = 1; // P bit
428 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
430 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
433 let Inst{5} = 1; // H bit
434 let Inst{6} = 1; // S bit
436 let Inst{20} = 1; // L bit
437 let Inst{21} = 0; // W bit
438 let Inst{24} = 1; // P bit
440 class AI3ldsb<dag oops, dag iops, Format f, string opc,
441 string asm, list<dag> pattern>
442 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
445 let Inst{5} = 0; // H bit
446 let Inst{6} = 1; // S bit
448 let Inst{20} = 1; // L bit
449 let Inst{21} = 0; // W bit
450 let Inst{24} = 1; // P bit
452 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
454 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
457 let Inst{5} = 0; // H bit
458 let Inst{6} = 1; // S bit
460 let Inst{20} = 1; // L bit
461 let Inst{21} = 0; // W bit
462 let Inst{24} = 1; // P bit
464 class AI3ldd<dag oops, dag iops, Format f, string opc,
465 string asm, list<dag> pattern>
466 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
469 let Inst{5} = 0; // H bit
470 let Inst{6} = 1; // S bit
472 let Inst{20} = 0; // L bit
473 let Inst{21} = 0; // W bit
474 let Inst{24} = 1; // P bit
478 class AI3sth<dag oops, dag iops, Format f, string opc,
479 string asm, list<dag> pattern>
480 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
483 let Inst{5} = 1; // H bit
484 let Inst{6} = 0; // S bit
486 let Inst{20} = 0; // L bit
487 let Inst{21} = 0; // W bit
488 let Inst{24} = 1; // P bit
490 class AXI3sth<dag oops, dag iops, Format f, string asm,
492 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
495 let Inst{5} = 1; // H bit
496 let Inst{6} = 0; // S bit
498 let Inst{20} = 0; // L bit
499 let Inst{21} = 0; // W bit
500 let Inst{24} = 1; // P bit
502 class AI3std<dag oops, dag iops, Format f, string opc,
503 string asm, list<dag> pattern>
504 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
507 let Inst{5} = 1; // H bit
508 let Inst{6} = 1; // S bit
510 let Inst{20} = 0; // L bit
511 let Inst{21} = 0; // W bit
512 let Inst{24} = 1; // P bit
516 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
517 string asm, string cstr, list<dag> pattern>
518 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
519 asm, cstr, pattern> {
521 let Inst{5} = 1; // H bit
522 let Inst{6} = 0; // S bit
524 let Inst{20} = 1; // L bit
525 let Inst{21} = 1; // W bit
526 let Inst{24} = 1; // P bit
528 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
529 string asm, string cstr, list<dag> pattern>
530 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
531 asm, cstr, pattern> {
533 let Inst{5} = 1; // H bit
534 let Inst{6} = 1; // S bit
536 let Inst{20} = 1; // L bit
537 let Inst{21} = 1; // W bit
538 let Inst{24} = 1; // P bit
540 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
541 string asm, string cstr, list<dag> pattern>
542 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
543 asm, cstr, pattern> {
545 let Inst{5} = 0; // H bit
546 let Inst{6} = 1; // S bit
548 let Inst{20} = 1; // L bit
549 let Inst{21} = 1; // W bit
550 let Inst{24} = 1; // P bit
553 // Pre-indexed stores
554 class AI3sthpr<dag oops, dag iops, Format f, string opc,
555 string asm, string cstr, list<dag> pattern>
556 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
557 asm, cstr, pattern> {
559 let Inst{5} = 1; // H bit
560 let Inst{6} = 0; // S bit
562 let Inst{20} = 0; // L bit
563 let Inst{21} = 1; // W bit
564 let Inst{24} = 1; // P bit
567 // Post-indexed loads
568 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
569 string asm, string cstr, list<dag> pattern>
570 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
573 let Inst{5} = 1; // H bit
574 let Inst{6} = 0; // S bit
576 let Inst{20} = 1; // L bit
577 let Inst{21} = 1; // W bit
578 let Inst{24} = 0; // P bit
580 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
581 string asm, string cstr, list<dag> pattern>
582 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
585 let Inst{5} = 1; // H bit
586 let Inst{6} = 1; // S bit
588 let Inst{20} = 1; // L bit
589 let Inst{21} = 1; // W bit
590 let Inst{24} = 0; // P bit
592 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
593 string asm, string cstr, list<dag> pattern>
594 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
597 let Inst{5} = 0; // H bit
598 let Inst{6} = 1; // S bit
600 let Inst{20} = 1; // L bit
601 let Inst{21} = 1; // W bit
602 let Inst{24} = 0; // P bit
605 // Post-indexed stores
606 class AI3sthpo<dag oops, dag iops, Format f, string opc,
607 string asm, string cstr, list<dag> pattern>
608 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
611 let Inst{5} = 1; // H bit
612 let Inst{6} = 0; // S bit
614 let Inst{20} = 0; // L bit
615 let Inst{21} = 1; // W bit
616 let Inst{24} = 0; // P bit
620 // addrmode4 instructions
621 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
622 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
624 let Inst{20} = 1; // L bit
625 let Inst{22} = 0; // S bit
626 let Inst{27-25} = 0b100;
628 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
629 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
631 let Inst{20} = 0; // L bit
632 let Inst{22} = 0; // S bit
633 let Inst{27-25} = 0b100;
636 // Unsigned multiply, multiply-accumulate instructions.
637 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
638 string asm, list<dag> pattern>
639 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
641 let Inst{7-4} = 0b1001;
642 let Inst{20} = 0; // S bit
643 let Inst{27-21} = opcod;
645 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
646 string asm, list<dag> pattern>
647 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
649 let Inst{7-4} = 0b1001;
650 let Inst{27-21} = opcod;
653 // Most significant word multiply
654 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
655 string asm, list<dag> pattern>
656 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
658 let Inst{7-4} = 0b1001;
660 let Inst{27-21} = opcod;
663 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
664 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
665 string asm, list<dag> pattern>
666 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
671 let Inst{27-21} = opcod;
674 // Extend instructions.
675 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
676 string asm, list<dag> pattern>
677 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
679 let Inst{7-4} = 0b0111;
680 let Inst{27-20} = opcod;
683 // Misc Arithmetic instructions.
684 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
685 string asm, list<dag> pattern>
686 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
688 let Inst{27-20} = opcod;
691 //===----------------------------------------------------------------------===//
693 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
694 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
695 list<Predicate> Predicates = [IsARM];
697 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
698 list<Predicate> Predicates = [IsARM, HasV5TE];
700 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
701 list<Predicate> Predicates = [IsARM, HasV6];
704 //===----------------------------------------------------------------------===//
706 // Thumb Instruction Format Definitions.
710 // TI - Thumb instruction.
712 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
713 string asm, string cstr, list<dag> pattern>
714 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
715 let OutOperandList = outs;
716 let InOperandList = ins;
718 let Pattern = pattern;
719 list<Predicate> Predicates = [IsThumb];
722 class TI<dag outs, dag ins, string asm, list<dag> pattern>
723 : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
724 class TI1<dag outs, dag ins, string asm, list<dag> pattern>
725 : ThumbI<outs, ins, AddrModeT1, Size2Bytes, asm, "", pattern>;
726 class TI2<dag outs, dag ins, string asm, list<dag> pattern>
727 : ThumbI<outs, ins, AddrModeT2, Size2Bytes, asm, "", pattern>;
728 class TI4<dag outs, dag ins, string asm, list<dag> pattern>
729 : ThumbI<outs, ins, AddrModeT4, Size2Bytes, asm, "", pattern>;
730 class TIs<dag outs, dag ins, string asm, list<dag> pattern>
731 : ThumbI<outs, ins, AddrModeTs, Size2Bytes, asm, "", pattern>;
733 // Two-address instructions
734 class TIt<dag outs, dag ins, string asm, list<dag> pattern>
735 : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
737 // BL, BLX(1) are translated by assembler into two instructions
738 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
739 : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
741 // BR_JT instructions
742 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
743 : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
745 // ThumbPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
746 class ThumbPat<dag pattern, dag result> : Pat<pattern, result> {
747 list<Predicate> Predicates = [IsThumb];
750 class ThumbV5Pat<dag pattern, dag result> : Pat<pattern, result> {
751 list<Predicate> Predicates = [IsThumb, HasV5T];
755 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
756 string asm, string cstr, list<dag> pattern>
757 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
758 let OutOperandList = outs;
759 let InOperandList = ins;
761 let Pattern = pattern;
762 list<Predicate> Predicates = [IsThumb1Only];
765 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
766 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
768 // Two-address instructions
769 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
770 : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
772 class Thumb1Pat<dag pattern, dag result> : Pat<pattern, result> {
773 list<Predicate> Predicates = [IsThumb1Only];
776 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
777 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
778 string opc, string asm, string cstr, list<dag> pattern>
779 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
780 let OutOperandList = oops;
781 let InOperandList = !con(iops, (ops pred:$p));
782 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
783 let Pattern = pattern;
784 list<Predicate> Predicates = [IsThumb, HasThumb2];
787 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
788 // an input operand since by default it's a zero register. It will
789 // become an implicit def once it's "flipped".
790 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
792 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
793 string opc, string asm, string cstr, list<dag> pattern>
794 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
795 let OutOperandList = oops;
796 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
797 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
798 let Pattern = pattern;
799 list<Predicate> Predicates = [IsThumb, HasThumb2];
803 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
804 string asm, string cstr, list<dag> pattern>
805 : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
806 let OutOperandList = oops;
807 let InOperandList = iops;
809 let Pattern = pattern;
810 list<Predicate> Predicates = [IsThumb, HasThumb2];
813 class T2I<dag oops, dag iops, string opc, string asm, list<dag> pattern>
814 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
816 class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
817 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>;
819 class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
820 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
822 // Thumb2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
823 class Thumb2Pat<dag pattern, dag result> : Pat<pattern, result> {
824 list<Predicate> Predicates = [IsThumb, HasThumb2];
827 //===----------------------------------------------------------------------===//
829 //===----------------------------------------------------------------------===//
830 // ARM VFP Instruction templates.
833 // ARM VFP addrmode5 loads and stores
834 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
835 string opc, string asm, list<dag> pattern>
836 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
837 VFPLdStFrm, opc, asm, "", pattern> {
838 // TODO: Mark the instructions with the appropriate subtarget info.
839 let Inst{27-24} = opcod1;
840 let Inst{21-20} = opcod2;
841 let Inst{11-8} = 0b1011;
844 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
845 string opc, string asm, list<dag> pattern>
846 : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
847 VFPLdStFrm, opc, asm, "", pattern> {
848 // TODO: Mark the instructions with the appropriate subtarget info.
849 let Inst{27-24} = opcod1;
850 let Inst{21-20} = opcod2;
851 let Inst{11-8} = 0b1010;
854 // Load / store multiple
855 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
856 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
857 VFPLdStMulFrm, asm, "", pattern> {
858 // TODO: Mark the instructions with the appropriate subtarget info.
859 let Inst{27-25} = 0b110;
860 let Inst{11-8} = 0b1011;
863 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
864 : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
865 VFPLdStMulFrm, asm, "", pattern> {
866 // TODO: Mark the instructions with the appropriate subtarget info.
867 let Inst{27-25} = 0b110;
868 let Inst{11-8} = 0b1010;
872 // Double precision, unary
873 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
874 string opc, string asm, list<dag> pattern>
875 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
876 let Inst{27-20} = opcod1;
877 let Inst{19-16} = opcod2;
878 let Inst{11-8} = 0b1011;
879 let Inst{7-4} = opcod3;
882 // Double precision, binary
883 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
884 string asm, list<dag> pattern>
885 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
886 let Inst{27-20} = opcod;
887 let Inst{11-8} = 0b1011;
890 // Single precision, unary
891 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
892 string opc, string asm, list<dag> pattern>
893 : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
894 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
895 let Inst{27-20} = opcod1;
896 let Inst{19-16} = opcod2;
897 let Inst{11-8} = 0b1010;
898 let Inst{7-4} = opcod3;
901 // Single precision, binary
902 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
903 string asm, list<dag> pattern>
904 : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
905 // Bit 22 (D bit) can be changed during instruction encoding.
906 let Inst{27-20} = opcod;
907 let Inst{11-8} = 0b1010;
910 // VFP conversion instructions
911 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
912 dag oops, dag iops, string opc, string asm, list<dag> pattern>
913 : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
914 let Inst{27-20} = opcod1;
915 let Inst{19-16} = opcod2;
916 let Inst{11-8} = opcod3;
920 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
921 string opc, string asm, list<dag> pattern>
922 : AI<oops, iops, f, opc, asm, pattern> {
923 let Inst{27-20} = opcod1;
924 let Inst{11-8} = opcod2;
928 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
929 string asm, list<dag> pattern>
930 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
932 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
933 string asm, list<dag> pattern>
934 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
936 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
937 string asm, list<dag> pattern>
938 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
940 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
941 string asm, list<dag> pattern>
942 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
944 //===----------------------------------------------------------------------===//
946 //===----------------------------------------------------------------------===//
947 // ARM NEON Instruction templates.
950 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
951 string cstr, list<dag> pattern>
952 : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
953 let OutOperandList = oops;
954 let InOperandList = iops;
956 let Pattern = pattern;
957 list<Predicate> Predicates = [HasNEON];
960 class NI<dag oops, dag iops, string asm, list<dag> pattern>
961 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
964 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
965 : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
966 let Inst{31-25} = 0b1111001;
969 // NEON "one register and a modified immediate" format.
970 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
972 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
973 : NDataI<oops, iops, asm, cstr, pattern> {
975 let Inst{21-19} = op21_19;
976 let Inst{11-8} = op11_8;
983 // NEON 2 vector register format.
984 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
985 bits<5> op11_7, bit op6, bit op4,
986 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
987 : NDataI<oops, iops, asm, cstr, pattern> {
988 let Inst{24-23} = op24_23;
989 let Inst{21-20} = op21_20;
990 let Inst{19-18} = op19_18;
991 let Inst{17-16} = op17_16;
992 let Inst{11-7} = op11_7;
997 // NEON 2 vector register with immediate.
998 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
1000 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1001 : NDataI<oops, iops, asm, cstr, pattern> {
1002 let Inst{24} = op24;
1003 let Inst{23} = op23;
1004 let Inst{21-16} = op21_16;
1005 let Inst{11-8} = op11_8;
1011 // NEON 3 vector register format.
1012 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1013 dag oops, dag iops, string asm, string cstr, list<dag> pattern>
1014 : NDataI<oops, iops, asm, cstr, pattern> {
1015 let Inst{24} = op24;
1016 let Inst{23} = op23;
1017 let Inst{21-20} = op21_20;
1018 let Inst{11-8} = op11_8;
1023 // NEON VMOVs between scalar and core registers.
1024 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1025 dag oops, dag iops, Format f, string opc, string asm,
1027 : AI<oops, iops, f, opc, asm, pattern> {
1028 let Inst{27-20} = opcod1;
1029 let Inst{11-8} = opcod2;
1030 let Inst{6-5} = opcod3;
1032 list<Predicate> Predicates = [HasNEON];
1034 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1035 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1036 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1038 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1039 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1040 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1042 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1043 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1044 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;