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 LdStExFrm : Format<28>;
38 def ArithMiscFrm : Format<11>;
39 def ExtFrm : Format<12>;
41 def VFPUnaryFrm : Format<13>;
42 def VFPBinaryFrm : Format<14>;
43 def VFPConv1Frm : Format<15>;
44 def VFPConv2Frm : Format<16>;
45 def VFPConv3Frm : Format<17>;
46 def VFPConv4Frm : Format<18>;
47 def VFPConv5Frm : Format<19>;
48 def VFPLdStFrm : Format<20>;
49 def VFPLdStMulFrm : Format<21>;
50 def VFPMiscFrm : Format<22>;
52 def ThumbFrm : Format<23>;
54 def NEONFrm : Format<24>;
55 def NEONGetLnFrm : Format<25>;
56 def NEONSetLnFrm : Format<26>;
57 def NEONDupFrm : Format<27>;
61 // the instruction has a Rn register operand.
62 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
63 // it doesn't have a Rn operand.
64 class UnaryDP { bit isUnaryDataProc = 1; }
66 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
67 // a 16-bit Thumb instruction if certain conditions are met.
68 class Xform16Bit { bit canXformTo16Bit = 1; }
70 //===----------------------------------------------------------------------===//
71 // ARM Instruction flags. These need to match ARMInstrInfo.h.
75 class AddrMode<bits<4> val> {
78 def AddrModeNone : AddrMode<0>;
79 def AddrMode1 : AddrMode<1>;
80 def AddrMode2 : AddrMode<2>;
81 def AddrMode3 : AddrMode<3>;
82 def AddrMode4 : AddrMode<4>;
83 def AddrMode5 : AddrMode<5>;
84 def AddrMode6 : AddrMode<6>;
85 def AddrModeT1_1 : AddrMode<7>;
86 def AddrModeT1_2 : AddrMode<8>;
87 def AddrModeT1_4 : AddrMode<9>;
88 def AddrModeT1_s : AddrMode<10>;
89 def AddrModeT2_i12: AddrMode<11>;
90 def AddrModeT2_i8 : AddrMode<12>;
91 def AddrModeT2_so : AddrMode<13>;
92 def AddrModeT2_pc : AddrMode<14>;
93 def AddrModeT2_i8s4 : AddrMode<15>;
96 class SizeFlagVal<bits<3> val> {
99 def SizeInvalid : SizeFlagVal<0>; // Unset.
100 def SizeSpecial : SizeFlagVal<1>; // Pseudo or special.
101 def Size8Bytes : SizeFlagVal<2>;
102 def Size4Bytes : SizeFlagVal<3>;
103 def Size2Bytes : SizeFlagVal<4>;
105 // Load / store index mode.
106 class IndexMode<bits<2> val> {
109 def IndexModeNone : IndexMode<0>;
110 def IndexModePre : IndexMode<1>;
111 def IndexModePost : IndexMode<2>;
113 // Instruction execution domain.
114 class Domain<bits<2> val> {
117 def GenericDomain : Domain<0>;
118 def VFPDomain : Domain<1>; // Instructions in VFP domain only
119 def NeonDomain : Domain<2>; // Instructions in Neon domain only
120 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
122 //===----------------------------------------------------------------------===//
124 // ARM special operands.
127 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
128 // register whose default is 0 (no register).
129 def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
130 (ops (i32 14), (i32 zero_reg))> {
131 let PrintMethod = "printPredicateOperand";
134 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
135 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
136 let PrintMethod = "printSBitModifierOperand";
139 // Same as cc_out except it defaults to setting CPSR.
140 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
141 let PrintMethod = "printSBitModifierOperand";
144 //===----------------------------------------------------------------------===//
146 // ARM Instruction templates.
149 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
150 Format f, Domain d, string cstr, InstrItinClass itin>
154 let Namespace = "ARM";
158 bits<4> AddrModeBits = AM.Value;
161 bits<3> SizeFlag = SZ.Value;
164 bits<2> IndexModeBits = IM.Value;
167 bits<5> Form = F.Value;
170 bits<2> Dom = D.Value;
173 // Attributes specific to ARM instructions...
175 bit isUnaryDataProc = 0;
176 bit canXformTo16Bit = 0;
178 let Constraints = cstr;
179 let Itinerary = itin;
182 class PseudoInst<dag oops, dag iops, InstrItinClass itin,
183 string asm, list<dag> pattern>
184 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, GenericDomain,
186 let OutOperandList = oops;
187 let InOperandList = iops;
189 let Pattern = pattern;
192 // Almost all ARM instructions are predicable.
193 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
194 IndexMode im, Format f, InstrItinClass itin,
195 string opc, string asm, string cstr,
197 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
198 let OutOperandList = oops;
199 let InOperandList = !con(iops, (ops pred:$p));
200 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
201 let Pattern = pattern;
202 list<Predicate> Predicates = [IsARM];
204 // A few are not predicable
205 class InoP<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
206 IndexMode im, Format f, InstrItinClass itin,
207 string opc, string asm, string cstr,
209 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
210 let OutOperandList = oops;
211 let InOperandList = iops;
212 let AsmString = !strconcat(opc, asm);
213 let Pattern = pattern;
214 let isPredicable = 0;
215 list<Predicate> Predicates = [IsARM];
218 // Same as I except it can optionally modify CPSR. Note it's modeled as
219 // an input operand since by default it's a zero register. It will
220 // become an implicit def once it's "flipped".
221 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
222 IndexMode im, Format f, InstrItinClass itin,
223 string opc, string asm, string cstr,
225 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
226 let OutOperandList = oops;
227 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
228 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
229 let Pattern = pattern;
230 list<Predicate> Predicates = [IsARM];
234 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
235 IndexMode im, Format f, InstrItinClass itin,
236 string asm, string cstr, list<dag> pattern>
237 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
238 let OutOperandList = oops;
239 let InOperandList = iops;
241 let Pattern = pattern;
242 list<Predicate> Predicates = [IsARM];
245 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
246 string opc, string asm, list<dag> pattern>
247 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
248 opc, asm, "", pattern>;
249 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
250 string opc, string asm, list<dag> pattern>
251 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
252 opc, asm, "", pattern>;
253 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
254 string asm, list<dag> pattern>
255 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
257 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
258 string opc, string asm, list<dag> pattern>
259 : InoP<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
260 opc, asm, "", pattern>;
262 // Ctrl flow instructions
263 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
264 string opc, string asm, list<dag> pattern>
265 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
266 opc, asm, "", pattern> {
267 let Inst{27-24} = opcod;
269 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
270 string asm, list<dag> pattern>
271 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
273 let Inst{27-24} = opcod;
275 class ABXIx2<dag oops, dag iops, InstrItinClass itin,
276 string asm, list<dag> pattern>
277 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, itin,
280 // BR_JT instructions
281 class JTI<dag oops, dag iops, InstrItinClass itin,
282 string asm, list<dag> pattern>
283 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm, itin,
287 // Atomic load/store instructions
289 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
290 string opc, string asm, list<dag> pattern>
291 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
292 opc, asm, "", pattern> {
293 let Inst{27-23} = 0b00011;
294 let Inst{22-21} = opcod;
296 let Inst{11-0} = 0b111110011111;
298 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
299 string opc, string asm, list<dag> pattern>
300 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
301 opc, asm, "", pattern> {
302 let Inst{27-23} = 0b00011;
303 let Inst{22-21} = opcod;
305 let Inst{11-4} = 0b11111001;
308 // addrmode1 instructions
309 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
310 string opc, string asm, list<dag> pattern>
311 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
312 opc, asm, "", pattern> {
313 let Inst{24-21} = opcod;
314 let Inst{27-26} = {0,0};
316 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
317 string opc, string asm, list<dag> pattern>
318 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
319 opc, asm, "", pattern> {
320 let Inst{24-21} = opcod;
321 let Inst{27-26} = {0,0};
323 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
324 string asm, list<dag> pattern>
325 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
327 let Inst{24-21} = opcod;
328 let Inst{27-26} = {0,0};
330 class AI1x2<dag oops, dag iops, Format f, InstrItinClass itin,
331 string opc, string asm, list<dag> pattern>
332 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, itin,
333 opc, asm, "", pattern>;
336 // addrmode2 loads and stores
337 class AI2<dag oops, dag iops, Format f, InstrItinClass itin,
338 string opc, string asm, list<dag> pattern>
339 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
340 opc, asm, "", pattern> {
341 let Inst{27-26} = {0,1};
345 class AI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
346 string opc, string asm, list<dag> pattern>
347 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
348 opc, asm, "", pattern> {
349 let Inst{20} = 1; // L bit
350 let Inst{21} = 0; // W bit
351 let Inst{22} = 0; // B bit
352 let Inst{24} = 1; // P bit
353 let Inst{27-26} = {0,1};
355 class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
356 string asm, list<dag> pattern>
357 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
359 let Inst{20} = 1; // L bit
360 let Inst{21} = 0; // W bit
361 let Inst{22} = 0; // B bit
362 let Inst{24} = 1; // P bit
363 let Inst{27-26} = {0,1};
365 class AI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
366 string opc, string asm, list<dag> pattern>
367 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
368 opc, asm, "", pattern> {
369 let Inst{20} = 1; // L bit
370 let Inst{21} = 0; // W bit
371 let Inst{22} = 1; // B bit
372 let Inst{24} = 1; // P bit
373 let Inst{27-26} = {0,1};
375 class AXI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
376 string asm, list<dag> pattern>
377 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
379 let Inst{20} = 1; // L bit
380 let Inst{21} = 0; // W bit
381 let Inst{22} = 1; // B bit
382 let Inst{24} = 1; // P bit
383 let Inst{27-26} = {0,1};
387 class AI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
388 string opc, string asm, list<dag> pattern>
389 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
390 opc, asm, "", pattern> {
391 let Inst{20} = 0; // L bit
392 let Inst{21} = 0; // W bit
393 let Inst{22} = 0; // B bit
394 let Inst{24} = 1; // P bit
395 let Inst{27-26} = {0,1};
397 class AXI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
398 string asm, list<dag> pattern>
399 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
401 let Inst{20} = 0; // L bit
402 let Inst{21} = 0; // W bit
403 let Inst{22} = 0; // B bit
404 let Inst{24} = 1; // P bit
405 let Inst{27-26} = {0,1};
407 class AI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
408 string opc, string asm, list<dag> pattern>
409 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
410 opc, asm, "", pattern> {
411 let Inst{20} = 0; // L bit
412 let Inst{21} = 0; // W bit
413 let Inst{22} = 1; // B bit
414 let Inst{24} = 1; // P bit
415 let Inst{27-26} = {0,1};
417 class AXI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
418 string asm, list<dag> pattern>
419 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
421 let Inst{20} = 0; // L bit
422 let Inst{21} = 0; // W bit
423 let Inst{22} = 1; // B bit
424 let Inst{24} = 1; // P bit
425 let Inst{27-26} = {0,1};
429 class AI2ldwpr<dag oops, dag iops, Format f, InstrItinClass itin,
430 string opc, string asm, string cstr, list<dag> pattern>
431 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
432 opc, asm, cstr, pattern> {
433 let Inst{20} = 1; // L bit
434 let Inst{21} = 1; // W bit
435 let Inst{22} = 0; // B bit
436 let Inst{24} = 1; // P bit
437 let Inst{27-26} = {0,1};
439 class AI2ldbpr<dag oops, dag iops, Format f, InstrItinClass itin,
440 string opc, string asm, string cstr, list<dag> pattern>
441 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
442 opc, asm, cstr, pattern> {
443 let Inst{20} = 1; // L bit
444 let Inst{21} = 1; // W bit
445 let Inst{22} = 1; // B bit
446 let Inst{24} = 1; // P bit
447 let Inst{27-26} = {0,1};
450 // Pre-indexed stores
451 class AI2stwpr<dag oops, dag iops, Format f, InstrItinClass itin,
452 string opc, string asm, string cstr, list<dag> pattern>
453 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
454 opc, asm, cstr, pattern> {
455 let Inst{20} = 0; // L bit
456 let Inst{21} = 1; // W bit
457 let Inst{22} = 0; // B bit
458 let Inst{24} = 1; // P bit
459 let Inst{27-26} = {0,1};
461 class AI2stbpr<dag oops, dag iops, Format f, InstrItinClass itin,
462 string opc, string asm, string cstr, list<dag> pattern>
463 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
464 opc, asm, cstr, pattern> {
465 let Inst{20} = 0; // L bit
466 let Inst{21} = 1; // W bit
467 let Inst{22} = 1; // B bit
468 let Inst{24} = 1; // P bit
469 let Inst{27-26} = {0,1};
472 // Post-indexed loads
473 class AI2ldwpo<dag oops, dag iops, Format f, InstrItinClass itin,
474 string opc, string asm, string cstr, list<dag> pattern>
475 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
476 opc, asm, cstr,pattern> {
477 let Inst{20} = 1; // L bit
478 let Inst{21} = 0; // W bit
479 let Inst{22} = 0; // B bit
480 let Inst{24} = 0; // P bit
481 let Inst{27-26} = {0,1};
483 class AI2ldbpo<dag oops, dag iops, Format f, InstrItinClass itin,
484 string opc, string asm, string cstr, list<dag> pattern>
485 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
486 opc, asm, cstr,pattern> {
487 let Inst{20} = 1; // L bit
488 let Inst{21} = 0; // W bit
489 let Inst{22} = 1; // B bit
490 let Inst{24} = 0; // P bit
491 let Inst{27-26} = {0,1};
494 // Post-indexed stores
495 class AI2stwpo<dag oops, dag iops, Format f, InstrItinClass itin,
496 string opc, string asm, string cstr, list<dag> pattern>
497 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
498 opc, asm, cstr,pattern> {
499 let Inst{20} = 0; // L bit
500 let Inst{21} = 0; // W bit
501 let Inst{22} = 0; // B bit
502 let Inst{24} = 0; // P bit
503 let Inst{27-26} = {0,1};
505 class AI2stbpo<dag oops, dag iops, Format f, InstrItinClass itin,
506 string opc, string asm, string cstr, list<dag> pattern>
507 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
508 opc, asm, cstr,pattern> {
509 let Inst{20} = 0; // L bit
510 let Inst{21} = 0; // W bit
511 let Inst{22} = 1; // B bit
512 let Inst{24} = 0; // P bit
513 let Inst{27-26} = {0,1};
516 // addrmode3 instructions
517 class AI3<dag oops, dag iops, Format f, InstrItinClass itin,
518 string opc, string asm, list<dag> pattern>
519 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
520 opc, asm, "", pattern>;
521 class AXI3<dag oops, dag iops, Format f, InstrItinClass itin,
522 string asm, list<dag> pattern>
523 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
527 class AI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
528 string opc, string asm, list<dag> pattern>
529 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
530 opc, asm, "", pattern> {
532 let Inst{5} = 1; // H bit
533 let Inst{6} = 0; // S bit
535 let Inst{20} = 1; // L bit
536 let Inst{21} = 0; // W bit
537 let Inst{24} = 1; // P bit
538 let Inst{27-25} = 0b000;
540 class AXI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
541 string asm, list<dag> pattern>
542 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
545 let Inst{5} = 1; // H bit
546 let Inst{6} = 0; // S bit
548 let Inst{20} = 1; // L bit
549 let Inst{21} = 0; // W bit
550 let Inst{24} = 1; // P bit
552 class AI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
553 string opc, string asm, list<dag> pattern>
554 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
555 opc, asm, "", pattern> {
557 let Inst{5} = 1; // H bit
558 let Inst{6} = 1; // S bit
560 let Inst{20} = 1; // L bit
561 let Inst{21} = 0; // W bit
562 let Inst{24} = 1; // P bit
563 let Inst{27-25} = 0b000;
565 class AXI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
566 string asm, list<dag> pattern>
567 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
570 let Inst{5} = 1; // H bit
571 let Inst{6} = 1; // S bit
573 let Inst{20} = 1; // L bit
574 let Inst{21} = 0; // W bit
575 let Inst{24} = 1; // P bit
577 class AI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
578 string opc, string asm, list<dag> pattern>
579 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
580 opc, asm, "", pattern> {
582 let Inst{5} = 0; // H bit
583 let Inst{6} = 1; // S bit
585 let Inst{20} = 1; // L bit
586 let Inst{21} = 0; // W bit
587 let Inst{24} = 1; // P bit
588 let Inst{27-25} = 0b000;
590 class AXI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
591 string asm, list<dag> pattern>
592 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
595 let Inst{5} = 0; // H bit
596 let Inst{6} = 1; // S bit
598 let Inst{20} = 1; // L bit
599 let Inst{21} = 0; // W bit
600 let Inst{24} = 1; // P bit
602 class AI3ldd<dag oops, dag iops, Format f, InstrItinClass itin,
603 string opc, string asm, list<dag> pattern>
604 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
605 opc, asm, "", pattern> {
607 let Inst{5} = 0; // H bit
608 let Inst{6} = 1; // S bit
610 let Inst{20} = 0; // L bit
611 let Inst{21} = 0; // W bit
612 let Inst{24} = 1; // P bit
613 let Inst{27-25} = 0b000;
617 class AI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
618 string opc, string asm, list<dag> pattern>
619 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
620 opc, asm, "", pattern> {
622 let Inst{5} = 1; // H bit
623 let Inst{6} = 0; // S bit
625 let Inst{20} = 0; // L bit
626 let Inst{21} = 0; // W bit
627 let Inst{24} = 1; // P bit
628 let Inst{27-25} = 0b000;
630 class AXI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
631 string asm, list<dag> pattern>
632 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
635 let Inst{5} = 1; // H bit
636 let Inst{6} = 0; // S bit
638 let Inst{20} = 0; // L bit
639 let Inst{21} = 0; // W bit
640 let Inst{24} = 1; // P bit
642 class AI3std<dag oops, dag iops, Format f, InstrItinClass itin,
643 string opc, string asm, list<dag> pattern>
644 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
645 opc, asm, "", pattern> {
647 let Inst{5} = 1; // H bit
648 let Inst{6} = 1; // S bit
650 let Inst{20} = 0; // L bit
651 let Inst{21} = 0; // W bit
652 let Inst{24} = 1; // P bit
653 let Inst{27-25} = 0b000;
657 class AI3ldhpr<dag oops, dag iops, Format f, InstrItinClass itin,
658 string opc, string asm, string cstr, list<dag> pattern>
659 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
660 opc, asm, cstr, pattern> {
662 let Inst{5} = 1; // H bit
663 let Inst{6} = 0; // S bit
665 let Inst{20} = 1; // L bit
666 let Inst{21} = 1; // W bit
667 let Inst{24} = 1; // P bit
668 let Inst{27-25} = 0b000;
670 class AI3ldshpr<dag oops, dag iops, Format f, InstrItinClass itin,
671 string opc, string asm, string cstr, list<dag> pattern>
672 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
673 opc, asm, cstr, pattern> {
675 let Inst{5} = 1; // H bit
676 let Inst{6} = 1; // S bit
678 let Inst{20} = 1; // L bit
679 let Inst{21} = 1; // W bit
680 let Inst{24} = 1; // P bit
681 let Inst{27-25} = 0b000;
683 class AI3ldsbpr<dag oops, dag iops, Format f, InstrItinClass itin,
684 string opc, string asm, string cstr, list<dag> pattern>
685 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
686 opc, asm, cstr, pattern> {
688 let Inst{5} = 0; // H bit
689 let Inst{6} = 1; // S bit
691 let Inst{20} = 1; // L bit
692 let Inst{21} = 1; // W bit
693 let Inst{24} = 1; // P bit
694 let Inst{27-25} = 0b000;
697 // Pre-indexed stores
698 class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
699 string opc, string asm, string cstr, list<dag> pattern>
700 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
701 opc, asm, cstr, pattern> {
703 let Inst{5} = 1; // H bit
704 let Inst{6} = 0; // S bit
706 let Inst{20} = 0; // L bit
707 let Inst{21} = 1; // W bit
708 let Inst{24} = 1; // P bit
709 let Inst{27-25} = 0b000;
712 // Post-indexed loads
713 class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin,
714 string opc, string asm, string cstr, list<dag> pattern>
715 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
716 opc, asm, cstr,pattern> {
718 let Inst{5} = 1; // H bit
719 let Inst{6} = 0; // S bit
721 let Inst{20} = 1; // L bit
722 let Inst{21} = 1; // W bit
723 let Inst{24} = 0; // P bit
724 let Inst{27-25} = 0b000;
726 class AI3ldshpo<dag oops, dag iops, Format f, InstrItinClass itin,
727 string opc, string asm, string cstr, list<dag> pattern>
728 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
729 opc, asm, cstr,pattern> {
731 let Inst{5} = 1; // H bit
732 let Inst{6} = 1; // S bit
734 let Inst{20} = 1; // L bit
735 let Inst{21} = 1; // W bit
736 let Inst{24} = 0; // P bit
737 let Inst{27-25} = 0b000;
739 class AI3ldsbpo<dag oops, dag iops, Format f, InstrItinClass itin,
740 string opc, string asm, string cstr, list<dag> pattern>
741 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
742 opc, asm, cstr,pattern> {
744 let Inst{5} = 0; // H bit
745 let Inst{6} = 1; // S bit
747 let Inst{20} = 1; // L bit
748 let Inst{21} = 1; // W bit
749 let Inst{24} = 0; // P bit
750 let Inst{27-25} = 0b000;
753 // Post-indexed stores
754 class AI3sthpo<dag oops, dag iops, Format f, InstrItinClass itin,
755 string opc, string asm, string cstr, list<dag> pattern>
756 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
757 opc, asm, cstr,pattern> {
759 let Inst{5} = 1; // H bit
760 let Inst{6} = 0; // S bit
762 let Inst{20} = 0; // L bit
763 let Inst{21} = 1; // W bit
764 let Inst{24} = 0; // P bit
765 let Inst{27-25} = 0b000;
769 // addrmode4 instructions
770 class AXI4ld<dag oops, dag iops, Format f, InstrItinClass itin,
771 string asm, list<dag> pattern>
772 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
774 let Inst{20} = 1; // L bit
775 let Inst{22} = 0; // S bit
776 let Inst{27-25} = 0b100;
778 class AXI4st<dag oops, dag iops, Format f, InstrItinClass itin,
779 string asm, list<dag> pattern>
780 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
782 let Inst{20} = 0; // L bit
783 let Inst{22} = 0; // S bit
784 let Inst{27-25} = 0b100;
787 // Unsigned multiply, multiply-accumulate instructions.
788 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
789 string opc, string asm, list<dag> pattern>
790 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
791 opc, asm, "", pattern> {
792 let Inst{7-4} = 0b1001;
793 let Inst{20} = 0; // S bit
794 let Inst{27-21} = opcod;
796 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
797 string opc, string asm, list<dag> pattern>
798 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
799 opc, asm, "", pattern> {
800 let Inst{7-4} = 0b1001;
801 let Inst{27-21} = opcod;
804 // Most significant word multiply
805 class AMul2I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
806 string opc, string asm, list<dag> pattern>
807 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
808 opc, asm, "", pattern> {
809 let Inst{7-4} = 0b1001;
811 let Inst{27-21} = opcod;
814 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
815 class AMulxyI<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
816 string opc, string asm, list<dag> pattern>
817 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
818 opc, asm, "", pattern> {
822 let Inst{27-21} = opcod;
825 // Extend instructions.
826 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
827 string opc, string asm, list<dag> pattern>
828 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin,
829 opc, asm, "", pattern> {
830 let Inst{7-4} = 0b0111;
831 let Inst{27-20} = opcod;
834 // Misc Arithmetic instructions.
835 class AMiscA1I<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
836 string opc, string asm, list<dag> pattern>
837 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin,
838 opc, asm, "", pattern> {
839 let Inst{27-20} = opcod;
842 //===----------------------------------------------------------------------===//
844 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
845 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
846 list<Predicate> Predicates = [IsARM];
848 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
849 list<Predicate> Predicates = [IsARM, HasV5TE];
851 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
852 list<Predicate> Predicates = [IsARM, HasV6];
855 //===----------------------------------------------------------------------===//
857 // Thumb Instruction Format Definitions.
860 // TI - Thumb instruction.
862 class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
863 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
864 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
865 let OutOperandList = oops;
866 let InOperandList = iops;
868 let Pattern = pattern;
869 list<Predicate> Predicates = [IsThumb];
872 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
873 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
875 // Two-address instructions
876 class TIt<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
877 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "$lhs = $dst", pattern>;
879 // tBL, tBX instructions
880 class TIx2<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
881 : ThumbI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
883 // BR_JT instructions
884 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
885 : ThumbI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
888 class Thumb1I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
889 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
890 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
891 let OutOperandList = oops;
892 let InOperandList = iops;
894 let Pattern = pattern;
895 list<Predicate> Predicates = [IsThumb1Only];
898 class T1I<dag oops, dag iops, InstrItinClass itin,
899 string asm, list<dag> pattern>
900 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
901 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
902 string asm, list<dag> pattern>
903 : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
904 class T1JTI<dag oops, dag iops, InstrItinClass itin,
905 string asm, list<dag> pattern>
906 : Thumb1I<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
908 // Two-address instructions
909 class T1It<dag oops, dag iops, InstrItinClass itin,
910 string asm, list<dag> pattern>
911 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin,
912 asm, "$lhs = $dst", pattern>;
914 // Thumb1 instruction that can either be predicated or set CPSR.
915 class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
917 string opc, string asm, string cstr, list<dag> pattern>
918 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
919 let OutOperandList = !con(oops, (ops s_cc_out:$s));
920 let InOperandList = !con(iops, (ops pred:$p));
921 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
922 let Pattern = pattern;
923 list<Predicate> Predicates = [IsThumb1Only];
926 class T1sI<dag oops, dag iops, InstrItinClass itin,
927 string opc, string asm, list<dag> pattern>
928 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
930 // Two-address instructions
931 class T1sIt<dag oops, dag iops, InstrItinClass itin,
932 string opc, string asm, list<dag> pattern>
933 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
934 "$lhs = $dst", pattern>;
936 // Thumb1 instruction that can be predicated.
937 class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
939 string opc, string asm, string cstr, list<dag> pattern>
940 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
941 let OutOperandList = oops;
942 let InOperandList = !con(iops, (ops pred:$p));
943 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
944 let Pattern = pattern;
945 list<Predicate> Predicates = [IsThumb1Only];
948 class T1pI<dag oops, dag iops, InstrItinClass itin,
949 string opc, string asm, list<dag> pattern>
950 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
952 // Two-address instructions
953 class T1pIt<dag oops, dag iops, InstrItinClass itin,
954 string opc, string asm, list<dag> pattern>
955 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
956 "$lhs = $dst", pattern>;
958 class T1pI1<dag oops, dag iops, InstrItinClass itin,
959 string opc, string asm, list<dag> pattern>
960 : Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, itin, opc, asm, "", pattern>;
961 class T1pI2<dag oops, dag iops, InstrItinClass itin,
962 string opc, string asm, list<dag> pattern>
963 : Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, itin, opc, asm, "", pattern>;
964 class T1pI4<dag oops, dag iops, InstrItinClass itin,
965 string opc, string asm, list<dag> pattern>
966 : Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, itin, opc, asm, "", pattern>;
967 class T1pIs<dag oops, dag iops,
968 InstrItinClass itin, string opc, string asm, list<dag> pattern>
969 : Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, itin, opc, asm, "", pattern>;
971 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
972 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
974 string opc, string asm, string cstr, list<dag> pattern>
975 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
976 let OutOperandList = oops;
977 let InOperandList = !con(iops, (ops pred:$p));
978 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
979 let Pattern = pattern;
980 list<Predicate> Predicates = [IsThumb2];
983 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
984 // an input operand since by default it's a zero register. It will
985 // become an implicit def once it's "flipped".
986 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
988 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
990 string opc, string asm, string cstr, list<dag> pattern>
991 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
992 let OutOperandList = oops;
993 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
994 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
995 let Pattern = pattern;
996 list<Predicate> Predicates = [IsThumb2];
1000 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1001 InstrItinClass itin,
1002 string asm, string cstr, list<dag> pattern>
1003 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1004 let OutOperandList = oops;
1005 let InOperandList = iops;
1006 let AsmString = asm;
1007 let Pattern = pattern;
1008 list<Predicate> Predicates = [IsThumb2];
1011 class ThumbXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1012 InstrItinClass itin,
1013 string asm, string cstr, list<dag> pattern>
1014 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1015 let OutOperandList = oops;
1016 let InOperandList = iops;
1017 let AsmString = asm;
1018 let Pattern = pattern;
1019 list<Predicate> Predicates = [IsThumb1Only];
1022 class T2I<dag oops, dag iops, InstrItinClass itin,
1023 string opc, string asm, list<dag> pattern>
1024 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1025 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1026 string opc, string asm, list<dag> pattern>
1027 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, itin, opc, asm, "", pattern>;
1028 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1029 string opc, string asm, list<dag> pattern>
1030 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, itin, opc, asm, "", pattern>;
1031 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1032 string opc, string asm, list<dag> pattern>
1033 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, itin, opc, asm, "", pattern>;
1034 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1035 string opc, string asm, list<dag> pattern>
1036 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, itin, opc, asm, "", pattern>;
1037 class T2Ii8s4<dag oops, dag iops, InstrItinClass itin,
1038 string opc, string asm, list<dag> pattern>
1039 : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, itin, opc, asm, "", pattern>;
1041 class T2sI<dag oops, dag iops, InstrItinClass itin,
1042 string opc, string asm, list<dag> pattern>
1043 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1045 class T2XI<dag oops, dag iops, InstrItinClass itin,
1046 string asm, list<dag> pattern>
1047 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
1048 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1049 string asm, list<dag> pattern>
1050 : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
1052 class T2Ix2<dag oops, dag iops, InstrItinClass itin,
1053 string opc, string asm, list<dag> pattern>
1054 : Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>;
1057 // T2Iidxldst - Thumb2 indexed load / store instructions.
1058 class T2Iidxldst<dag oops, dag iops, AddrMode am, IndexMode im,
1059 InstrItinClass itin,
1060 string opc, string asm, string cstr, list<dag> pattern>
1061 : InstARM<am, Size4Bytes, im, ThumbFrm, GenericDomain, cstr, itin> {
1062 let OutOperandList = oops;
1063 let InOperandList = !con(iops, (ops pred:$p));
1064 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1065 let Pattern = pattern;
1066 list<Predicate> Predicates = [IsThumb2];
1069 // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
1070 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
1071 list<Predicate> Predicates = [IsThumb1Only, HasV5T];
1074 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1075 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1076 list<Predicate> Predicates = [IsThumb1Only];
1079 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1080 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1081 list<Predicate> Predicates = [IsThumb2];
1084 //===----------------------------------------------------------------------===//
1086 //===----------------------------------------------------------------------===//
1087 // ARM VFP Instruction templates.
1090 // Almost all VFP instructions are predicable.
1091 class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1092 IndexMode im, Format f, InstrItinClass itin,
1093 string opc, string asm, string cstr, list<dag> pattern>
1094 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1095 let OutOperandList = oops;
1096 let InOperandList = !con(iops, (ops pred:$p));
1097 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1098 let Pattern = pattern;
1099 list<Predicate> Predicates = [HasVFP2];
1103 class VFPXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1104 IndexMode im, Format f, InstrItinClass itin,
1105 string asm, string cstr, list<dag> pattern>
1106 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1107 let OutOperandList = oops;
1108 let InOperandList = iops;
1109 let AsmString = asm;
1110 let Pattern = pattern;
1111 list<Predicate> Predicates = [HasVFP2];
1114 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1115 string opc, string asm, list<dag> pattern>
1116 : VFPI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
1117 opc, asm, "", pattern>;
1119 // ARM VFP addrmode5 loads and stores
1120 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1121 InstrItinClass itin,
1122 string opc, string asm, list<dag> pattern>
1123 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1124 VFPLdStFrm, itin, opc, asm, "", pattern> {
1125 // TODO: Mark the instructions with the appropriate subtarget info.
1126 let Inst{27-24} = opcod1;
1127 let Inst{21-20} = opcod2;
1128 let Inst{11-8} = 0b1011;
1130 // 64-bit loads & stores operate on both NEON and VFP pipelines.
1131 let Dom = VFPNeonDomain.Value;
1134 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1135 InstrItinClass itin,
1136 string opc, string asm, list<dag> pattern>
1137 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1138 VFPLdStFrm, itin, opc, asm, "", pattern> {
1139 // TODO: Mark the instructions with the appropriate subtarget info.
1140 let Inst{27-24} = opcod1;
1141 let Inst{21-20} = opcod2;
1142 let Inst{11-8} = 0b1010;
1145 // Load / store multiple
1146 class AXDI5<dag oops, dag iops, InstrItinClass itin,
1147 string asm, list<dag> pattern>
1148 : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1149 VFPLdStMulFrm, itin, asm, "", pattern> {
1150 // TODO: Mark the instructions with the appropriate subtarget info.
1151 let Inst{27-25} = 0b110;
1152 let Inst{11-8} = 0b1011;
1154 // 64-bit loads & stores operate on both NEON and VFP pipelines.
1155 let Dom = VFPNeonDomain.Value;
1158 class AXSI5<dag oops, dag iops, InstrItinClass itin,
1159 string asm, list<dag> pattern>
1160 : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1161 VFPLdStMulFrm, itin, asm, "", pattern> {
1162 // TODO: Mark the instructions with the appropriate subtarget info.
1163 let Inst{27-25} = 0b110;
1164 let Inst{11-8} = 0b1010;
1167 // Double precision, unary
1168 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
1169 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1170 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1171 let Inst{27-20} = opcod1;
1172 let Inst{19-16} = opcod2;
1173 let Inst{11-8} = 0b1011;
1174 let Inst{7-4} = opcod3;
1177 // Double precision, binary
1178 class ADbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
1179 string opc, string asm, list<dag> pattern>
1180 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1181 let Inst{27-20} = opcod;
1182 let Inst{11-8} = 0b1011;
1185 // Single precision, unary
1186 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
1187 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1188 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1189 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
1190 let Inst{27-20} = opcod1;
1191 let Inst{19-16} = opcod2;
1192 let Inst{11-8} = 0b1010;
1193 let Inst{7-4} = opcod3;
1196 // Single precision unary, if no NEON
1197 // Same as ASuI except not available if NEON is enabled
1198 class ASuIn<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
1199 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1200 : ASuI<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> {
1201 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1204 // Single precision, binary
1205 class ASbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
1206 string opc, string asm, list<dag> pattern>
1207 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1208 // Bit 22 (D bit) can be changed during instruction encoding.
1209 let Inst{27-20} = opcod;
1210 let Inst{11-8} = 0b1010;
1213 // Single precision binary, if no NEON
1214 // Same as ASbI except not available if NEON is enabled
1215 class ASbIn<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
1216 string opc, string asm, list<dag> pattern>
1217 : ASbI<opcod, oops, iops, itin, opc, asm, pattern> {
1218 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1221 // VFP conversion instructions
1222 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
1223 dag oops, dag iops, InstrItinClass itin,
1224 string opc, string asm, list<dag> pattern>
1225 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1226 let Inst{27-20} = opcod1;
1227 let Inst{19-16} = opcod2;
1228 let Inst{11-8} = opcod3;
1232 // VFP conversion instructions, if no NEON
1233 class AVConv1In<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
1234 dag oops, dag iops, InstrItinClass itin,
1235 string opc, string asm, list<dag> pattern>
1236 : AVConv1I<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> {
1237 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1240 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
1241 InstrItinClass itin,
1242 string opc, string asm, list<dag> pattern>
1243 : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
1244 let Inst{27-20} = opcod1;
1245 let Inst{11-8} = opcod2;
1249 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1250 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1251 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
1253 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1254 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1255 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
1257 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1258 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1259 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
1261 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1262 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1263 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
1265 //===----------------------------------------------------------------------===//
1267 //===----------------------------------------------------------------------===//
1268 // ARM NEON Instruction templates.
1271 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
1272 string opc, string dt, string asm, string cstr, list<dag> pattern>
1273 : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
1274 let OutOperandList = oops;
1275 let InOperandList = !con(iops, (ops pred:$p));
1276 let AsmString = !strconcat(
1277 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1278 !strconcat("\t", asm));
1279 let Pattern = pattern;
1280 list<Predicate> Predicates = [HasNEON];
1283 // Same as NeonI except it does not have a "data type" specifier.
1284 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
1285 string opc, string asm, string cstr, list<dag> pattern>
1286 : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
1287 let OutOperandList = oops;
1288 let InOperandList = !con(iops, (ops pred:$p));
1289 let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
1290 let Pattern = pattern;
1291 list<Predicate> Predicates = [HasNEON];
1294 class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1296 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, "",
1300 class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
1301 string asm, list<dag> pattern>
1302 : NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "",
1306 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1307 dag oops, dag iops, InstrItinClass itin,
1308 string opc, string dt, string asm, string cstr, list<dag> pattern>
1309 : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, dt, asm, cstr,
1311 let Inst{31-24} = 0b11110100;
1312 let Inst{23} = op23;
1313 let Inst{21-20} = op21_20;
1314 let Inst{11-8} = op11_8;
1315 let Inst{7-4} = op7_4;
1318 class NDataI<dag oops, dag iops, InstrItinClass itin,
1319 string opc, string dt, string asm, string cstr, list<dag> pattern>
1320 : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, dt, asm,
1322 let Inst{31-25} = 0b1111001;
1325 class NDataXI<dag oops, dag iops, InstrItinClass itin,
1326 string opc, string asm, string cstr, list<dag> pattern>
1327 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm,
1329 let Inst{31-25} = 0b1111001;
1332 // NEON "one register and a modified immediate" format.
1333 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1335 dag oops, dag iops, InstrItinClass itin,
1336 string opc, string dt, string asm, string cstr, list<dag> pattern>
1337 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1338 let Inst{23} = op23;
1339 let Inst{21-19} = op21_19;
1340 let Inst{11-8} = op11_8;
1347 // NEON 2 vector register format.
1348 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1349 bits<5> op11_7, bit op6, bit op4,
1350 dag oops, dag iops, InstrItinClass itin,
1351 string opc, string dt, string asm, string cstr, list<dag> pattern>
1352 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1353 let Inst{24-23} = op24_23;
1354 let Inst{21-20} = op21_20;
1355 let Inst{19-18} = op19_18;
1356 let Inst{17-16} = op17_16;
1357 let Inst{11-7} = op11_7;
1362 // Same as N2V except it doesn't have a datatype suffix.
1363 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1364 bits<5> op11_7, bit op6, bit op4,
1365 dag oops, dag iops, InstrItinClass itin,
1366 string opc, string asm, string cstr, list<dag> pattern>
1367 : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> {
1368 let Inst{24-23} = op24_23;
1369 let Inst{21-20} = op21_20;
1370 let Inst{19-18} = op19_18;
1371 let Inst{17-16} = op17_16;
1372 let Inst{11-7} = op11_7;
1377 // NEON 2 vector register with immediate.
1378 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
1379 dag oops, dag iops, InstrItinClass itin,
1380 string opc, string dt, string asm, string cstr, list<dag> pattern>
1381 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1382 let Inst{24} = op24;
1383 let Inst{23} = op23;
1384 let Inst{11-8} = op11_8;
1390 // NEON 3 vector register format.
1391 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1392 dag oops, dag iops, InstrItinClass itin,
1393 string opc, string dt, string asm, string cstr, list<dag> pattern>
1394 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> {
1395 let Inst{24} = op24;
1396 let Inst{23} = op23;
1397 let Inst{21-20} = op21_20;
1398 let Inst{11-8} = op11_8;
1403 // Same as N3VX except it doesn't have a data type suffix.
1404 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1405 dag oops, dag iops, InstrItinClass itin,
1406 string opc, string asm, string cstr, list<dag> pattern>
1407 : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> {
1408 let Inst{24} = op24;
1409 let Inst{23} = op23;
1410 let Inst{21-20} = op21_20;
1411 let Inst{11-8} = op11_8;
1416 // NEON VMOVs between scalar and core registers.
1417 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1418 dag oops, dag iops, Format f, InstrItinClass itin,
1419 string opc, string dt, string asm, list<dag> pattern>
1420 : InstARM<AddrModeNone, Size4Bytes, IndexModeNone, f, GenericDomain,
1422 let Inst{27-20} = opcod1;
1423 let Inst{11-8} = opcod2;
1424 let Inst{6-5} = opcod3;
1427 let OutOperandList = oops;
1428 let InOperandList = !con(iops, (ops pred:$p));
1429 let AsmString = !strconcat(
1430 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1431 !strconcat("\t", asm));
1432 let Pattern = pattern;
1433 list<Predicate> Predicates = [HasNEON];
1435 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1436 dag oops, dag iops, InstrItinClass itin,
1437 string opc, string dt, string asm, list<dag> pattern>
1438 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, itin,
1439 opc, dt, asm, pattern>;
1440 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1441 dag oops, dag iops, InstrItinClass itin,
1442 string opc, string dt, string asm, list<dag> pattern>
1443 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, itin,
1444 opc, dt, asm, pattern>;
1445 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1446 dag oops, dag iops, InstrItinClass itin,
1447 string opc, string dt, string asm, list<dag> pattern>
1448 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, itin,
1449 opc, dt, asm, pattern>;
1451 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
1452 // for single-precision FP.
1453 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
1454 list<Predicate> Predicates = [HasNEON,UseNEONForFP];