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 DPSoRegRegFrm : 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 SatFrm : Format<13>;
40 def ExtFrm : Format<14>;
42 def VFPUnaryFrm : Format<15>;
43 def VFPBinaryFrm : Format<16>;
44 def VFPConv1Frm : Format<17>;
45 def VFPConv2Frm : Format<18>;
46 def VFPConv3Frm : Format<19>;
47 def VFPConv4Frm : Format<20>;
48 def VFPConv5Frm : Format<21>;
49 def VFPLdStFrm : Format<22>;
50 def VFPLdStMulFrm : Format<23>;
51 def VFPMiscFrm : Format<24>;
53 def ThumbFrm : Format<25>;
54 def MiscFrm : Format<26>;
56 def NGetLnFrm : Format<27>;
57 def NSetLnFrm : Format<28>;
58 def NDupFrm : Format<29>;
59 def NLdStFrm : Format<30>;
60 def N1RegModImmFrm: Format<31>;
61 def N2RegFrm : Format<32>;
62 def NVCVTFrm : Format<33>;
63 def NVDupLnFrm : Format<34>;
64 def N2RegVShLFrm : Format<35>;
65 def N2RegVShRFrm : Format<36>;
66 def N3RegFrm : Format<37>;
67 def N3RegVShFrm : Format<38>;
68 def NVExtFrm : Format<39>;
69 def NVMulSLFrm : Format<40>;
70 def NVTBLFrm : Format<41>;
71 def DPSoRegImmFrm : Format<42>;
75 // The instruction has an Rn register operand.
76 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
77 // it doesn't have a Rn operand.
78 class UnaryDP { bit isUnaryDataProc = 1; }
80 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
81 // a 16-bit Thumb instruction if certain conditions are met.
82 class Xform16Bit { bit canXformTo16Bit = 1; }
84 //===----------------------------------------------------------------------===//
85 // ARM Instruction flags. These need to match ARMBaseInstrInfo.h.
88 // FIXME: Once the JIT is MC-ized, these can go away.
90 class AddrMode<bits<5> val> {
93 def AddrModeNone : AddrMode<0>;
94 def AddrMode1 : AddrMode<1>;
95 def AddrMode2 : AddrMode<2>;
96 def AddrMode3 : AddrMode<3>;
97 def AddrMode4 : AddrMode<4>;
98 def AddrMode5 : AddrMode<5>;
99 def AddrMode6 : AddrMode<6>;
100 def AddrModeT1_1 : AddrMode<7>;
101 def AddrModeT1_2 : AddrMode<8>;
102 def AddrModeT1_4 : AddrMode<9>;
103 def AddrModeT1_s : AddrMode<10>;
104 def AddrModeT2_i12 : AddrMode<11>;
105 def AddrModeT2_i8 : AddrMode<12>;
106 def AddrModeT2_so : AddrMode<13>;
107 def AddrModeT2_pc : AddrMode<14>;
108 def AddrModeT2_i8s4 : AddrMode<15>;
109 def AddrMode_i12 : AddrMode<16>;
111 // Load / store index mode.
112 class IndexMode<bits<2> val> {
115 def IndexModeNone : IndexMode<0>;
116 def IndexModePre : IndexMode<1>;
117 def IndexModePost : IndexMode<2>;
118 def IndexModeUpd : IndexMode<3>;
120 // Instruction execution domain.
121 class Domain<bits<3> val> {
124 def GenericDomain : Domain<0>;
125 def VFPDomain : Domain<1>; // Instructions in VFP domain only
126 def NeonDomain : Domain<2>; // Instructions in Neon domain only
127 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
128 def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
130 //===----------------------------------------------------------------------===//
131 // ARM special operands.
134 // ARM imod and iflag operands, used only by the CPS instruction.
135 def imod_op : Operand<i32> {
136 let PrintMethod = "printCPSIMod";
139 def ProcIFlagsOperand : AsmOperandClass {
140 let Name = "ProcIFlags";
141 let ParserMethod = "parseProcIFlagsOperand";
143 def iflags_op : Operand<i32> {
144 let PrintMethod = "printCPSIFlag";
145 let ParserMatchClass = ProcIFlagsOperand;
148 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
149 // register whose default is 0 (no register).
150 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
151 def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
152 (ops (i32 14), (i32 zero_reg))> {
153 let PrintMethod = "printPredicateOperand";
154 let ParserMatchClass = CondCodeOperand;
155 let DecoderMethod = "DecodePredicateOperand";
158 // Selectable predicate operand for CMOV instructions. We can't use a normal
159 // predicate because the default values interfere with instruction selection. In
160 // all other respects it is identical though: pseudo-instruction expansion
161 // relies on the MachineOperands being compatible.
162 def cmovpred : Operand<i32>, PredicateOp,
163 ComplexPattern<i32, 2, "SelectCMOVPred"> {
164 let MIOperandInfo = (ops i32imm, i32imm);
165 let PrintMethod = "printPredicateOperand";
168 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
169 def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
170 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
171 let EncoderMethod = "getCCOutOpValue";
172 let PrintMethod = "printSBitModifierOperand";
173 let ParserMatchClass = CCOutOperand;
174 let DecoderMethod = "DecodeCCOutOperand";
177 // Same as cc_out except it defaults to setting CPSR.
178 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
179 let EncoderMethod = "getCCOutOpValue";
180 let PrintMethod = "printSBitModifierOperand";
181 let ParserMatchClass = CCOutOperand;
182 let DecoderMethod = "DecodeCCOutOperand";
185 // ARM special operands for disassembly only.
187 def SetEndAsmOperand : ImmAsmOperand {
188 let Name = "SetEndImm";
189 let ParserMethod = "parseSetEndImm";
191 def setend_op : Operand<i32> {
192 let PrintMethod = "printSetendOperand";
193 let ParserMatchClass = SetEndAsmOperand;
196 def MSRMaskOperand : AsmOperandClass {
197 let Name = "MSRMask";
198 let ParserMethod = "parseMSRMaskOperand";
200 def msr_mask : Operand<i32> {
201 let PrintMethod = "printMSRMaskOperand";
202 let DecoderMethod = "DecodeMSRMask";
203 let ParserMatchClass = MSRMaskOperand;
206 // Shift Right Immediate - A shift right immediate is encoded differently from
207 // other shift immediates. The imm6 field is encoded like so:
210 // 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
211 // 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
212 // 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
213 // 64 64 - <imm> is encoded in imm6<5:0>
214 def shr_imm8_asm_operand : ImmAsmOperand { let Name = "ShrImm8"; }
215 def shr_imm8 : Operand<i32> {
216 let EncoderMethod = "getShiftRight8Imm";
217 let DecoderMethod = "DecodeShiftRight8Imm";
218 let ParserMatchClass = shr_imm8_asm_operand;
220 def shr_imm16_asm_operand : ImmAsmOperand { let Name = "ShrImm16"; }
221 def shr_imm16 : Operand<i32> {
222 let EncoderMethod = "getShiftRight16Imm";
223 let DecoderMethod = "DecodeShiftRight16Imm";
224 let ParserMatchClass = shr_imm16_asm_operand;
226 def shr_imm32_asm_operand : ImmAsmOperand { let Name = "ShrImm32"; }
227 def shr_imm32 : Operand<i32> {
228 let EncoderMethod = "getShiftRight32Imm";
229 let DecoderMethod = "DecodeShiftRight32Imm";
230 let ParserMatchClass = shr_imm32_asm_operand;
232 def shr_imm64_asm_operand : ImmAsmOperand { let Name = "ShrImm64"; }
233 def shr_imm64 : Operand<i32> {
234 let EncoderMethod = "getShiftRight64Imm";
235 let DecoderMethod = "DecodeShiftRight64Imm";
236 let ParserMatchClass = shr_imm64_asm_operand;
239 //===----------------------------------------------------------------------===//
240 // ARM Assembler alias templates.
242 class ARMInstAlias<string Asm, dag Result, bit Emit = 0b1>
243 : InstAlias<Asm, Result, Emit>, Requires<[IsARM]>;
244 class tInstAlias<string Asm, dag Result, bit Emit = 0b1>
245 : InstAlias<Asm, Result, Emit>, Requires<[IsThumb]>;
246 class t2InstAlias<string Asm, dag Result, bit Emit = 0b1>
247 : InstAlias<Asm, Result, Emit>, Requires<[IsThumb2]>;
248 class VFP2InstAlias<string Asm, dag Result, bit Emit = 0b1>
249 : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2]>;
250 class VFP3InstAlias<string Asm, dag Result, bit Emit = 0b1>
251 : InstAlias<Asm, Result, Emit>, Requires<[HasVFP3]>;
252 class NEONInstAlias<string Asm, dag Result, bit Emit = 0b1>
253 : InstAlias<Asm, Result, Emit>, Requires<[HasNEON]>;
256 class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
258 class NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
261 //===----------------------------------------------------------------------===//
262 // ARM Instruction templates.
266 class InstTemplate<AddrMode am, int sz, IndexMode im,
267 Format f, Domain d, string cstr, InstrItinClass itin>
269 let Namespace = "ARM";
274 bits<2> IndexModeBits = IM.Value;
276 bits<6> Form = F.Value;
278 bit isUnaryDataProc = 0;
279 bit canXformTo16Bit = 0;
280 // The instruction is a 16-bit flag setting Thumb instruction. Used
281 // by the parser to determine whether to require the 'S' suffix on the
282 // mnemonic (when not in an IT block) or preclude it (when in an IT block).
283 bit thumbArithFlagSetting = 0;
285 // If this is a pseudo instruction, mark it isCodeGenOnly.
286 let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
288 // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
289 let TSFlags{4-0} = AM.Value;
290 let TSFlags{6-5} = IndexModeBits;
291 let TSFlags{12-7} = Form;
292 let TSFlags{13} = isUnaryDataProc;
293 let TSFlags{14} = canXformTo16Bit;
294 let TSFlags{17-15} = D.Value;
295 let TSFlags{18} = thumbArithFlagSetting;
297 let Constraints = cstr;
298 let Itinerary = itin;
303 // Mask of bits that cause an encoding to be UNPREDICTABLE.
304 // If a bit is set, then if the corresponding bit in the
305 // target encoding differs from its value in the "Inst" field,
306 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
307 field bits<32> Unpredictable = 0;
308 // SoftFail is the generic name for this field, but we alias it so
309 // as to make it more obvious what it means in ARM-land.
310 field bits<32> SoftFail = Unpredictable;
313 class InstARM<AddrMode am, int sz, IndexMode im,
314 Format f, Domain d, string cstr, InstrItinClass itin>
315 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
316 let DecoderNamespace = "ARM";
319 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
320 // on by adding flavors to specific instructions.
321 class InstThumb<AddrMode am, int sz, IndexMode im,
322 Format f, Domain d, string cstr, InstrItinClass itin>
323 : InstTemplate<am, sz, im, f, d, cstr, itin> {
324 let DecoderNamespace = "Thumb";
327 // Pseudo-instructions for alternate assembly syntax (never used by codegen).
328 // These are aliases that require C++ handling to convert to the target
329 // instruction, while InstAliases can be handled directly by tblgen.
330 class AsmPseudoInst<string asm, dag iops>
331 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
333 let OutOperandList = (outs);
334 let InOperandList = iops;
336 let isCodeGenOnly = 0; // So we get asm matcher for it.
341 class ARMAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
343 class tAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
345 class t2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
346 Requires<[IsThumb2]>;
347 class VFP2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
349 class NEONAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
352 // Pseudo instructions for the code generator.
353 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
354 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
355 GenericDomain, "", itin> {
356 let OutOperandList = oops;
357 let InOperandList = iops;
358 let Pattern = pattern;
359 let isCodeGenOnly = 1;
363 // PseudoInst that's ARM-mode only.
364 class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
366 : PseudoInst<oops, iops, itin, pattern> {
368 list<Predicate> Predicates = [IsARM];
371 // PseudoInst that's Thumb-mode only.
372 class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
374 : PseudoInst<oops, iops, itin, pattern> {
376 list<Predicate> Predicates = [IsThumb];
379 // PseudoInst that's Thumb2-mode only.
380 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
382 : PseudoInst<oops, iops, itin, pattern> {
384 list<Predicate> Predicates = [IsThumb2];
387 class ARMPseudoExpand<dag oops, dag iops, int sz,
388 InstrItinClass itin, list<dag> pattern,
390 : ARMPseudoInst<oops, iops, sz, itin, pattern>,
391 PseudoInstExpansion<Result>;
393 class tPseudoExpand<dag oops, dag iops, int sz,
394 InstrItinClass itin, list<dag> pattern,
396 : tPseudoInst<oops, iops, sz, itin, pattern>,
397 PseudoInstExpansion<Result>;
399 class t2PseudoExpand<dag oops, dag iops, int sz,
400 InstrItinClass itin, list<dag> pattern,
402 : t2PseudoInst<oops, iops, sz, itin, pattern>,
403 PseudoInstExpansion<Result>;
405 // Almost all ARM instructions are predicable.
406 class I<dag oops, dag iops, AddrMode am, int sz,
407 IndexMode im, Format f, InstrItinClass itin,
408 string opc, string asm, string cstr,
410 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
413 let OutOperandList = oops;
414 let InOperandList = !con(iops, (ins pred:$p));
415 let AsmString = !strconcat(opc, "${p}", asm);
416 let Pattern = pattern;
417 list<Predicate> Predicates = [IsARM];
420 // A few are not predicable
421 class InoP<dag oops, dag iops, AddrMode am, int sz,
422 IndexMode im, Format f, InstrItinClass itin,
423 string opc, string asm, string cstr,
425 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
426 let OutOperandList = oops;
427 let InOperandList = iops;
428 let AsmString = !strconcat(opc, asm);
429 let Pattern = pattern;
430 let isPredicable = 0;
431 list<Predicate> Predicates = [IsARM];
434 // Same as I except it can optionally modify CPSR. Note it's modeled as an input
435 // operand since by default it's a zero register. It will become an implicit def
436 // once it's "flipped".
437 class sI<dag oops, dag iops, AddrMode am, int sz,
438 IndexMode im, Format f, InstrItinClass itin,
439 string opc, string asm, string cstr,
441 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
442 bits<4> p; // Predicate operand
443 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
447 let OutOperandList = oops;
448 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
449 let AsmString = !strconcat(opc, "${s}${p}", asm);
450 let Pattern = pattern;
451 list<Predicate> Predicates = [IsARM];
455 class XI<dag oops, dag iops, AddrMode am, int sz,
456 IndexMode im, Format f, InstrItinClass itin,
457 string asm, string cstr, list<dag> pattern>
458 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
459 let OutOperandList = oops;
460 let InOperandList = iops;
462 let Pattern = pattern;
463 list<Predicate> Predicates = [IsARM];
466 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
467 string opc, string asm, list<dag> pattern>
468 : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
469 opc, asm, "", pattern>;
470 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
471 string opc, string asm, list<dag> pattern>
472 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
473 opc, asm, "", pattern>;
474 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
475 string asm, list<dag> pattern>
476 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
478 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
479 string opc, string asm, list<dag> pattern>
480 : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
481 opc, asm, "", pattern>;
483 // Ctrl flow instructions
484 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
485 string opc, string asm, list<dag> pattern>
486 : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
487 opc, asm, "", pattern> {
488 let Inst{27-24} = opcod;
490 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
491 string asm, list<dag> pattern>
492 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
494 let Inst{27-24} = opcod;
497 // BR_JT instructions
498 class JTI<dag oops, dag iops, InstrItinClass itin,
499 string asm, list<dag> pattern>
500 : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
503 class AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
504 string opc, string asm, list<dag> pattern>
505 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
506 opc, asm, "", pattern> {
509 let Inst{27-23} = 0b00011;
510 let Inst{22-21} = opcod;
512 let Inst{19-16} = addr;
513 let Inst{15-12} = Rt;
514 let Inst{11-10} = 0b11;
515 let Inst{9-8} = opcod2;
516 let Inst{7-0} = 0b10011111;
518 class AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
519 string opc, string asm, list<dag> pattern>
520 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
521 opc, asm, "", pattern> {
524 let Inst{27-23} = 0b00011;
525 let Inst{22-21} = opcod;
527 let Inst{19-16} = addr;
528 let Inst{11-10} = 0b11;
529 let Inst{9-8} = opcod2;
530 let Inst{7-4} = 0b1001;
533 // Atomic load/store instructions
534 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
535 string opc, string asm, list<dag> pattern>
536 : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>;
538 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
539 string opc, string asm, list<dag> pattern>
540 : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> {
542 let Inst{15-12} = Rd;
545 // Exclusive load/store instructions
547 class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
548 string opc, string asm, list<dag> pattern>
549 : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
550 Requires<[IsARM, HasV8]>;
552 class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
553 string opc, string asm, list<dag> pattern>
554 : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
555 Requires<[IsARM, HasV8]> {
557 let Inst{15-12} = Rd;
560 class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
561 : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
565 let Inst{27-23} = 0b00010;
567 let Inst{21-20} = 0b00;
568 let Inst{19-16} = addr;
569 let Inst{15-12} = Rt;
570 let Inst{11-4} = 0b00001001;
573 let Unpredictable{11-8} = 0b1111;
574 let DecoderMethod = "DecodeSwap";
576 // Acquire/Release load/store instructions
577 class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
578 string opc, string asm, list<dag> pattern>
579 : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
580 Requires<[IsARM, HasV8]>;
582 class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
583 string opc, string asm, list<dag> pattern>
584 : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
585 Requires<[IsARM, HasV8]> {
586 let Inst{15-12} = 0b1111;
589 // addrmode1 instructions
590 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
591 string opc, string asm, list<dag> pattern>
592 : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
593 opc, asm, "", pattern> {
594 let Inst{24-21} = opcod;
595 let Inst{27-26} = 0b00;
597 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
598 string opc, string asm, list<dag> pattern>
599 : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
600 opc, asm, "", pattern> {
601 let Inst{24-21} = opcod;
602 let Inst{27-26} = 0b00;
604 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
605 string asm, list<dag> pattern>
606 : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
608 let Inst{24-21} = opcod;
609 let Inst{27-26} = 0b00;
614 // LDR/LDRB/STR/STRB/...
615 class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
616 Format f, InstrItinClass itin, string opc, string asm,
618 : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
620 let Inst{27-25} = op;
621 let Inst{24} = 1; // 24 == P
623 let Inst{22} = isByte;
624 let Inst{21} = 0; // 21 == W
627 // Indexed load/stores
628 class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
629 IndexMode im, Format f, InstrItinClass itin, string opc,
630 string asm, string cstr, list<dag> pattern>
631 : I<oops, iops, AddrMode2, 4, im, f, itin,
632 opc, asm, cstr, pattern> {
634 let Inst{27-26} = 0b01;
635 let Inst{24} = isPre; // P bit
636 let Inst{22} = isByte; // B bit
637 let Inst{21} = isPre; // W bit
638 let Inst{20} = isLd; // L bit
639 let Inst{15-12} = Rt;
641 class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
642 IndexMode im, Format f, InstrItinClass itin, string opc,
643 string asm, string cstr, list<dag> pattern>
644 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
646 // AM2 store w/ two operands: (GPR, am2offset)
652 let Inst{23} = offset{12};
653 let Inst{19-16} = Rn;
654 let Inst{11-5} = offset{11-5};
656 let Inst{3-0} = offset{3-0};
659 class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
660 IndexMode im, Format f, InstrItinClass itin, string opc,
661 string asm, string cstr, list<dag> pattern>
662 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
664 // AM2 store w/ two operands: (GPR, am2offset)
670 let Inst{23} = offset{12};
671 let Inst{19-16} = Rn;
672 let Inst{11-0} = offset{11-0};
676 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
677 // but for now use this class for STRT and STRBT.
678 class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
679 IndexMode im, Format f, InstrItinClass itin, string opc,
680 string asm, string cstr, list<dag> pattern>
681 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
683 // AM2 store w/ two operands: (GPR, am2offset)
685 // {13} 1 == Rm, 0 == imm12
689 let Inst{25} = addr{13};
690 let Inst{23} = addr{12};
691 let Inst{19-16} = addr{17-14};
692 let Inst{11-0} = addr{11-0};
695 // addrmode3 instructions
696 class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
697 InstrItinClass itin, string opc, string asm, list<dag> pattern>
698 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
699 opc, asm, "", pattern> {
702 let Inst{27-25} = 0b000;
703 let Inst{24} = 1; // P bit
704 let Inst{23} = addr{8}; // U bit
705 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
706 let Inst{21} = 0; // W bit
707 let Inst{20} = op20; // L bit
708 let Inst{19-16} = addr{12-9}; // Rn
709 let Inst{15-12} = Rt; // Rt
710 let Inst{11-8} = addr{7-4}; // imm7_4/zero
712 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
714 let DecoderMethod = "DecodeAddrMode3Instruction";
717 class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
718 IndexMode im, Format f, InstrItinClass itin, string opc,
719 string asm, string cstr, list<dag> pattern>
720 : I<oops, iops, AddrMode3, 4, im, f, itin,
721 opc, asm, cstr, pattern> {
723 let Inst{27-25} = 0b000;
724 let Inst{24} = isPre; // P bit
725 let Inst{21} = isPre; // W bit
726 let Inst{20} = op20; // L bit
727 let Inst{15-12} = Rt; // Rt
731 // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
732 // but for now use this class for LDRSBT, LDRHT, LDSHT.
733 class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
734 IndexMode im, Format f, InstrItinClass itin, string opc,
735 string asm, string cstr, list<dag> pattern>
736 : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
737 // {13} 1 == imm8, 0 == Rm
744 let Inst{27-25} = 0b000;
745 let Inst{24} = 0; // P bit
747 let Inst{20} = isLoad; // L bit
748 let Inst{19-16} = addr; // Rn
749 let Inst{15-12} = Rt; // Rt
754 class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
755 string opc, string asm, list<dag> pattern>
756 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
757 opc, asm, "", pattern> {
760 let Inst{27-25} = 0b000;
761 let Inst{24} = 1; // P bit
762 let Inst{23} = addr{8}; // U bit
763 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
764 let Inst{21} = 0; // W bit
765 let Inst{20} = 0; // L bit
766 let Inst{19-16} = addr{12-9}; // Rn
767 let Inst{15-12} = Rt; // Rt
768 let Inst{11-8} = addr{7-4}; // imm7_4/zero
770 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
771 let DecoderMethod = "DecodeAddrMode3Instruction";
774 // addrmode4 instructions
775 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
776 string asm, string cstr, list<dag> pattern>
777 : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
782 let Inst{27-25} = 0b100;
783 let Inst{22} = 0; // S bit
784 let Inst{19-16} = Rn;
785 let Inst{15-0} = regs;
788 // Unsigned multiply, multiply-accumulate instructions.
789 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
790 string opc, string asm, list<dag> pattern>
791 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
792 opc, asm, "", pattern> {
793 let Inst{7-4} = 0b1001;
794 let Inst{20} = 0; // S bit
795 let Inst{27-21} = opcod;
797 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
798 string opc, string asm, list<dag> pattern>
799 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
800 opc, asm, "", pattern> {
801 let Inst{7-4} = 0b1001;
802 let Inst{27-21} = opcod;
805 // Most significant word multiply
806 class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
807 InstrItinClass itin, string opc, string asm, list<dag> pattern>
808 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
809 opc, asm, "", pattern> {
813 let Inst{7-4} = opc7_4;
815 let Inst{27-21} = opcod;
816 let Inst{19-16} = Rd;
820 // MSW multiple w/ Ra operand
821 class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
822 InstrItinClass itin, string opc, string asm, list<dag> pattern>
823 : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
825 let Inst{15-12} = Ra;
828 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
829 class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
830 InstrItinClass itin, string opc, string asm, list<dag> pattern>
831 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
832 opc, asm, "", pattern> {
838 let Inst{27-21} = opcod;
839 let Inst{6-5} = bit6_5;
843 class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
844 InstrItinClass itin, string opc, string asm, list<dag> pattern>
845 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
847 let Inst{19-16} = Rd;
850 // AMulxyI with Ra operand
851 class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
852 InstrItinClass itin, string opc, string asm, list<dag> pattern>
853 : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
855 let Inst{15-12} = Ra;
858 class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
859 InstrItinClass itin, string opc, string asm, list<dag> pattern>
860 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
863 let Inst{19-16} = RdHi;
864 let Inst{15-12} = RdLo;
867 // Extend instructions.
868 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
869 string opc, string asm, list<dag> pattern>
870 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
871 opc, asm, "", pattern> {
872 // All AExtI instructions have Rd and Rm register operands.
875 let Inst{15-12} = Rd;
877 let Inst{7-4} = 0b0111;
878 let Inst{9-8} = 0b00;
879 let Inst{27-20} = opcod;
881 let Unpredictable{9-8} = 0b11;
884 // Misc Arithmetic instructions.
885 class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
886 InstrItinClass itin, string opc, string asm, list<dag> pattern>
887 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
888 opc, asm, "", pattern> {
891 let Inst{27-20} = opcod;
892 let Inst{19-16} = 0b1111;
893 let Inst{15-12} = Rd;
894 let Inst{11-8} = 0b1111;
895 let Inst{7-4} = opc7_4;
899 // Division instructions.
900 class ADivA1I<bits<3> opcod, dag oops, dag iops,
901 InstrItinClass itin, string opc, string asm, list<dag> pattern>
902 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
903 opc, asm, "", pattern> {
907 let Inst{27-23} = 0b01110;
908 let Inst{22-20} = opcod;
909 let Inst{19-16} = Rd;
910 let Inst{15-12} = 0b1111;
912 let Inst{7-4} = 0b0001;
917 def PKHLSLAsmOperand : ImmAsmOperand {
918 let Name = "PKHLSLImm";
919 let ParserMethod = "parsePKHLSLImm";
921 def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
922 let PrintMethod = "printPKHLSLShiftImm";
923 let ParserMatchClass = PKHLSLAsmOperand;
925 def PKHASRAsmOperand : AsmOperandClass {
926 let Name = "PKHASRImm";
927 let ParserMethod = "parsePKHASRImm";
929 def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
930 let PrintMethod = "printPKHASRShiftImm";
931 let ParserMatchClass = PKHASRAsmOperand;
934 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
935 string opc, string asm, list<dag> pattern>
936 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
937 opc, asm, "", pattern> {
942 let Inst{27-20} = opcod;
943 let Inst{19-16} = Rn;
944 let Inst{15-12} = Rd;
947 let Inst{5-4} = 0b01;
951 //===----------------------------------------------------------------------===//
953 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
954 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
955 list<Predicate> Predicates = [IsARM];
957 class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
958 list<Predicate> Predicates = [IsARM, HasV5T];
960 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
961 list<Predicate> Predicates = [IsARM, HasV5TE];
963 // ARMV5MOPat - Same as ARMV5TEPat with UseMulOps.
964 class ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> {
965 list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps];
967 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
968 list<Predicate> Predicates = [IsARM, HasV6];
971 //===----------------------------------------------------------------------===//
972 // Thumb Instruction Format Definitions.
975 class ThumbI<dag oops, dag iops, AddrMode am, int sz,
976 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
977 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
978 let OutOperandList = oops;
979 let InOperandList = iops;
981 let Pattern = pattern;
982 list<Predicate> Predicates = [IsThumb];
985 // TI - Thumb instruction.
986 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
987 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
989 // Two-address instructions
990 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
992 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
995 // tBL, tBX 32-bit instructions
996 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
997 dag oops, dag iops, InstrItinClass itin, string asm,
999 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
1001 let Inst{31-27} = opcod1;
1002 let Inst{15-14} = opcod2;
1003 let Inst{12} = opcod3;
1006 // BR_JT instructions
1007 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
1009 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1012 class Thumb1I<dag oops, dag iops, AddrMode am, int sz,
1013 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1014 : InstThumb<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 = [IsThumb, IsThumb1Only];
1022 class T1I<dag oops, dag iops, InstrItinClass itin,
1023 string asm, list<dag> pattern>
1024 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1025 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1026 string asm, list<dag> pattern>
1027 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1029 // Two-address instructions
1030 class T1It<dag oops, dag iops, InstrItinClass itin,
1031 string asm, string cstr, list<dag> pattern>
1032 : Thumb1I<oops, iops, AddrModeNone, 2, itin,
1033 asm, cstr, pattern>;
1035 // Thumb1 instruction that can either be predicated or set CPSR.
1036 class Thumb1sI<dag oops, dag iops, AddrMode am, int 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 = !con(oops, (outs s_cc_out:$s));
1041 let InOperandList = !con(iops, (ins pred:$p));
1042 let AsmString = !strconcat(opc, "${s}${p}", asm);
1043 let Pattern = pattern;
1044 let thumbArithFlagSetting = 1;
1045 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1046 let DecoderNamespace = "ThumbSBit";
1049 class T1sI<dag oops, dag iops, InstrItinClass itin,
1050 string opc, string asm, list<dag> pattern>
1051 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1053 // Two-address instructions
1054 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1055 string opc, string asm, list<dag> pattern>
1056 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1057 "$Rn = $Rdn", pattern>;
1059 // Thumb1 instruction that can be predicated.
1060 class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
1061 InstrItinClass itin,
1062 string opc, string asm, string cstr, list<dag> pattern>
1063 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1064 let OutOperandList = oops;
1065 let InOperandList = !con(iops, (ins pred:$p));
1066 let AsmString = !strconcat(opc, "${p}", asm);
1067 let Pattern = pattern;
1068 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1071 class T1pI<dag oops, dag iops, InstrItinClass itin,
1072 string opc, string asm, list<dag> pattern>
1073 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1075 // Two-address instructions
1076 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1077 string opc, string asm, list<dag> pattern>
1078 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1079 "$Rn = $Rdn", pattern>;
1081 class T1pIs<dag oops, dag iops,
1082 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1083 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
1085 class Encoding16 : Encoding {
1086 let Inst{31-16} = 0x0000;
1089 // A6.2 16-bit Thumb instruction encoding
1090 class T1Encoding<bits<6> opcode> : Encoding16 {
1091 let Inst{15-10} = opcode;
1094 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1095 class T1General<bits<5> opcode> : Encoding16 {
1096 let Inst{15-14} = 0b00;
1097 let Inst{13-9} = opcode;
1100 // A6.2.2 Data-processing encoding.
1101 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1102 let Inst{15-10} = 0b010000;
1103 let Inst{9-6} = opcode;
1106 // A6.2.3 Special data instructions and branch and exchange encoding.
1107 class T1Special<bits<4> opcode> : Encoding16 {
1108 let Inst{15-10} = 0b010001;
1109 let Inst{9-6} = opcode;
1112 // A6.2.4 Load/store single data item encoding.
1113 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1114 let Inst{15-12} = opA;
1115 let Inst{11-9} = opB;
1117 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
1119 class T1BranchCond<bits<4> opcode> : Encoding16 {
1120 let Inst{15-12} = opcode;
1123 // Helper classes to encode Thumb1 loads and stores. For immediates, the
1124 // following bits are used for "opA" (see A6.2.4):
1126 // 0b0110 => Immediate, 4 bytes
1127 // 0b1000 => Immediate, 2 bytes
1128 // 0b0111 => Immediate, 1 byte
1129 class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
1130 InstrItinClass itin, string opc, string asm,
1132 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1133 T1LoadStore<0b0101, opcode> {
1136 let Inst{8-6} = addr{5-3}; // Rm
1137 let Inst{5-3} = addr{2-0}; // Rn
1140 class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
1141 InstrItinClass itin, string opc, string asm,
1143 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1144 T1LoadStore<opA, {opB,?,?}> {
1147 let Inst{10-6} = addr{7-3}; // imm5
1148 let Inst{5-3} = addr{2-0}; // Rn
1152 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1153 class T1Misc<bits<7> opcode> : Encoding16 {
1154 let Inst{15-12} = 0b1011;
1155 let Inst{11-5} = opcode;
1158 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1159 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
1160 InstrItinClass itin,
1161 string opc, string asm, string cstr, list<dag> pattern>
1162 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1163 let OutOperandList = oops;
1164 let InOperandList = !con(iops, (ins pred:$p));
1165 let AsmString = !strconcat(opc, "${p}", asm);
1166 let Pattern = pattern;
1167 list<Predicate> Predicates = [IsThumb2];
1168 let DecoderNamespace = "Thumb2";
1171 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
1172 // input operand since by default it's a zero register. It will become an
1173 // implicit def once it's "flipped".
1175 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1177 class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
1178 InstrItinClass itin,
1179 string opc, string asm, string cstr, list<dag> pattern>
1180 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1181 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
1184 let OutOperandList = oops;
1185 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1186 let AsmString = !strconcat(opc, "${s}${p}", asm);
1187 let Pattern = pattern;
1188 list<Predicate> Predicates = [IsThumb2];
1189 let DecoderNamespace = "Thumb2";
1193 class Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
1194 InstrItinClass itin,
1195 string asm, string cstr, list<dag> pattern>
1196 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1197 let OutOperandList = oops;
1198 let InOperandList = iops;
1199 let AsmString = asm;
1200 let Pattern = pattern;
1201 list<Predicate> Predicates = [IsThumb2];
1202 let DecoderNamespace = "Thumb2";
1205 class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
1206 InstrItinClass itin,
1207 string asm, string cstr, list<dag> pattern>
1208 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1209 let OutOperandList = oops;
1210 let InOperandList = iops;
1211 let AsmString = asm;
1212 let Pattern = pattern;
1213 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1214 let DecoderNamespace = "Thumb";
1217 class T2I<dag oops, dag iops, InstrItinClass itin,
1218 string opc, string asm, list<dag> pattern>
1219 : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1220 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1221 string opc, string asm, list<dag> pattern>
1222 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
1223 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1224 string opc, string asm, list<dag> pattern>
1225 : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>;
1226 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1227 string opc, string asm, list<dag> pattern>
1228 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
1229 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1230 string opc, string asm, list<dag> pattern>
1231 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
1232 class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
1233 string opc, string asm, string cstr, list<dag> pattern>
1234 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1239 let Inst{31-25} = 0b1110100;
1241 let Inst{23} = addr{8};
1244 let Inst{20} = isLoad;
1245 let Inst{19-16} = addr{12-9};
1246 let Inst{15-12} = Rt{3-0};
1247 let Inst{11-8} = Rt2{3-0};
1248 let Inst{7-0} = addr{7-0};
1250 class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
1251 InstrItinClass itin, string opc, string asm, string cstr,
1253 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1259 let Inst{31-25} = 0b1110100;
1261 let Inst{23} = imm{8};
1264 let Inst{20} = isLoad;
1265 let Inst{19-16} = addr;
1266 let Inst{15-12} = Rt{3-0};
1267 let Inst{11-8} = Rt2{3-0};
1268 let Inst{7-0} = imm{7-0};
1271 class T2sI<dag oops, dag iops, InstrItinClass itin,
1272 string opc, string asm, list<dag> pattern>
1273 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1275 class T2XI<dag oops, dag iops, InstrItinClass itin,
1276 string asm, list<dag> pattern>
1277 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1278 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1279 string asm, list<dag> pattern>
1280 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1282 // Move to/from coprocessor instructions
1283 class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
1285 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
1286 let Inst{31-28} = opc;
1289 // Two-address instructions
1290 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1291 string asm, string cstr, list<dag> pattern>
1292 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
1294 // T2Ipreldst - Thumb2 pre-indexed load / store instructions.
1295 class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
1297 AddrMode am, IndexMode im, InstrItinClass itin,
1298 string opc, string asm, string cstr, list<dag> pattern>
1299 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1300 let OutOperandList = oops;
1301 let InOperandList = !con(iops, (ins pred:$p));
1302 let AsmString = !strconcat(opc, "${p}", asm);
1303 let Pattern = pattern;
1304 list<Predicate> Predicates = [IsThumb2];
1305 let DecoderNamespace = "Thumb2";
1309 let Inst{31-27} = 0b11111;
1310 let Inst{26-25} = 0b00;
1311 let Inst{24} = signed;
1313 let Inst{22-21} = opcod;
1314 let Inst{20} = load;
1315 let Inst{19-16} = addr{12-9};
1316 let Inst{15-12} = Rt{3-0};
1318 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1319 let Inst{10} = pre; // The P bit.
1320 let Inst{9} = addr{8}; // Sign bit
1321 let Inst{8} = 1; // The W bit.
1322 let Inst{7-0} = addr{7-0};
1324 let DecoderMethod = "DecodeT2LdStPre";
1327 // T2Ipostldst - Thumb2 post-indexed load / store instructions.
1328 class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
1330 AddrMode am, IndexMode im, InstrItinClass itin,
1331 string opc, string asm, string cstr, list<dag> pattern>
1332 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1333 let OutOperandList = oops;
1334 let InOperandList = !con(iops, (ins pred:$p));
1335 let AsmString = !strconcat(opc, "${p}", asm);
1336 let Pattern = pattern;
1337 list<Predicate> Predicates = [IsThumb2];
1338 let DecoderNamespace = "Thumb2";
1343 let Inst{31-27} = 0b11111;
1344 let Inst{26-25} = 0b00;
1345 let Inst{24} = signed;
1347 let Inst{22-21} = opcod;
1348 let Inst{20} = load;
1349 let Inst{19-16} = Rn;
1350 let Inst{15-12} = Rt{3-0};
1352 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1353 let Inst{10} = pre; // The P bit.
1354 let Inst{9} = offset{8}; // Sign bit
1355 let Inst{8} = 1; // The W bit.
1356 let Inst{7-0} = offset{7-0};
1358 let DecoderMethod = "DecodeT2LdStPre";
1361 // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
1362 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
1363 list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T];
1366 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1367 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1368 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1371 // T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
1372 class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
1373 list<Predicate> Predicates = [IsThumb2, HasV6T2];
1376 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1377 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1378 list<Predicate> Predicates = [IsThumb2];
1381 //===----------------------------------------------------------------------===//
1383 //===----------------------------------------------------------------------===//
1384 // ARM VFP Instruction templates.
1387 // Almost all VFP instructions are predicable.
1388 class VFPI<dag oops, dag iops, AddrMode am, int sz,
1389 IndexMode im, Format f, InstrItinClass itin,
1390 string opc, string asm, string cstr, list<dag> pattern>
1391 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1393 let Inst{31-28} = p;
1394 let OutOperandList = oops;
1395 let InOperandList = !con(iops, (ins pred:$p));
1396 let AsmString = !strconcat(opc, "${p}", asm);
1397 let Pattern = pattern;
1398 let PostEncoderMethod = "VFPThumb2PostEncoder";
1399 let DecoderNamespace = "VFP";
1400 list<Predicate> Predicates = [HasVFP2];
1404 class VFPXI<dag oops, dag iops, AddrMode am, int sz,
1405 IndexMode im, Format f, InstrItinClass itin,
1406 string asm, string cstr, list<dag> pattern>
1407 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1409 let Inst{31-28} = p;
1410 let OutOperandList = oops;
1411 let InOperandList = iops;
1412 let AsmString = asm;
1413 let Pattern = pattern;
1414 let PostEncoderMethod = "VFPThumb2PostEncoder";
1415 let DecoderNamespace = "VFP";
1416 list<Predicate> Predicates = [HasVFP2];
1419 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1420 string opc, string asm, list<dag> pattern>
1421 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
1422 opc, asm, "", pattern> {
1423 let PostEncoderMethod = "VFPThumb2PostEncoder";
1426 // ARM VFP addrmode5 loads and stores
1427 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1428 InstrItinClass itin,
1429 string opc, string asm, list<dag> pattern>
1430 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1431 VFPLdStFrm, itin, opc, asm, "", pattern> {
1432 // Instruction operands.
1436 // Encode instruction operands.
1437 let Inst{23} = addr{8}; // U (add = (U == '1'))
1438 let Inst{22} = Dd{4};
1439 let Inst{19-16} = addr{12-9}; // Rn
1440 let Inst{15-12} = Dd{3-0};
1441 let Inst{7-0} = addr{7-0}; // imm8
1443 let Inst{27-24} = opcod1;
1444 let Inst{21-20} = opcod2;
1445 let Inst{11-9} = 0b101;
1446 let Inst{8} = 1; // Double precision
1448 // Loads & stores operate on both NEON and VFP pipelines.
1449 let D = VFPNeonDomain;
1452 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1453 InstrItinClass itin,
1454 string opc, string asm, list<dag> pattern>
1455 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1456 VFPLdStFrm, itin, opc, asm, "", pattern> {
1457 // Instruction operands.
1461 // Encode instruction operands.
1462 let Inst{23} = addr{8}; // U (add = (U == '1'))
1463 let Inst{22} = Sd{0};
1464 let Inst{19-16} = addr{12-9}; // Rn
1465 let Inst{15-12} = Sd{4-1};
1466 let Inst{7-0} = addr{7-0}; // imm8
1468 let Inst{27-24} = opcod1;
1469 let Inst{21-20} = opcod2;
1470 let Inst{11-9} = 0b101;
1471 let Inst{8} = 0; // Single precision
1473 // Loads & stores operate on both NEON and VFP pipelines.
1474 let D = VFPNeonDomain;
1477 // VFP Load / store multiple pseudo instructions.
1478 class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
1480 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
1482 let OutOperandList = oops;
1483 let InOperandList = !con(iops, (ins pred:$p));
1484 let Pattern = pattern;
1485 list<Predicate> Predicates = [HasVFP2];
1488 // Load / store multiple
1490 // Unknown precision
1491 class AXXI4<dag oops, dag iops, IndexMode im,
1492 string asm, string cstr, list<dag> pattern>
1493 : VFPXI<oops, iops, AddrMode4, 4, im,
1494 VFPLdStFrm, NoItinerary, asm, cstr, pattern> {
1495 // Instruction operands.
1499 // Encode instruction operands.
1500 let Inst{19-16} = Rn;
1502 let Inst{15-12} = regs{11-8};
1503 let Inst{7-1} = regs{7-1};
1505 let Inst{27-25} = 0b110;
1506 let Inst{11-8} = 0b1011;
1511 class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1512 string asm, string cstr, list<dag> pattern>
1513 : VFPXI<oops, iops, AddrMode4, 4, im,
1514 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1515 // Instruction operands.
1519 // Encode instruction operands.
1520 let Inst{19-16} = Rn;
1521 let Inst{22} = regs{12};
1522 let Inst{15-12} = regs{11-8};
1523 let Inst{7-1} = regs{7-1};
1525 let Inst{27-25} = 0b110;
1526 let Inst{11-9} = 0b101;
1527 let Inst{8} = 1; // Double precision
1532 class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1533 string asm, string cstr, list<dag> pattern>
1534 : VFPXI<oops, iops, AddrMode4, 4, im,
1535 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1536 // Instruction operands.
1540 // Encode instruction operands.
1541 let Inst{19-16} = Rn;
1542 let Inst{22} = regs{8};
1543 let Inst{15-12} = regs{12-9};
1544 let Inst{7-0} = regs{7-0};
1546 let Inst{27-25} = 0b110;
1547 let Inst{11-9} = 0b101;
1548 let Inst{8} = 0; // Single precision
1551 // Double precision, unary
1552 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1553 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1554 string asm, list<dag> pattern>
1555 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1556 // Instruction operands.
1560 // Encode instruction operands.
1561 let Inst{3-0} = Dm{3-0};
1562 let Inst{5} = Dm{4};
1563 let Inst{15-12} = Dd{3-0};
1564 let Inst{22} = Dd{4};
1566 let Inst{27-23} = opcod1;
1567 let Inst{21-20} = opcod2;
1568 let Inst{19-16} = opcod3;
1569 let Inst{11-9} = 0b101;
1570 let Inst{8} = 1; // Double precision
1571 let Inst{7-6} = opcod4;
1572 let Inst{4} = opcod5;
1575 // Double precision, unary, not-predicated
1576 class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1577 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1578 string asm, list<dag> pattern>
1579 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> {
1580 // Instruction operands.
1584 let Inst{31-28} = 0b1111;
1586 // Encode instruction operands.
1587 let Inst{3-0} = Dm{3-0};
1588 let Inst{5} = Dm{4};
1589 let Inst{15-12} = Dd{3-0};
1590 let Inst{22} = Dd{4};
1592 let Inst{27-23} = opcod1;
1593 let Inst{21-20} = opcod2;
1594 let Inst{19-16} = opcod3;
1595 let Inst{11-9} = 0b101;
1596 let Inst{8} = 1; // Double precision
1597 let Inst{7-6} = opcod4;
1598 let Inst{4} = opcod5;
1601 // Double precision, binary
1602 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1603 dag iops, InstrItinClass itin, string opc, string asm,
1605 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1606 // Instruction operands.
1611 // Encode instruction operands.
1612 let Inst{3-0} = Dm{3-0};
1613 let Inst{5} = Dm{4};
1614 let Inst{19-16} = Dn{3-0};
1615 let Inst{7} = Dn{4};
1616 let Inst{15-12} = Dd{3-0};
1617 let Inst{22} = Dd{4};
1619 let Inst{27-23} = opcod1;
1620 let Inst{21-20} = opcod2;
1621 let Inst{11-9} = 0b101;
1622 let Inst{8} = 1; // Double precision
1627 // FP, binary, not predicated
1628 class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1629 InstrItinClass itin, string asm, list<dag> pattern>
1630 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
1633 // Instruction operands.
1638 let Inst{31-28} = 0b1111;
1640 // Encode instruction operands.
1641 let Inst{3-0} = Dm{3-0};
1642 let Inst{5} = Dm{4};
1643 let Inst{19-16} = Dn{3-0};
1644 let Inst{7} = Dn{4};
1645 let Inst{15-12} = Dd{3-0};
1646 let Inst{22} = Dd{4};
1648 let Inst{27-23} = opcod1;
1649 let Inst{21-20} = opcod2;
1650 let Inst{11-9} = 0b101;
1651 let Inst{8} = 1; // double precision
1652 let Inst{6} = opcod3;
1656 // Single precision, unary, predicated
1657 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1658 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1659 string asm, list<dag> pattern>
1660 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1661 // Instruction operands.
1665 // Encode instruction operands.
1666 let Inst{3-0} = Sm{4-1};
1667 let Inst{5} = Sm{0};
1668 let Inst{15-12} = Sd{4-1};
1669 let Inst{22} = Sd{0};
1671 let Inst{27-23} = opcod1;
1672 let Inst{21-20} = opcod2;
1673 let Inst{19-16} = opcod3;
1674 let Inst{11-9} = 0b101;
1675 let Inst{8} = 0; // Single precision
1676 let Inst{7-6} = opcod4;
1677 let Inst{4} = opcod5;
1680 // Single precision, unary, non-predicated
1681 class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1682 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1683 string asm, list<dag> pattern>
1684 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1685 VFPUnaryFrm, itin, asm, "", pattern> {
1686 // Instruction operands.
1690 let Inst{31-28} = 0b1111;
1692 // Encode instruction operands.
1693 let Inst{3-0} = Sm{4-1};
1694 let Inst{5} = Sm{0};
1695 let Inst{15-12} = Sd{4-1};
1696 let Inst{22} = Sd{0};
1698 let Inst{27-23} = opcod1;
1699 let Inst{21-20} = opcod2;
1700 let Inst{19-16} = opcod3;
1701 let Inst{11-9} = 0b101;
1702 let Inst{8} = 0; // Single precision
1703 let Inst{7-6} = opcod4;
1704 let Inst{4} = opcod5;
1707 // Single precision unary, if no NEON. Same as ASuI except not available if
1709 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1710 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1711 string asm, list<dag> pattern>
1712 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1714 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1717 // Single precision, binary
1718 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1719 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1720 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1721 // Instruction operands.
1726 // Encode instruction operands.
1727 let Inst{3-0} = Sm{4-1};
1728 let Inst{5} = Sm{0};
1729 let Inst{19-16} = Sn{4-1};
1730 let Inst{7} = Sn{0};
1731 let Inst{15-12} = Sd{4-1};
1732 let Inst{22} = Sd{0};
1734 let Inst{27-23} = opcod1;
1735 let Inst{21-20} = opcod2;
1736 let Inst{11-9} = 0b101;
1737 let Inst{8} = 0; // Single precision
1742 // Single precision, binary, not predicated
1743 class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1744 InstrItinClass itin, string asm, list<dag> pattern>
1745 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1746 VFPBinaryFrm, itin, asm, "", pattern>
1748 // Instruction operands.
1753 let Inst{31-28} = 0b1111;
1755 // Encode instruction operands.
1756 let Inst{3-0} = Sm{4-1};
1757 let Inst{5} = Sm{0};
1758 let Inst{19-16} = Sn{4-1};
1759 let Inst{7} = Sn{0};
1760 let Inst{15-12} = Sd{4-1};
1761 let Inst{22} = Sd{0};
1763 let Inst{27-23} = opcod1;
1764 let Inst{21-20} = opcod2;
1765 let Inst{11-9} = 0b101;
1766 let Inst{8} = 0; // Single precision
1767 let Inst{6} = opcod3;
1771 // Single precision binary, if no NEON. Same as ASbI except not available if
1773 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1774 dag iops, InstrItinClass itin, string opc, string asm,
1776 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1777 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1779 // Instruction operands.
1784 // Encode instruction operands.
1785 let Inst{3-0} = Sm{4-1};
1786 let Inst{5} = Sm{0};
1787 let Inst{19-16} = Sn{4-1};
1788 let Inst{7} = Sn{0};
1789 let Inst{15-12} = Sd{4-1};
1790 let Inst{22} = Sd{0};
1793 // VFP conversion instructions
1794 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1795 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1797 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1798 let Inst{27-23} = opcod1;
1799 let Inst{21-20} = opcod2;
1800 let Inst{19-16} = opcod3;
1801 let Inst{11-8} = opcod4;
1806 // VFP conversion between floating-point and fixed-point
1807 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
1808 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1810 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
1812 // size (fixed-point number): sx == 0 ? 16 : 32
1813 let Inst{7} = op5; // sx
1814 let Inst{5} = fbits{0};
1815 let Inst{3-0} = fbits{4-1};
1818 // VFP conversion instructions, if no NEON
1819 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1820 dag oops, dag iops, InstrItinClass itin,
1821 string opc, string asm, list<dag> pattern>
1822 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1824 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1827 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
1828 InstrItinClass itin,
1829 string opc, string asm, list<dag> pattern>
1830 : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
1831 let Inst{27-20} = opcod1;
1832 let Inst{11-8} = opcod2;
1836 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1837 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1838 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
1840 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1841 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1842 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
1844 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1845 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1846 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
1848 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
1849 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1850 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
1852 //===----------------------------------------------------------------------===//
1854 //===----------------------------------------------------------------------===//
1855 // ARM NEON Instruction templates.
1858 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1859 InstrItinClass itin, string opc, string dt, string asm, string cstr,
1861 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1862 let OutOperandList = oops;
1863 let InOperandList = !con(iops, (ins pred:$p));
1864 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
1865 let Pattern = pattern;
1866 list<Predicate> Predicates = [HasNEON];
1867 let DecoderNamespace = "NEON";
1870 // Same as NeonI except it does not have a "data type" specifier.
1871 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1872 InstrItinClass itin, string opc, string asm, string cstr,
1874 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1875 let OutOperandList = oops;
1876 let InOperandList = !con(iops, (ins pred:$p));
1877 let AsmString = !strconcat(opc, "${p}", "\t", asm);
1878 let Pattern = pattern;
1879 list<Predicate> Predicates = [HasNEON];
1880 let DecoderNamespace = "NEON";
1883 // Same as NeonI except it is not predicated
1884 class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
1885 InstrItinClass itin, string opc, string dt, string asm, string cstr,
1887 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
1888 let OutOperandList = oops;
1889 let InOperandList = iops;
1890 let AsmString = !strconcat(opc, ".", dt, "\t", asm);
1891 let Pattern = pattern;
1892 list<Predicate> Predicates = [HasNEON];
1893 let DecoderNamespace = "NEON";
1895 let Inst{31-28} = 0b1111;
1898 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1899 dag oops, dag iops, InstrItinClass itin,
1900 string opc, string dt, string asm, string cstr, list<dag> pattern>
1901 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
1903 let Inst{31-24} = 0b11110100;
1904 let Inst{23} = op23;
1905 let Inst{21-20} = op21_20;
1906 let Inst{11-8} = op11_8;
1907 let Inst{7-4} = op7_4;
1909 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
1910 let DecoderNamespace = "NEONLoadStore";
1916 let Inst{22} = Vd{4};
1917 let Inst{15-12} = Vd{3-0};
1918 let Inst{19-16} = Rn{3-0};
1919 let Inst{3-0} = Rm{3-0};
1922 class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
1923 dag oops, dag iops, InstrItinClass itin,
1924 string opc, string dt, string asm, string cstr, list<dag> pattern>
1925 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
1926 dt, asm, cstr, pattern> {
1930 class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
1931 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
1933 let OutOperandList = oops;
1934 let InOperandList = !con(iops, (ins pred:$p));
1935 list<Predicate> Predicates = [HasNEON];
1938 class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
1940 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
1942 let OutOperandList = oops;
1943 let InOperandList = !con(iops, (ins pred:$p));
1944 let Pattern = pattern;
1945 list<Predicate> Predicates = [HasNEON];
1948 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
1949 string opc, string dt, string asm, string cstr, list<dag> pattern>
1950 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
1952 let Inst{31-25} = 0b1111001;
1953 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
1954 let DecoderNamespace = "NEONData";
1957 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
1958 string opc, string asm, string cstr, list<dag> pattern>
1959 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
1961 let Inst{31-25} = 0b1111001;
1962 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
1963 let DecoderNamespace = "NEONData";
1966 // NEON "one register and a modified immediate" format.
1967 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
1969 dag oops, dag iops, InstrItinClass itin,
1970 string opc, string dt, string asm, string cstr,
1972 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
1973 let Inst{23} = op23;
1974 let Inst{21-19} = op21_19;
1975 let Inst{11-8} = op11_8;
1981 // Instruction operands.
1985 let Inst{15-12} = Vd{3-0};
1986 let Inst{22} = Vd{4};
1987 let Inst{24} = SIMM{7};
1988 let Inst{18-16} = SIMM{6-4};
1989 let Inst{3-0} = SIMM{3-0};
1990 let DecoderMethod = "DecodeNEONModImmInstruction";
1993 // NEON 2 vector register format.
1994 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
1995 bits<5> op11_7, bit op6, bit op4,
1996 dag oops, dag iops, InstrItinClass itin,
1997 string opc, string dt, string asm, string cstr, list<dag> pattern>
1998 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
1999 let Inst{24-23} = op24_23;
2000 let Inst{21-20} = op21_20;
2001 let Inst{19-18} = op19_18;
2002 let Inst{17-16} = op17_16;
2003 let Inst{11-7} = op11_7;
2007 // Instruction operands.
2011 let Inst{15-12} = Vd{3-0};
2012 let Inst{22} = Vd{4};
2013 let Inst{3-0} = Vm{3-0};
2014 let Inst{5} = Vm{4};
2017 // Same as N2V but not predicated.
2018 class N2Vnp<bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
2019 dag oops, dag iops, InstrItinClass itin, string OpcodeStr,
2020 string Dt, ValueType ResTy, ValueType OpTy, list<dag> pattern>
2021 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin,
2022 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> {
2026 // Encode instruction operands
2027 let Inst{22} = Vd{4};
2028 let Inst{15-12} = Vd{3-0};
2029 let Inst{5} = Vm{4};
2030 let Inst{3-0} = Vm{3-0};
2032 // Encode constant bits
2033 let Inst{27-23} = 0b00111;
2034 let Inst{21-20} = 0b11;
2035 let Inst{19-18} = 0b10;
2036 let Inst{17-16} = op17_16;
2038 let Inst{10-8} = op10_8;
2043 let DecoderNamespace = "NEON";
2046 // Same as N2V except it doesn't have a datatype suffix.
2047 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2048 bits<5> op11_7, bit op6, bit op4,
2049 dag oops, dag iops, InstrItinClass itin,
2050 string opc, string asm, string cstr, list<dag> pattern>
2051 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
2052 let Inst{24-23} = op24_23;
2053 let Inst{21-20} = op21_20;
2054 let Inst{19-18} = op19_18;
2055 let Inst{17-16} = op17_16;
2056 let Inst{11-7} = op11_7;
2060 // Instruction operands.
2064 let Inst{15-12} = Vd{3-0};
2065 let Inst{22} = Vd{4};
2066 let Inst{3-0} = Vm{3-0};
2067 let Inst{5} = Vm{4};
2070 // NEON 2 vector register with immediate.
2071 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
2072 dag oops, dag iops, Format f, InstrItinClass itin,
2073 string opc, string dt, string asm, string cstr, list<dag> pattern>
2074 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2075 let Inst{24} = op24;
2076 let Inst{23} = op23;
2077 let Inst{11-8} = op11_8;
2082 // Instruction operands.
2087 let Inst{15-12} = Vd{3-0};
2088 let Inst{22} = Vd{4};
2089 let Inst{3-0} = Vm{3-0};
2090 let Inst{5} = Vm{4};
2091 let Inst{21-16} = SIMM{5-0};
2094 // NEON 3 vector register format.
2096 class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2097 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2098 string opc, string dt, string asm, string cstr,
2100 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2101 let Inst{24} = op24;
2102 let Inst{23} = op23;
2103 let Inst{21-20} = op21_20;
2104 let Inst{11-8} = op11_8;
2109 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
2110 dag oops, dag iops, Format f, InstrItinClass itin,
2111 string opc, string dt, string asm, string cstr, list<dag> pattern>
2112 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2113 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2114 // Instruction operands.
2119 let Inst{15-12} = Vd{3-0};
2120 let Inst{22} = Vd{4};
2121 let Inst{19-16} = Vn{3-0};
2122 let Inst{7} = Vn{4};
2123 let Inst{3-0} = Vm{3-0};
2124 let Inst{5} = Vm{4};
2127 class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2128 bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2129 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
2130 SDPatternOperator IntOp, bit Commutable, list<dag> pattern>
2131 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
2132 Dt, "$Vd, $Vn, $Vm", "", pattern> {
2137 // Encode instruction operands
2138 let Inst{22} = Vd{4};
2139 let Inst{15-12} = Vd{3-0};
2140 let Inst{19-16} = Vn{3-0};
2141 let Inst{7} = Vn{4};
2142 let Inst{5} = Vm{4};
2143 let Inst{3-0} = Vm{3-0};
2145 // Encode constant bits
2146 let Inst{27-23} = op27_23;
2147 let Inst{21-20} = op21_20;
2148 let Inst{11-8} = op11_8;
2153 class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2154 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2155 string opc, string dt, string asm, string cstr,
2157 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2158 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2160 // Instruction operands.
2166 let Inst{15-12} = Vd{3-0};
2167 let Inst{22} = Vd{4};
2168 let Inst{19-16} = Vn{3-0};
2169 let Inst{7} = Vn{4};
2170 let Inst{3-0} = Vm{3-0};
2174 class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2175 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2176 string opc, string dt, string asm, string cstr,
2178 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2179 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2181 // Instruction operands.
2187 let Inst{15-12} = Vd{3-0};
2188 let Inst{22} = Vd{4};
2189 let Inst{19-16} = Vn{3-0};
2190 let Inst{7} = Vn{4};
2191 let Inst{2-0} = Vm{2-0};
2192 let Inst{5} = lane{1};
2193 let Inst{3} = lane{0};
2196 // Same as N3V except it doesn't have a data type suffix.
2197 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2199 dag oops, dag iops, Format f, InstrItinClass itin,
2200 string opc, string asm, string cstr, list<dag> pattern>
2201 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
2202 let Inst{24} = op24;
2203 let Inst{23} = op23;
2204 let Inst{21-20} = op21_20;
2205 let Inst{11-8} = op11_8;
2209 // Instruction operands.
2214 let Inst{15-12} = Vd{3-0};
2215 let Inst{22} = Vd{4};
2216 let Inst{19-16} = Vn{3-0};
2217 let Inst{7} = Vn{4};
2218 let Inst{3-0} = Vm{3-0};
2219 let Inst{5} = Vm{4};
2222 // NEON VMOVs between scalar and core registers.
2223 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2224 dag oops, dag iops, Format f, InstrItinClass itin,
2225 string opc, string dt, string asm, list<dag> pattern>
2226 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
2228 let Inst{27-20} = opcod1;
2229 let Inst{11-8} = opcod2;
2230 let Inst{6-5} = opcod3;
2232 // A8.6.303, A8.6.328, A8.6.329
2233 let Inst{3-0} = 0b0000;
2235 let OutOperandList = oops;
2236 let InOperandList = !con(iops, (ins pred:$p));
2237 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2238 let Pattern = pattern;
2239 list<Predicate> Predicates = [HasNEON];
2241 let PostEncoderMethod = "NEONThumb2DupPostEncoder";
2242 let DecoderNamespace = "NEONDup";
2249 let Inst{31-28} = p{3-0};
2251 let Inst{19-16} = V{3-0};
2252 let Inst{15-12} = R{3-0};
2254 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2255 dag oops, dag iops, InstrItinClass itin,
2256 string opc, string dt, string asm, list<dag> pattern>
2257 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
2258 opc, dt, asm, pattern>;
2259 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2260 dag oops, dag iops, InstrItinClass itin,
2261 string opc, string dt, string asm, list<dag> pattern>
2262 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
2263 opc, dt, asm, pattern>;
2264 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2265 dag oops, dag iops, InstrItinClass itin,
2266 string opc, string dt, string asm, list<dag> pattern>
2267 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
2268 opc, dt, asm, pattern>;
2270 // Vector Duplicate Lane (from scalar to all elements)
2271 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
2272 InstrItinClass itin, string opc, string dt, string asm,
2274 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
2275 let Inst{24-23} = 0b11;
2276 let Inst{21-20} = 0b11;
2277 let Inst{19-16} = op19_16;
2278 let Inst{11-7} = 0b11000;
2285 let Inst{22} = Vd{4};
2286 let Inst{15-12} = Vd{3-0};
2287 let Inst{5} = Vm{4};
2288 let Inst{3-0} = Vm{3-0};
2291 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
2292 // for single-precision FP.
2293 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
2294 list<Predicate> Predicates = [HasNEON,UseNEONForFP];
2297 // VFP/NEON Instruction aliases for type suffices.
2298 class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result> :
2299 InstAlias<!strconcat(opc, dt, "\t", asm), Result>, Requires<[HasVFP2]>;
2301 multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result> {
2302 def : VFPDataTypeInstAlias<opc, ".8", asm, Result>;
2303 def : VFPDataTypeInstAlias<opc, ".16", asm, Result>;
2304 def : VFPDataTypeInstAlias<opc, ".32", asm, Result>;
2305 def : VFPDataTypeInstAlias<opc, ".64", asm, Result>;
2308 multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result> {
2309 let Predicates = [HasNEON] in {
2310 def : VFPDataTypeInstAlias<opc, ".8", asm, Result>;
2311 def : VFPDataTypeInstAlias<opc, ".16", asm, Result>;
2312 def : VFPDataTypeInstAlias<opc, ".32", asm, Result>;
2313 def : VFPDataTypeInstAlias<opc, ".64", asm, Result>;
2317 // The same alias classes using AsmPseudo instead, for the more complex
2318 // stuff in NEON that InstAlias can't quite handle.
2319 // Note that we can't use anonymous defm references here like we can
2320 // above, as we care about the ultimate instruction enum names generated, unlike
2321 // for instalias defs.
2322 class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> :
2323 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>;
2325 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
2326 def : TokenAlias<".s8", ".i8">;
2327 def : TokenAlias<".u8", ".i8">;
2328 def : TokenAlias<".s16", ".i16">;
2329 def : TokenAlias<".u16", ".i16">;
2330 def : TokenAlias<".s32", ".i32">;
2331 def : TokenAlias<".u32", ".i32">;
2332 def : TokenAlias<".s64", ".i64">;
2333 def : TokenAlias<".u64", ".i64">;
2335 def : TokenAlias<".i8", ".8">;
2336 def : TokenAlias<".i16", ".16">;
2337 def : TokenAlias<".i32", ".32">;
2338 def : TokenAlias<".i64", ".64">;
2340 def : TokenAlias<".p8", ".8">;
2341 def : TokenAlias<".p16", ".16">;
2343 def : TokenAlias<".f32", ".32">;
2344 def : TokenAlias<".f64", ".64">;
2345 def : TokenAlias<".f", ".f32">;
2346 def : TokenAlias<".d", ".f64">;