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<0,1> {
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 def BankedRegOperand : AsmOperandClass {
207 let Name = "BankedReg";
208 let ParserMethod = "parseBankedRegOperand";
210 def banked_reg : Operand<i32> {
211 let PrintMethod = "printBankedRegOperand";
212 let DecoderMethod = "DecodeBankedReg";
213 let ParserMatchClass = BankedRegOperand;
216 // Shift Right Immediate - A shift right immediate is encoded differently from
217 // other shift immediates. The imm6 field is encoded like so:
220 // 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
221 // 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
222 // 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
223 // 64 64 - <imm> is encoded in imm6<5:0>
224 def shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; }
225 def shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> {
226 let EncoderMethod = "getShiftRight8Imm";
227 let DecoderMethod = "DecodeShiftRight8Imm";
228 let ParserMatchClass = shr_imm8_asm_operand;
230 def shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; }
231 def shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> {
232 let EncoderMethod = "getShiftRight16Imm";
233 let DecoderMethod = "DecodeShiftRight16Imm";
234 let ParserMatchClass = shr_imm16_asm_operand;
236 def shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; }
237 def shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> {
238 let EncoderMethod = "getShiftRight32Imm";
239 let DecoderMethod = "DecodeShiftRight32Imm";
240 let ParserMatchClass = shr_imm32_asm_operand;
242 def shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; }
243 def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> {
244 let EncoderMethod = "getShiftRight64Imm";
245 let DecoderMethod = "DecodeShiftRight64Imm";
246 let ParserMatchClass = shr_imm64_asm_operand;
250 // ARM Assembler operand for ldr Rd, =expression which generates an offset
251 // to a constant pool entry or a MOV depending on the value of expression
252 def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; }
253 def const_pool_asm_imm : Operand<i32> {
254 let ParserMatchClass = const_pool_asm_operand;
258 //===----------------------------------------------------------------------===//
259 // ARM Assembler alias templates.
261 // Note: When EmitPriority == 1, the alias will be used for printing
262 class ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0>
263 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>;
264 class ARMInstSubst<string Asm, dag Result, bit EmitPriority = 0>
265 : InstAlias<Asm, Result, EmitPriority>,
266 Requires<[IsARM,UseNegativeImmediates]>;
267 class tInstAlias<string Asm, dag Result, bit EmitPriority = 0>
268 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>;
269 class tInstSubst<string Asm, dag Result, bit EmitPriority = 0>
270 : InstAlias<Asm, Result, EmitPriority>,
271 Requires<[IsThumb,UseNegativeImmediates]>;
272 class t2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
273 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>;
274 class t2InstSubst<string Asm, dag Result, bit EmitPriority = 0>
275 : InstAlias<Asm, Result, EmitPriority>,
276 Requires<[IsThumb2,UseNegativeImmediates]>;
277 class VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
278 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>;
279 class VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0>
280 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>;
281 class VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0>
282 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>;
283 class NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0>
284 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>;
287 class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
289 class NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
292 //===----------------------------------------------------------------------===//
293 // ARM Instruction templates.
297 class InstTemplate<AddrMode am, int sz, IndexMode im,
298 Format f, Domain d, string cstr, InstrItinClass itin>
300 let Namespace = "ARM";
305 bits<2> IndexModeBits = IM.Value;
307 bits<6> Form = F.Value;
309 bit isUnaryDataProc = 0;
310 bit canXformTo16Bit = 0;
311 // The instruction is a 16-bit flag setting Thumb instruction. Used
312 // by the parser to determine whether to require the 'S' suffix on the
313 // mnemonic (when not in an IT block) or preclude it (when in an IT block).
314 bit thumbArithFlagSetting = 0;
316 // If this is a pseudo instruction, mark it isCodeGenOnly.
317 let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
319 // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
320 let TSFlags{4-0} = AM.Value;
321 let TSFlags{6-5} = IndexModeBits;
322 let TSFlags{12-7} = Form;
323 let TSFlags{13} = isUnaryDataProc;
324 let TSFlags{14} = canXformTo16Bit;
325 let TSFlags{17-15} = D.Value;
326 let TSFlags{18} = thumbArithFlagSetting;
328 let Constraints = cstr;
329 let Itinerary = itin;
334 // Mask of bits that cause an encoding to be UNPREDICTABLE.
335 // If a bit is set, then if the corresponding bit in the
336 // target encoding differs from its value in the "Inst" field,
337 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
338 field bits<32> Unpredictable = 0;
339 // SoftFail is the generic name for this field, but we alias it so
340 // as to make it more obvious what it means in ARM-land.
341 field bits<32> SoftFail = Unpredictable;
344 class InstARM<AddrMode am, int sz, IndexMode im,
345 Format f, Domain d, string cstr, InstrItinClass itin>
346 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
347 let DecoderNamespace = "ARM";
350 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
351 // on by adding flavors to specific instructions.
352 class InstThumb<AddrMode am, int sz, IndexMode im,
353 Format f, Domain d, string cstr, InstrItinClass itin>
354 : InstTemplate<am, sz, im, f, d, cstr, itin> {
355 let DecoderNamespace = "Thumb";
358 // Pseudo-instructions for alternate assembly syntax (never used by codegen).
359 // These are aliases that require C++ handling to convert to the target
360 // instruction, while InstAliases can be handled directly by tblgen.
361 class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
362 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
364 let OutOperandList = oops;
365 let InOperandList = iops;
367 let isCodeGenOnly = 0; // So we get asm matcher for it.
372 class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)>
373 : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>;
374 class tAsmPseudo<string asm, dag iops, dag oops = (outs)>
375 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>;
376 class t2AsmPseudo<string asm, dag iops, dag oops = (outs)>
377 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>;
378 class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)>
379 : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>;
380 class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)>
381 : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>;
383 // Pseudo instructions for the code generator.
384 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
385 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
386 GenericDomain, "", itin> {
387 let OutOperandList = oops;
388 let InOperandList = iops;
389 let Pattern = pattern;
390 let isCodeGenOnly = 1;
394 // PseudoInst that's ARM-mode only.
395 class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
397 : PseudoInst<oops, iops, itin, pattern> {
399 list<Predicate> Predicates = [IsARM];
402 // PseudoInst that's Thumb-mode only.
403 class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
405 : PseudoInst<oops, iops, itin, pattern> {
407 list<Predicate> Predicates = [IsThumb];
410 // PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2)
411 class t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
413 : PseudoInst<oops, iops, itin, pattern> {
415 list<Predicate> Predicates = [IsThumb,HasV8MBaseline];
418 // PseudoInst that's Thumb2-mode only.
419 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
421 : PseudoInst<oops, iops, itin, pattern> {
423 list<Predicate> Predicates = [IsThumb2];
426 class ARMPseudoExpand<dag oops, dag iops, int sz,
427 InstrItinClass itin, list<dag> pattern,
429 : ARMPseudoInst<oops, iops, sz, itin, pattern>,
430 PseudoInstExpansion<Result>;
432 class tPseudoExpand<dag oops, dag iops, int sz,
433 InstrItinClass itin, list<dag> pattern,
435 : tPseudoInst<oops, iops, sz, itin, pattern>,
436 PseudoInstExpansion<Result>;
438 class t2PseudoExpand<dag oops, dag iops, int sz,
439 InstrItinClass itin, list<dag> pattern,
441 : t2PseudoInst<oops, iops, sz, itin, pattern>,
442 PseudoInstExpansion<Result>;
444 // Almost all ARM instructions are predicable.
445 class I<dag oops, dag iops, AddrMode am, int sz,
446 IndexMode im, Format f, InstrItinClass itin,
447 string opc, string asm, string cstr,
449 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
452 let OutOperandList = oops;
453 let InOperandList = !con(iops, (ins pred:$p));
454 let AsmString = !strconcat(opc, "${p}", asm);
455 let Pattern = pattern;
456 list<Predicate> Predicates = [IsARM];
459 // A few are not predicable
460 class InoP<dag oops, dag iops, AddrMode am, int sz,
461 IndexMode im, Format f, InstrItinClass itin,
462 string opc, string asm, string cstr,
464 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
465 let OutOperandList = oops;
466 let InOperandList = iops;
467 let AsmString = !strconcat(opc, asm);
468 let Pattern = pattern;
469 let isPredicable = 0;
470 list<Predicate> Predicates = [IsARM];
473 // Same as I except it can optionally modify CPSR. Note it's modeled as an input
474 // operand since by default it's a zero register. It will become an implicit def
475 // once it's "flipped".
476 class sI<dag oops, dag iops, AddrMode am, int sz,
477 IndexMode im, Format f, InstrItinClass itin,
478 string opc, string asm, string cstr,
480 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
481 bits<4> p; // Predicate operand
482 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
486 let OutOperandList = oops;
487 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
488 let AsmString = !strconcat(opc, "${s}${p}", asm);
489 let Pattern = pattern;
490 list<Predicate> Predicates = [IsARM];
494 class XI<dag oops, dag iops, AddrMode am, int sz,
495 IndexMode im, Format f, InstrItinClass itin,
496 string asm, string cstr, list<dag> pattern>
497 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
498 let OutOperandList = oops;
499 let InOperandList = iops;
501 let Pattern = pattern;
502 list<Predicate> Predicates = [IsARM];
505 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
506 string opc, string asm, list<dag> pattern>
507 : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
508 opc, asm, "", pattern>;
509 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
510 string opc, string asm, list<dag> pattern>
511 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
512 opc, asm, "", pattern>;
513 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
514 string asm, list<dag> pattern>
515 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
517 class AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin,
518 string asm, list<dag> pattern>
519 : XI<oops, iops, am, 4, IndexModeNone, f, itin,
521 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
522 string opc, string asm, list<dag> pattern>
523 : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
524 opc, asm, "", pattern>;
526 // Ctrl flow instructions
527 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
528 string opc, string asm, list<dag> pattern>
529 : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
530 opc, asm, "", pattern> {
531 let Inst{27-24} = opcod;
533 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
534 string asm, list<dag> pattern>
535 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
537 let Inst{27-24} = opcod;
540 // BR_JT instructions
541 class JTI<dag oops, dag iops, InstrItinClass itin,
542 string asm, list<dag> pattern>
543 : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
546 class AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
547 string opc, string asm, list<dag> pattern>
548 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
549 opc, asm, "", pattern> {
552 let Inst{27-23} = 0b00011;
553 let Inst{22-21} = opcod;
555 let Inst{19-16} = addr;
556 let Inst{15-12} = Rt;
557 let Inst{11-10} = 0b11;
558 let Inst{9-8} = opcod2;
559 let Inst{7-0} = 0b10011111;
561 class AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
562 string opc, string asm, list<dag> pattern>
563 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
564 opc, asm, "", pattern> {
567 let Inst{27-23} = 0b00011;
568 let Inst{22-21} = opcod;
570 let Inst{19-16} = addr;
571 let Inst{11-10} = 0b11;
572 let Inst{9-8} = opcod2;
573 let Inst{7-4} = 0b1001;
576 // Atomic load/store instructions
577 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
578 string opc, string asm, list<dag> pattern>
579 : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>;
581 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
582 string opc, string asm, list<dag> pattern>
583 : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> {
585 let Inst{15-12} = Rd;
588 // Exclusive load/store instructions
590 class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
591 string opc, string asm, list<dag> pattern>
592 : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
593 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>;
595 class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
596 string opc, string asm, list<dag> pattern>
597 : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
598 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> {
600 let Inst{15-12} = Rd;
603 class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
604 : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
608 let Inst{27-23} = 0b00010;
610 let Inst{21-20} = 0b00;
611 let Inst{19-16} = addr;
612 let Inst{15-12} = Rt;
613 let Inst{11-4} = 0b00001001;
616 let Unpredictable{11-8} = 0b1111;
617 let DecoderMethod = "DecodeSwap";
619 // Acquire/Release load/store instructions
620 class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
621 string opc, string asm, list<dag> pattern>
622 : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
623 Requires<[IsARM, HasAcquireRelease]>;
625 class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
626 string opc, string asm, list<dag> pattern>
627 : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
628 Requires<[IsARM, HasAcquireRelease]> {
629 let Inst{15-12} = 0b1111;
632 // addrmode1 instructions
633 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
634 string opc, string asm, list<dag> pattern>
635 : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
636 opc, asm, "", pattern> {
637 let Inst{24-21} = opcod;
638 let Inst{27-26} = 0b00;
640 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
641 string opc, string asm, list<dag> pattern>
642 : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
643 opc, asm, "", pattern> {
644 let Inst{24-21} = opcod;
645 let Inst{27-26} = 0b00;
647 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
648 string asm, list<dag> pattern>
649 : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
651 let Inst{24-21} = opcod;
652 let Inst{27-26} = 0b00;
657 // LDR/LDRB/STR/STRB/...
658 class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
659 Format f, InstrItinClass itin, string opc, string asm,
661 : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
663 let Inst{27-25} = op;
664 let Inst{24} = 1; // 24 == P
666 let Inst{22} = isByte;
667 let Inst{21} = 0; // 21 == W
670 // Indexed load/stores
671 class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
672 IndexMode im, Format f, InstrItinClass itin, string opc,
673 string asm, string cstr, list<dag> pattern>
674 : I<oops, iops, AddrMode2, 4, im, f, itin,
675 opc, asm, cstr, pattern> {
677 let Inst{27-26} = 0b01;
678 let Inst{24} = isPre; // P bit
679 let Inst{22} = isByte; // B bit
680 let Inst{21} = isPre; // W bit
681 let Inst{20} = isLd; // L bit
682 let Inst{15-12} = Rt;
684 class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
685 IndexMode im, Format f, InstrItinClass itin, string opc,
686 string asm, string cstr, list<dag> pattern>
687 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
689 // AM2 store w/ two operands: (GPR, am2offset)
695 let Inst{23} = offset{12};
696 let Inst{19-16} = Rn;
697 let Inst{11-5} = offset{11-5};
699 let Inst{3-0} = offset{3-0};
702 class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
703 IndexMode im, Format f, InstrItinClass itin, string opc,
704 string asm, string cstr, list<dag> pattern>
705 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
707 // AM2 store w/ two operands: (GPR, am2offset)
713 let Inst{23} = offset{12};
714 let Inst{19-16} = Rn;
715 let Inst{11-0} = offset{11-0};
719 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
720 // but for now use this class for STRT and STRBT.
721 class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
722 IndexMode im, Format f, InstrItinClass itin, string opc,
723 string asm, string cstr, list<dag> pattern>
724 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
726 // AM2 store w/ two operands: (GPR, am2offset)
728 // {13} 1 == Rm, 0 == imm12
732 let Inst{25} = addr{13};
733 let Inst{23} = addr{12};
734 let Inst{19-16} = addr{17-14};
735 let Inst{11-0} = addr{11-0};
738 // addrmode3 instructions
739 class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
740 InstrItinClass itin, string opc, string asm, list<dag> pattern>
741 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
742 opc, asm, "", pattern> {
745 let Inst{27-25} = 0b000;
746 let Inst{24} = 1; // P bit
747 let Inst{23} = addr{8}; // U bit
748 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
749 let Inst{21} = 0; // W bit
750 let Inst{20} = op20; // L bit
751 let Inst{19-16} = addr{12-9}; // Rn
752 let Inst{15-12} = Rt; // Rt
753 let Inst{11-8} = addr{7-4}; // imm7_4/zero
755 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
757 let DecoderMethod = "DecodeAddrMode3Instruction";
760 class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
761 IndexMode im, Format f, InstrItinClass itin, string opc,
762 string asm, string cstr, list<dag> pattern>
763 : I<oops, iops, AddrMode3, 4, im, f, itin,
764 opc, asm, cstr, pattern> {
766 let Inst{27-25} = 0b000;
767 let Inst{24} = isPre; // P bit
768 let Inst{21} = isPre; // W bit
769 let Inst{20} = op20; // L bit
770 let Inst{15-12} = Rt; // Rt
774 // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
775 // but for now use this class for LDRSBT, LDRHT, LDSHT.
776 class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
777 IndexMode im, Format f, InstrItinClass itin, string opc,
778 string asm, string cstr, list<dag> pattern>
779 : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
780 // {13} 1 == imm8, 0 == Rm
787 let Inst{27-25} = 0b000;
788 let Inst{24} = 0; // P bit
790 let Inst{20} = isLoad; // L bit
791 let Inst{19-16} = addr; // Rn
792 let Inst{15-12} = Rt; // Rt
797 class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
798 string opc, string asm, list<dag> pattern>
799 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
800 opc, asm, "", pattern> {
803 let Inst{27-25} = 0b000;
804 let Inst{24} = 1; // P bit
805 let Inst{23} = addr{8}; // U bit
806 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
807 let Inst{21} = 0; // W bit
808 let Inst{20} = 0; // L bit
809 let Inst{19-16} = addr{12-9}; // Rn
810 let Inst{15-12} = Rt; // Rt
811 let Inst{11-8} = addr{7-4}; // imm7_4/zero
813 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
814 let DecoderMethod = "DecodeAddrMode3Instruction";
817 // addrmode4 instructions
818 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
819 string asm, string cstr, list<dag> pattern>
820 : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
825 let Inst{27-25} = 0b100;
826 let Inst{22} = 0; // S bit
827 let Inst{19-16} = Rn;
828 let Inst{15-0} = regs;
831 // Unsigned multiply, multiply-accumulate instructions.
832 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
833 string opc, string asm, list<dag> pattern>
834 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
835 opc, asm, "", pattern> {
836 let Inst{7-4} = 0b1001;
837 let Inst{20} = 0; // S bit
838 let Inst{27-21} = opcod;
840 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
841 string opc, string asm, list<dag> pattern>
842 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
843 opc, asm, "", pattern> {
844 let Inst{7-4} = 0b1001;
845 let Inst{27-21} = opcod;
848 // Most significant word multiply
849 class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
850 InstrItinClass itin, string opc, string asm, list<dag> pattern>
851 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
852 opc, asm, "", pattern> {
856 let Inst{7-4} = opc7_4;
858 let Inst{27-21} = opcod;
859 let Inst{19-16} = Rd;
863 // MSW multiple w/ Ra operand
864 class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
865 InstrItinClass itin, string opc, string asm, list<dag> pattern>
866 : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
868 let Inst{15-12} = Ra;
871 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
872 class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
873 InstrItinClass itin, string opc, string asm, list<dag> pattern>
874 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
875 opc, asm, "", pattern> {
881 let Inst{27-21} = opcod;
882 let Inst{6-5} = bit6_5;
886 class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
887 InstrItinClass itin, string opc, string asm, list<dag> pattern>
888 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
890 let Inst{19-16} = Rd;
893 // AMulxyI with Ra operand
894 class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
895 InstrItinClass itin, string opc, string asm, list<dag> pattern>
896 : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
898 let Inst{15-12} = Ra;
901 class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
902 InstrItinClass itin, string opc, string asm, list<dag> pattern>
903 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
906 let Inst{19-16} = RdHi;
907 let Inst{15-12} = RdLo;
910 // Extend instructions.
911 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
912 string opc, string asm, list<dag> pattern>
913 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
914 opc, asm, "", pattern> {
915 // All AExtI instructions have Rd and Rm register operands.
918 let Inst{15-12} = Rd;
920 let Inst{7-4} = 0b0111;
921 let Inst{9-8} = 0b00;
922 let Inst{27-20} = opcod;
924 let Unpredictable{9-8} = 0b11;
927 // Misc Arithmetic instructions.
928 class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
929 InstrItinClass itin, string opc, string asm, list<dag> pattern>
930 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
931 opc, asm, "", pattern> {
934 let Inst{27-20} = opcod;
935 let Inst{19-16} = 0b1111;
936 let Inst{15-12} = Rd;
937 let Inst{11-8} = 0b1111;
938 let Inst{7-4} = opc7_4;
942 // Division instructions.
943 class ADivA1I<bits<3> opcod, dag oops, dag iops,
944 InstrItinClass itin, string opc, string asm, list<dag> pattern>
945 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
946 opc, asm, "", pattern> {
950 let Inst{27-23} = 0b01110;
951 let Inst{22-20} = opcod;
952 let Inst{19-16} = Rd;
953 let Inst{15-12} = 0b1111;
955 let Inst{7-4} = 0b0001;
960 def PKHLSLAsmOperand : ImmAsmOperand<0,31> {
961 let Name = "PKHLSLImm";
962 let ParserMethod = "parsePKHLSLImm";
964 def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
965 let PrintMethod = "printPKHLSLShiftImm";
966 let ParserMatchClass = PKHLSLAsmOperand;
968 def PKHASRAsmOperand : AsmOperandClass {
969 let Name = "PKHASRImm";
970 let ParserMethod = "parsePKHASRImm";
972 def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
973 let PrintMethod = "printPKHASRShiftImm";
974 let ParserMatchClass = PKHASRAsmOperand;
977 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
978 string opc, string asm, list<dag> pattern>
979 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
980 opc, asm, "", pattern> {
985 let Inst{27-20} = opcod;
986 let Inst{19-16} = Rn;
987 let Inst{15-12} = Rd;
990 let Inst{5-4} = 0b01;
994 //===----------------------------------------------------------------------===//
996 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
997 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
998 list<Predicate> Predicates = [IsARM];
1000 class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
1001 list<Predicate> Predicates = [IsARM, HasV5T];
1003 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
1004 list<Predicate> Predicates = [IsARM, HasV5TE];
1006 // ARMV5MOPat - Same as ARMV5TEPat with UseMulOps.
1007 class ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> {
1008 list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps];
1010 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
1011 list<Predicate> Predicates = [IsARM, HasV6];
1013 class VFPPat<dag pattern, dag result> : Pat<pattern, result> {
1014 list<Predicate> Predicates = [HasVFP2];
1016 class VFPNoNEONPat<dag pattern, dag result> : Pat<pattern, result> {
1017 list<Predicate> Predicates = [HasVFP2, DontUseNEONForFP];
1019 class Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> {
1020 list<Predicate> Predicates = [IsThumb2, HasDSP];
1022 class Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> {
1023 list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP];
1025 //===----------------------------------------------------------------------===//
1026 // Thumb Instruction Format Definitions.
1029 class ThumbI<dag oops, dag iops, AddrMode am, int sz,
1030 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1031 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1032 let OutOperandList = oops;
1033 let InOperandList = iops;
1034 let AsmString = asm;
1035 let Pattern = pattern;
1036 list<Predicate> Predicates = [IsThumb];
1039 // TI - Thumb instruction.
1040 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
1041 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1043 // Two-address instructions
1044 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
1046 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
1049 // tBL, tBX 32-bit instructions
1050 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
1051 dag oops, dag iops, InstrItinClass itin, string asm,
1053 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
1055 let Inst{31-27} = opcod1;
1056 let Inst{15-14} = opcod2;
1057 let Inst{12} = opcod3;
1060 // BR_JT instructions
1061 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
1063 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1066 class Thumb1I<dag oops, dag iops, AddrMode am, int sz,
1067 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1068 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1069 let OutOperandList = oops;
1070 let InOperandList = iops;
1071 let AsmString = asm;
1072 let Pattern = pattern;
1073 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1076 class T1I<dag oops, dag iops, InstrItinClass itin,
1077 string asm, list<dag> pattern>
1078 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1079 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1080 string asm, list<dag> pattern>
1081 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1083 // Two-address instructions
1084 class T1It<dag oops, dag iops, InstrItinClass itin,
1085 string asm, string cstr, list<dag> pattern>
1086 : Thumb1I<oops, iops, AddrModeNone, 2, itin,
1087 asm, cstr, pattern>;
1089 // Thumb1 instruction that can either be predicated or set CPSR.
1090 class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
1091 InstrItinClass itin,
1092 string opc, string asm, string cstr, list<dag> pattern>
1093 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1094 let OutOperandList = !con(oops, (outs s_cc_out:$s));
1095 let InOperandList = !con(iops, (ins pred:$p));
1096 let AsmString = !strconcat(opc, "${s}${p}", asm);
1097 let Pattern = pattern;
1098 let thumbArithFlagSetting = 1;
1099 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1100 let DecoderNamespace = "ThumbSBit";
1103 class T1sI<dag oops, dag iops, InstrItinClass itin,
1104 string opc, string asm, list<dag> pattern>
1105 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1107 // Two-address instructions
1108 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1109 string opc, string asm, list<dag> pattern>
1110 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1111 "$Rn = $Rdn", pattern>;
1113 // Thumb1 instruction that can be predicated.
1114 class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
1115 InstrItinClass itin,
1116 string opc, string asm, string cstr, list<dag> pattern>
1117 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1118 let OutOperandList = oops;
1119 let InOperandList = !con(iops, (ins pred:$p));
1120 let AsmString = !strconcat(opc, "${p}", asm);
1121 let Pattern = pattern;
1122 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1125 class T1pI<dag oops, dag iops, InstrItinClass itin,
1126 string opc, string asm, list<dag> pattern>
1127 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1129 // Two-address instructions
1130 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1131 string opc, string asm, list<dag> pattern>
1132 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1133 "$Rn = $Rdn", pattern>;
1135 class T1pIs<dag oops, dag iops,
1136 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1137 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
1139 class Encoding16 : Encoding {
1140 let Inst{31-16} = 0x0000;
1143 // A6.2 16-bit Thumb instruction encoding
1144 class T1Encoding<bits<6> opcode> : Encoding16 {
1145 let Inst{15-10} = opcode;
1148 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1149 class T1General<bits<5> opcode> : Encoding16 {
1150 let Inst{15-14} = 0b00;
1151 let Inst{13-9} = opcode;
1154 // A6.2.2 Data-processing encoding.
1155 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1156 let Inst{15-10} = 0b010000;
1157 let Inst{9-6} = opcode;
1160 // A6.2.3 Special data instructions and branch and exchange encoding.
1161 class T1Special<bits<4> opcode> : Encoding16 {
1162 let Inst{15-10} = 0b010001;
1163 let Inst{9-6} = opcode;
1166 // A6.2.4 Load/store single data item encoding.
1167 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1168 let Inst{15-12} = opA;
1169 let Inst{11-9} = opB;
1171 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
1173 class T1BranchCond<bits<4> opcode> : Encoding16 {
1174 let Inst{15-12} = opcode;
1177 // Helper classes to encode Thumb1 loads and stores. For immediates, the
1178 // following bits are used for "opA" (see A6.2.4):
1180 // 0b0110 => Immediate, 4 bytes
1181 // 0b1000 => Immediate, 2 bytes
1182 // 0b0111 => Immediate, 1 byte
1183 class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
1184 InstrItinClass itin, string opc, string asm,
1186 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1187 T1LoadStore<0b0101, opcode> {
1190 let Inst{8-6} = addr{5-3}; // Rm
1191 let Inst{5-3} = addr{2-0}; // Rn
1194 class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
1195 InstrItinClass itin, string opc, string asm,
1197 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1198 T1LoadStore<opA, {opB,?,?}> {
1201 let Inst{10-6} = addr{7-3}; // imm5
1202 let Inst{5-3} = addr{2-0}; // Rn
1206 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1207 class T1Misc<bits<7> opcode> : Encoding16 {
1208 let Inst{15-12} = 0b1011;
1209 let Inst{11-5} = opcode;
1212 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1213 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
1214 InstrItinClass itin,
1215 string opc, string asm, string cstr, list<dag> pattern>
1216 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1217 let OutOperandList = oops;
1218 let InOperandList = !con(iops, (ins pred:$p));
1219 let AsmString = !strconcat(opc, "${p}", asm);
1220 let Pattern = pattern;
1221 list<Predicate> Predicates = [IsThumb2];
1222 let DecoderNamespace = "Thumb2";
1225 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
1226 // input operand since by default it's a zero register. It will become an
1227 // implicit def once it's "flipped".
1229 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1231 class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
1232 InstrItinClass itin,
1233 string opc, string asm, string cstr, list<dag> pattern>
1234 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1235 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
1238 let OutOperandList = oops;
1239 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1240 let AsmString = !strconcat(opc, "${s}${p}", asm);
1241 let Pattern = pattern;
1242 list<Predicate> Predicates = [IsThumb2];
1243 let DecoderNamespace = "Thumb2";
1247 class Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
1248 InstrItinClass itin,
1249 string asm, string cstr, list<dag> pattern>
1250 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1251 let OutOperandList = oops;
1252 let InOperandList = iops;
1253 let AsmString = asm;
1254 let Pattern = pattern;
1255 list<Predicate> Predicates = [IsThumb2];
1256 let DecoderNamespace = "Thumb2";
1259 class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
1260 InstrItinClass itin,
1261 string asm, string cstr, list<dag> pattern>
1262 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1263 let OutOperandList = oops;
1264 let InOperandList = iops;
1265 let AsmString = asm;
1266 let Pattern = pattern;
1267 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1268 let DecoderNamespace = "Thumb";
1271 class T2I<dag oops, dag iops, InstrItinClass itin,
1272 string opc, string asm, list<dag> pattern>
1273 : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1274 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1275 string opc, string asm, list<dag> pattern>
1276 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
1277 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1278 string opc, string asm, list<dag> pattern>
1279 : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>;
1280 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1281 string opc, string asm, list<dag> pattern>
1282 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
1283 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1284 string opc, string asm, list<dag> pattern>
1285 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
1286 class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
1287 string opc, string asm, string cstr, list<dag> pattern>
1288 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1293 let Inst{31-25} = 0b1110100;
1295 let Inst{23} = addr{8};
1298 let Inst{20} = isLoad;
1299 let Inst{19-16} = addr{12-9};
1300 let Inst{15-12} = Rt{3-0};
1301 let Inst{11-8} = Rt2{3-0};
1302 let Inst{7-0} = addr{7-0};
1304 class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
1305 InstrItinClass itin, string opc, string asm, string cstr,
1307 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1313 let Inst{31-25} = 0b1110100;
1315 let Inst{23} = imm{8};
1318 let Inst{20} = isLoad;
1319 let Inst{19-16} = addr;
1320 let Inst{15-12} = Rt{3-0};
1321 let Inst{11-8} = Rt2{3-0};
1322 let Inst{7-0} = imm{7-0};
1325 class T2sI<dag oops, dag iops, InstrItinClass itin,
1326 string opc, string asm, list<dag> pattern>
1327 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1329 class T2XI<dag oops, dag iops, InstrItinClass itin,
1330 string asm, list<dag> pattern>
1331 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1332 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1333 string asm, list<dag> pattern>
1334 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1336 // Move to/from coprocessor instructions
1337 class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
1339 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
1340 let Inst{31-28} = opc;
1343 // Two-address instructions
1344 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1345 string asm, string cstr, list<dag> pattern>
1346 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
1348 // T2Ipreldst - Thumb2 pre-indexed load / store instructions.
1349 class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
1351 AddrMode am, IndexMode im, InstrItinClass itin,
1352 string opc, string asm, string cstr, list<dag> pattern>
1353 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1354 let OutOperandList = oops;
1355 let InOperandList = !con(iops, (ins pred:$p));
1356 let AsmString = !strconcat(opc, "${p}", asm);
1357 let Pattern = pattern;
1358 list<Predicate> Predicates = [IsThumb2];
1359 let DecoderNamespace = "Thumb2";
1363 let Inst{31-27} = 0b11111;
1364 let Inst{26-25} = 0b00;
1365 let Inst{24} = signed;
1367 let Inst{22-21} = opcod;
1368 let Inst{20} = load;
1369 let Inst{19-16} = addr{12-9};
1370 let Inst{15-12} = Rt{3-0};
1372 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1373 let Inst{10} = pre; // The P bit.
1374 let Inst{9} = addr{8}; // Sign bit
1375 let Inst{8} = 1; // The W bit.
1376 let Inst{7-0} = addr{7-0};
1378 let DecoderMethod = "DecodeT2LdStPre";
1381 // T2Ipostldst - Thumb2 post-indexed load / store instructions.
1382 class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
1384 AddrMode am, IndexMode im, InstrItinClass itin,
1385 string opc, string asm, string cstr, list<dag> pattern>
1386 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1387 let OutOperandList = oops;
1388 let InOperandList = !con(iops, (ins pred:$p));
1389 let AsmString = !strconcat(opc, "${p}", asm);
1390 let Pattern = pattern;
1391 list<Predicate> Predicates = [IsThumb2];
1392 let DecoderNamespace = "Thumb2";
1397 let Inst{31-27} = 0b11111;
1398 let Inst{26-25} = 0b00;
1399 let Inst{24} = signed;
1401 let Inst{22-21} = opcod;
1402 let Inst{20} = load;
1403 let Inst{19-16} = Rn;
1404 let Inst{15-12} = Rt{3-0};
1406 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1407 let Inst{10} = pre; // The P bit.
1408 let Inst{9} = offset{8}; // Sign bit
1409 let Inst{8} = 1; // The W bit.
1410 let Inst{7-0} = offset{7-0};
1412 let DecoderMethod = "DecodeT2LdStPre";
1415 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1416 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1417 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1420 // T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
1421 class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
1422 list<Predicate> Predicates = [IsThumb2, HasV6T2];
1425 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1426 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1427 list<Predicate> Predicates = [IsThumb2];
1430 //===----------------------------------------------------------------------===//
1432 //===----------------------------------------------------------------------===//
1433 // ARM VFP Instruction templates.
1436 // Almost all VFP instructions are predicable.
1437 class VFPI<dag oops, dag iops, AddrMode am, int sz,
1438 IndexMode im, Format f, InstrItinClass itin,
1439 string opc, string asm, string cstr, list<dag> pattern>
1440 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1442 let Inst{31-28} = p;
1443 let OutOperandList = oops;
1444 let InOperandList = !con(iops, (ins pred:$p));
1445 let AsmString = !strconcat(opc, "${p}", asm);
1446 let Pattern = pattern;
1447 let PostEncoderMethod = "VFPThumb2PostEncoder";
1448 let DecoderNamespace = "VFP";
1449 list<Predicate> Predicates = [HasVFP2];
1453 class VFPXI<dag oops, dag iops, AddrMode am, int sz,
1454 IndexMode im, Format f, InstrItinClass itin,
1455 string asm, string cstr, list<dag> pattern>
1456 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1458 let Inst{31-28} = p;
1459 let OutOperandList = oops;
1460 let InOperandList = iops;
1461 let AsmString = asm;
1462 let Pattern = pattern;
1463 let PostEncoderMethod = "VFPThumb2PostEncoder";
1464 let DecoderNamespace = "VFP";
1465 list<Predicate> Predicates = [HasVFP2];
1468 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1469 string opc, string asm, list<dag> pattern>
1470 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
1471 opc, asm, "", pattern> {
1472 let PostEncoderMethod = "VFPThumb2PostEncoder";
1475 // ARM VFP addrmode5 loads and stores
1476 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1477 InstrItinClass itin,
1478 string opc, string asm, list<dag> pattern>
1479 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1480 VFPLdStFrm, itin, opc, asm, "", pattern> {
1481 // Instruction operands.
1485 // Encode instruction operands.
1486 let Inst{23} = addr{8}; // U (add = (U == '1'))
1487 let Inst{22} = Dd{4};
1488 let Inst{19-16} = addr{12-9}; // Rn
1489 let Inst{15-12} = Dd{3-0};
1490 let Inst{7-0} = addr{7-0}; // imm8
1492 let Inst{27-24} = opcod1;
1493 let Inst{21-20} = opcod2;
1494 let Inst{11-9} = 0b101;
1495 let Inst{8} = 1; // Double precision
1497 // Loads & stores operate on both NEON and VFP pipelines.
1498 let D = VFPNeonDomain;
1501 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1502 InstrItinClass itin,
1503 string opc, string asm, list<dag> pattern>
1504 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1505 VFPLdStFrm, itin, opc, asm, "", pattern> {
1506 // Instruction operands.
1510 // Encode instruction operands.
1511 let Inst{23} = addr{8}; // U (add = (U == '1'))
1512 let Inst{22} = Sd{0};
1513 let Inst{19-16} = addr{12-9}; // Rn
1514 let Inst{15-12} = Sd{4-1};
1515 let Inst{7-0} = addr{7-0}; // imm8
1517 let Inst{27-24} = opcod1;
1518 let Inst{21-20} = opcod2;
1519 let Inst{11-9} = 0b101;
1520 let Inst{8} = 0; // Single precision
1522 // Loads & stores operate on both NEON and VFP pipelines.
1523 let D = VFPNeonDomain;
1526 class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1527 InstrItinClass itin,
1528 string opc, string asm, list<dag> pattern>
1529 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1530 VFPLdStFrm, itin, opc, asm, "", pattern> {
1531 list<Predicate> Predicates = [HasFullFP16];
1533 // Instruction operands.
1537 // Encode instruction operands.
1538 let Inst{23} = addr{8}; // U (add = (U == '1'))
1539 let Inst{22} = Sd{0};
1540 let Inst{19-16} = addr{12-9}; // Rn
1541 let Inst{15-12} = Sd{4-1};
1542 let Inst{7-0} = addr{7-0}; // imm8
1544 let Inst{27-24} = opcod1;
1545 let Inst{21-20} = opcod2;
1546 let Inst{11-8} = 0b1001; // Half precision
1548 // Loads & stores operate on both NEON and VFP pipelines.
1549 let D = VFPNeonDomain;
1552 // VFP Load / store multiple pseudo instructions.
1553 class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
1555 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
1557 let OutOperandList = oops;
1558 let InOperandList = !con(iops, (ins pred:$p));
1559 let Pattern = pattern;
1560 list<Predicate> Predicates = [HasVFP2];
1563 // Load / store multiple
1565 // Unknown precision
1566 class AXXI4<dag oops, dag iops, IndexMode im,
1567 string asm, string cstr, list<dag> pattern>
1568 : VFPXI<oops, iops, AddrMode4, 4, im,
1569 VFPLdStFrm, NoItinerary, asm, cstr, pattern> {
1570 // Instruction operands.
1574 // Encode instruction operands.
1575 let Inst{19-16} = Rn;
1577 let Inst{15-12} = regs{11-8};
1578 let Inst{7-1} = regs{7-1};
1580 let Inst{27-25} = 0b110;
1581 let Inst{11-8} = 0b1011;
1586 class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1587 string asm, string cstr, list<dag> pattern>
1588 : VFPXI<oops, iops, AddrMode4, 4, im,
1589 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1590 // Instruction operands.
1594 // Encode instruction operands.
1595 let Inst{19-16} = Rn;
1596 let Inst{22} = regs{12};
1597 let Inst{15-12} = regs{11-8};
1598 let Inst{7-1} = regs{7-1};
1600 let Inst{27-25} = 0b110;
1601 let Inst{11-9} = 0b101;
1602 let Inst{8} = 1; // Double precision
1607 class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1608 string asm, string cstr, list<dag> pattern>
1609 : VFPXI<oops, iops, AddrMode4, 4, im,
1610 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1611 // Instruction operands.
1615 // Encode instruction operands.
1616 let Inst{19-16} = Rn;
1617 let Inst{22} = regs{8};
1618 let Inst{15-12} = regs{12-9};
1619 let Inst{7-0} = regs{7-0};
1621 let Inst{27-25} = 0b110;
1622 let Inst{11-9} = 0b101;
1623 let Inst{8} = 0; // Single precision
1626 // Double precision, unary
1627 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1628 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1629 string asm, list<dag> pattern>
1630 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1631 // Instruction operands.
1635 // Encode instruction operands.
1636 let Inst{3-0} = Dm{3-0};
1637 let Inst{5} = Dm{4};
1638 let Inst{15-12} = Dd{3-0};
1639 let Inst{22} = Dd{4};
1641 let Inst{27-23} = opcod1;
1642 let Inst{21-20} = opcod2;
1643 let Inst{19-16} = opcod3;
1644 let Inst{11-9} = 0b101;
1645 let Inst{8} = 1; // Double precision
1646 let Inst{7-6} = opcod4;
1647 let Inst{4} = opcod5;
1649 let Predicates = [HasVFP2, HasDPVFP];
1652 // Double precision, unary, not-predicated
1653 class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1654 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1655 string asm, list<dag> pattern>
1656 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> {
1657 // Instruction operands.
1661 let Inst{31-28} = 0b1111;
1663 // Encode instruction operands.
1664 let Inst{3-0} = Dm{3-0};
1665 let Inst{5} = Dm{4};
1666 let Inst{15-12} = Dd{3-0};
1667 let Inst{22} = Dd{4};
1669 let Inst{27-23} = opcod1;
1670 let Inst{21-20} = opcod2;
1671 let Inst{19-16} = opcod3;
1672 let Inst{11-9} = 0b101;
1673 let Inst{8} = 1; // Double precision
1674 let Inst{7-6} = opcod4;
1675 let Inst{4} = opcod5;
1678 // Double precision, binary
1679 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1680 dag iops, InstrItinClass itin, string opc, string asm,
1682 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1683 // Instruction operands.
1688 // Encode instruction operands.
1689 let Inst{3-0} = Dm{3-0};
1690 let Inst{5} = Dm{4};
1691 let Inst{19-16} = Dn{3-0};
1692 let Inst{7} = Dn{4};
1693 let Inst{15-12} = Dd{3-0};
1694 let Inst{22} = Dd{4};
1696 let Inst{27-23} = opcod1;
1697 let Inst{21-20} = opcod2;
1698 let Inst{11-9} = 0b101;
1699 let Inst{8} = 1; // Double precision
1703 let Predicates = [HasVFP2, HasDPVFP];
1706 // FP, binary, not predicated
1707 class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1708 InstrItinClass itin, string asm, list<dag> pattern>
1709 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
1712 // Instruction operands.
1717 let Inst{31-28} = 0b1111;
1719 // Encode instruction operands.
1720 let Inst{3-0} = Dm{3-0};
1721 let Inst{5} = Dm{4};
1722 let Inst{19-16} = Dn{3-0};
1723 let Inst{7} = Dn{4};
1724 let Inst{15-12} = Dd{3-0};
1725 let Inst{22} = Dd{4};
1727 let Inst{27-23} = opcod1;
1728 let Inst{21-20} = opcod2;
1729 let Inst{11-9} = 0b101;
1730 let Inst{8} = 1; // double precision
1731 let Inst{6} = opcod3;
1734 let Predicates = [HasVFP2, HasDPVFP];
1737 // Single precision, unary, predicated
1738 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1739 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1740 string asm, list<dag> pattern>
1741 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1742 // Instruction operands.
1746 // Encode instruction operands.
1747 let Inst{3-0} = Sm{4-1};
1748 let Inst{5} = Sm{0};
1749 let Inst{15-12} = Sd{4-1};
1750 let Inst{22} = Sd{0};
1752 let Inst{27-23} = opcod1;
1753 let Inst{21-20} = opcod2;
1754 let Inst{19-16} = opcod3;
1755 let Inst{11-9} = 0b101;
1756 let Inst{8} = 0; // Single precision
1757 let Inst{7-6} = opcod4;
1758 let Inst{4} = opcod5;
1761 // Single precision, unary, non-predicated
1762 class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1763 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1764 string asm, list<dag> pattern>
1765 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1766 VFPUnaryFrm, itin, asm, "", pattern> {
1767 // Instruction operands.
1771 let Inst{31-28} = 0b1111;
1773 // Encode instruction operands.
1774 let Inst{3-0} = Sm{4-1};
1775 let Inst{5} = Sm{0};
1776 let Inst{15-12} = Sd{4-1};
1777 let Inst{22} = Sd{0};
1779 let Inst{27-23} = opcod1;
1780 let Inst{21-20} = opcod2;
1781 let Inst{19-16} = opcod3;
1782 let Inst{11-9} = 0b101;
1783 let Inst{8} = 0; // Single precision
1784 let Inst{7-6} = opcod4;
1785 let Inst{4} = opcod5;
1788 // Single precision unary, if no NEON. Same as ASuI except not available if
1790 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1791 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1792 string asm, list<dag> pattern>
1793 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1795 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1798 // Single precision, binary
1799 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1800 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1801 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1802 // Instruction operands.
1807 // Encode instruction operands.
1808 let Inst{3-0} = Sm{4-1};
1809 let Inst{5} = Sm{0};
1810 let Inst{19-16} = Sn{4-1};
1811 let Inst{7} = Sn{0};
1812 let Inst{15-12} = Sd{4-1};
1813 let Inst{22} = Sd{0};
1815 let Inst{27-23} = opcod1;
1816 let Inst{21-20} = opcod2;
1817 let Inst{11-9} = 0b101;
1818 let Inst{8} = 0; // Single precision
1823 // Single precision, binary, not predicated
1824 class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1825 InstrItinClass itin, string asm, list<dag> pattern>
1826 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1827 VFPBinaryFrm, itin, asm, "", pattern>
1829 // Instruction operands.
1834 let Inst{31-28} = 0b1111;
1836 // Encode instruction operands.
1837 let Inst{3-0} = Sm{4-1};
1838 let Inst{5} = Sm{0};
1839 let Inst{19-16} = Sn{4-1};
1840 let Inst{7} = Sn{0};
1841 let Inst{15-12} = Sd{4-1};
1842 let Inst{22} = Sd{0};
1844 let Inst{27-23} = opcod1;
1845 let Inst{21-20} = opcod2;
1846 let Inst{11-9} = 0b101;
1847 let Inst{8} = 0; // Single precision
1848 let Inst{6} = opcod3;
1852 // Single precision binary, if no NEON. Same as ASbI except not available if
1854 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1855 dag iops, InstrItinClass itin, string opc, string asm,
1857 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1858 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1860 // Instruction operands.
1865 // Encode instruction operands.
1866 let Inst{3-0} = Sm{4-1};
1867 let Inst{5} = Sm{0};
1868 let Inst{19-16} = Sn{4-1};
1869 let Inst{7} = Sn{0};
1870 let Inst{15-12} = Sd{4-1};
1871 let Inst{22} = Sd{0};
1874 // Half precision, unary, predicated
1875 class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1876 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1877 string asm, list<dag> pattern>
1878 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1879 list<Predicate> Predicates = [HasFullFP16];
1881 // Instruction operands.
1885 // Encode instruction operands.
1886 let Inst{3-0} = Sm{4-1};
1887 let Inst{5} = Sm{0};
1888 let Inst{15-12} = Sd{4-1};
1889 let Inst{22} = Sd{0};
1891 let Inst{27-23} = opcod1;
1892 let Inst{21-20} = opcod2;
1893 let Inst{19-16} = opcod3;
1894 let Inst{11-8} = 0b1001; // Half precision
1895 let Inst{7-6} = opcod4;
1896 let Inst{4} = opcod5;
1899 // Half precision, unary, non-predicated
1900 class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1901 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1902 string asm, list<dag> pattern>
1903 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1904 VFPUnaryFrm, itin, asm, "", pattern> {
1905 list<Predicate> Predicates = [HasFullFP16];
1907 // Instruction operands.
1911 let Inst{31-28} = 0b1111;
1913 // Encode instruction operands.
1914 let Inst{3-0} = Sm{4-1};
1915 let Inst{5} = Sm{0};
1916 let Inst{15-12} = Sd{4-1};
1917 let Inst{22} = Sd{0};
1919 let Inst{27-23} = opcod1;
1920 let Inst{21-20} = opcod2;
1921 let Inst{19-16} = opcod3;
1922 let Inst{11-8} = 0b1001; // Half precision
1923 let Inst{7-6} = opcod4;
1924 let Inst{4} = opcod5;
1927 // Half precision, binary
1928 class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1929 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1930 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1931 list<Predicate> Predicates = [HasFullFP16];
1933 // Instruction operands.
1938 // Encode instruction operands.
1939 let Inst{3-0} = Sm{4-1};
1940 let Inst{5} = Sm{0};
1941 let Inst{19-16} = Sn{4-1};
1942 let Inst{7} = Sn{0};
1943 let Inst{15-12} = Sd{4-1};
1944 let Inst{22} = Sd{0};
1946 let Inst{27-23} = opcod1;
1947 let Inst{21-20} = opcod2;
1948 let Inst{11-8} = 0b1001; // Half precision
1953 // Half precision, binary, not predicated
1954 class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1955 InstrItinClass itin, string asm, list<dag> pattern>
1956 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1957 VFPBinaryFrm, itin, asm, "", pattern> {
1958 list<Predicate> Predicates = [HasFullFP16];
1960 // Instruction operands.
1965 let Inst{31-28} = 0b1111;
1967 // Encode instruction operands.
1968 let Inst{3-0} = Sm{4-1};
1969 let Inst{5} = Sm{0};
1970 let Inst{19-16} = Sn{4-1};
1971 let Inst{7} = Sn{0};
1972 let Inst{15-12} = Sd{4-1};
1973 let Inst{22} = Sd{0};
1975 let Inst{27-23} = opcod1;
1976 let Inst{21-20} = opcod2;
1977 let Inst{11-8} = 0b1001; // Half precision
1978 let Inst{6} = opcod3;
1982 // VFP conversion instructions
1983 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1984 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1986 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1987 let Inst{27-23} = opcod1;
1988 let Inst{21-20} = opcod2;
1989 let Inst{19-16} = opcod3;
1990 let Inst{11-8} = opcod4;
1995 // VFP conversion between floating-point and fixed-point
1996 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
1997 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1999 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
2001 // size (fixed-point number): sx == 0 ? 16 : 32
2002 let Inst{7} = op5; // sx
2003 let Inst{5} = fbits{0};
2004 let Inst{3-0} = fbits{4-1};
2007 // VFP conversion instructions, if no NEON
2008 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
2009 dag oops, dag iops, InstrItinClass itin,
2010 string opc, string asm, list<dag> pattern>
2011 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
2013 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
2016 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
2017 InstrItinClass itin,
2018 string opc, string asm, list<dag> pattern>
2019 : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
2020 let Inst{27-20} = opcod1;
2021 let Inst{11-8} = opcod2;
2025 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2026 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2027 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
2029 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2030 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2031 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
2033 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2034 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2035 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
2037 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2038 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2039 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
2041 //===----------------------------------------------------------------------===//
2043 //===----------------------------------------------------------------------===//
2044 // ARM NEON Instruction templates.
2047 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2048 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2050 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2051 let OutOperandList = oops;
2052 let InOperandList = !con(iops, (ins pred:$p));
2053 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2054 let Pattern = pattern;
2055 list<Predicate> Predicates = [HasNEON];
2056 let DecoderNamespace = "NEON";
2059 // Same as NeonI except it does not have a "data type" specifier.
2060 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2061 InstrItinClass itin, string opc, string asm, string cstr,
2063 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2064 let OutOperandList = oops;
2065 let InOperandList = !con(iops, (ins pred:$p));
2066 let AsmString = !strconcat(opc, "${p}", "\t", asm);
2067 let Pattern = pattern;
2068 list<Predicate> Predicates = [HasNEON];
2069 let DecoderNamespace = "NEON";
2072 // Same as NeonI except it is not predicated
2073 class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2074 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2076 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2077 let OutOperandList = oops;
2078 let InOperandList = iops;
2079 let AsmString = !strconcat(opc, ".", dt, "\t", asm);
2080 let Pattern = pattern;
2081 list<Predicate> Predicates = [HasNEON];
2082 let DecoderNamespace = "NEON";
2084 let Inst{31-28} = 0b1111;
2087 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2088 dag oops, dag iops, InstrItinClass itin,
2089 string opc, string dt, string asm, string cstr, list<dag> pattern>
2090 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
2092 let Inst{31-24} = 0b11110100;
2093 let Inst{23} = op23;
2094 let Inst{21-20} = op21_20;
2095 let Inst{11-8} = op11_8;
2096 let Inst{7-4} = op7_4;
2098 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
2099 let DecoderNamespace = "NEONLoadStore";
2105 let Inst{22} = Vd{4};
2106 let Inst{15-12} = Vd{3-0};
2107 let Inst{19-16} = Rn{3-0};
2108 let Inst{3-0} = Rm{3-0};
2111 class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2112 dag oops, dag iops, InstrItinClass itin,
2113 string opc, string dt, string asm, string cstr, list<dag> pattern>
2114 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
2115 dt, asm, cstr, pattern> {
2119 class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
2120 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2122 let OutOperandList = oops;
2123 let InOperandList = !con(iops, (ins pred:$p));
2124 list<Predicate> Predicates = [HasNEON];
2127 class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
2129 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2131 let OutOperandList = oops;
2132 let InOperandList = !con(iops, (ins pred:$p));
2133 let Pattern = pattern;
2134 list<Predicate> Predicates = [HasNEON];
2137 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
2138 string opc, string dt, string asm, string cstr, list<dag> pattern>
2139 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
2141 let Inst{31-25} = 0b1111001;
2142 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2143 let DecoderNamespace = "NEONData";
2146 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
2147 string opc, string asm, string cstr, list<dag> pattern>
2148 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
2150 let Inst{31-25} = 0b1111001;
2151 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2152 let DecoderNamespace = "NEONData";
2155 // NEON "one register and a modified immediate" format.
2156 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
2158 dag oops, dag iops, InstrItinClass itin,
2159 string opc, string dt, string asm, string cstr,
2161 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
2162 let Inst{23} = op23;
2163 let Inst{21-19} = op21_19;
2164 let Inst{11-8} = op11_8;
2170 // Instruction operands.
2174 let Inst{15-12} = Vd{3-0};
2175 let Inst{22} = Vd{4};
2176 let Inst{24} = SIMM{7};
2177 let Inst{18-16} = SIMM{6-4};
2178 let Inst{3-0} = SIMM{3-0};
2179 let DecoderMethod = "DecodeNEONModImmInstruction";
2182 // NEON 2 vector register format.
2183 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2184 bits<5> op11_7, bit op6, bit op4,
2185 dag oops, dag iops, InstrItinClass itin,
2186 string opc, string dt, string asm, string cstr, list<dag> pattern>
2187 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
2188 let Inst{24-23} = op24_23;
2189 let Inst{21-20} = op21_20;
2190 let Inst{19-18} = op19_18;
2191 let Inst{17-16} = op17_16;
2192 let Inst{11-7} = op11_7;
2196 // Instruction operands.
2200 let Inst{15-12} = Vd{3-0};
2201 let Inst{22} = Vd{4};
2202 let Inst{3-0} = Vm{3-0};
2203 let Inst{5} = Vm{4};
2206 // Same as N2V but not predicated.
2207 class N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
2208 dag oops, dag iops, InstrItinClass itin, string OpcodeStr,
2209 string Dt, list<dag> pattern>
2210 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin,
2211 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> {
2215 // Encode instruction operands
2216 let Inst{22} = Vd{4};
2217 let Inst{15-12} = Vd{3-0};
2218 let Inst{5} = Vm{4};
2219 let Inst{3-0} = Vm{3-0};
2221 // Encode constant bits
2222 let Inst{27-23} = 0b00111;
2223 let Inst{21-20} = 0b11;
2224 let Inst{19-18} = op19_18;
2225 let Inst{17-16} = op17_16;
2227 let Inst{10-8} = op10_8;
2232 let DecoderNamespace = "NEON";
2235 // Same as N2V except it doesn't have a datatype suffix.
2236 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2237 bits<5> op11_7, bit op6, bit op4,
2238 dag oops, dag iops, InstrItinClass itin,
2239 string opc, string asm, string cstr, list<dag> pattern>
2240 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
2241 let Inst{24-23} = op24_23;
2242 let Inst{21-20} = op21_20;
2243 let Inst{19-18} = op19_18;
2244 let Inst{17-16} = op17_16;
2245 let Inst{11-7} = op11_7;
2249 // Instruction operands.
2253 let Inst{15-12} = Vd{3-0};
2254 let Inst{22} = Vd{4};
2255 let Inst{3-0} = Vm{3-0};
2256 let Inst{5} = Vm{4};
2259 // NEON 2 vector register with immediate.
2260 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
2261 dag oops, dag iops, Format f, InstrItinClass itin,
2262 string opc, string dt, string asm, string cstr, list<dag> pattern>
2263 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2264 let Inst{24} = op24;
2265 let Inst{23} = op23;
2266 let Inst{11-8} = op11_8;
2271 // Instruction operands.
2276 let Inst{15-12} = Vd{3-0};
2277 let Inst{22} = Vd{4};
2278 let Inst{3-0} = Vm{3-0};
2279 let Inst{5} = Vm{4};
2280 let Inst{21-16} = SIMM{5-0};
2283 // NEON 3 vector register format.
2285 class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2286 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2287 string opc, string dt, string asm, string cstr,
2289 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2290 let Inst{24} = op24;
2291 let Inst{23} = op23;
2292 let Inst{21-20} = op21_20;
2293 let Inst{11-8} = op11_8;
2298 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
2299 dag oops, dag iops, Format f, InstrItinClass itin,
2300 string opc, string dt, string asm, string cstr, list<dag> pattern>
2301 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2302 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2303 // Instruction operands.
2308 let Inst{15-12} = Vd{3-0};
2309 let Inst{22} = Vd{4};
2310 let Inst{19-16} = Vn{3-0};
2311 let Inst{7} = Vn{4};
2312 let Inst{3-0} = Vm{3-0};
2313 let Inst{5} = Vm{4};
2316 class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2317 bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2318 string OpcodeStr, string Dt, list<dag> pattern>
2319 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
2320 Dt, "$Vd, $Vn, $Vm", "", pattern> {
2325 // Encode instruction operands
2326 let Inst{22} = Vd{4};
2327 let Inst{15-12} = Vd{3-0};
2328 let Inst{19-16} = Vn{3-0};
2329 let Inst{7} = Vn{4};
2330 let Inst{5} = Vm{4};
2331 let Inst{3-0} = Vm{3-0};
2333 // Encode constant bits
2334 let Inst{27-23} = op27_23;
2335 let Inst{21-20} = op21_20;
2336 let Inst{11-8} = op11_8;
2341 class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2342 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2343 string opc, string dt, string asm, string cstr,
2345 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2346 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2348 // Instruction operands.
2354 let Inst{15-12} = Vd{3-0};
2355 let Inst{22} = Vd{4};
2356 let Inst{19-16} = Vn{3-0};
2357 let Inst{7} = Vn{4};
2358 let Inst{3-0} = Vm{3-0};
2362 class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2363 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2364 string opc, string dt, string asm, string cstr,
2366 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2367 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2369 // Instruction operands.
2375 let Inst{15-12} = Vd{3-0};
2376 let Inst{22} = Vd{4};
2377 let Inst{19-16} = Vn{3-0};
2378 let Inst{7} = Vn{4};
2379 let Inst{2-0} = Vm{2-0};
2380 let Inst{5} = lane{1};
2381 let Inst{3} = lane{0};
2384 // Same as N3V except it doesn't have a data type suffix.
2385 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2387 dag oops, dag iops, Format f, InstrItinClass itin,
2388 string opc, string asm, string cstr, list<dag> pattern>
2389 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
2390 let Inst{24} = op24;
2391 let Inst{23} = op23;
2392 let Inst{21-20} = op21_20;
2393 let Inst{11-8} = op11_8;
2397 // Instruction operands.
2402 let Inst{15-12} = Vd{3-0};
2403 let Inst{22} = Vd{4};
2404 let Inst{19-16} = Vn{3-0};
2405 let Inst{7} = Vn{4};
2406 let Inst{3-0} = Vm{3-0};
2407 let Inst{5} = Vm{4};
2410 // NEON VMOVs between scalar and core registers.
2411 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2412 dag oops, dag iops, Format f, InstrItinClass itin,
2413 string opc, string dt, string asm, list<dag> pattern>
2414 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
2416 let Inst{27-20} = opcod1;
2417 let Inst{11-8} = opcod2;
2418 let Inst{6-5} = opcod3;
2420 // A8.6.303, A8.6.328, A8.6.329
2421 let Inst{3-0} = 0b0000;
2423 let OutOperandList = oops;
2424 let InOperandList = !con(iops, (ins pred:$p));
2425 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2426 let Pattern = pattern;
2427 list<Predicate> Predicates = [HasNEON];
2429 let PostEncoderMethod = "NEONThumb2DupPostEncoder";
2430 let DecoderNamespace = "NEONDup";
2437 let Inst{31-28} = p{3-0};
2439 let Inst{19-16} = V{3-0};
2440 let Inst{15-12} = R{3-0};
2442 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2443 dag oops, dag iops, InstrItinClass itin,
2444 string opc, string dt, string asm, list<dag> pattern>
2445 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
2446 opc, dt, asm, pattern>;
2447 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2448 dag oops, dag iops, InstrItinClass itin,
2449 string opc, string dt, string asm, list<dag> pattern>
2450 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
2451 opc, dt, asm, pattern>;
2452 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2453 dag oops, dag iops, InstrItinClass itin,
2454 string opc, string dt, string asm, list<dag> pattern>
2455 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
2456 opc, dt, asm, pattern>;
2458 // Vector Duplicate Lane (from scalar to all elements)
2459 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
2460 InstrItinClass itin, string opc, string dt, string asm,
2462 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
2463 let Inst{24-23} = 0b11;
2464 let Inst{21-20} = 0b11;
2465 let Inst{19-16} = op19_16;
2466 let Inst{11-7} = 0b11000;
2473 let Inst{22} = Vd{4};
2474 let Inst{15-12} = Vd{3-0};
2475 let Inst{5} = Vm{4};
2476 let Inst{3-0} = Vm{3-0};
2479 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
2480 // for single-precision FP.
2481 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
2482 list<Predicate> Predicates = [HasNEON,UseNEONForFP];
2485 // VFP/NEON Instruction aliases for type suffices.
2486 // Note: When EmitPriority == 1, the alias will be used for printing
2487 class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> :
2488 InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasVFP2]>;
2490 // Note: When EmitPriority == 1, the alias will be used for printing
2491 multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2492 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2493 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2494 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2495 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2498 // Note: When EmitPriority == 1, the alias will be used for printing
2499 multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2500 let Predicates = [HasNEON] in {
2501 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2502 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2503 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2504 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2508 // The same alias classes using AsmPseudo instead, for the more complex
2509 // stuff in NEON that InstAlias can't quite handle.
2510 // Note that we can't use anonymous defm references here like we can
2511 // above, as we care about the ultimate instruction enum names generated, unlike
2512 // for instalias defs.
2513 class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> :
2514 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>;
2516 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
2517 def : TokenAlias<".s8", ".i8">;
2518 def : TokenAlias<".u8", ".i8">;
2519 def : TokenAlias<".s16", ".i16">;
2520 def : TokenAlias<".u16", ".i16">;
2521 def : TokenAlias<".s32", ".i32">;
2522 def : TokenAlias<".u32", ".i32">;
2523 def : TokenAlias<".s64", ".i64">;
2524 def : TokenAlias<".u64", ".i64">;
2526 def : TokenAlias<".i8", ".8">;
2527 def : TokenAlias<".i16", ".16">;
2528 def : TokenAlias<".i32", ".32">;
2529 def : TokenAlias<".i64", ".64">;
2531 def : TokenAlias<".p8", ".8">;
2532 def : TokenAlias<".p16", ".16">;
2534 def : TokenAlias<".f32", ".32">;
2535 def : TokenAlias<".f64", ".64">;
2536 def : TokenAlias<".f", ".f32">;
2537 def : TokenAlias<".d", ".f64">;