1 //===-- ARMInstrFormats.td - ARM Instruction Formats -------*- tablegen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
11 // ARM Instruction Format Definitions.
14 // Format specifies the encoding used by the instruction. This is part of the
15 // ad-hoc solution used to emit machine instruction encodings by our machine
17 class Format<bits<6> val> {
21 def Pseudo : Format<0>;
22 def MulFrm : Format<1>;
23 def BrFrm : Format<2>;
24 def BrMiscFrm : Format<3>;
26 def DPFrm : Format<4>;
27 def DPSoRegRegFrm : Format<5>;
29 def LdFrm : Format<6>;
30 def StFrm : Format<7>;
31 def LdMiscFrm : Format<8>;
32 def StMiscFrm : Format<9>;
33 def LdStMulFrm : Format<10>;
35 def LdStExFrm : Format<11>;
37 def ArithMiscFrm : Format<12>;
38 def SatFrm : Format<13>;
39 def ExtFrm : Format<14>;
41 def VFPUnaryFrm : Format<15>;
42 def VFPBinaryFrm : Format<16>;
43 def VFPConv1Frm : Format<17>;
44 def VFPConv2Frm : Format<18>;
45 def VFPConv3Frm : Format<19>;
46 def VFPConv4Frm : Format<20>;
47 def VFPConv5Frm : Format<21>;
48 def VFPLdStFrm : Format<22>;
49 def VFPLdStMulFrm : Format<23>;
50 def VFPMiscFrm : Format<24>;
52 def ThumbFrm : Format<25>;
53 def MiscFrm : Format<26>;
55 def NGetLnFrm : Format<27>;
56 def NSetLnFrm : Format<28>;
57 def NDupFrm : Format<29>;
58 def NLdStFrm : Format<30>;
59 def N1RegModImmFrm: Format<31>;
60 def N2RegFrm : Format<32>;
61 def NVCVTFrm : Format<33>;
62 def NVDupLnFrm : Format<34>;
63 def N2RegVShLFrm : Format<35>;
64 def N2RegVShRFrm : Format<36>;
65 def N3RegFrm : Format<37>;
66 def N3RegVShFrm : Format<38>;
67 def NVExtFrm : Format<39>;
68 def NVMulSLFrm : Format<40>;
69 def NVTBLFrm : Format<41>;
70 def DPSoRegImmFrm : Format<42>;
71 def N3RegCplxFrm : Format<43>;
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>;
110 def AddrMode5FP16 : AddrMode<17>;
111 def AddrModeT2_ldrex : AddrMode<18>;
113 // Load / store index mode.
114 class IndexMode<bits<2> val> {
117 def IndexModeNone : IndexMode<0>;
118 def IndexModePre : IndexMode<1>;
119 def IndexModePost : IndexMode<2>;
120 def IndexModeUpd : IndexMode<3>;
122 // Instruction execution domain.
123 class Domain<bits<3> val> {
126 def GenericDomain : Domain<0>;
127 def VFPDomain : Domain<1>; // Instructions in VFP domain only
128 def NeonDomain : Domain<2>; // Instructions in Neon domain only
129 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
130 def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
132 //===----------------------------------------------------------------------===//
133 // ARM special operands.
136 // ARM imod and iflag operands, used only by the CPS instruction.
137 def imod_op : Operand<i32> {
138 let PrintMethod = "printCPSIMod";
141 def ProcIFlagsOperand : AsmOperandClass {
142 let Name = "ProcIFlags";
143 let ParserMethod = "parseProcIFlagsOperand";
145 def iflags_op : Operand<i32> {
146 let PrintMethod = "printCPSIFlag";
147 let ParserMatchClass = ProcIFlagsOperand;
150 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
151 // register whose default is 0 (no register).
152 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
153 def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
154 (ops (i32 14), (i32 zero_reg))> {
155 let PrintMethod = "printPredicateOperand";
156 let ParserMatchClass = CondCodeOperand;
157 let DecoderMethod = "DecodePredicateOperand";
160 // Selectable predicate operand for CMOV instructions. We can't use a normal
161 // predicate because the default values interfere with instruction selection. In
162 // all other respects it is identical though: pseudo-instruction expansion
163 // relies on the MachineOperands being compatible.
164 def cmovpred : Operand<i32>, PredicateOp,
165 ComplexPattern<i32, 2, "SelectCMOVPred"> {
166 let MIOperandInfo = (ops i32imm, i32imm);
167 let PrintMethod = "printPredicateOperand";
170 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
171 def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
172 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
173 let EncoderMethod = "getCCOutOpValue";
174 let PrintMethod = "printSBitModifierOperand";
175 let ParserMatchClass = CCOutOperand;
176 let DecoderMethod = "DecodeCCOutOperand";
179 // Same as cc_out except it defaults to setting CPSR.
180 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
181 let EncoderMethod = "getCCOutOpValue";
182 let PrintMethod = "printSBitModifierOperand";
183 let ParserMatchClass = CCOutOperand;
184 let DecoderMethod = "DecodeCCOutOperand";
187 // ARM special operands for disassembly only.
189 def SetEndAsmOperand : ImmAsmOperand<0,1> {
190 let Name = "SetEndImm";
191 let ParserMethod = "parseSetEndImm";
193 def setend_op : Operand<i32> {
194 let PrintMethod = "printSetendOperand";
195 let ParserMatchClass = SetEndAsmOperand;
198 def MSRMaskOperand : AsmOperandClass {
199 let Name = "MSRMask";
200 let ParserMethod = "parseMSRMaskOperand";
202 def msr_mask : Operand<i32> {
203 let PrintMethod = "printMSRMaskOperand";
204 let DecoderMethod = "DecodeMSRMask";
205 let ParserMatchClass = MSRMaskOperand;
208 def BankedRegOperand : AsmOperandClass {
209 let Name = "BankedReg";
210 let ParserMethod = "parseBankedRegOperand";
212 def banked_reg : Operand<i32> {
213 let PrintMethod = "printBankedRegOperand";
214 let DecoderMethod = "DecodeBankedReg";
215 let ParserMatchClass = BankedRegOperand;
218 // Shift Right Immediate - A shift right immediate is encoded differently from
219 // other shift immediates. The imm6 field is encoded like so:
222 // 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
223 // 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
224 // 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
225 // 64 64 - <imm> is encoded in imm6<5:0>
226 def shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; }
227 def shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> {
228 let EncoderMethod = "getShiftRight8Imm";
229 let DecoderMethod = "DecodeShiftRight8Imm";
230 let ParserMatchClass = shr_imm8_asm_operand;
232 def shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; }
233 def shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> {
234 let EncoderMethod = "getShiftRight16Imm";
235 let DecoderMethod = "DecodeShiftRight16Imm";
236 let ParserMatchClass = shr_imm16_asm_operand;
238 def shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; }
239 def shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> {
240 let EncoderMethod = "getShiftRight32Imm";
241 let DecoderMethod = "DecodeShiftRight32Imm";
242 let ParserMatchClass = shr_imm32_asm_operand;
244 def shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; }
245 def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> {
246 let EncoderMethod = "getShiftRight64Imm";
247 let DecoderMethod = "DecodeShiftRight64Imm";
248 let ParserMatchClass = shr_imm64_asm_operand;
252 // ARM Assembler operand for ldr Rd, =expression which generates an offset
253 // to a constant pool entry or a MOV depending on the value of expression
254 def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; }
255 def const_pool_asm_imm : Operand<i32> {
256 let ParserMatchClass = const_pool_asm_operand;
260 //===----------------------------------------------------------------------===//
261 // ARM Assembler alias templates.
263 // Note: When EmitPriority == 1, the alias will be used for printing
264 class ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0>
265 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>;
266 class ARMInstSubst<string Asm, dag Result, bit EmitPriority = 0>
267 : InstAlias<Asm, Result, EmitPriority>,
268 Requires<[IsARM,UseNegativeImmediates]>;
269 class tInstAlias<string Asm, dag Result, bit EmitPriority = 0>
270 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>;
271 class tInstSubst<string Asm, dag Result, bit EmitPriority = 0>
272 : InstAlias<Asm, Result, EmitPriority>,
273 Requires<[IsThumb,UseNegativeImmediates]>;
274 class t2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
275 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>;
276 class t2InstSubst<string Asm, dag Result, bit EmitPriority = 0>
277 : InstAlias<Asm, Result, EmitPriority>,
278 Requires<[IsThumb2,UseNegativeImmediates]>;
279 class VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
280 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>;
281 class VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0>
282 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>;
283 class VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0>
284 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>;
285 class NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0>
286 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>;
289 class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
291 class NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
294 //===----------------------------------------------------------------------===//
295 // ARM Instruction templates.
299 class InstTemplate<AddrMode am, int sz, IndexMode im,
300 Format f, Domain d, string cstr, InstrItinClass itin>
302 let Namespace = "ARM";
307 bits<2> IndexModeBits = IM.Value;
309 bits<6> Form = F.Value;
311 bit isUnaryDataProc = 0;
312 bit canXformTo16Bit = 0;
313 // The instruction is a 16-bit flag setting Thumb instruction. Used
314 // by the parser to determine whether to require the 'S' suffix on the
315 // mnemonic (when not in an IT block) or preclude it (when in an IT block).
316 bit thumbArithFlagSetting = 0;
318 // If this is a pseudo instruction, mark it isCodeGenOnly.
319 let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
321 // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
322 let TSFlags{4-0} = AM.Value;
323 let TSFlags{6-5} = IndexModeBits;
324 let TSFlags{12-7} = Form;
325 let TSFlags{13} = isUnaryDataProc;
326 let TSFlags{14} = canXformTo16Bit;
327 let TSFlags{17-15} = D.Value;
328 let TSFlags{18} = thumbArithFlagSetting;
330 let Constraints = cstr;
331 let Itinerary = itin;
336 // Mask of bits that cause an encoding to be UNPREDICTABLE.
337 // If a bit is set, then if the corresponding bit in the
338 // target encoding differs from its value in the "Inst" field,
339 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
340 field bits<32> Unpredictable = 0;
341 // SoftFail is the generic name for this field, but we alias it so
342 // as to make it more obvious what it means in ARM-land.
343 field bits<32> SoftFail = Unpredictable;
346 class InstARM<AddrMode am, int sz, IndexMode im,
347 Format f, Domain d, string cstr, InstrItinClass itin>
348 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
349 let DecoderNamespace = "ARM";
352 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
353 // on by adding flavors to specific instructions.
354 class InstThumb<AddrMode am, int sz, IndexMode im,
355 Format f, Domain d, string cstr, InstrItinClass itin>
356 : InstTemplate<am, sz, im, f, d, cstr, itin> {
357 let DecoderNamespace = "Thumb";
360 // Pseudo-instructions for alternate assembly syntax (never used by codegen).
361 // These are aliases that require C++ handling to convert to the target
362 // instruction, while InstAliases can be handled directly by tblgen.
363 class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
364 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
366 let OutOperandList = oops;
367 let InOperandList = iops;
369 let isCodeGenOnly = 0; // So we get asm matcher for it.
374 class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)>
375 : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>;
376 class tAsmPseudo<string asm, dag iops, dag oops = (outs)>
377 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>;
378 class t2AsmPseudo<string asm, dag iops, dag oops = (outs)>
379 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>;
380 class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)>
381 : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>;
382 class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)>
383 : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>;
385 // Pseudo instructions for the code generator.
386 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
387 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
388 GenericDomain, "", itin> {
389 let OutOperandList = oops;
390 let InOperandList = iops;
391 let Pattern = pattern;
392 let isCodeGenOnly = 1;
396 // PseudoInst that's ARM-mode only.
397 class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
399 : PseudoInst<oops, iops, itin, pattern> {
401 list<Predicate> Predicates = [IsARM];
404 // PseudoInst that's Thumb-mode only.
405 class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
407 : PseudoInst<oops, iops, itin, pattern> {
409 list<Predicate> Predicates = [IsThumb];
412 // PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2)
413 class t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
415 : PseudoInst<oops, iops, itin, pattern> {
417 list<Predicate> Predicates = [IsThumb,HasV8MBaseline];
420 // PseudoInst that's Thumb2-mode only.
421 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
423 : PseudoInst<oops, iops, itin, pattern> {
425 list<Predicate> Predicates = [IsThumb2];
428 class ARMPseudoExpand<dag oops, dag iops, int sz,
429 InstrItinClass itin, list<dag> pattern,
431 : ARMPseudoInst<oops, iops, sz, itin, pattern>,
432 PseudoInstExpansion<Result>;
434 class tPseudoExpand<dag oops, dag iops, int sz,
435 InstrItinClass itin, list<dag> pattern,
437 : tPseudoInst<oops, iops, sz, itin, pattern>,
438 PseudoInstExpansion<Result>;
440 class t2PseudoExpand<dag oops, dag iops, int sz,
441 InstrItinClass itin, list<dag> pattern,
443 : t2PseudoInst<oops, iops, sz, itin, pattern>,
444 PseudoInstExpansion<Result>;
446 // Almost all ARM instructions are predicable.
447 class I<dag oops, dag iops, AddrMode am, int sz,
448 IndexMode im, Format f, InstrItinClass itin,
449 string opc, string asm, string cstr,
451 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
454 let OutOperandList = oops;
455 let InOperandList = !con(iops, (ins pred:$p));
456 let AsmString = !strconcat(opc, "${p}", asm);
457 let Pattern = pattern;
458 list<Predicate> Predicates = [IsARM];
461 // A few are not predicable
462 class InoP<dag oops, dag iops, AddrMode am, int sz,
463 IndexMode im, Format f, InstrItinClass itin,
464 string opc, string asm, string cstr,
466 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
467 let OutOperandList = oops;
468 let InOperandList = iops;
469 let AsmString = !strconcat(opc, asm);
470 let Pattern = pattern;
471 let isPredicable = 0;
472 list<Predicate> Predicates = [IsARM];
475 // Same as I except it can optionally modify CPSR. Note it's modeled as an input
476 // operand since by default it's a zero register. It will become an implicit def
477 // once it's "flipped".
478 class sI<dag oops, dag iops, AddrMode am, int sz,
479 IndexMode im, Format f, InstrItinClass itin,
480 string opc, string asm, string cstr,
482 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
483 bits<4> p; // Predicate operand
484 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
488 let OutOperandList = oops;
489 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
490 let AsmString = !strconcat(opc, "${s}${p}", asm);
491 let Pattern = pattern;
492 list<Predicate> Predicates = [IsARM];
496 class XI<dag oops, dag iops, AddrMode am, int sz,
497 IndexMode im, Format f, InstrItinClass itin,
498 string asm, string cstr, list<dag> pattern>
499 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
500 let OutOperandList = oops;
501 let InOperandList = iops;
503 let Pattern = pattern;
504 list<Predicate> Predicates = [IsARM];
507 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
508 string opc, string asm, list<dag> pattern>
509 : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
510 opc, asm, "", pattern>;
511 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
512 string opc, string asm, list<dag> pattern>
513 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
514 opc, asm, "", pattern>;
515 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
516 string asm, list<dag> pattern>
517 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
519 class AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin,
520 string asm, list<dag> pattern>
521 : XI<oops, iops, am, 4, IndexModeNone, f, itin,
523 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
524 string opc, string asm, list<dag> pattern>
525 : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
526 opc, asm, "", pattern>;
528 // Ctrl flow instructions
529 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
530 string opc, string asm, list<dag> pattern>
531 : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
532 opc, asm, "", pattern> {
533 let Inst{27-24} = opcod;
535 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
536 string asm, list<dag> pattern>
537 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
539 let Inst{27-24} = opcod;
542 // BR_JT instructions
543 class JTI<dag oops, dag iops, InstrItinClass itin,
544 string asm, list<dag> pattern>
545 : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
548 class AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
549 string opc, string asm, list<dag> pattern>
550 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
551 opc, asm, "", pattern> {
554 let Inst{27-23} = 0b00011;
555 let Inst{22-21} = opcod;
557 let Inst{19-16} = addr;
558 let Inst{15-12} = Rt;
559 let Inst{11-10} = 0b11;
560 let Inst{9-8} = opcod2;
561 let Inst{7-0} = 0b10011111;
563 class AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
564 string opc, string asm, list<dag> pattern>
565 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
566 opc, asm, "", pattern> {
569 let Inst{27-23} = 0b00011;
570 let Inst{22-21} = opcod;
572 let Inst{19-16} = addr;
573 let Inst{11-10} = 0b11;
574 let Inst{9-8} = opcod2;
575 let Inst{7-4} = 0b1001;
578 // Atomic load/store instructions
579 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
580 string opc, string asm, list<dag> pattern>
581 : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>;
583 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
584 string opc, string asm, list<dag> pattern>
585 : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> {
587 let Inst{15-12} = Rd;
590 // Exclusive load/store instructions
592 class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
593 string opc, string asm, list<dag> pattern>
594 : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
595 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>;
597 class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
598 string opc, string asm, list<dag> pattern>
599 : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
600 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> {
602 let Inst{15-12} = Rd;
605 class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
606 : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
610 let Inst{27-23} = 0b00010;
612 let Inst{21-20} = 0b00;
613 let Inst{19-16} = addr;
614 let Inst{15-12} = Rt;
615 let Inst{11-4} = 0b00001001;
618 let Unpredictable{11-8} = 0b1111;
619 let DecoderMethod = "DecodeSwap";
621 // Acquire/Release load/store instructions
622 class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
623 string opc, string asm, list<dag> pattern>
624 : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
625 Requires<[IsARM, HasAcquireRelease]>;
627 class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
628 string opc, string asm, list<dag> pattern>
629 : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
630 Requires<[IsARM, HasAcquireRelease]> {
631 let Inst{15-12} = 0b1111;
634 // addrmode1 instructions
635 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
636 string opc, string asm, list<dag> pattern>
637 : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
638 opc, asm, "", pattern> {
639 let Inst{24-21} = opcod;
640 let Inst{27-26} = 0b00;
642 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
643 string opc, string asm, list<dag> pattern>
644 : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
645 opc, asm, "", pattern> {
646 let Inst{24-21} = opcod;
647 let Inst{27-26} = 0b00;
649 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
650 string asm, list<dag> pattern>
651 : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
653 let Inst{24-21} = opcod;
654 let Inst{27-26} = 0b00;
659 // LDR/LDRB/STR/STRB/...
660 class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
661 Format f, InstrItinClass itin, string opc, string asm,
663 : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
665 let Inst{27-25} = op;
666 let Inst{24} = 1; // 24 == P
668 let Inst{22} = isByte;
669 let Inst{21} = 0; // 21 == W
672 // Indexed load/stores
673 class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
674 IndexMode im, Format f, InstrItinClass itin, string opc,
675 string asm, string cstr, list<dag> pattern>
676 : I<oops, iops, AddrMode2, 4, im, f, itin,
677 opc, asm, cstr, pattern> {
679 let Inst{27-26} = 0b01;
680 let Inst{24} = isPre; // P bit
681 let Inst{22} = isByte; // B bit
682 let Inst{21} = isPre; // W bit
683 let Inst{20} = isLd; // L bit
684 let Inst{15-12} = Rt;
686 class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
687 IndexMode im, Format f, InstrItinClass itin, string opc,
688 string asm, string cstr, list<dag> pattern>
689 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
691 // AM2 store w/ two operands: (GPR, am2offset)
697 let Inst{23} = offset{12};
698 let Inst{19-16} = Rn;
699 let Inst{11-5} = offset{11-5};
701 let Inst{3-0} = offset{3-0};
704 class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
705 IndexMode im, Format f, InstrItinClass itin, string opc,
706 string asm, string cstr, list<dag> pattern>
707 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
709 // AM2 store w/ two operands: (GPR, am2offset)
715 let Inst{23} = offset{12};
716 let Inst{19-16} = Rn;
717 let Inst{11-0} = offset{11-0};
721 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
722 // but for now use this class for STRT and STRBT.
723 class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
724 IndexMode im, Format f, InstrItinClass itin, string opc,
725 string asm, string cstr, list<dag> pattern>
726 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
728 // AM2 store w/ two operands: (GPR, am2offset)
730 // {13} 1 == Rm, 0 == imm12
734 let Inst{25} = addr{13};
735 let Inst{23} = addr{12};
736 let Inst{19-16} = addr{17-14};
737 let Inst{11-0} = addr{11-0};
740 // addrmode3 instructions
741 class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
742 InstrItinClass itin, string opc, string asm, list<dag> pattern>
743 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
744 opc, asm, "", pattern> {
747 let Inst{27-25} = 0b000;
748 let Inst{24} = 1; // P bit
749 let Inst{23} = addr{8}; // U bit
750 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
751 let Inst{21} = 0; // W bit
752 let Inst{20} = op20; // L bit
753 let Inst{19-16} = addr{12-9}; // Rn
754 let Inst{15-12} = Rt; // Rt
755 let Inst{11-8} = addr{7-4}; // imm7_4/zero
757 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
759 let DecoderMethod = "DecodeAddrMode3Instruction";
762 class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
763 IndexMode im, Format f, InstrItinClass itin, string opc,
764 string asm, string cstr, list<dag> pattern>
765 : I<oops, iops, AddrMode3, 4, im, f, itin,
766 opc, asm, cstr, pattern> {
768 let Inst{27-25} = 0b000;
769 let Inst{24} = isPre; // P bit
770 let Inst{21} = isPre; // W bit
771 let Inst{20} = op20; // L bit
772 let Inst{15-12} = Rt; // Rt
776 // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
777 // but for now use this class for LDRSBT, LDRHT, LDSHT.
778 class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
779 IndexMode im, Format f, InstrItinClass itin, string opc,
780 string asm, string cstr, list<dag> pattern>
781 : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
782 // {13} 1 == imm8, 0 == Rm
789 let Inst{27-25} = 0b000;
790 let Inst{24} = 0; // P bit
792 let Inst{20} = isLoad; // L bit
793 let Inst{19-16} = addr; // Rn
794 let Inst{15-12} = Rt; // Rt
799 class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
800 string opc, string asm, list<dag> pattern>
801 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
802 opc, asm, "", pattern> {
805 let Inst{27-25} = 0b000;
806 let Inst{24} = 1; // P bit
807 let Inst{23} = addr{8}; // U bit
808 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
809 let Inst{21} = 0; // W bit
810 let Inst{20} = 0; // L bit
811 let Inst{19-16} = addr{12-9}; // Rn
812 let Inst{15-12} = Rt; // Rt
813 let Inst{11-8} = addr{7-4}; // imm7_4/zero
815 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
816 let DecoderMethod = "DecodeAddrMode3Instruction";
819 // addrmode4 instructions
820 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
821 string asm, string cstr, list<dag> pattern>
822 : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
827 let Inst{27-25} = 0b100;
828 let Inst{22} = 0; // S bit
829 let Inst{19-16} = Rn;
830 let Inst{15-0} = regs;
833 // Unsigned multiply, multiply-accumulate instructions.
834 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
835 string opc, string asm, list<dag> pattern>
836 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
837 opc, asm, "", pattern> {
838 let Inst{7-4} = 0b1001;
839 let Inst{20} = 0; // S bit
840 let Inst{27-21} = opcod;
842 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
843 string opc, string asm, list<dag> pattern>
844 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
845 opc, asm, "", pattern> {
846 let Inst{7-4} = 0b1001;
847 let Inst{27-21} = opcod;
850 // Most significant word multiply
851 class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
852 InstrItinClass itin, string opc, string asm, list<dag> pattern>
853 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
854 opc, asm, "", pattern> {
858 let Inst{7-4} = opc7_4;
860 let Inst{27-21} = opcod;
861 let Inst{19-16} = Rd;
865 // MSW multiple w/ Ra operand
866 class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
867 InstrItinClass itin, string opc, string asm, list<dag> pattern>
868 : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
870 let Inst{15-12} = Ra;
873 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
874 class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
875 InstrItinClass itin, string opc, string asm, list<dag> pattern>
876 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
877 opc, asm, "", pattern> {
883 let Inst{27-21} = opcod;
884 let Inst{6-5} = bit6_5;
888 class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
889 InstrItinClass itin, string opc, string asm, list<dag> pattern>
890 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
892 let Inst{19-16} = Rd;
895 // AMulxyI with Ra operand
896 class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
897 InstrItinClass itin, string opc, string asm, list<dag> pattern>
898 : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
900 let Inst{15-12} = Ra;
903 class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
904 InstrItinClass itin, string opc, string asm, list<dag> pattern>
905 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
908 let Inst{19-16} = RdHi;
909 let Inst{15-12} = RdLo;
912 // Extend instructions.
913 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
914 string opc, string asm, list<dag> pattern>
915 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
916 opc, asm, "", pattern> {
917 // All AExtI instructions have Rd and Rm register operands.
920 let Inst{15-12} = Rd;
922 let Inst{7-4} = 0b0111;
923 let Inst{9-8} = 0b00;
924 let Inst{27-20} = opcod;
926 let Unpredictable{9-8} = 0b11;
929 // Misc Arithmetic instructions.
930 class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
931 InstrItinClass itin, string opc, string asm, list<dag> pattern>
932 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
933 opc, asm, "", pattern> {
936 let Inst{27-20} = opcod;
937 let Inst{19-16} = 0b1111;
938 let Inst{15-12} = Rd;
939 let Inst{11-8} = 0b1111;
940 let Inst{7-4} = opc7_4;
944 // Division instructions.
945 class ADivA1I<bits<3> opcod, dag oops, dag iops,
946 InstrItinClass itin, string opc, string asm, list<dag> pattern>
947 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
948 opc, asm, "", pattern> {
952 let Inst{27-23} = 0b01110;
953 let Inst{22-20} = opcod;
954 let Inst{19-16} = Rd;
955 let Inst{15-12} = 0b1111;
957 let Inst{7-4} = 0b0001;
962 def PKHLSLAsmOperand : ImmAsmOperand<0,31> {
963 let Name = "PKHLSLImm";
964 let ParserMethod = "parsePKHLSLImm";
966 def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
967 let PrintMethod = "printPKHLSLShiftImm";
968 let ParserMatchClass = PKHLSLAsmOperand;
970 def PKHASRAsmOperand : AsmOperandClass {
971 let Name = "PKHASRImm";
972 let ParserMethod = "parsePKHASRImm";
974 def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
975 let PrintMethod = "printPKHASRShiftImm";
976 let ParserMatchClass = PKHASRAsmOperand;
979 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
980 string opc, string asm, list<dag> pattern>
981 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
982 opc, asm, "", pattern> {
987 let Inst{27-20} = opcod;
988 let Inst{19-16} = Rn;
989 let Inst{15-12} = Rd;
992 let Inst{5-4} = 0b01;
996 //===----------------------------------------------------------------------===//
998 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
999 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
1000 list<Predicate> Predicates = [IsARM];
1002 class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
1003 list<Predicate> Predicates = [IsARM, HasV5T];
1005 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
1006 list<Predicate> Predicates = [IsARM, HasV5TE];
1008 // ARMV5MOPat - Same as ARMV5TEPat with UseMulOps.
1009 class ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> {
1010 list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps];
1012 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
1013 list<Predicate> Predicates = [IsARM, HasV6];
1015 class VFPPat<dag pattern, dag result> : Pat<pattern, result> {
1016 list<Predicate> Predicates = [HasVFP2];
1018 class VFPNoNEONPat<dag pattern, dag result> : Pat<pattern, result> {
1019 list<Predicate> Predicates = [HasVFP2, DontUseNEONForFP];
1021 class Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> {
1022 list<Predicate> Predicates = [IsThumb2, HasDSP];
1024 class Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> {
1025 list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP];
1027 class FP16Pat<dag pattern, dag result> : Pat<pattern, result> {
1028 list<Predicate> Predicates = [HasFP16];
1030 class FullFP16Pat<dag pattern, dag result> : Pat<pattern, result> {
1031 list<Predicate> Predicates = [HasFullFP16];
1033 //===----------------------------------------------------------------------===//
1034 // Thumb Instruction Format Definitions.
1037 class ThumbI<dag oops, dag iops, AddrMode am, int sz,
1038 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1039 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1040 let OutOperandList = oops;
1041 let InOperandList = iops;
1042 let AsmString = asm;
1043 let Pattern = pattern;
1044 list<Predicate> Predicates = [IsThumb];
1047 // TI - Thumb instruction.
1048 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
1049 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1051 // Two-address instructions
1052 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
1054 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
1057 // tBL, tBX 32-bit instructions
1058 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
1059 dag oops, dag iops, InstrItinClass itin, string asm,
1061 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
1063 let Inst{31-27} = opcod1;
1064 let Inst{15-14} = opcod2;
1065 let Inst{12} = opcod3;
1068 // BR_JT instructions
1069 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
1071 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1074 class Thumb1I<dag oops, dag iops, AddrMode am, int sz,
1075 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1076 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1077 let OutOperandList = oops;
1078 let InOperandList = iops;
1079 let AsmString = asm;
1080 let Pattern = pattern;
1081 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1084 class T1I<dag oops, dag iops, InstrItinClass itin,
1085 string asm, list<dag> pattern>
1086 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1087 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1088 string asm, list<dag> pattern>
1089 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1091 // Two-address instructions
1092 class T1It<dag oops, dag iops, InstrItinClass itin,
1093 string asm, string cstr, list<dag> pattern>
1094 : Thumb1I<oops, iops, AddrModeNone, 2, itin,
1095 asm, cstr, pattern>;
1097 // Thumb1 instruction that can either be predicated or set CPSR.
1098 class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
1099 InstrItinClass itin,
1100 string opc, string asm, string cstr, list<dag> pattern>
1101 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1102 let OutOperandList = !con(oops, (outs s_cc_out:$s));
1103 let InOperandList = !con(iops, (ins pred:$p));
1104 let AsmString = !strconcat(opc, "${s}${p}", asm);
1105 let Pattern = pattern;
1106 let thumbArithFlagSetting = 1;
1107 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1108 let DecoderNamespace = "ThumbSBit";
1111 class T1sI<dag oops, dag iops, InstrItinClass itin,
1112 string opc, string asm, list<dag> pattern>
1113 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1115 // Two-address instructions
1116 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1117 string opc, string asm, list<dag> pattern>
1118 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1119 "$Rn = $Rdn", pattern>;
1121 // Thumb1 instruction that can be predicated.
1122 class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
1123 InstrItinClass itin,
1124 string opc, string asm, string cstr, list<dag> pattern>
1125 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1126 let OutOperandList = oops;
1127 let InOperandList = !con(iops, (ins pred:$p));
1128 let AsmString = !strconcat(opc, "${p}", asm);
1129 let Pattern = pattern;
1130 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1133 class T1pI<dag oops, dag iops, InstrItinClass itin,
1134 string opc, string asm, list<dag> pattern>
1135 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1137 // Two-address instructions
1138 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1139 string opc, string asm, list<dag> pattern>
1140 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1141 "$Rn = $Rdn", pattern>;
1143 class T1pIs<dag oops, dag iops,
1144 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1145 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
1147 class Encoding16 : Encoding {
1148 let Inst{31-16} = 0x0000;
1151 // A6.2 16-bit Thumb instruction encoding
1152 class T1Encoding<bits<6> opcode> : Encoding16 {
1153 let Inst{15-10} = opcode;
1156 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1157 class T1General<bits<5> opcode> : Encoding16 {
1158 let Inst{15-14} = 0b00;
1159 let Inst{13-9} = opcode;
1162 // A6.2.2 Data-processing encoding.
1163 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1164 let Inst{15-10} = 0b010000;
1165 let Inst{9-6} = opcode;
1168 // A6.2.3 Special data instructions and branch and exchange encoding.
1169 class T1Special<bits<4> opcode> : Encoding16 {
1170 let Inst{15-10} = 0b010001;
1171 let Inst{9-6} = opcode;
1174 // A6.2.4 Load/store single data item encoding.
1175 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1176 let Inst{15-12} = opA;
1177 let Inst{11-9} = opB;
1179 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
1181 class T1BranchCond<bits<4> opcode> : Encoding16 {
1182 let Inst{15-12} = opcode;
1185 // Helper classes to encode Thumb1 loads and stores. For immediates, the
1186 // following bits are used for "opA" (see A6.2.4):
1188 // 0b0110 => Immediate, 4 bytes
1189 // 0b1000 => Immediate, 2 bytes
1190 // 0b0111 => Immediate, 1 byte
1191 class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
1192 InstrItinClass itin, string opc, string asm,
1194 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1195 T1LoadStore<0b0101, opcode> {
1198 let Inst{8-6} = addr{5-3}; // Rm
1199 let Inst{5-3} = addr{2-0}; // Rn
1202 class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
1203 InstrItinClass itin, string opc, string asm,
1205 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1206 T1LoadStore<opA, {opB,?,?}> {
1209 let Inst{10-6} = addr{7-3}; // imm5
1210 let Inst{5-3} = addr{2-0}; // Rn
1214 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1215 class T1Misc<bits<7> opcode> : Encoding16 {
1216 let Inst{15-12} = 0b1011;
1217 let Inst{11-5} = opcode;
1220 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1221 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
1222 InstrItinClass itin,
1223 string opc, string asm, string cstr, list<dag> pattern>
1224 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1225 let OutOperandList = oops;
1226 let InOperandList = !con(iops, (ins pred:$p));
1227 let AsmString = !strconcat(opc, "${p}", asm);
1228 let Pattern = pattern;
1229 list<Predicate> Predicates = [IsThumb2];
1230 let DecoderNamespace = "Thumb2";
1233 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
1234 // input operand since by default it's a zero register. It will become an
1235 // implicit def once it's "flipped".
1237 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1239 class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
1240 InstrItinClass itin,
1241 string opc, string asm, string cstr, list<dag> pattern>
1242 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1243 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
1246 let OutOperandList = oops;
1247 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1248 let AsmString = !strconcat(opc, "${s}${p}", asm);
1249 let Pattern = pattern;
1250 list<Predicate> Predicates = [IsThumb2];
1251 let DecoderNamespace = "Thumb2";
1255 class Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
1256 InstrItinClass itin,
1257 string asm, string cstr, list<dag> pattern>
1258 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1259 let OutOperandList = oops;
1260 let InOperandList = iops;
1261 let AsmString = asm;
1262 let Pattern = pattern;
1263 list<Predicate> Predicates = [IsThumb2];
1264 let DecoderNamespace = "Thumb2";
1267 class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
1268 InstrItinClass itin,
1269 string asm, string cstr, list<dag> pattern>
1270 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1271 let OutOperandList = oops;
1272 let InOperandList = iops;
1273 let AsmString = asm;
1274 let Pattern = pattern;
1275 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1276 let DecoderNamespace = "Thumb";
1279 class T2I<dag oops, dag iops, InstrItinClass itin,
1280 string opc, string asm, list<dag> pattern>
1281 : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1282 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1283 string opc, string asm, list<dag> pattern>
1284 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
1285 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
1286 string opc, string asm, list<dag> pattern>
1287 : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>;
1288 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1289 string opc, string asm, list<dag> pattern>
1290 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
1291 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1292 string opc, string asm, list<dag> pattern>
1293 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
1294 class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
1295 string opc, string asm, string cstr, list<dag> pattern>
1296 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1301 let Inst{31-25} = 0b1110100;
1303 let Inst{23} = addr{8};
1306 let Inst{20} = isLoad;
1307 let Inst{19-16} = addr{12-9};
1308 let Inst{15-12} = Rt{3-0};
1309 let Inst{11-8} = Rt2{3-0};
1310 let Inst{7-0} = addr{7-0};
1312 class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
1313 InstrItinClass itin, string opc, string asm, string cstr,
1315 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1321 let Inst{31-25} = 0b1110100;
1323 let Inst{23} = imm{8};
1326 let Inst{20} = isLoad;
1327 let Inst{19-16} = addr;
1328 let Inst{15-12} = Rt{3-0};
1329 let Inst{11-8} = Rt2{3-0};
1330 let Inst{7-0} = imm{7-0};
1333 class T2sI<dag oops, dag iops, InstrItinClass itin,
1334 string opc, string asm, list<dag> pattern>
1335 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1337 class T2XI<dag oops, dag iops, InstrItinClass itin,
1338 string asm, list<dag> pattern>
1339 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1340 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1341 string asm, list<dag> pattern>
1342 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1344 // Move to/from coprocessor instructions
1345 class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
1347 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
1348 let Inst{31-28} = opc;
1351 // Two-address instructions
1352 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1353 string asm, string cstr, list<dag> pattern>
1354 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
1356 // T2Ipreldst - Thumb2 pre-indexed load / store instructions.
1357 class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
1359 AddrMode am, IndexMode im, InstrItinClass itin,
1360 string opc, string asm, string cstr, list<dag> pattern>
1361 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1362 let OutOperandList = oops;
1363 let InOperandList = !con(iops, (ins pred:$p));
1364 let AsmString = !strconcat(opc, "${p}", asm);
1365 let Pattern = pattern;
1366 list<Predicate> Predicates = [IsThumb2];
1367 let DecoderNamespace = "Thumb2";
1371 let Inst{31-27} = 0b11111;
1372 let Inst{26-25} = 0b00;
1373 let Inst{24} = signed;
1375 let Inst{22-21} = opcod;
1376 let Inst{20} = load;
1377 let Inst{19-16} = addr{12-9};
1378 let Inst{15-12} = Rt{3-0};
1380 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1381 let Inst{10} = pre; // The P bit.
1382 let Inst{9} = addr{8}; // Sign bit
1383 let Inst{8} = 1; // The W bit.
1384 let Inst{7-0} = addr{7-0};
1386 let DecoderMethod = "DecodeT2LdStPre";
1389 // T2Ipostldst - Thumb2 post-indexed load / store instructions.
1390 class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
1392 AddrMode am, IndexMode im, InstrItinClass itin,
1393 string opc, string asm, string cstr, list<dag> pattern>
1394 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1395 let OutOperandList = oops;
1396 let InOperandList = !con(iops, (ins pred:$p));
1397 let AsmString = !strconcat(opc, "${p}", asm);
1398 let Pattern = pattern;
1399 list<Predicate> Predicates = [IsThumb2];
1400 let DecoderNamespace = "Thumb2";
1405 let Inst{31-27} = 0b11111;
1406 let Inst{26-25} = 0b00;
1407 let Inst{24} = signed;
1409 let Inst{22-21} = opcod;
1410 let Inst{20} = load;
1411 let Inst{19-16} = Rn;
1412 let Inst{15-12} = Rt{3-0};
1414 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1415 let Inst{10} = pre; // The P bit.
1416 let Inst{9} = offset{8}; // Sign bit
1417 let Inst{8} = 1; // The W bit.
1418 let Inst{7-0} = offset{7-0};
1420 let DecoderMethod = "DecodeT2LdStPre";
1423 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1424 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1425 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1428 // T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
1429 class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
1430 list<Predicate> Predicates = [IsThumb2, HasV6T2];
1433 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1434 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1435 list<Predicate> Predicates = [IsThumb2];
1438 //===----------------------------------------------------------------------===//
1440 //===----------------------------------------------------------------------===//
1441 // ARM VFP Instruction templates.
1444 // Almost all VFP instructions are predicable.
1445 class VFPI<dag oops, dag iops, AddrMode am, int sz,
1446 IndexMode im, Format f, InstrItinClass itin,
1447 string opc, string asm, string cstr, list<dag> pattern>
1448 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1450 let Inst{31-28} = p;
1451 let OutOperandList = oops;
1452 let InOperandList = !con(iops, (ins pred:$p));
1453 let AsmString = !strconcat(opc, "${p}", asm);
1454 let Pattern = pattern;
1455 let PostEncoderMethod = "VFPThumb2PostEncoder";
1456 let DecoderNamespace = "VFP";
1457 list<Predicate> Predicates = [HasVFP2];
1461 class VFPXI<dag oops, dag iops, AddrMode am, int sz,
1462 IndexMode im, Format f, InstrItinClass itin,
1463 string asm, string cstr, list<dag> pattern>
1464 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1466 let Inst{31-28} = p;
1467 let OutOperandList = oops;
1468 let InOperandList = iops;
1469 let AsmString = asm;
1470 let Pattern = pattern;
1471 let PostEncoderMethod = "VFPThumb2PostEncoder";
1472 let DecoderNamespace = "VFP";
1473 list<Predicate> Predicates = [HasVFP2];
1476 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1477 string opc, string asm, list<dag> pattern>
1478 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
1479 opc, asm, "", pattern> {
1480 let PostEncoderMethod = "VFPThumb2PostEncoder";
1483 // ARM VFP addrmode5 loads and stores
1484 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1485 InstrItinClass itin,
1486 string opc, string asm, list<dag> pattern>
1487 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1488 VFPLdStFrm, itin, opc, asm, "", pattern> {
1489 // Instruction operands.
1493 // Encode instruction operands.
1494 let Inst{23} = addr{8}; // U (add = (U == '1'))
1495 let Inst{22} = Dd{4};
1496 let Inst{19-16} = addr{12-9}; // Rn
1497 let Inst{15-12} = Dd{3-0};
1498 let Inst{7-0} = addr{7-0}; // imm8
1500 let Inst{27-24} = opcod1;
1501 let Inst{21-20} = opcod2;
1502 let Inst{11-9} = 0b101;
1503 let Inst{8} = 1; // Double precision
1505 // Loads & stores operate on both NEON and VFP pipelines.
1506 let D = VFPNeonDomain;
1509 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1510 InstrItinClass itin,
1511 string opc, string asm, list<dag> pattern>
1512 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1513 VFPLdStFrm, itin, opc, asm, "", pattern> {
1514 // Instruction operands.
1518 // Encode instruction operands.
1519 let Inst{23} = addr{8}; // U (add = (U == '1'))
1520 let Inst{22} = Sd{0};
1521 let Inst{19-16} = addr{12-9}; // Rn
1522 let Inst{15-12} = Sd{4-1};
1523 let Inst{7-0} = addr{7-0}; // imm8
1525 let Inst{27-24} = opcod1;
1526 let Inst{21-20} = opcod2;
1527 let Inst{11-9} = 0b101;
1528 let Inst{8} = 0; // Single precision
1530 // Loads & stores operate on both NEON and VFP pipelines.
1531 let D = VFPNeonDomain;
1534 class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1535 InstrItinClass itin,
1536 string opc, string asm, list<dag> pattern>
1537 : VFPI<oops, iops, AddrMode5FP16, 4, IndexModeNone,
1538 VFPLdStFrm, itin, opc, asm, "", pattern> {
1539 list<Predicate> Predicates = [HasFullFP16];
1541 // Instruction operands.
1545 // Encode instruction operands.
1546 let Inst{23} = addr{8}; // U (add = (U == '1'))
1547 let Inst{22} = Sd{0};
1548 let Inst{19-16} = addr{12-9}; // Rn
1549 let Inst{15-12} = Sd{4-1};
1550 let Inst{7-0} = addr{7-0}; // imm8
1552 let Inst{27-24} = opcod1;
1553 let Inst{21-20} = opcod2;
1554 let Inst{11-8} = 0b1001; // Half precision
1556 // Loads & stores operate on both NEON and VFP pipelines.
1557 let D = VFPNeonDomain;
1560 // VFP Load / store multiple pseudo instructions.
1561 class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
1563 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
1565 let OutOperandList = oops;
1566 let InOperandList = !con(iops, (ins pred:$p));
1567 let Pattern = pattern;
1568 list<Predicate> Predicates = [HasVFP2];
1571 // Load / store multiple
1573 // Unknown precision
1574 class AXXI4<dag oops, dag iops, IndexMode im,
1575 string asm, string cstr, list<dag> pattern>
1576 : VFPXI<oops, iops, AddrMode4, 4, im,
1577 VFPLdStFrm, NoItinerary, asm, cstr, pattern> {
1578 // Instruction operands.
1582 // Encode instruction operands.
1583 let Inst{19-16} = Rn;
1585 let Inst{15-12} = regs{11-8};
1586 let Inst{7-1} = regs{7-1};
1588 let Inst{27-25} = 0b110;
1589 let Inst{11-8} = 0b1011;
1594 class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1595 string asm, string cstr, list<dag> pattern>
1596 : VFPXI<oops, iops, AddrMode4, 4, im,
1597 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1598 // Instruction operands.
1602 // Encode instruction operands.
1603 let Inst{19-16} = Rn;
1604 let Inst{22} = regs{12};
1605 let Inst{15-12} = regs{11-8};
1606 let Inst{7-1} = regs{7-1};
1608 let Inst{27-25} = 0b110;
1609 let Inst{11-9} = 0b101;
1610 let Inst{8} = 1; // Double precision
1615 class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1616 string asm, string cstr, list<dag> pattern>
1617 : VFPXI<oops, iops, AddrMode4, 4, im,
1618 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1619 // Instruction operands.
1623 // Encode instruction operands.
1624 let Inst{19-16} = Rn;
1625 let Inst{22} = regs{8};
1626 let Inst{15-12} = regs{12-9};
1627 let Inst{7-0} = regs{7-0};
1629 let Inst{27-25} = 0b110;
1630 let Inst{11-9} = 0b101;
1631 let Inst{8} = 0; // Single precision
1634 // Double precision, unary
1635 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1636 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1637 string asm, list<dag> pattern>
1638 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1639 // Instruction operands.
1643 // Encode instruction operands.
1644 let Inst{3-0} = Dm{3-0};
1645 let Inst{5} = Dm{4};
1646 let Inst{15-12} = Dd{3-0};
1647 let Inst{22} = Dd{4};
1649 let Inst{27-23} = opcod1;
1650 let Inst{21-20} = opcod2;
1651 let Inst{19-16} = opcod3;
1652 let Inst{11-9} = 0b101;
1653 let Inst{8} = 1; // Double precision
1654 let Inst{7-6} = opcod4;
1655 let Inst{4} = opcod5;
1657 let Predicates = [HasVFP2, HasDPVFP];
1660 // Double precision, unary, not-predicated
1661 class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1662 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1663 string asm, list<dag> pattern>
1664 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> {
1665 // Instruction operands.
1669 let Inst{31-28} = 0b1111;
1671 // Encode instruction operands.
1672 let Inst{3-0} = Dm{3-0};
1673 let Inst{5} = Dm{4};
1674 let Inst{15-12} = Dd{3-0};
1675 let Inst{22} = Dd{4};
1677 let Inst{27-23} = opcod1;
1678 let Inst{21-20} = opcod2;
1679 let Inst{19-16} = opcod3;
1680 let Inst{11-9} = 0b101;
1681 let Inst{8} = 1; // Double precision
1682 let Inst{7-6} = opcod4;
1683 let Inst{4} = opcod5;
1686 // Double precision, binary
1687 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1688 dag iops, InstrItinClass itin, string opc, string asm,
1690 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1691 // Instruction operands.
1696 // Encode instruction operands.
1697 let Inst{3-0} = Dm{3-0};
1698 let Inst{5} = Dm{4};
1699 let Inst{19-16} = Dn{3-0};
1700 let Inst{7} = Dn{4};
1701 let Inst{15-12} = Dd{3-0};
1702 let Inst{22} = Dd{4};
1704 let Inst{27-23} = opcod1;
1705 let Inst{21-20} = opcod2;
1706 let Inst{11-9} = 0b101;
1707 let Inst{8} = 1; // Double precision
1711 let Predicates = [HasVFP2, HasDPVFP];
1714 // FP, binary, not predicated
1715 class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1716 InstrItinClass itin, string asm, list<dag> pattern>
1717 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
1720 // Instruction operands.
1725 let Inst{31-28} = 0b1111;
1727 // Encode instruction operands.
1728 let Inst{3-0} = Dm{3-0};
1729 let Inst{5} = Dm{4};
1730 let Inst{19-16} = Dn{3-0};
1731 let Inst{7} = Dn{4};
1732 let Inst{15-12} = Dd{3-0};
1733 let Inst{22} = Dd{4};
1735 let Inst{27-23} = opcod1;
1736 let Inst{21-20} = opcod2;
1737 let Inst{11-9} = 0b101;
1738 let Inst{8} = 1; // double precision
1739 let Inst{6} = opcod3;
1742 let Predicates = [HasVFP2, HasDPVFP];
1745 // Single precision, unary, predicated
1746 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1747 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1748 string asm, list<dag> pattern>
1749 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1750 // Instruction operands.
1754 // Encode instruction operands.
1755 let Inst{3-0} = Sm{4-1};
1756 let Inst{5} = Sm{0};
1757 let Inst{15-12} = Sd{4-1};
1758 let Inst{22} = Sd{0};
1760 let Inst{27-23} = opcod1;
1761 let Inst{21-20} = opcod2;
1762 let Inst{19-16} = opcod3;
1763 let Inst{11-9} = 0b101;
1764 let Inst{8} = 0; // Single precision
1765 let Inst{7-6} = opcod4;
1766 let Inst{4} = opcod5;
1769 // Single precision, unary, non-predicated
1770 class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1771 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1772 string asm, list<dag> pattern>
1773 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1774 VFPUnaryFrm, itin, asm, "", pattern> {
1775 // Instruction operands.
1779 let Inst{31-28} = 0b1111;
1781 // Encode instruction operands.
1782 let Inst{3-0} = Sm{4-1};
1783 let Inst{5} = Sm{0};
1784 let Inst{15-12} = Sd{4-1};
1785 let Inst{22} = Sd{0};
1787 let Inst{27-23} = opcod1;
1788 let Inst{21-20} = opcod2;
1789 let Inst{19-16} = opcod3;
1790 let Inst{11-9} = 0b101;
1791 let Inst{8} = 0; // Single precision
1792 let Inst{7-6} = opcod4;
1793 let Inst{4} = opcod5;
1796 // Single precision unary, if no NEON. Same as ASuI except not available if
1798 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1799 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1800 string asm, list<dag> pattern>
1801 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1803 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1806 // Single precision, binary
1807 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1808 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1809 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1810 // Instruction operands.
1815 // Encode instruction operands.
1816 let Inst{3-0} = Sm{4-1};
1817 let Inst{5} = Sm{0};
1818 let Inst{19-16} = Sn{4-1};
1819 let Inst{7} = Sn{0};
1820 let Inst{15-12} = Sd{4-1};
1821 let Inst{22} = Sd{0};
1823 let Inst{27-23} = opcod1;
1824 let Inst{21-20} = opcod2;
1825 let Inst{11-9} = 0b101;
1826 let Inst{8} = 0; // Single precision
1831 // Single precision, binary, not predicated
1832 class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1833 InstrItinClass itin, string asm, list<dag> pattern>
1834 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1835 VFPBinaryFrm, itin, asm, "", pattern>
1837 // Instruction operands.
1842 let Inst{31-28} = 0b1111;
1844 // Encode instruction operands.
1845 let Inst{3-0} = Sm{4-1};
1846 let Inst{5} = Sm{0};
1847 let Inst{19-16} = Sn{4-1};
1848 let Inst{7} = Sn{0};
1849 let Inst{15-12} = Sd{4-1};
1850 let Inst{22} = Sd{0};
1852 let Inst{27-23} = opcod1;
1853 let Inst{21-20} = opcod2;
1854 let Inst{11-9} = 0b101;
1855 let Inst{8} = 0; // Single precision
1856 let Inst{6} = opcod3;
1860 // Single precision binary, if no NEON. Same as ASbI except not available if
1862 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1863 dag iops, InstrItinClass itin, string opc, string asm,
1865 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1866 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1868 // Instruction operands.
1873 // Encode instruction operands.
1874 let Inst{3-0} = Sm{4-1};
1875 let Inst{5} = Sm{0};
1876 let Inst{19-16} = Sn{4-1};
1877 let Inst{7} = Sn{0};
1878 let Inst{15-12} = Sd{4-1};
1879 let Inst{22} = Sd{0};
1882 // Half precision, unary, predicated
1883 class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1884 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1885 string asm, list<dag> pattern>
1886 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
1887 list<Predicate> Predicates = [HasFullFP16];
1889 // Instruction operands.
1893 // Encode instruction operands.
1894 let Inst{3-0} = Sm{4-1};
1895 let Inst{5} = Sm{0};
1896 let Inst{15-12} = Sd{4-1};
1897 let Inst{22} = Sd{0};
1899 let Inst{27-23} = opcod1;
1900 let Inst{21-20} = opcod2;
1901 let Inst{19-16} = opcod3;
1902 let Inst{11-8} = 0b1001; // Half precision
1903 let Inst{7-6} = opcod4;
1904 let Inst{4} = opcod5;
1907 // Half precision, unary, non-predicated
1908 class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1909 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1910 string asm, list<dag> pattern>
1911 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1912 VFPUnaryFrm, itin, asm, "", pattern> {
1913 list<Predicate> Predicates = [HasFullFP16];
1915 // Instruction operands.
1919 let Inst{31-28} = 0b1111;
1921 // Encode instruction operands.
1922 let Inst{3-0} = Sm{4-1};
1923 let Inst{5} = Sm{0};
1924 let Inst{15-12} = Sd{4-1};
1925 let Inst{22} = Sd{0};
1927 let Inst{27-23} = opcod1;
1928 let Inst{21-20} = opcod2;
1929 let Inst{19-16} = opcod3;
1930 let Inst{11-8} = 0b1001; // Half precision
1931 let Inst{7-6} = opcod4;
1932 let Inst{4} = opcod5;
1935 // Half precision, binary
1936 class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1937 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1938 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
1939 list<Predicate> Predicates = [HasFullFP16];
1941 // Instruction operands.
1946 // Encode instruction operands.
1947 let Inst{3-0} = Sm{4-1};
1948 let Inst{5} = Sm{0};
1949 let Inst{19-16} = Sn{4-1};
1950 let Inst{7} = Sn{0};
1951 let Inst{15-12} = Sd{4-1};
1952 let Inst{22} = Sd{0};
1954 let Inst{27-23} = opcod1;
1955 let Inst{21-20} = opcod2;
1956 let Inst{11-8} = 0b1001; // Half precision
1961 // Half precision, binary, not predicated
1962 class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1963 InstrItinClass itin, string asm, list<dag> pattern>
1964 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1965 VFPBinaryFrm, itin, asm, "", pattern> {
1966 list<Predicate> Predicates = [HasFullFP16];
1968 // Instruction operands.
1973 let Inst{31-28} = 0b1111;
1975 // Encode instruction operands.
1976 let Inst{3-0} = Sm{4-1};
1977 let Inst{5} = Sm{0};
1978 let Inst{19-16} = Sn{4-1};
1979 let Inst{7} = Sn{0};
1980 let Inst{15-12} = Sd{4-1};
1981 let Inst{22} = Sd{0};
1983 let Inst{27-23} = opcod1;
1984 let Inst{21-20} = opcod2;
1985 let Inst{11-8} = 0b1001; // Half precision
1986 let Inst{6} = opcod3;
1990 // VFP conversion instructions
1991 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
1992 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
1994 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
1995 let Inst{27-23} = opcod1;
1996 let Inst{21-20} = opcod2;
1997 let Inst{19-16} = opcod3;
1998 let Inst{11-8} = opcod4;
2003 // VFP conversion between floating-point and fixed-point
2004 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
2005 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
2007 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
2009 // size (fixed-point number): sx == 0 ? 16 : 32
2010 let Inst{7} = op5; // sx
2011 let Inst{5} = fbits{0};
2012 let Inst{3-0} = fbits{4-1};
2015 // VFP conversion instructions, if no NEON
2016 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
2017 dag oops, dag iops, InstrItinClass itin,
2018 string opc, string asm, list<dag> pattern>
2019 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
2021 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
2024 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
2025 InstrItinClass itin,
2026 string opc, string asm, list<dag> pattern>
2027 : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
2028 let Inst{27-20} = opcod1;
2029 let Inst{11-8} = opcod2;
2033 class AVConv2I<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, VFPConv2Frm, itin, opc, asm, pattern>;
2037 class AVConv3I<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, VFPConv3Frm, itin, opc, asm, pattern>;
2041 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2042 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2043 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
2045 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2046 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2047 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
2049 //===----------------------------------------------------------------------===//
2051 //===----------------------------------------------------------------------===//
2052 // ARM NEON Instruction templates.
2055 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2056 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2058 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2059 let OutOperandList = oops;
2060 let InOperandList = !con(iops, (ins pred:$p));
2061 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2062 let Pattern = pattern;
2063 list<Predicate> Predicates = [HasNEON];
2064 let DecoderNamespace = "NEON";
2067 // Same as NeonI except it does not have a "data type" specifier.
2068 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2069 InstrItinClass itin, string opc, string asm, string cstr,
2071 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2072 let OutOperandList = oops;
2073 let InOperandList = !con(iops, (ins pred:$p));
2074 let AsmString = !strconcat(opc, "${p}", "\t", asm);
2075 let Pattern = pattern;
2076 list<Predicate> Predicates = [HasNEON];
2077 let DecoderNamespace = "NEON";
2080 // Same as NeonI except it is not predicated
2081 class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2082 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2084 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2085 let OutOperandList = oops;
2086 let InOperandList = iops;
2087 let AsmString = !strconcat(opc, ".", dt, "\t", asm);
2088 let Pattern = pattern;
2089 list<Predicate> Predicates = [HasNEON];
2090 let DecoderNamespace = "NEON";
2092 let Inst{31-28} = 0b1111;
2095 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2096 dag oops, dag iops, InstrItinClass itin,
2097 string opc, string dt, string asm, string cstr, list<dag> pattern>
2098 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
2100 let Inst{31-24} = 0b11110100;
2101 let Inst{23} = op23;
2102 let Inst{21-20} = op21_20;
2103 let Inst{11-8} = op11_8;
2104 let Inst{7-4} = op7_4;
2106 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
2107 let DecoderNamespace = "NEONLoadStore";
2113 let Inst{22} = Vd{4};
2114 let Inst{15-12} = Vd{3-0};
2115 let Inst{19-16} = Rn{3-0};
2116 let Inst{3-0} = Rm{3-0};
2119 class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2120 dag oops, dag iops, InstrItinClass itin,
2121 string opc, string dt, string asm, string cstr, list<dag> pattern>
2122 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
2123 dt, asm, cstr, pattern> {
2127 class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
2128 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2130 let OutOperandList = oops;
2131 let InOperandList = !con(iops, (ins pred:$p));
2132 list<Predicate> Predicates = [HasNEON];
2135 class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
2137 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2139 let OutOperandList = oops;
2140 let InOperandList = !con(iops, (ins pred:$p));
2141 let Pattern = pattern;
2142 list<Predicate> Predicates = [HasNEON];
2145 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
2146 string opc, string dt, string asm, string cstr, list<dag> pattern>
2147 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
2149 let Inst{31-25} = 0b1111001;
2150 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2151 let DecoderNamespace = "NEONData";
2154 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
2155 string opc, string asm, string cstr, list<dag> pattern>
2156 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
2158 let Inst{31-25} = 0b1111001;
2159 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2160 let DecoderNamespace = "NEONData";
2163 // NEON "one register and a modified immediate" format.
2164 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
2166 dag oops, dag iops, InstrItinClass itin,
2167 string opc, string dt, string asm, string cstr,
2169 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
2170 let Inst{23} = op23;
2171 let Inst{21-19} = op21_19;
2172 let Inst{11-8} = op11_8;
2178 // Instruction operands.
2182 let Inst{15-12} = Vd{3-0};
2183 let Inst{22} = Vd{4};
2184 let Inst{24} = SIMM{7};
2185 let Inst{18-16} = SIMM{6-4};
2186 let Inst{3-0} = SIMM{3-0};
2187 let DecoderMethod = "DecodeNEONModImmInstruction";
2190 // NEON 2 vector register format.
2191 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2192 bits<5> op11_7, bit op6, bit op4,
2193 dag oops, dag iops, InstrItinClass itin,
2194 string opc, string dt, string asm, string cstr, list<dag> pattern>
2195 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
2196 let Inst{24-23} = op24_23;
2197 let Inst{21-20} = op21_20;
2198 let Inst{19-18} = op19_18;
2199 let Inst{17-16} = op17_16;
2200 let Inst{11-7} = op11_7;
2204 // Instruction operands.
2208 let Inst{15-12} = Vd{3-0};
2209 let Inst{22} = Vd{4};
2210 let Inst{3-0} = Vm{3-0};
2211 let Inst{5} = Vm{4};
2214 // Same as N2V but not predicated.
2215 class N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
2216 dag oops, dag iops, InstrItinClass itin, string OpcodeStr,
2217 string Dt, list<dag> pattern>
2218 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin,
2219 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> {
2223 // Encode instruction operands
2224 let Inst{22} = Vd{4};
2225 let Inst{15-12} = Vd{3-0};
2226 let Inst{5} = Vm{4};
2227 let Inst{3-0} = Vm{3-0};
2229 // Encode constant bits
2230 let Inst{27-23} = 0b00111;
2231 let Inst{21-20} = 0b11;
2232 let Inst{19-18} = op19_18;
2233 let Inst{17-16} = op17_16;
2235 let Inst{10-8} = op10_8;
2240 let DecoderNamespace = "NEON";
2243 // Same as N2V except it doesn't have a datatype suffix.
2244 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2245 bits<5> op11_7, bit op6, bit op4,
2246 dag oops, dag iops, InstrItinClass itin,
2247 string opc, string asm, string cstr, list<dag> pattern>
2248 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
2249 let Inst{24-23} = op24_23;
2250 let Inst{21-20} = op21_20;
2251 let Inst{19-18} = op19_18;
2252 let Inst{17-16} = op17_16;
2253 let Inst{11-7} = op11_7;
2257 // Instruction operands.
2261 let Inst{15-12} = Vd{3-0};
2262 let Inst{22} = Vd{4};
2263 let Inst{3-0} = Vm{3-0};
2264 let Inst{5} = Vm{4};
2267 // NEON 2 vector register with immediate.
2268 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
2269 dag oops, dag iops, Format f, InstrItinClass itin,
2270 string opc, string dt, string asm, string cstr, list<dag> pattern>
2271 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2272 let Inst{24} = op24;
2273 let Inst{23} = op23;
2274 let Inst{11-8} = op11_8;
2279 // Instruction operands.
2284 let Inst{15-12} = Vd{3-0};
2285 let Inst{22} = Vd{4};
2286 let Inst{3-0} = Vm{3-0};
2287 let Inst{5} = Vm{4};
2288 let Inst{21-16} = SIMM{5-0};
2291 // NEON 3 vector register format.
2293 class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2294 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2295 string opc, string dt, string asm, string cstr,
2297 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2298 let Inst{24} = op24;
2299 let Inst{23} = op23;
2300 let Inst{21-20} = op21_20;
2301 let Inst{11-8} = op11_8;
2306 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
2307 dag oops, dag iops, Format f, InstrItinClass itin,
2308 string opc, string dt, string asm, string cstr, list<dag> pattern>
2309 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2310 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2311 // Instruction operands.
2316 let Inst{15-12} = Vd{3-0};
2317 let Inst{22} = Vd{4};
2318 let Inst{19-16} = Vn{3-0};
2319 let Inst{7} = Vn{4};
2320 let Inst{3-0} = Vm{3-0};
2321 let Inst{5} = Vm{4};
2324 class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2325 bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2326 string OpcodeStr, string Dt, list<dag> pattern>
2327 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
2328 Dt, "$Vd, $Vn, $Vm", "", pattern> {
2333 // Encode instruction operands
2334 let Inst{22} = Vd{4};
2335 let Inst{15-12} = Vd{3-0};
2336 let Inst{19-16} = Vn{3-0};
2337 let Inst{7} = Vn{4};
2338 let Inst{5} = Vm{4};
2339 let Inst{3-0} = Vm{3-0};
2341 // Encode constant bits
2342 let Inst{27-23} = op27_23;
2343 let Inst{21-20} = op21_20;
2344 let Inst{11-8} = op11_8;
2349 class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2350 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2351 string opc, string dt, string asm, string cstr,
2353 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2354 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2356 // Instruction operands.
2362 let Inst{15-12} = Vd{3-0};
2363 let Inst{22} = Vd{4};
2364 let Inst{19-16} = Vn{3-0};
2365 let Inst{7} = Vn{4};
2366 let Inst{3-0} = Vm{3-0};
2370 class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2371 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2372 string opc, string dt, string asm, string cstr,
2374 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2375 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2377 // Instruction operands.
2383 let Inst{15-12} = Vd{3-0};
2384 let Inst{22} = Vd{4};
2385 let Inst{19-16} = Vn{3-0};
2386 let Inst{7} = Vn{4};
2387 let Inst{2-0} = Vm{2-0};
2388 let Inst{5} = lane{1};
2389 let Inst{3} = lane{0};
2392 // Same as N3V except it doesn't have a data type suffix.
2393 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2395 dag oops, dag iops, Format f, InstrItinClass itin,
2396 string opc, string asm, string cstr, list<dag> pattern>
2397 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
2398 let Inst{24} = op24;
2399 let Inst{23} = op23;
2400 let Inst{21-20} = op21_20;
2401 let Inst{11-8} = op11_8;
2405 // Instruction operands.
2410 let Inst{15-12} = Vd{3-0};
2411 let Inst{22} = Vd{4};
2412 let Inst{19-16} = Vn{3-0};
2413 let Inst{7} = Vn{4};
2414 let Inst{3-0} = Vm{3-0};
2415 let Inst{5} = Vm{4};
2418 // NEON VMOVs between scalar and core registers.
2419 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2420 dag oops, dag iops, Format f, InstrItinClass itin,
2421 string opc, string dt, string asm, list<dag> pattern>
2422 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
2424 let Inst{27-20} = opcod1;
2425 let Inst{11-8} = opcod2;
2426 let Inst{6-5} = opcod3;
2428 // A8.6.303, A8.6.328, A8.6.329
2429 let Inst{3-0} = 0b0000;
2431 let OutOperandList = oops;
2432 let InOperandList = !con(iops, (ins pred:$p));
2433 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2434 let Pattern = pattern;
2435 list<Predicate> Predicates = [HasNEON];
2437 let PostEncoderMethod = "NEONThumb2DupPostEncoder";
2438 let DecoderNamespace = "NEONDup";
2445 let Inst{31-28} = p{3-0};
2447 let Inst{19-16} = V{3-0};
2448 let Inst{15-12} = R{3-0};
2450 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2451 dag oops, dag iops, InstrItinClass itin,
2452 string opc, string dt, string asm, list<dag> pattern>
2453 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
2454 opc, dt, asm, pattern>;
2455 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2456 dag oops, dag iops, InstrItinClass itin,
2457 string opc, string dt, string asm, list<dag> pattern>
2458 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
2459 opc, dt, asm, pattern>;
2460 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2461 dag oops, dag iops, InstrItinClass itin,
2462 string opc, string dt, string asm, list<dag> pattern>
2463 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
2464 opc, dt, asm, pattern>;
2466 // Vector Duplicate Lane (from scalar to all elements)
2467 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
2468 InstrItinClass itin, string opc, string dt, string asm,
2470 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
2471 let Inst{24-23} = 0b11;
2472 let Inst{21-20} = 0b11;
2473 let Inst{19-16} = op19_16;
2474 let Inst{11-7} = 0b11000;
2481 let Inst{22} = Vd{4};
2482 let Inst{15-12} = Vd{3-0};
2483 let Inst{5} = Vm{4};
2484 let Inst{3-0} = Vm{3-0};
2487 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
2488 // for single-precision FP.
2489 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
2490 list<Predicate> Predicates = [HasNEON,UseNEONForFP];
2493 // VFP/NEON Instruction aliases for type suffices.
2494 // Note: When EmitPriority == 1, the alias will be used for printing
2495 class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> :
2496 InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasVFP2]>;
2498 // Note: When EmitPriority == 1, the alias will be used for printing
2499 multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2500 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2501 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2502 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2503 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2506 // Note: When EmitPriority == 1, the alias will be used for printing
2507 multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2508 let Predicates = [HasNEON] in {
2509 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2510 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2511 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2512 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2516 // The same alias classes using AsmPseudo instead, for the more complex
2517 // stuff in NEON that InstAlias can't quite handle.
2518 // Note that we can't use anonymous defm references here like we can
2519 // above, as we care about the ultimate instruction enum names generated, unlike
2520 // for instalias defs.
2521 class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> :
2522 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>;
2524 // Extension of NEON 3-vector data processing instructions in coprocessor 8
2525 // encoding space, introduced in ARMv8.3-A.
2526 class N3VCP8<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4,
2527 dag oops, dag iops, InstrItinClass itin,
2528 string opc, string dt, string asm, string cstr, list<dag> pattern>
2529 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc,
2530 dt, asm, cstr, pattern> {
2535 let DecoderNamespace = "VFPV8";
2536 // These have the same encodings in ARM and Thumb2
2537 let PostEncoderMethod = "";
2539 let Inst{31-25} = 0b1111110;
2540 let Inst{24-23} = op24_23;
2541 let Inst{22} = Vd{4};
2542 let Inst{21-20} = op21_20;
2543 let Inst{19-16} = Vn{3-0};
2544 let Inst{15-12} = Vd{3-0};
2545 let Inst{11-8} = 0b1000;
2546 let Inst{7} = Vn{4};
2548 let Inst{5} = Vm{4};
2550 let Inst{3-0} = Vm{3-0};
2553 // Extension of NEON 2-vector-and-scalar data processing instructions in
2554 // coprocessor 8 encoding space, introduced in ARMv8.3-A.
2555 class N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4,
2556 dag oops, dag iops, InstrItinClass itin,
2557 string opc, string dt, string asm, string cstr, list<dag> pattern>
2558 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc,
2559 dt, asm, cstr, pattern> {
2564 let DecoderNamespace = "VFPV8";
2565 // These have the same encodings in ARM and Thumb2
2566 let PostEncoderMethod = "";
2568 let Inst{31-24} = 0b11111110;
2569 let Inst{23} = op23;
2570 let Inst{22} = Vd{4};
2571 let Inst{21-20} = op21_20;
2572 let Inst{19-16} = Vn{3-0};
2573 let Inst{15-12} = Vd{3-0};
2574 let Inst{11-8} = 0b1000;
2575 let Inst{7} = Vn{4};
2577 // Bit 5 set by sub-classes
2579 let Inst{3-0} = Vm{3-0};
2582 // In Armv8.2-A, some NEON instructions are added that encode Vn and Vm
2584 // if Q == ‘1’ then UInt(N:Vn) else UInt(Vn:N);
2585 // if Q == ‘1’ then UInt(M:Vm) else UInt(Vm:M);
2586 // Class N3VCP8 above describes the Q=1 case, and this class the Q=0 case.
2587 class N3VCP8Q0<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4,
2588 dag oops, dag iops, InstrItinClass itin,
2589 string opc, string dt, string asm, string cstr, list<dag> pattern>
2590 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, dt, asm, cstr, pattern> {
2595 let DecoderNamespace = "VFPV8";
2596 // These have the same encodings in ARM and Thumb2
2597 let PostEncoderMethod = "";
2599 let Inst{31-25} = 0b1111110;
2600 let Inst{24-23} = op24_23;
2601 let Inst{22} = Vd{4};
2602 let Inst{21-20} = op21_20;
2603 let Inst{19-16} = Vn{4-1};
2604 let Inst{15-12} = Vd{3-0};
2605 let Inst{11-8} = 0b1000;
2606 let Inst{7} = Vn{0};
2608 let Inst{5} = Vm{0};
2610 let Inst{3-0} = Vm{4-1};
2613 // Operand types for complex instructions
2614 class ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag>
2616 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
2617 let DiagnosticString = "complex rotation must be " # Diag;
2618 let Name = "ComplexRotation" # Type;
2620 def complexrotateop : Operand<i32> {
2621 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">;
2622 let PrintMethod = "printComplexRotationOp<90, 0>";
2624 def complexrotateopodd : Operand<i32> {
2625 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">;
2626 let PrintMethod = "printComplexRotationOp<180, 90>";
2629 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
2630 def : TokenAlias<".s8", ".i8">;
2631 def : TokenAlias<".u8", ".i8">;
2632 def : TokenAlias<".s16", ".i16">;
2633 def : TokenAlias<".u16", ".i16">;
2634 def : TokenAlias<".s32", ".i32">;
2635 def : TokenAlias<".u32", ".i32">;
2636 def : TokenAlias<".s64", ".i64">;
2637 def : TokenAlias<".u64", ".i64">;
2639 def : TokenAlias<".i8", ".8">;
2640 def : TokenAlias<".i16", ".16">;
2641 def : TokenAlias<".i32", ".32">;
2642 def : TokenAlias<".i64", ".64">;
2644 def : TokenAlias<".p8", ".8">;
2645 def : TokenAlias<".p16", ".16">;
2647 def : TokenAlias<".f32", ".32">;
2648 def : TokenAlias<".f64", ".64">;
2649 def : TokenAlias<".f", ".f32">;
2650 def : TokenAlias<".d", ".f64">;