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<6> 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<11>;
38 def ArithMiscFrm : Format<12>;
39 def ExtFrm : Format<13>;
41 def VFPUnaryFrm : Format<14>;
42 def VFPBinaryFrm : Format<15>;
43 def VFPConv1Frm : Format<16>;
44 def VFPConv2Frm : Format<17>;
45 def VFPConv3Frm : Format<18>;
46 def VFPConv4Frm : Format<19>;
47 def VFPConv5Frm : Format<20>;
48 def VFPLdStFrm : Format<21>;
49 def VFPLdStMulFrm : Format<22>;
50 def VFPMiscFrm : Format<23>;
52 def ThumbFrm : Format<24>;
54 def NEONFrm : Format<25>;
55 def NEONGetLnFrm : Format<26>;
56 def NEONSetLnFrm : Format<27>;
57 def NEONDupFrm : Format<28>;
59 def MiscFrm : Format<29>;
60 def ThumbMiscFrm : Format<30>;
62 def NLdStFrm : Format<31>;
63 def N1RegModImmFrm : Format<32>;
64 def N2RegFrm : Format<33>;
68 // the instruction has a Rn register operand.
69 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
70 // it doesn't have a Rn operand.
71 class UnaryDP { bit isUnaryDataProc = 1; }
73 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
74 // a 16-bit Thumb instruction if certain conditions are met.
75 class Xform16Bit { bit canXformTo16Bit = 1; }
77 //===----------------------------------------------------------------------===//
78 // ARM Instruction flags. These need to match ARMBaseInstrInfo.h.
82 class AddrMode<bits<4> val> {
85 def AddrModeNone : AddrMode<0>;
86 def AddrMode1 : AddrMode<1>;
87 def AddrMode2 : AddrMode<2>;
88 def AddrMode3 : AddrMode<3>;
89 def AddrMode4 : AddrMode<4>;
90 def AddrMode5 : AddrMode<5>;
91 def AddrMode6 : AddrMode<6>;
92 def AddrModeT1_1 : AddrMode<7>;
93 def AddrModeT1_2 : AddrMode<8>;
94 def AddrModeT1_4 : AddrMode<9>;
95 def AddrModeT1_s : AddrMode<10>;
96 def AddrModeT2_i12: AddrMode<11>;
97 def AddrModeT2_i8 : AddrMode<12>;
98 def AddrModeT2_so : AddrMode<13>;
99 def AddrModeT2_pc : AddrMode<14>;
100 def AddrModeT2_i8s4 : AddrMode<15>;
103 class SizeFlagVal<bits<3> val> {
106 def SizeInvalid : SizeFlagVal<0>; // Unset.
107 def SizeSpecial : SizeFlagVal<1>; // Pseudo or special.
108 def Size8Bytes : SizeFlagVal<2>;
109 def Size4Bytes : SizeFlagVal<3>;
110 def Size2Bytes : SizeFlagVal<4>;
112 // Load / store index mode.
113 class IndexMode<bits<2> val> {
116 def IndexModeNone : IndexMode<0>;
117 def IndexModePre : IndexMode<1>;
118 def IndexModePost : IndexMode<2>;
119 def IndexModeUpd : IndexMode<3>;
121 // Instruction execution domain.
122 class Domain<bits<2> val> {
125 def GenericDomain : Domain<0>;
126 def VFPDomain : Domain<1>; // Instructions in VFP domain only
127 def NeonDomain : Domain<2>; // Instructions in Neon domain only
128 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
130 //===----------------------------------------------------------------------===//
132 // ARM special operands.
135 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
136 // register whose default is 0 (no register).
137 def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
138 (ops (i32 14), (i32 zero_reg))> {
139 let PrintMethod = "printPredicateOperand";
142 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
143 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
144 let PrintMethod = "printSBitModifierOperand";
147 // Same as cc_out except it defaults to setting CPSR.
148 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
149 let PrintMethod = "printSBitModifierOperand";
152 // ARM special operands for disassembly only.
155 def cps_opt : Operand<i32> {
156 let PrintMethod = "printCPSOptionOperand";
159 def msr_mask : Operand<i32> {
160 let PrintMethod = "printMSRMaskOperand";
163 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
164 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
165 def neg_zero : Operand<i32> {
166 let PrintMethod = "printNegZeroOperand";
169 //===----------------------------------------------------------------------===//
171 // ARM Instruction templates.
174 class InstTemplate<AddrMode am, SizeFlagVal sz, IndexMode im,
175 Format f, Domain d, string cstr, InstrItinClass itin>
177 let Namespace = "ARM";
181 bits<4> AddrModeBits = AM.Value;
184 bits<3> SizeFlag = SZ.Value;
187 bits<2> IndexModeBits = IM.Value;
190 bits<6> Form = F.Value;
193 bits<2> Dom = D.Value;
196 // Attributes specific to ARM instructions...
198 bit isUnaryDataProc = 0;
199 bit canXformTo16Bit = 0;
201 let Constraints = cstr;
202 let Itinerary = itin;
209 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
210 Format f, Domain d, string cstr, InstrItinClass itin>
211 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding;
213 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
214 // on by adding flavors to specific instructions.
215 class InstThumb<AddrMode am, SizeFlagVal sz, IndexMode im,
216 Format f, Domain d, string cstr, InstrItinClass itin>
217 : InstTemplate<am, sz, im, f, d, cstr, itin>;
219 class PseudoInst<dag oops, dag iops, InstrItinClass itin,
220 string asm, list<dag> pattern>
221 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, GenericDomain,
223 let OutOperandList = oops;
224 let InOperandList = iops;
226 let Pattern = pattern;
229 // Almost all ARM instructions are predicable.
230 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
231 IndexMode im, Format f, InstrItinClass itin,
232 string opc, string asm, string cstr,
234 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
235 let OutOperandList = oops;
236 let InOperandList = !con(iops, (ins pred:$p));
237 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
238 let Pattern = pattern;
239 list<Predicate> Predicates = [IsARM];
241 // A few are not predicable
242 class InoP<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
243 IndexMode im, Format f, InstrItinClass itin,
244 string opc, string asm, string cstr,
246 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
247 let OutOperandList = oops;
248 let InOperandList = iops;
249 let AsmString = !strconcat(opc, asm);
250 let Pattern = pattern;
251 let isPredicable = 0;
252 list<Predicate> Predicates = [IsARM];
255 // Same as I except it can optionally modify CPSR. Note it's modeled as
256 // an input operand since by default it's a zero register. It will
257 // become an implicit def once it's "flipped".
258 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
259 IndexMode im, Format f, InstrItinClass itin,
260 string opc, string asm, string cstr,
262 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
263 let OutOperandList = oops;
264 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
265 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
266 let Pattern = pattern;
267 list<Predicate> Predicates = [IsARM];
271 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
272 IndexMode im, Format f, InstrItinClass itin,
273 string asm, string cstr, list<dag> pattern>
274 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
275 let OutOperandList = oops;
276 let InOperandList = iops;
278 let Pattern = pattern;
279 list<Predicate> Predicates = [IsARM];
282 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
283 string opc, string asm, list<dag> pattern>
284 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
285 opc, asm, "", pattern>;
286 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
287 string opc, string asm, list<dag> pattern>
288 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
289 opc, asm, "", pattern>;
290 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
291 string asm, list<dag> pattern>
292 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
294 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
295 string opc, string asm, list<dag> pattern>
296 : InoP<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
297 opc, asm, "", pattern>;
299 // Ctrl flow instructions
300 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
301 string opc, string asm, list<dag> pattern>
302 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
303 opc, asm, "", pattern> {
304 let Inst{27-24} = opcod;
306 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
307 string asm, list<dag> pattern>
308 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin,
310 let Inst{27-24} = opcod;
312 class ABXIx2<dag oops, dag iops, InstrItinClass itin,
313 string asm, list<dag> pattern>
314 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, itin,
317 // BR_JT instructions
318 class JTI<dag oops, dag iops, InstrItinClass itin,
319 string asm, list<dag> pattern>
320 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm, itin,
324 // Atomic load/store instructions
326 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
327 string opc, string asm, list<dag> pattern>
328 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
329 opc, asm, "", pattern> {
330 let Inst{27-23} = 0b00011;
331 let Inst{22-21} = opcod;
333 let Inst{11-0} = 0b111110011111;
335 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
336 string opc, string asm, list<dag> pattern>
337 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin,
338 opc, asm, "", pattern> {
339 let Inst{27-23} = 0b00011;
340 let Inst{22-21} = opcod;
342 let Inst{11-4} = 0b11111001;
345 // addrmode1 instructions
346 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
347 string opc, string asm, list<dag> pattern>
348 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
349 opc, asm, "", pattern> {
350 let Inst{24-21} = opcod;
351 let Inst{27-26} = {0,0};
353 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
354 string opc, string asm, list<dag> pattern>
355 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
356 opc, asm, "", pattern> {
357 let Inst{24-21} = opcod;
358 let Inst{27-26} = {0,0};
360 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
361 string asm, list<dag> pattern>
362 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin,
364 let Inst{24-21} = opcod;
365 let Inst{27-26} = {0,0};
367 class AI1x2<dag oops, dag iops, Format f, InstrItinClass itin,
368 string opc, string asm, list<dag> pattern>
369 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, itin,
370 opc, asm, "", pattern>;
373 // addrmode2 loads and stores
374 class AI2<dag oops, dag iops, Format f, InstrItinClass itin,
375 string opc, string asm, list<dag> pattern>
376 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
377 opc, asm, "", pattern> {
378 let Inst{27-26} = {0,1};
382 class AI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
383 string opc, string asm, list<dag> pattern>
384 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
385 opc, asm, "", pattern> {
386 let Inst{20} = 1; // L bit
387 let Inst{21} = 0; // W bit
388 let Inst{22} = 0; // B bit
389 let Inst{24} = 1; // P bit
390 let Inst{27-26} = {0,1};
392 class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
393 string asm, list<dag> pattern>
394 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
396 let Inst{20} = 1; // L bit
397 let Inst{21} = 0; // W bit
398 let Inst{22} = 0; // B bit
399 let Inst{24} = 1; // P bit
400 let Inst{27-26} = {0,1};
402 class AI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
403 string opc, string asm, list<dag> pattern>
404 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
405 opc, asm, "", pattern> {
406 let Inst{20} = 1; // L bit
407 let Inst{21} = 0; // W bit
408 let Inst{22} = 1; // B bit
409 let Inst{24} = 1; // P bit
410 let Inst{27-26} = {0,1};
412 class AXI2ldb<dag oops, dag iops, Format f, InstrItinClass itin,
413 string asm, list<dag> pattern>
414 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
416 let Inst{20} = 1; // L bit
417 let Inst{21} = 0; // W bit
418 let Inst{22} = 1; // B bit
419 let Inst{24} = 1; // P bit
420 let Inst{27-26} = {0,1};
424 class AI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
425 string opc, string asm, list<dag> pattern>
426 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
427 opc, asm, "", pattern> {
428 let Inst{20} = 0; // L bit
429 let Inst{21} = 0; // W bit
430 let Inst{22} = 0; // B bit
431 let Inst{24} = 1; // P bit
432 let Inst{27-26} = {0,1};
434 class AXI2stw<dag oops, dag iops, Format f, InstrItinClass itin,
435 string asm, list<dag> pattern>
436 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
438 let Inst{20} = 0; // L bit
439 let Inst{21} = 0; // W bit
440 let Inst{22} = 0; // B bit
441 let Inst{24} = 1; // P bit
442 let Inst{27-26} = {0,1};
444 class AI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
445 string opc, string asm, list<dag> pattern>
446 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
447 opc, asm, "", pattern> {
448 let Inst{20} = 0; // L bit
449 let Inst{21} = 0; // W bit
450 let Inst{22} = 1; // B bit
451 let Inst{24} = 1; // P bit
452 let Inst{27-26} = {0,1};
454 class AXI2stb<dag oops, dag iops, Format f, InstrItinClass itin,
455 string asm, list<dag> pattern>
456 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin,
458 let Inst{20} = 0; // L bit
459 let Inst{21} = 0; // W bit
460 let Inst{22} = 1; // B bit
461 let Inst{24} = 1; // P bit
462 let Inst{27-26} = {0,1};
466 class AI2ldwpr<dag oops, dag iops, Format f, InstrItinClass itin,
467 string opc, string asm, string cstr, list<dag> pattern>
468 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
469 opc, asm, cstr, pattern> {
470 let Inst{20} = 1; // L bit
471 let Inst{21} = 1; // W bit
472 let Inst{22} = 0; // B bit
473 let Inst{24} = 1; // P bit
474 let Inst{27-26} = {0,1};
476 class AI2ldbpr<dag oops, dag iops, Format f, InstrItinClass itin,
477 string opc, string asm, string cstr, list<dag> pattern>
478 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
479 opc, asm, cstr, pattern> {
480 let Inst{20} = 1; // L bit
481 let Inst{21} = 1; // W bit
482 let Inst{22} = 1; // B bit
483 let Inst{24} = 1; // P bit
484 let Inst{27-26} = {0,1};
487 // Pre-indexed stores
488 class AI2stwpr<dag oops, dag iops, Format f, InstrItinClass itin,
489 string opc, string asm, string cstr, list<dag> pattern>
490 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
491 opc, asm, cstr, pattern> {
492 let Inst{20} = 0; // L bit
493 let Inst{21} = 1; // W bit
494 let Inst{22} = 0; // B bit
495 let Inst{24} = 1; // P bit
496 let Inst{27-26} = {0,1};
498 class AI2stbpr<dag oops, dag iops, Format f, InstrItinClass itin,
499 string opc, string asm, string cstr, list<dag> pattern>
500 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin,
501 opc, asm, cstr, pattern> {
502 let Inst{20} = 0; // L bit
503 let Inst{21} = 1; // W bit
504 let Inst{22} = 1; // B bit
505 let Inst{24} = 1; // P bit
506 let Inst{27-26} = {0,1};
509 // Post-indexed loads
510 class AI2ldwpo<dag oops, dag iops, Format f, InstrItinClass itin,
511 string opc, string asm, string cstr, list<dag> pattern>
512 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
513 opc, asm, cstr,pattern> {
514 let Inst{20} = 1; // L bit
515 let Inst{21} = 0; // W bit
516 let Inst{22} = 0; // B bit
517 let Inst{24} = 0; // P bit
518 let Inst{27-26} = {0,1};
520 class AI2ldbpo<dag oops, dag iops, Format f, InstrItinClass itin,
521 string opc, string asm, string cstr, list<dag> pattern>
522 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
523 opc, asm, cstr,pattern> {
524 let Inst{20} = 1; // L bit
525 let Inst{21} = 0; // W bit
526 let Inst{22} = 1; // B bit
527 let Inst{24} = 0; // P bit
528 let Inst{27-26} = {0,1};
531 // Post-indexed stores
532 class AI2stwpo<dag oops, dag iops, Format f, InstrItinClass itin,
533 string opc, string asm, string cstr, list<dag> pattern>
534 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
535 opc, asm, cstr,pattern> {
536 let Inst{20} = 0; // L bit
537 let Inst{21} = 0; // W bit
538 let Inst{22} = 0; // B bit
539 let Inst{24} = 0; // P bit
540 let Inst{27-26} = {0,1};
542 class AI2stbpo<dag oops, dag iops, Format f, InstrItinClass itin,
543 string opc, string asm, string cstr, list<dag> pattern>
544 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin,
545 opc, asm, cstr,pattern> {
546 let Inst{20} = 0; // L bit
547 let Inst{21} = 0; // W bit
548 let Inst{22} = 1; // B bit
549 let Inst{24} = 0; // P bit
550 let Inst{27-26} = {0,1};
553 // addrmode3 instructions
554 class AI3<dag oops, dag iops, Format f, InstrItinClass itin,
555 string opc, string asm, list<dag> pattern>
556 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
557 opc, asm, "", pattern>;
558 class AXI3<dag oops, dag iops, Format f, InstrItinClass itin,
559 string asm, list<dag> pattern>
560 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
564 class AI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
565 string opc, string asm, list<dag> pattern>
566 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
567 opc, asm, "", pattern> {
569 let Inst{5} = 1; // H bit
570 let Inst{6} = 0; // S bit
572 let Inst{20} = 1; // L bit
573 let Inst{21} = 0; // W bit
574 let Inst{24} = 1; // P bit
575 let Inst{27-25} = 0b000;
577 class AXI3ldh<dag oops, dag iops, Format f, InstrItinClass itin,
578 string asm, list<dag> pattern>
579 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
582 let Inst{5} = 1; // H bit
583 let Inst{6} = 0; // S bit
585 let Inst{20} = 1; // L bit
586 let Inst{21} = 0; // W bit
587 let Inst{24} = 1; // P bit
589 class AI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
590 string opc, string asm, list<dag> pattern>
591 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
592 opc, asm, "", pattern> {
594 let Inst{5} = 1; // H bit
595 let Inst{6} = 1; // S bit
597 let Inst{20} = 1; // L bit
598 let Inst{21} = 0; // W bit
599 let Inst{24} = 1; // P bit
600 let Inst{27-25} = 0b000;
602 class AXI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin,
603 string asm, list<dag> pattern>
604 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
607 let Inst{5} = 1; // H bit
608 let Inst{6} = 1; // S bit
610 let Inst{20} = 1; // L bit
611 let Inst{21} = 0; // W bit
612 let Inst{24} = 1; // P bit
614 class AI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
615 string opc, string asm, list<dag> pattern>
616 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
617 opc, asm, "", pattern> {
619 let Inst{5} = 0; // H bit
620 let Inst{6} = 1; // S bit
622 let Inst{20} = 1; // L bit
623 let Inst{21} = 0; // W bit
624 let Inst{24} = 1; // P bit
625 let Inst{27-25} = 0b000;
627 class AXI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin,
628 string asm, list<dag> pattern>
629 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
632 let Inst{5} = 0; // H bit
633 let Inst{6} = 1; // S bit
635 let Inst{20} = 1; // L bit
636 let Inst{21} = 0; // W bit
637 let Inst{24} = 1; // P bit
639 class AI3ldd<dag oops, dag iops, Format f, InstrItinClass itin,
640 string opc, string asm, list<dag> pattern>
641 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
642 opc, asm, "", pattern> {
644 let Inst{5} = 0; // H bit
645 let Inst{6} = 1; // S bit
647 let Inst{20} = 0; // L bit
648 let Inst{21} = 0; // W bit
649 let Inst{24} = 1; // P bit
650 let Inst{27-25} = 0b000;
654 class AI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
655 string opc, string asm, list<dag> pattern>
656 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
657 opc, asm, "", pattern> {
659 let Inst{5} = 1; // H bit
660 let Inst{6} = 0; // S bit
662 let Inst{20} = 0; // L bit
663 let Inst{21} = 0; // W bit
664 let Inst{24} = 1; // P bit
665 let Inst{27-25} = 0b000;
667 class AXI3sth<dag oops, dag iops, Format f, InstrItinClass itin,
668 string asm, list<dag> pattern>
669 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
672 let Inst{5} = 1; // H bit
673 let Inst{6} = 0; // S bit
675 let Inst{20} = 0; // L bit
676 let Inst{21} = 0; // W bit
677 let Inst{24} = 1; // P bit
679 class AI3std<dag oops, dag iops, Format f, InstrItinClass itin,
680 string opc, string asm, list<dag> pattern>
681 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin,
682 opc, asm, "", pattern> {
684 let Inst{5} = 1; // H bit
685 let Inst{6} = 1; // S bit
687 let Inst{20} = 0; // L bit
688 let Inst{21} = 0; // W bit
689 let Inst{24} = 1; // P bit
690 let Inst{27-25} = 0b000;
694 class AI3ldhpr<dag oops, dag iops, Format f, InstrItinClass itin,
695 string opc, string asm, string cstr, list<dag> pattern>
696 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
697 opc, asm, cstr, pattern> {
699 let Inst{5} = 1; // H bit
700 let Inst{6} = 0; // S bit
702 let Inst{20} = 1; // L bit
703 let Inst{21} = 1; // W bit
704 let Inst{24} = 1; // P bit
705 let Inst{27-25} = 0b000;
707 class AI3ldshpr<dag oops, dag iops, Format f, InstrItinClass itin,
708 string opc, string asm, string cstr, list<dag> pattern>
709 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
710 opc, asm, cstr, pattern> {
712 let Inst{5} = 1; // H bit
713 let Inst{6} = 1; // S bit
715 let Inst{20} = 1; // L bit
716 let Inst{21} = 1; // W bit
717 let Inst{24} = 1; // P bit
718 let Inst{27-25} = 0b000;
720 class AI3ldsbpr<dag oops, dag iops, Format f, InstrItinClass itin,
721 string opc, string asm, string cstr, list<dag> pattern>
722 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
723 opc, asm, cstr, pattern> {
725 let Inst{5} = 0; // H bit
726 let Inst{6} = 1; // S bit
728 let Inst{20} = 1; // L bit
729 let Inst{21} = 1; // W bit
730 let Inst{24} = 1; // P bit
731 let Inst{27-25} = 0b000;
733 class AI3lddpr<dag oops, dag iops, Format f, InstrItinClass itin,
734 string opc, string asm, string cstr, list<dag> pattern>
735 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
736 opc, asm, cstr, pattern> {
738 let Inst{5} = 0; // H bit
739 let Inst{6} = 1; // S bit
741 let Inst{20} = 0; // L bit
742 let Inst{21} = 1; // W bit
743 let Inst{24} = 1; // P bit
744 let Inst{27-25} = 0b000;
748 // Pre-indexed stores
749 class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
750 string opc, string asm, string cstr, list<dag> pattern>
751 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
752 opc, asm, cstr, pattern> {
754 let Inst{5} = 1; // H bit
755 let Inst{6} = 0; // S bit
757 let Inst{20} = 0; // L bit
758 let Inst{21} = 1; // W bit
759 let Inst{24} = 1; // P bit
760 let Inst{27-25} = 0b000;
762 class AI3stdpr<dag oops, dag iops, Format f, InstrItinClass itin,
763 string opc, string asm, string cstr, list<dag> pattern>
764 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
765 opc, asm, cstr, pattern> {
767 let Inst{5} = 1; // H bit
768 let Inst{6} = 1; // S bit
770 let Inst{20} = 0; // L bit
771 let Inst{21} = 1; // W bit
772 let Inst{24} = 1; // P bit
773 let Inst{27-25} = 0b000;
776 // Post-indexed loads
777 class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin,
778 string opc, string asm, string cstr, list<dag> pattern>
779 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
780 opc, asm, cstr,pattern> {
782 let Inst{5} = 1; // H bit
783 let Inst{6} = 0; // S bit
785 let Inst{20} = 1; // L bit
786 let Inst{21} = 0; // W bit
787 let Inst{24} = 0; // P bit
788 let Inst{27-25} = 0b000;
790 class AI3ldshpo<dag oops, dag iops, Format f, InstrItinClass itin,
791 string opc, string asm, string cstr, list<dag> pattern>
792 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
793 opc, asm, cstr,pattern> {
795 let Inst{5} = 1; // H bit
796 let Inst{6} = 1; // S bit
798 let Inst{20} = 1; // L bit
799 let Inst{21} = 0; // W bit
800 let Inst{24} = 0; // P bit
801 let Inst{27-25} = 0b000;
803 class AI3ldsbpo<dag oops, dag iops, Format f, InstrItinClass itin,
804 string opc, string asm, string cstr, list<dag> pattern>
805 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
806 opc, asm, cstr,pattern> {
808 let Inst{5} = 0; // H bit
809 let Inst{6} = 1; // S bit
811 let Inst{20} = 1; // L bit
812 let Inst{21} = 0; // W bit
813 let Inst{24} = 0; // P bit
814 let Inst{27-25} = 0b000;
816 class AI3lddpo<dag oops, dag iops, Format f, InstrItinClass itin,
817 string opc, string asm, string cstr, list<dag> pattern>
818 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
819 opc, asm, cstr, pattern> {
821 let Inst{5} = 0; // H bit
822 let Inst{6} = 1; // S bit
824 let Inst{20} = 0; // L bit
825 let Inst{21} = 0; // W bit
826 let Inst{24} = 0; // P bit
827 let Inst{27-25} = 0b000;
830 // Post-indexed stores
831 class AI3sthpo<dag oops, dag iops, Format f, InstrItinClass itin,
832 string opc, string asm, string cstr, list<dag> pattern>
833 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
834 opc, asm, cstr,pattern> {
836 let Inst{5} = 1; // H bit
837 let Inst{6} = 0; // S bit
839 let Inst{20} = 0; // L bit
840 let Inst{21} = 0; // W bit
841 let Inst{24} = 0; // P bit
842 let Inst{27-25} = 0b000;
844 class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
845 string opc, string asm, string cstr, list<dag> pattern>
846 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
847 opc, asm, cstr, pattern> {
849 let Inst{5} = 1; // H bit
850 let Inst{6} = 1; // S bit
852 let Inst{20} = 0; // L bit
853 let Inst{21} = 0; // W bit
854 let Inst{24} = 0; // P bit
855 let Inst{27-25} = 0b000;
858 // addrmode4 instructions
859 class AXI4ld<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
860 string asm, string cstr, list<dag> pattern>
861 : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
862 asm, cstr, pattern> {
863 let Inst{20} = 1; // L bit
864 let Inst{22} = 0; // S bit
865 let Inst{27-25} = 0b100;
867 class AXI4st<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
868 string asm, string cstr, list<dag> pattern>
869 : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
870 asm, cstr, pattern> {
871 let Inst{20} = 0; // L bit
872 let Inst{22} = 0; // S bit
873 let Inst{27-25} = 0b100;
876 // Unsigned multiply, multiply-accumulate instructions.
877 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
878 string opc, string asm, list<dag> pattern>
879 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
880 opc, asm, "", pattern> {
881 let Inst{7-4} = 0b1001;
882 let Inst{20} = 0; // S bit
883 let Inst{27-21} = opcod;
885 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
886 string opc, string asm, list<dag> pattern>
887 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
888 opc, asm, "", pattern> {
889 let Inst{7-4} = 0b1001;
890 let Inst{27-21} = opcod;
893 // Most significant word multiply
894 class AMul2I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
895 string opc, string asm, list<dag> pattern>
896 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
897 opc, asm, "", pattern> {
898 let Inst{7-4} = 0b1001;
900 let Inst{27-21} = opcod;
903 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
904 class AMulxyI<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
905 string opc, string asm, list<dag> pattern>
906 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
907 opc, asm, "", pattern> {
911 let Inst{27-21} = opcod;
914 // Extend instructions.
915 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
916 string opc, string asm, list<dag> pattern>
917 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin,
918 opc, asm, "", pattern> {
919 let Inst{7-4} = 0b0111;
920 let Inst{27-20} = opcod;
923 // Misc Arithmetic instructions.
924 class AMiscA1I<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
925 string opc, string asm, list<dag> pattern>
926 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin,
927 opc, asm, "", pattern> {
928 let Inst{27-20} = opcod;
931 //===----------------------------------------------------------------------===//
933 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
934 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
935 list<Predicate> Predicates = [IsARM];
937 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
938 list<Predicate> Predicates = [IsARM, HasV5TE];
940 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
941 list<Predicate> Predicates = [IsARM, HasV6];
944 //===----------------------------------------------------------------------===//
946 // Thumb Instruction Format Definitions.
949 // TI - Thumb instruction.
951 class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
952 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
953 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
954 let OutOperandList = oops;
955 let InOperandList = iops;
957 let Pattern = pattern;
958 list<Predicate> Predicates = [IsThumb];
961 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
962 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
964 // Two-address instructions
965 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
967 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "$lhs = $dst",
970 // tBL, tBX 32-bit instructions
971 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
972 dag oops, dag iops, InstrItinClass itin, string asm,
974 : ThumbI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>,
976 let Inst{31-27} = opcod1;
977 let Inst{15-14} = opcod2;
978 let Inst{12} = opcod3;
981 // BR_JT instructions
982 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
984 : ThumbI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
987 class Thumb1I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
988 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
989 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
990 let OutOperandList = oops;
991 let InOperandList = iops;
993 let Pattern = pattern;
994 list<Predicate> Predicates = [IsThumb1Only];
997 class T1I<dag oops, dag iops, InstrItinClass itin,
998 string asm, list<dag> pattern>
999 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>;
1000 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1001 string asm, list<dag> pattern>
1002 : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
1003 class T1JTI<dag oops, dag iops, InstrItinClass itin,
1004 string asm, list<dag> pattern>
1005 : Thumb1I<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
1007 // Two-address instructions
1008 class T1It<dag oops, dag iops, InstrItinClass itin,
1009 string asm, string cstr, list<dag> pattern>
1010 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin,
1011 asm, cstr, pattern>;
1013 // Thumb1 instruction that can either be predicated or set CPSR.
1014 class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1015 InstrItinClass itin,
1016 string opc, string asm, string cstr, list<dag> pattern>
1017 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1018 let OutOperandList = !con(oops, (outs s_cc_out:$s));
1019 let InOperandList = !con(iops, (ins pred:$p));
1020 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
1021 let Pattern = pattern;
1022 list<Predicate> Predicates = [IsThumb1Only];
1025 class T1sI<dag oops, dag iops, InstrItinClass itin,
1026 string opc, string asm, list<dag> pattern>
1027 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
1029 // Two-address instructions
1030 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1031 string opc, string asm, list<dag> pattern>
1032 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
1033 "$lhs = $dst", pattern>;
1035 // Thumb1 instruction that can be predicated.
1036 class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1037 InstrItinClass itin,
1038 string opc, string asm, string cstr, list<dag> pattern>
1039 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1040 let OutOperandList = oops;
1041 let InOperandList = !con(iops, (ins pred:$p));
1042 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1043 let Pattern = pattern;
1044 list<Predicate> Predicates = [IsThumb1Only];
1047 class T1pI<dag oops, dag iops, InstrItinClass itin,
1048 string opc, string asm, list<dag> pattern>
1049 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>;
1051 // Two-address instructions
1052 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1053 string opc, string asm, list<dag> pattern>
1054 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
1055 "$lhs = $dst", pattern>;
1057 class T1pI1<dag oops, dag iops, InstrItinClass itin,
1058 string opc, string asm, list<dag> pattern>
1059 : Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, itin, opc, asm, "", pattern>;
1060 class T1pI2<dag oops, dag iops, InstrItinClass itin,
1061 string opc, string asm, list<dag> pattern>
1062 : Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, itin, opc, asm, "", pattern>;
1063 class T1pI4<dag oops, dag iops, InstrItinClass itin,
1064 string opc, string asm, list<dag> pattern>
1065 : Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, itin, opc, asm, "", pattern>;
1066 class T1pIs<dag oops, dag iops,
1067 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1068 : Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, itin, opc, asm, "", pattern>;
1070 class Encoding16 : Encoding {
1071 let Inst{31-16} = 0x0000;
1074 // A6.2 16-bit Thumb instruction encoding
1075 class T1Encoding<bits<6> opcode> : Encoding16 {
1076 let Inst{15-10} = opcode;
1079 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1080 class T1General<bits<5> opcode> : Encoding16 {
1081 let Inst{15-14} = 0b00;
1082 let Inst{13-9} = opcode;
1085 // A6.2.2 Data-processing encoding.
1086 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1087 let Inst{15-10} = 0b010000;
1088 let Inst{9-6} = opcode;
1091 // A6.2.3 Special data instructions and branch and exchange encoding.
1092 class T1Special<bits<4> opcode> : Encoding16 {
1093 let Inst{15-10} = 0b010001;
1094 let Inst{9-6} = opcode;
1097 // A6.2.4 Load/store single data item encoding.
1098 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1099 let Inst{15-12} = opA;
1100 let Inst{11-9} = opB;
1102 class T1LdSt<bits<3> opB> : T1LoadStore<0b0101, opB>;
1103 class T1LdSt4Imm<bits<3> opB> : T1LoadStore<0b0110, opB>; // Immediate, 4 bytes
1104 class T1LdSt1Imm<bits<3> opB> : T1LoadStore<0b0111, opB>; // Immediate, 1 byte
1105 class T1LdSt2Imm<bits<3> opB> : T1LoadStore<0b1000, opB>; // Immediate, 2 bytes
1106 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
1108 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1109 class T1Misc<bits<7> opcode> : Encoding16 {
1110 let Inst{15-12} = 0b1011;
1111 let Inst{11-5} = opcode;
1114 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1115 class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1116 InstrItinClass itin,
1117 string opc, string asm, string cstr, list<dag> pattern>
1118 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1119 let OutOperandList = oops;
1120 let InOperandList = !con(iops, (ins pred:$p));
1121 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1122 let Pattern = pattern;
1123 list<Predicate> Predicates = [IsThumb2];
1126 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as
1127 // an input operand since by default it's a zero register. It will
1128 // become an implicit def once it's "flipped".
1129 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1131 class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1132 InstrItinClass itin,
1133 string opc, string asm, string cstr, list<dag> pattern>
1134 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1135 let OutOperandList = oops;
1136 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1137 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
1138 let Pattern = pattern;
1139 list<Predicate> Predicates = [IsThumb2];
1143 class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1144 InstrItinClass itin,
1145 string asm, string cstr, list<dag> pattern>
1146 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1147 let OutOperandList = oops;
1148 let InOperandList = iops;
1149 let AsmString = asm;
1150 let Pattern = pattern;
1151 list<Predicate> Predicates = [IsThumb2];
1154 class ThumbXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1155 InstrItinClass itin,
1156 string asm, string cstr, list<dag> pattern>
1157 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1158 let OutOperandList = oops;
1159 let InOperandList = iops;
1160 let AsmString = asm;
1161 let Pattern = pattern;
1162 list<Predicate> Predicates = [IsThumb1Only];
1165 class T2I<dag oops, dag iops, InstrItinClass itin,
1166 string opc, string asm, list<dag> pattern>
1167 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1168 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1169 string opc, string asm, list<dag> pattern>
1170 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, itin, opc, asm, "",pattern>;
1171 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1172 string opc, string asm, list<dag> pattern>
1173 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, itin, opc, asm, "", pattern>;
1174 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1175 string opc, string asm, list<dag> pattern>
1176 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, itin, opc, asm, "", pattern>;
1177 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1178 string opc, string asm, list<dag> pattern>
1179 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, itin, opc, asm, "", pattern>;
1180 class T2Ii8s4<bit P, bit W, bit load, dag oops, dag iops, InstrItinClass itin,
1181 string opc, string asm, list<dag> pattern>
1182 : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, itin, opc, asm, "",
1184 let Inst{31-27} = 0b11101;
1185 let Inst{26-25} = 0b00;
1187 let Inst{23} = ?; // The U bit.
1190 let Inst{20} = load;
1193 class T2sI<dag oops, dag iops, InstrItinClass itin,
1194 string opc, string asm, list<dag> pattern>
1195 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
1197 class T2XI<dag oops, dag iops, InstrItinClass itin,
1198 string asm, list<dag> pattern>
1199 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
1200 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1201 string asm, list<dag> pattern>
1202 : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
1204 class T2Ix2<dag oops, dag iops, InstrItinClass itin,
1205 string opc, string asm, list<dag> pattern>
1206 : Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>;
1208 // Two-address instructions
1209 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1210 string asm, string cstr, list<dag> pattern>
1211 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, cstr, pattern>;
1213 // T2Iidxldst - Thumb2 indexed load / store instructions.
1214 class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
1216 AddrMode am, IndexMode im, InstrItinClass itin,
1217 string opc, string asm, string cstr, list<dag> pattern>
1218 : InstARM<am, Size4Bytes, im, ThumbFrm, GenericDomain, cstr, itin> {
1219 let OutOperandList = oops;
1220 let InOperandList = !con(iops, (ins pred:$p));
1221 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1222 let Pattern = pattern;
1223 list<Predicate> Predicates = [IsThumb2];
1224 let Inst{31-27} = 0b11111;
1225 let Inst{26-25} = 0b00;
1226 let Inst{24} = signed;
1228 let Inst{22-21} = opcod;
1229 let Inst{20} = load;
1231 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1232 let Inst{10} = pre; // The P bit.
1233 let Inst{8} = 1; // The W bit.
1236 // Helper class for disassembly only
1237 // A6.3.16 & A6.3.17
1238 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1239 class T2I_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, dag iops,
1240 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1241 : T2I<oops, iops, itin, opc, asm, pattern> {
1242 let Inst{31-27} = 0b11111;
1243 let Inst{26-24} = 0b011;
1244 let Inst{23} = long;
1245 let Inst{22-20} = op22_20;
1246 let Inst{7-4} = op7_4;
1249 // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
1250 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
1251 list<Predicate> Predicates = [IsThumb1Only, HasV5T];
1254 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1255 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1256 list<Predicate> Predicates = [IsThumb1Only];
1259 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1260 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1261 list<Predicate> Predicates = [IsThumb2];
1264 //===----------------------------------------------------------------------===//
1266 //===----------------------------------------------------------------------===//
1267 // ARM VFP Instruction templates.
1270 // Almost all VFP instructions are predicable.
1271 class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1272 IndexMode im, Format f, InstrItinClass itin,
1273 string opc, string asm, string cstr, list<dag> pattern>
1274 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1275 let OutOperandList = oops;
1276 let InOperandList = !con(iops, (ins pred:$p));
1277 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
1278 let Pattern = pattern;
1279 list<Predicate> Predicates = [HasVFP2];
1283 class VFPXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1284 IndexMode im, Format f, InstrItinClass itin,
1285 string asm, string cstr, list<dag> pattern>
1286 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1287 let OutOperandList = oops;
1288 let InOperandList = iops;
1289 let AsmString = asm;
1290 let Pattern = pattern;
1291 list<Predicate> Predicates = [HasVFP2];
1294 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1295 string opc, string asm, list<dag> pattern>
1296 : VFPI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin,
1297 opc, asm, "", pattern>;
1299 // ARM VFP addrmode5 loads and stores
1300 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1301 InstrItinClass itin,
1302 string opc, string asm, list<dag> pattern>
1303 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1304 VFPLdStFrm, itin, opc, asm, "", pattern> {
1305 // TODO: Mark the instructions with the appropriate subtarget info.
1306 let Inst{27-24} = opcod1;
1307 let Inst{21-20} = opcod2;
1308 let Inst{11-8} = 0b1011;
1310 // 64-bit loads & stores operate on both NEON and VFP pipelines.
1311 let Dom = VFPNeonDomain.Value;
1314 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1315 InstrItinClass itin,
1316 string opc, string asm, list<dag> pattern>
1317 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
1318 VFPLdStFrm, itin, opc, asm, "", pattern> {
1319 // TODO: Mark the instructions with the appropriate subtarget info.
1320 let Inst{27-24} = opcod1;
1321 let Inst{21-20} = opcod2;
1322 let Inst{11-8} = 0b1010;
1325 // Load / store multiple
1326 class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1327 string asm, string cstr, list<dag> pattern>
1328 : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
1329 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1330 // TODO: Mark the instructions with the appropriate subtarget info.
1331 let Inst{27-25} = 0b110;
1332 let Inst{11-8} = 0b1011;
1334 // 64-bit loads & stores operate on both NEON and VFP pipelines.
1335 let Dom = VFPNeonDomain.Value;
1338 class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1339 string asm, string cstr, list<dag> pattern>
1340 : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
1341 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1342 // TODO: Mark the instructions with the appropriate subtarget info.
1343 let Inst{27-25} = 0b110;
1344 let Inst{11-8} = 0b1010;
1347 // Double precision, unary
1348 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1349 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1350 string asm, list<dag> pattern>
1351 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1352 let Inst{27-23} = opcod1;
1353 let Inst{21-20} = opcod2;
1354 let Inst{19-16} = opcod3;
1355 let Inst{11-8} = 0b1011;
1356 let Inst{7-6} = opcod4;
1357 let Inst{4} = opcod5;
1360 // Double precision, binary
1361 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1362 dag iops, InstrItinClass itin, string opc, string asm,
1364 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1365 let Inst{27-23} = opcod1;
1366 let Inst{21-20} = opcod2;
1367 let Inst{11-8} = 0b1011;
1372 // Single precision, unary
1373 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1374 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1375 string asm, list<dag> pattern>
1376 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1377 let Inst{27-23} = opcod1;
1378 let Inst{21-20} = opcod2;
1379 let Inst{19-16} = opcod3;
1380 let Inst{11-8} = 0b1010;
1381 let Inst{7-6} = opcod4;
1382 let Inst{4} = opcod5;
1385 // Single precision unary, if no NEON
1386 // Same as ASuI except not available if NEON is enabled
1387 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1388 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1389 string asm, list<dag> pattern>
1390 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1392 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1395 // Single precision, binary
1396 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1397 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1398 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1399 let Inst{27-23} = opcod1;
1400 let Inst{21-20} = opcod2;
1401 let Inst{11-8} = 0b1010;
1406 // Single precision binary, if no NEON
1407 // Same as ASbI except not available if NEON is enabled
1408 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1409 dag iops, InstrItinClass itin, string opc, string asm,
1411 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1412 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1415 // VFP conversion instructions
1416 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1417 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1419 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1420 let Inst{27-23} = opcod1;
1421 let Inst{21-20} = opcod2;
1422 let Inst{19-16} = opcod3;
1423 let Inst{11-8} = opcod4;
1428 // VFP conversion between floating-point and fixed-point
1429 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
1430 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1432 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
1433 // size (fixed-point number): sx == 0 ? 16 : 32
1434 let Inst{7} = op5; // sx
1437 // VFP conversion instructions, if no NEON
1438 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1439 dag oops, dag iops, InstrItinClass itin,
1440 string opc, string asm, list<dag> pattern>
1441 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1443 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1446 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
1447 InstrItinClass itin,
1448 string opc, string asm, list<dag> pattern>
1449 : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
1450 let Inst{27-20} = opcod1;
1451 let Inst{11-8} = opcod2;
1455 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1456 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1457 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
1459 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1460 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1461 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
1463 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1464 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1465 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
1467 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1468 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1469 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
1471 //===----------------------------------------------------------------------===//
1473 //===----------------------------------------------------------------------===//
1474 // ARM NEON Instruction templates.
1477 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1478 InstrItinClass itin, string opc, string dt, string asm, string cstr,
1480 : InstARM<am, Size4Bytes, im, f, NeonDomain, cstr, itin> {
1481 let OutOperandList = oops;
1482 let InOperandList = !con(iops, (ins pred:$p));
1483 let AsmString = !strconcat(
1484 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1485 !strconcat("\t", asm));
1486 let Pattern = pattern;
1487 list<Predicate> Predicates = [HasNEON];
1490 // Same as NeonI except it does not have a "data type" specifier.
1491 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1492 InstrItinClass itin, string opc, string asm, string cstr,
1494 : InstARM<am, Size4Bytes, im, f, NeonDomain, cstr, itin> {
1495 let OutOperandList = oops;
1496 let InOperandList = !con(iops, (ins pred:$p));
1497 let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
1498 let Pattern = pattern;
1499 list<Predicate> Predicates = [HasNEON];
1502 class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1504 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, NEONFrm, itin, opc, asm, "",
1508 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1509 dag oops, dag iops, InstrItinClass itin,
1510 string opc, string dt, string asm, string cstr, list<dag> pattern>
1511 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
1513 let Inst{31-24} = 0b11110100;
1514 let Inst{23} = op23;
1515 let Inst{21-20} = op21_20;
1516 let Inst{11-8} = op11_8;
1517 let Inst{7-4} = op7_4;
1520 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
1521 string opc, string dt, string asm, string cstr, list<dag> pattern>
1522 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
1524 let Inst{31-25} = 0b1111001;
1527 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
1528 string opc, string asm, string cstr, list<dag> pattern>
1529 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
1531 let Inst{31-25} = 0b1111001;
1534 // NEON "one register and a modified immediate" format.
1535 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1537 dag oops, dag iops, InstrItinClass itin,
1538 string opc, string dt, string asm, string cstr,
1540 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
1541 let Inst{23} = op23;
1542 let Inst{21-19} = op21_19;
1543 let Inst{11-8} = op11_8;
1550 // NEON 2 vector register format.
1551 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1552 bits<5> op11_7, bit op6, bit op4,
1553 dag oops, dag iops, InstrItinClass itin,
1554 string opc, string dt, string asm, string cstr, list<dag> pattern>
1555 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
1556 let Inst{24-23} = op24_23;
1557 let Inst{21-20} = op21_20;
1558 let Inst{19-18} = op19_18;
1559 let Inst{17-16} = op17_16;
1560 let Inst{11-7} = op11_7;
1565 // Same as N2V except it doesn't have a datatype suffix.
1566 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1567 bits<5> op11_7, bit op6, bit op4,
1568 dag oops, dag iops, InstrItinClass itin,
1569 string opc, string asm, string cstr, list<dag> pattern>
1570 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
1571 let Inst{24-23} = op24_23;
1572 let Inst{21-20} = op21_20;
1573 let Inst{19-18} = op19_18;
1574 let Inst{17-16} = op17_16;
1575 let Inst{11-7} = op11_7;
1580 // NEON 2 vector register with immediate.
1581 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
1582 dag oops, dag iops, InstrItinClass itin,
1583 string opc, string dt, string asm, string cstr, list<dag> pattern>
1584 : NDataI<oops, iops, NEONFrm, itin, opc, dt, asm, cstr, pattern> {
1585 let Inst{24} = op24;
1586 let Inst{23} = op23;
1587 let Inst{11-8} = op11_8;
1593 // NEON 3 vector register format.
1594 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
1595 dag oops, dag iops, InstrItinClass itin,
1596 string opc, string dt, string asm, string cstr, list<dag> pattern>
1597 : NDataI<oops, iops, NEONFrm, itin, opc, dt, asm, cstr, pattern> {
1598 let Inst{24} = op24;
1599 let Inst{23} = op23;
1600 let Inst{21-20} = op21_20;
1601 let Inst{11-8} = op11_8;
1606 // Same as N3V except it doesn't have a data type suffix.
1607 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
1609 dag oops, dag iops, InstrItinClass itin,
1610 string opc, string asm, string cstr, list<dag> pattern>
1611 : NDataXI<oops, iops, NEONFrm, itin, opc, asm, cstr, pattern> {
1612 let Inst{24} = op24;
1613 let Inst{23} = op23;
1614 let Inst{21-20} = op21_20;
1615 let Inst{11-8} = op11_8;
1620 // NEON VMOVs between scalar and core registers.
1621 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1622 dag oops, dag iops, Format f, InstrItinClass itin,
1623 string opc, string dt, string asm, list<dag> pattern>
1624 : InstARM<AddrModeNone, Size4Bytes, IndexModeNone, f, GenericDomain,
1626 let Inst{27-20} = opcod1;
1627 let Inst{11-8} = opcod2;
1628 let Inst{6-5} = opcod3;
1631 let OutOperandList = oops;
1632 let InOperandList = !con(iops, (ins pred:$p));
1633 let AsmString = !strconcat(
1634 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
1635 !strconcat("\t", asm));
1636 let Pattern = pattern;
1637 list<Predicate> Predicates = [HasNEON];
1639 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1640 dag oops, dag iops, InstrItinClass itin,
1641 string opc, string dt, string asm, list<dag> pattern>
1642 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, itin,
1643 opc, dt, asm, pattern>;
1644 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1645 dag oops, dag iops, InstrItinClass itin,
1646 string opc, string dt, string asm, list<dag> pattern>
1647 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, itin,
1648 opc, dt, asm, pattern>;
1649 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1650 dag oops, dag iops, InstrItinClass itin,
1651 string opc, string dt, string asm, list<dag> pattern>
1652 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, itin,
1653 opc, dt, asm, pattern>;
1655 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
1656 // for single-precision FP.
1657 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
1658 list<Predicate> Predicates = [HasNEON,UseNEONForFP];