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_i8pos : AddrMode<13>;
107 def AddrModeT2_i8neg : AddrMode<14>;
108 def AddrModeT2_so : AddrMode<15>;
109 def AddrModeT2_pc : AddrMode<16>;
110 def AddrModeT2_i8s4 : AddrMode<17>;
111 def AddrMode_i12 : AddrMode<18>;
112 def AddrMode5FP16 : AddrMode<19>;
113 def AddrModeT2_ldrex : AddrMode<20>;
114 def AddrModeT2_i7s4 : AddrMode<21>;
115 def AddrModeT2_i7s2 : AddrMode<22>;
116 def AddrModeT2_i7 : AddrMode<23>;
118 // Load / store index mode.
119 class IndexMode<bits<2> val> {
122 def IndexModeNone : IndexMode<0>;
123 def IndexModePre : IndexMode<1>;
124 def IndexModePost : IndexMode<2>;
125 def IndexModeUpd : IndexMode<3>;
127 // Instruction execution domain.
128 class Domain<bits<4> val> {
131 def GenericDomain : Domain<0>;
132 def VFPDomain : Domain<1>; // Instructions in VFP domain only
133 def NeonDomain : Domain<2>; // Instructions in Neon domain only
134 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
135 def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
136 def MVEDomain : Domain<8>; // Instructions in MVE and ARMv8.1m
138 //===----------------------------------------------------------------------===//
139 // ARM special operands.
142 // ARM imod and iflag operands, used only by the CPS instruction.
143 def imod_op : Operand<i32> {
144 let PrintMethod = "printCPSIMod";
147 def ProcIFlagsOperand : AsmOperandClass {
148 let Name = "ProcIFlags";
149 let ParserMethod = "parseProcIFlagsOperand";
151 def iflags_op : Operand<i32> {
152 let PrintMethod = "printCPSIFlag";
153 let ParserMatchClass = ProcIFlagsOperand;
156 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
157 // register whose default is 0 (no register).
158 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
159 def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
160 (ops (i32 14), (i32 zero_reg))> {
161 let PrintMethod = "printPredicateOperand";
162 let ParserMatchClass = CondCodeOperand;
163 let DecoderMethod = "DecodePredicateOperand";
166 // Selectable predicate operand for CMOV instructions. We can't use a normal
167 // predicate because the default values interfere with instruction selection. In
168 // all other respects it is identical though: pseudo-instruction expansion
169 // relies on the MachineOperands being compatible.
170 def cmovpred : Operand<i32>, PredicateOp,
171 ComplexPattern<i32, 2, "SelectCMOVPred"> {
172 let MIOperandInfo = (ops i32imm, i32imm);
173 let PrintMethod = "printPredicateOperand";
176 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
177 def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
178 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
179 let EncoderMethod = "getCCOutOpValue";
180 let PrintMethod = "printSBitModifierOperand";
181 let ParserMatchClass = CCOutOperand;
182 let DecoderMethod = "DecodeCCOutOperand";
185 // Same as cc_out except it defaults to setting CPSR.
186 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
187 let EncoderMethod = "getCCOutOpValue";
188 let PrintMethod = "printSBitModifierOperand";
189 let ParserMatchClass = CCOutOperand;
190 let DecoderMethod = "DecodeCCOutOperand";
193 // Transform to generate the inverse of a condition code during ISel
194 def inv_cond_XFORM : SDNodeXForm<imm, [{
195 ARMCC::CondCodes CC = static_cast<ARMCC::CondCodes>(N->getZExtValue());
196 return CurDAG->getTargetConstant(ARMCC::getOppositeCondition(CC), SDLoc(N),
202 def VPTPredNOperand : AsmOperandClass {
203 let Name = "VPTPredN";
204 let PredicateMethod = "isVPTPred";
206 def VPTPredROperand : AsmOperandClass {
207 let Name = "VPTPredR";
208 let PredicateMethod = "isVPTPred";
211 // Operand classes for the cluster of MC operands describing a
212 // VPT-predicated MVE instruction.
214 // There are two of these classes. Both of them have the same first
217 // $cond (an integer) indicates the instruction's predication status:
218 // * ARMVCC::None means it's unpredicated
219 // * ARMVCC::Then means it's in a VPT block and appears with the T suffix
220 // * ARMVCC::Else means it's in a VPT block and appears with the E suffix.
221 // During code generation, unpredicated and predicated instructions
222 // are indicated by setting this parameter to 'None' or to 'Then'; the
223 // third value 'Else' is only used for assembly and disassembly.
225 // $cond_reg (type VCCR) gives the input predicate register. This is
226 // always either zero_reg or VPR, but needs to be modelled as an
227 // explicit operand so that it can be register-allocated and spilled
228 // when these operands are used in code generation).
230 // For 'vpred_r', there's an extra operand $inactive, which specifies
231 // the vector register which will supply any lanes of the output
232 // register that the predication mask prevents from being written by
233 // this instruction. It's always tied to the actual output register
234 // (i.e. must be allocated into the same physical reg), but again,
235 // code generation will need to model it as a separate input value.
237 // 'vpred_n' doesn't have that extra operand: it only has $cond and
238 // $cond_reg. This variant is used for any instruction that can't, or
239 // doesn't want to, tie $inactive to the output register. Sometimes
240 // that's because another input parameter is already tied to it (e.g.
241 // instructions that both read and write their Qd register even when
242 // unpredicated, either because they only partially overwrite it like
243 // a narrowing integer conversion, or simply because the instruction
244 // encoding doesn't have enough register fields to make the output
245 // independent of all inputs). It can also be because the instruction
246 // is defined to set disabled output lanes to zero rather than leaving
247 // them unchanged (vector loads), or because it doesn't output a
248 // vector register at all (stores, compares). In any of these
249 // situations it's unnecessary to have an extra operand tied to the
250 // output, and inconvenient to leave it there unused.
252 // Base class for both kinds of vpred.
253 class vpred_ops<dag extra_op, dag extra_mi> : OperandWithDefaultOps<OtherVT,
254 !con((ops (i32 0), (i32 zero_reg), (i32 zero_reg)), extra_op)> {
255 let PrintMethod = "printVPTPredicateOperand";
256 let OperandNamespace = "ARM";
257 let MIOperandInfo = !con((ops i32imm:$cond, VCCR:$cond_reg, GPRlr:$tp_reg), extra_mi);
259 // For convenience, we provide a string value that can be appended
260 // to the constraints string. It's empty for vpred_n, and for
261 // vpred_r it ties the $inactive operand to the output q-register
262 // (which by convention will be called $Qd).
263 string vpred_constraint;
266 def vpred_r : vpred_ops<(ops (v4i32 undef_tied_input)), (ops MQPR:$inactive)> {
267 let ParserMatchClass = VPTPredROperand;
268 let OperandType = "OPERAND_VPRED_R";
269 let DecoderMethod = "DecodeVpredROperand";
270 let vpred_constraint = ",$Qd = $vp.inactive";
273 def vpred_n : vpred_ops<(ops), (ops)> {
274 let ParserMatchClass = VPTPredNOperand;
275 let OperandType = "OPERAND_VPRED_N";
276 let DecoderMethod = "DecodeVpredNOperand";
277 let vpred_constraint = "";
280 // ARM special operands for disassembly only.
282 def SetEndAsmOperand : ImmAsmOperand<0,1> {
283 let Name = "SetEndImm";
284 let ParserMethod = "parseSetEndImm";
286 def setend_op : Operand<i32> {
287 let PrintMethod = "printSetendOperand";
288 let ParserMatchClass = SetEndAsmOperand;
291 def MSRMaskOperand : AsmOperandClass {
292 let Name = "MSRMask";
293 let ParserMethod = "parseMSRMaskOperand";
295 def msr_mask : Operand<i32> {
296 let PrintMethod = "printMSRMaskOperand";
297 let DecoderMethod = "DecodeMSRMask";
298 let ParserMatchClass = MSRMaskOperand;
301 def BankedRegOperand : AsmOperandClass {
302 let Name = "BankedReg";
303 let ParserMethod = "parseBankedRegOperand";
305 def banked_reg : Operand<i32> {
306 let PrintMethod = "printBankedRegOperand";
307 let DecoderMethod = "DecodeBankedReg";
308 let ParserMatchClass = BankedRegOperand;
311 // Shift Right Immediate - A shift right immediate is encoded differently from
312 // other shift immediates. The imm6 field is encoded like so:
315 // 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
316 // 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
317 // 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
318 // 64 64 - <imm> is encoded in imm6<5:0>
319 def shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; }
320 def shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> {
321 let EncoderMethod = "getShiftRight8Imm";
322 let DecoderMethod = "DecodeShiftRight8Imm";
323 let ParserMatchClass = shr_imm8_asm_operand;
325 def shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; }
326 def shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> {
327 let EncoderMethod = "getShiftRight16Imm";
328 let DecoderMethod = "DecodeShiftRight16Imm";
329 let ParserMatchClass = shr_imm16_asm_operand;
331 def shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; }
332 def shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> {
333 let EncoderMethod = "getShiftRight32Imm";
334 let DecoderMethod = "DecodeShiftRight32Imm";
335 let ParserMatchClass = shr_imm32_asm_operand;
337 def shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; }
338 def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> {
339 let EncoderMethod = "getShiftRight64Imm";
340 let DecoderMethod = "DecodeShiftRight64Imm";
341 let ParserMatchClass = shr_imm64_asm_operand;
345 // ARM Assembler operand for ldr Rd, =expression which generates an offset
346 // to a constant pool entry or a MOV depending on the value of expression
347 def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; }
348 def const_pool_asm_imm : Operand<i32> {
349 let ParserMatchClass = const_pool_asm_operand;
353 //===----------------------------------------------------------------------===//
354 // ARM Assembler alias templates.
356 // Note: When EmitPriority == 1, the alias will be used for printing
357 class ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0>
358 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>;
359 class ARMInstSubst<string Asm, dag Result, bit EmitPriority = 0>
360 : InstAlias<Asm, Result, EmitPriority>,
361 Requires<[IsARM,UseNegativeImmediates]>;
362 class tInstAlias<string Asm, dag Result, bit EmitPriority = 0>
363 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>;
364 class tInstSubst<string Asm, dag Result, bit EmitPriority = 0>
365 : InstAlias<Asm, Result, EmitPriority>,
366 Requires<[IsThumb,UseNegativeImmediates]>;
367 class t2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
368 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>;
369 class t2InstSubst<string Asm, dag Result, bit EmitPriority = 0>
370 : InstAlias<Asm, Result, EmitPriority>,
371 Requires<[IsThumb2,UseNegativeImmediates]>;
372 class VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0>
373 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>;
374 class VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0>
375 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>;
376 class VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0>
377 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>;
378 class NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0>
379 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>;
380 class MVEInstAlias<string Asm, dag Result, bit EmitPriority = 1>
381 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasMVEInt, IsThumb]>;
384 class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
386 class NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>,
389 //===----------------------------------------------------------------------===//
390 // ARM Instruction templates.
394 class InstTemplate<AddrMode am, int sz, IndexMode im,
395 Format f, Domain d, string cstr, InstrItinClass itin>
397 let Namespace = "ARM";
402 bits<2> IndexModeBits = IM.Value;
404 bits<6> Form = F.Value;
406 bit isUnaryDataProc = 0;
407 bit canXformTo16Bit = 0;
408 // The instruction is a 16-bit flag setting Thumb instruction. Used
409 // by the parser and if-converter to determine whether to require the 'S'
410 // suffix on the mnemonic (when not in an IT block) or preclude it (when
412 bit thumbArithFlagSetting = 0;
415 bit validForTailPredication = 0;
416 bit retainsPreviousHalfElement = 0;
417 bit horizontalReduction = 0;
418 bit doubleWidthResult = 0;
420 // If this is a pseudo instruction, mark it isCodeGenOnly.
421 let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
423 // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
424 let TSFlags{4-0} = AM.Value;
425 let TSFlags{6-5} = IndexModeBits;
426 let TSFlags{12-7} = Form;
427 let TSFlags{13} = isUnaryDataProc;
428 let TSFlags{14} = canXformTo16Bit;
429 let TSFlags{18-15} = D.Value;
430 let TSFlags{19} = thumbArithFlagSetting;
431 let TSFlags{20} = validForTailPredication;
432 let TSFlags{21} = retainsPreviousHalfElement;
433 let TSFlags{22} = horizontalReduction;
434 let TSFlags{23} = doubleWidthResult;
435 let TSFlags{25-24} = VecSize;
437 let Constraints = cstr;
438 let Itinerary = itin;
443 // Mask of bits that cause an encoding to be UNPREDICTABLE.
444 // If a bit is set, then if the corresponding bit in the
445 // target encoding differs from its value in the "Inst" field,
446 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
447 field bits<32> Unpredictable = 0;
448 // SoftFail is the generic name for this field, but we alias it so
449 // as to make it more obvious what it means in ARM-land.
450 field bits<32> SoftFail = Unpredictable;
453 class InstARM<AddrMode am, int sz, IndexMode im,
454 Format f, Domain d, string cstr, InstrItinClass itin>
455 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
456 let DecoderNamespace = "ARM";
459 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
460 // on by adding flavors to specific instructions.
461 class InstThumb<AddrMode am, int sz, IndexMode im,
462 Format f, Domain d, string cstr, InstrItinClass itin>
463 : InstTemplate<am, sz, im, f, d, cstr, itin> {
464 let DecoderNamespace = "Thumb";
467 // Pseudo-instructions for alternate assembly syntax (never used by codegen).
468 // These are aliases that require C++ handling to convert to the target
469 // instruction, while InstAliases can be handled directly by tblgen.
470 class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
471 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
473 let OutOperandList = oops;
474 let InOperandList = iops;
476 let isCodeGenOnly = 0; // So we get asm matcher for it.
479 let hasNoSchedulingInfo = 1;
482 class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)>
483 : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>;
484 class tAsmPseudo<string asm, dag iops, dag oops = (outs)>
485 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>;
486 class t2AsmPseudo<string asm, dag iops, dag oops = (outs)>
487 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>;
488 class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)>
489 : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>;
490 class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)>
491 : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>;
492 class MVEAsmPseudo<string asm, dag iops, dag oops = (outs)>
493 : AsmPseudoInst<asm, iops, oops>, Requires<[HasMVEInt]>;
495 // Pseudo instructions for the code generator.
496 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
497 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
498 GenericDomain, "", itin> {
499 let OutOperandList = oops;
500 let InOperandList = iops;
501 let Pattern = pattern;
502 let isCodeGenOnly = 1;
506 // PseudoInst that's ARM-mode only.
507 class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
509 : PseudoInst<oops, iops, itin, pattern> {
511 list<Predicate> Predicates = [IsARM];
514 // PseudoInst that's Thumb-mode only.
515 class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
517 : PseudoInst<oops, iops, itin, pattern> {
519 list<Predicate> Predicates = [IsThumb];
522 // PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2)
523 class t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
525 : PseudoInst<oops, iops, itin, pattern> {
527 list<Predicate> Predicates = [IsThumb,HasV8MBaseline];
530 // PseudoInst that's Thumb2-mode only.
531 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
533 : PseudoInst<oops, iops, itin, pattern> {
535 list<Predicate> Predicates = [IsThumb2];
538 class ARMPseudoExpand<dag oops, dag iops, int sz,
539 InstrItinClass itin, list<dag> pattern,
541 : ARMPseudoInst<oops, iops, sz, itin, pattern>,
542 PseudoInstExpansion<Result>;
544 class tPseudoExpand<dag oops, dag iops, int sz,
545 InstrItinClass itin, list<dag> pattern,
547 : tPseudoInst<oops, iops, sz, itin, pattern>,
548 PseudoInstExpansion<Result>;
550 class t2PseudoExpand<dag oops, dag iops, int sz,
551 InstrItinClass itin, list<dag> pattern,
553 : t2PseudoInst<oops, iops, sz, itin, pattern>,
554 PseudoInstExpansion<Result>;
556 // Almost all ARM instructions are predicable.
557 class I<dag oops, dag iops, AddrMode am, int sz,
558 IndexMode im, Format f, InstrItinClass itin,
559 string opc, string asm, string cstr,
561 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
564 let OutOperandList = oops;
565 let InOperandList = !con(iops, (ins pred:$p));
566 let AsmString = !strconcat(opc, "${p}", asm);
567 let Pattern = pattern;
568 list<Predicate> Predicates = [IsARM];
571 // A few are not predicable
572 class InoP<dag oops, dag iops, AddrMode am, int sz,
573 IndexMode im, Format f, InstrItinClass itin,
574 string opc, string asm, string cstr,
576 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
577 let OutOperandList = oops;
578 let InOperandList = iops;
579 let AsmString = !strconcat(opc, asm);
580 let Pattern = pattern;
581 let isPredicable = 0;
582 list<Predicate> Predicates = [IsARM];
585 // Same as I except it can optionally modify CPSR. Note it's modeled as an input
586 // operand since by default it's a zero register. It will become an implicit def
587 // once it's "flipped".
588 class sI<dag oops, dag iops, AddrMode am, int sz,
589 IndexMode im, Format f, InstrItinClass itin,
590 string opc, string asm, string cstr,
592 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
593 bits<4> p; // Predicate operand
594 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
598 let OutOperandList = oops;
599 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
600 let AsmString = !strconcat(opc, "${s}${p}", asm);
601 let Pattern = pattern;
602 list<Predicate> Predicates = [IsARM];
606 class XI<dag oops, dag iops, AddrMode am, int sz,
607 IndexMode im, Format f, InstrItinClass itin,
608 string asm, string cstr, list<dag> pattern>
609 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
610 let OutOperandList = oops;
611 let InOperandList = iops;
613 let Pattern = pattern;
614 list<Predicate> Predicates = [IsARM];
617 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
618 string opc, string asm, list<dag> pattern>
619 : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
620 opc, asm, "", pattern>;
621 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
622 string opc, string asm, list<dag> pattern>
623 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
624 opc, asm, "", pattern>;
625 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
626 string asm, list<dag> pattern>
627 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
629 class AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin,
630 string asm, list<dag> pattern>
631 : XI<oops, iops, am, 4, IndexModeNone, f, itin,
633 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
634 string opc, string asm, list<dag> pattern>
635 : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
636 opc, asm, "", pattern>;
638 // Ctrl flow instructions
639 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
640 string opc, string asm, list<dag> pattern>
641 : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
642 opc, asm, "", pattern> {
643 let Inst{27-24} = opcod;
645 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
646 string asm, list<dag> pattern>
647 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
649 let Inst{27-24} = opcod;
652 // BR_JT instructions
653 class JTI<dag oops, dag iops, InstrItinClass itin,
654 string asm, list<dag> pattern>
655 : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
658 class AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
659 string opc, string asm, list<dag> pattern>
660 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
661 opc, asm, "", pattern> {
664 let Inst{27-23} = 0b00011;
665 let Inst{22-21} = opcod;
667 let Inst{19-16} = addr;
668 let Inst{15-12} = Rt;
669 let Inst{11-10} = 0b11;
670 let Inst{9-8} = opcod2;
671 let Inst{7-0} = 0b10011111;
673 class AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin,
674 string opc, string asm, list<dag> pattern>
675 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
676 opc, asm, "", pattern> {
679 let Inst{27-23} = 0b00011;
680 let Inst{22-21} = opcod;
682 let Inst{19-16} = addr;
683 let Inst{11-10} = 0b11;
684 let Inst{9-8} = opcod2;
685 let Inst{7-4} = 0b1001;
688 // Atomic load/store instructions
689 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
690 string opc, string asm, list<dag> pattern>
691 : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>;
693 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
694 string opc, string asm, list<dag> pattern>
695 : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> {
697 let Inst{15-12} = Rd;
700 // Exclusive load/store instructions
702 class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
703 string opc, string asm, list<dag> pattern>
704 : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
705 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>;
707 class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
708 string opc, string asm, list<dag> pattern>
709 : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>,
710 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> {
712 let Inst{15-12} = Rd;
715 class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
716 : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
720 let Inst{27-23} = 0b00010;
722 let Inst{21-20} = 0b00;
723 let Inst{19-16} = addr;
724 let Inst{15-12} = Rt;
725 let Inst{11-4} = 0b00001001;
728 let Unpredictable{11-8} = 0b1111;
729 let DecoderMethod = "DecodeSwap";
731 // Acquire/Release load/store instructions
732 class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
733 string opc, string asm, list<dag> pattern>
734 : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
735 Requires<[IsARM, HasAcquireRelease]>;
737 class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
738 string opc, string asm, list<dag> pattern>
739 : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>,
740 Requires<[IsARM, HasAcquireRelease]> {
741 let Inst{15-12} = 0b1111;
744 // addrmode1 instructions
745 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
746 string opc, string asm, list<dag> pattern>
747 : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
748 opc, asm, "", pattern> {
749 let Inst{24-21} = opcod;
750 let Inst{27-26} = 0b00;
752 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
753 string opc, string asm, list<dag> pattern>
754 : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
755 opc, asm, "", pattern> {
756 let Inst{24-21} = opcod;
757 let Inst{27-26} = 0b00;
759 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
760 string asm, list<dag> pattern>
761 : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
763 let Inst{24-21} = opcod;
764 let Inst{27-26} = 0b00;
769 // LDR/LDRB/STR/STRB/...
770 class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
771 Format f, InstrItinClass itin, string opc, string asm,
773 : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
775 let Inst{27-25} = op;
776 let Inst{24} = 1; // 24 == P
778 let Inst{22} = isByte;
779 let Inst{21} = 0; // 21 == W
782 // Indexed load/stores
783 class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
784 IndexMode im, Format f, InstrItinClass itin, string opc,
785 string asm, string cstr, list<dag> pattern>
786 : I<oops, iops, AddrMode2, 4, im, f, itin,
787 opc, asm, cstr, pattern> {
789 let Inst{27-26} = 0b01;
790 let Inst{24} = isPre; // P bit
791 let Inst{22} = isByte; // B bit
792 let Inst{21} = isPre; // W bit
793 let Inst{20} = isLd; // L bit
794 let Inst{15-12} = Rt;
796 class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
797 IndexMode im, Format f, InstrItinClass itin, string opc,
798 string asm, string cstr, list<dag> pattern>
799 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
801 // AM2 store w/ two operands: (GPR, am2offset)
807 let Inst{23} = offset{12};
808 let Inst{19-16} = Rn;
809 let Inst{11-5} = offset{11-5};
811 let Inst{3-0} = offset{3-0};
814 class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
815 IndexMode im, Format f, InstrItinClass itin, string opc,
816 string asm, string cstr, list<dag> pattern>
817 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
819 // AM2 store w/ two operands: (GPR, am2offset)
825 let Inst{23} = offset{12};
826 let Inst{19-16} = Rn;
827 let Inst{11-0} = offset{11-0};
831 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
832 // but for now use this class for STRT and STRBT.
833 class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
834 IndexMode im, Format f, InstrItinClass itin, string opc,
835 string asm, string cstr, list<dag> pattern>
836 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
838 // AM2 store w/ two operands: (GPR, am2offset)
840 // {13} 1 == Rm, 0 == imm12
844 let Inst{25} = addr{13};
845 let Inst{23} = addr{12};
846 let Inst{19-16} = addr{17-14};
847 let Inst{11-0} = addr{11-0};
850 // addrmode3 instructions
851 class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
852 InstrItinClass itin, string opc, string asm, list<dag> pattern>
853 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
854 opc, asm, "", pattern> {
857 let Inst{27-25} = 0b000;
858 let Inst{24} = 1; // P bit
859 let Inst{23} = addr{8}; // U bit
860 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
861 let Inst{21} = 0; // W bit
862 let Inst{20} = op20; // L bit
863 let Inst{19-16} = addr{12-9}; // Rn
864 let Inst{15-12} = Rt; // Rt
865 let Inst{11-8} = addr{7-4}; // imm7_4/zero
867 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
869 let DecoderMethod = "DecodeAddrMode3Instruction";
872 class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
873 IndexMode im, Format f, InstrItinClass itin, string opc,
874 string asm, string cstr, list<dag> pattern>
875 : I<oops, iops, AddrMode3, 4, im, f, itin,
876 opc, asm, cstr, pattern> {
878 let Inst{27-25} = 0b000;
879 let Inst{24} = isPre; // P bit
880 let Inst{21} = isPre; // W bit
881 let Inst{20} = op20; // L bit
882 let Inst{15-12} = Rt; // Rt
886 // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
887 // but for now use this class for LDRSBT, LDRHT, LDSHT.
888 class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
889 IndexMode im, Format f, InstrItinClass itin, string opc,
890 string asm, string cstr, list<dag> pattern>
891 : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
892 // {13} 1 == imm8, 0 == Rm
899 let Inst{27-25} = 0b000;
900 let Inst{24} = 0; // P bit
902 let Inst{20} = isLoad; // L bit
903 let Inst{19-16} = addr; // Rn
904 let Inst{15-12} = Rt; // Rt
909 class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
910 string opc, string asm, list<dag> pattern>
911 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
912 opc, asm, "", pattern> {
915 let Inst{27-25} = 0b000;
916 let Inst{24} = 1; // P bit
917 let Inst{23} = addr{8}; // U bit
918 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
919 let Inst{21} = 0; // W bit
920 let Inst{20} = 0; // L bit
921 let Inst{19-16} = addr{12-9}; // Rn
922 let Inst{15-12} = Rt; // Rt
923 let Inst{11-8} = addr{7-4}; // imm7_4/zero
925 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
926 let DecoderMethod = "DecodeAddrMode3Instruction";
929 // addrmode4 instructions
930 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
931 string asm, string cstr, list<dag> pattern>
932 : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
937 let Inst{27-25} = 0b100;
938 let Inst{22} = 0; // S bit
939 let Inst{19-16} = Rn;
940 let Inst{15-0} = regs;
943 // Unsigned multiply, multiply-accumulate instructions.
944 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
945 string opc, string asm, list<dag> pattern>
946 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
947 opc, asm, "", pattern> {
948 let Inst{7-4} = 0b1001;
949 let Inst{20} = 0; // S bit
950 let Inst{27-21} = opcod;
952 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
953 string opc, string asm, list<dag> pattern>
954 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
955 opc, asm, "", pattern> {
956 let Inst{7-4} = 0b1001;
957 let Inst{27-21} = opcod;
960 // Most significant word multiply
961 class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
962 InstrItinClass itin, string opc, string asm, list<dag> pattern>
963 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
964 opc, asm, "", pattern> {
968 let Inst{7-4} = opc7_4;
970 let Inst{27-21} = opcod;
971 let Inst{19-16} = Rd;
975 // MSW multiple w/ Ra operand
976 class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
977 InstrItinClass itin, string opc, string asm, list<dag> pattern>
978 : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
980 let Inst{15-12} = Ra;
983 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
984 class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
985 InstrItinClass itin, string opc, string asm, list<dag> pattern>
986 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
987 opc, asm, "", pattern> {
993 let Inst{27-21} = opcod;
994 let Inst{6-5} = bit6_5;
998 class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
999 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1000 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
1002 let Inst{19-16} = Rd;
1005 // AMulxyI with Ra operand
1006 class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
1007 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1008 : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
1010 let Inst{15-12} = Ra;
1013 class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
1014 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1015 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
1018 let Inst{19-16} = RdHi;
1019 let Inst{15-12} = RdLo;
1022 // Extend instructions.
1023 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
1024 string opc, string asm, list<dag> pattern>
1025 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
1026 opc, asm, "", pattern> {
1027 // All AExtI instructions have Rd and Rm register operands.
1030 let Inst{15-12} = Rd;
1032 let Inst{7-4} = 0b0111;
1033 let Inst{9-8} = 0b00;
1034 let Inst{27-20} = opcod;
1036 let Unpredictable{9-8} = 0b11;
1039 // Misc Arithmetic instructions.
1040 class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
1041 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1042 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
1043 opc, asm, "", pattern> {
1046 let Inst{27-20} = opcod;
1047 let Inst{19-16} = 0b1111;
1048 let Inst{15-12} = Rd;
1049 let Inst{11-8} = 0b1111;
1050 let Inst{7-4} = opc7_4;
1054 // Division instructions.
1055 class ADivA1I<bits<3> opcod, dag oops, dag iops,
1056 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1057 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
1058 opc, asm, "", pattern> {
1062 let Inst{27-23} = 0b01110;
1063 let Inst{22-20} = opcod;
1064 let Inst{19-16} = Rd;
1065 let Inst{15-12} = 0b1111;
1066 let Inst{11-8} = Rm;
1067 let Inst{7-4} = 0b0001;
1072 def PKHLSLAsmOperand : ImmAsmOperand<0,31> {
1073 let Name = "PKHLSLImm";
1074 let ParserMethod = "parsePKHLSLImm";
1076 def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
1077 let PrintMethod = "printPKHLSLShiftImm";
1078 let ParserMatchClass = PKHLSLAsmOperand;
1080 def PKHASRAsmOperand : AsmOperandClass {
1081 let Name = "PKHASRImm";
1082 let ParserMethod = "parsePKHASRImm";
1084 def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
1085 let PrintMethod = "printPKHASRShiftImm";
1086 let ParserMatchClass = PKHASRAsmOperand;
1089 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
1090 string opc, string asm, list<dag> pattern>
1091 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
1092 opc, asm, "", pattern> {
1097 let Inst{27-20} = opcod;
1098 let Inst{19-16} = Rn;
1099 let Inst{15-12} = Rd;
1100 let Inst{11-7} = sh;
1102 let Inst{5-4} = 0b01;
1106 //===----------------------------------------------------------------------===//
1108 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
1109 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
1110 list<Predicate> Predicates = [IsARM];
1112 class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
1113 list<Predicate> Predicates = [IsARM, HasV5T];
1115 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
1116 list<Predicate> Predicates = [IsARM, HasV5TE];
1118 // ARMV5MOPat - Same as ARMV5TEPat with UseMulOps.
1119 class ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> {
1120 list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps];
1122 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
1123 list<Predicate> Predicates = [IsARM, HasV6];
1125 class VFPPat<dag pattern, dag result> : Pat<pattern, result> {
1126 list<Predicate> Predicates = [HasVFP2];
1128 class VFPNoNEONPat<dag pattern, dag result> : Pat<pattern, result> {
1129 list<Predicate> Predicates = [HasVFP2, DontUseNEONForFP];
1131 class Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> {
1132 list<Predicate> Predicates = [IsThumb2, HasDSP];
1134 class Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> {
1135 list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP];
1137 class FPRegs16Pat<dag pattern, dag result> : Pat<pattern, result> {
1138 list<Predicate> Predicates = [HasFPRegs16];
1140 class FP16Pat<dag pattern, dag result> : Pat<pattern, result> {
1141 list<Predicate> Predicates = [HasFP16];
1143 class FullFP16Pat<dag pattern, dag result> : Pat<pattern, result> {
1144 list<Predicate> Predicates = [HasFullFP16];
1146 //===----------------------------------------------------------------------===//
1147 // Thumb Instruction Format Definitions.
1150 class ThumbI<dag oops, dag iops, AddrMode am, int sz,
1151 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1152 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1153 let OutOperandList = oops;
1154 let InOperandList = iops;
1155 let AsmString = asm;
1156 let Pattern = pattern;
1157 list<Predicate> Predicates = [IsThumb];
1160 // TI - Thumb instruction.
1161 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
1162 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1164 // Two-address instructions
1165 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
1167 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
1170 // tBL, tBX 32-bit instructions
1171 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
1172 dag oops, dag iops, InstrItinClass itin, string asm,
1174 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
1176 let Inst{31-27} = opcod1;
1177 let Inst{15-14} = opcod2;
1178 let Inst{12} = opcod3;
1181 // BR_JT instructions
1182 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
1184 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1187 class Thumb1I<dag oops, dag iops, AddrMode am, int sz,
1188 InstrItinClass itin, string asm, string cstr, list<dag> pattern>
1189 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1190 let OutOperandList = oops;
1191 let InOperandList = iops;
1192 let AsmString = asm;
1193 let Pattern = pattern;
1194 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1197 class T1I<dag oops, dag iops, InstrItinClass itin,
1198 string asm, list<dag> pattern>
1199 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
1200 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
1201 string asm, list<dag> pattern>
1202 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1204 // Two-address instructions
1205 class T1It<dag oops, dag iops, InstrItinClass itin,
1206 string asm, string cstr, list<dag> pattern>
1207 : Thumb1I<oops, iops, AddrModeNone, 2, itin,
1208 asm, cstr, pattern>;
1210 // Thumb1 instruction that can either be predicated or set CPSR.
1211 class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
1212 InstrItinClass itin,
1213 string opc, string asm, string cstr, list<dag> pattern>
1214 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1215 let OutOperandList = !con(oops, (outs s_cc_out:$s));
1216 let InOperandList = !con(iops, (ins pred:$p));
1217 let AsmString = !strconcat(opc, "${s}${p}", asm);
1218 let Pattern = pattern;
1219 let thumbArithFlagSetting = 1;
1220 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1221 let DecoderNamespace = "ThumbSBit";
1224 class T1sI<dag oops, dag iops, InstrItinClass itin,
1225 string opc, string asm, list<dag> pattern>
1226 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1228 // Two-address instructions
1229 class T1sIt<dag oops, dag iops, InstrItinClass itin,
1230 string opc, string asm, list<dag> pattern>
1231 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1232 "$Rn = $Rdn", pattern>;
1234 // Thumb1 instruction that can be predicated.
1235 class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
1236 InstrItinClass itin,
1237 string opc, string asm, string cstr, list<dag> pattern>
1238 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1239 let OutOperandList = oops;
1240 let InOperandList = !con(iops, (ins pred:$p));
1241 let AsmString = !strconcat(opc, "${p}", asm);
1242 let Pattern = pattern;
1243 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1246 class T1pI<dag oops, dag iops, InstrItinClass itin,
1247 string opc, string asm, list<dag> pattern>
1248 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
1250 // Two-address instructions
1251 class T1pIt<dag oops, dag iops, InstrItinClass itin,
1252 string opc, string asm, list<dag> pattern>
1253 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
1254 "$Rn = $Rdn", pattern>;
1256 class T1pIs<dag oops, dag iops,
1257 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1258 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
1260 class Encoding16 : Encoding {
1261 let Inst{31-16} = 0x0000;
1264 // A6.2 16-bit Thumb instruction encoding
1265 class T1Encoding<bits<6> opcode> : Encoding16 {
1266 let Inst{15-10} = opcode;
1269 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
1270 class T1General<bits<5> opcode> : Encoding16 {
1271 let Inst{15-14} = 0b00;
1272 let Inst{13-9} = opcode;
1275 // A6.2.2 Data-processing encoding.
1276 class T1DataProcessing<bits<4> opcode> : Encoding16 {
1277 let Inst{15-10} = 0b010000;
1278 let Inst{9-6} = opcode;
1281 // A6.2.3 Special data instructions and branch and exchange encoding.
1282 class T1Special<bits<4> opcode> : Encoding16 {
1283 let Inst{15-10} = 0b010001;
1284 let Inst{9-6} = opcode;
1287 // A6.2.4 Load/store single data item encoding.
1288 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
1289 let Inst{15-12} = opA;
1290 let Inst{11-9} = opB;
1292 class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
1294 class T1BranchCond<bits<4> opcode> : Encoding16 {
1295 let Inst{15-12} = opcode;
1298 // Helper classes to encode Thumb1 loads and stores. For immediates, the
1299 // following bits are used for "opA" (see A6.2.4):
1301 // 0b0110 => Immediate, 4 bytes
1302 // 0b1000 => Immediate, 2 bytes
1303 // 0b0111 => Immediate, 1 byte
1304 class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
1305 InstrItinClass itin, string opc, string asm,
1307 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1308 T1LoadStore<0b0101, opcode> {
1311 let Inst{8-6} = addr{5-3}; // Rm
1312 let Inst{5-3} = addr{2-0}; // Rn
1315 class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
1316 InstrItinClass itin, string opc, string asm,
1318 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
1319 T1LoadStore<opA, {opB,?,?}> {
1322 let Inst{10-6} = addr{7-3}; // imm5
1323 let Inst{5-3} = addr{2-0}; // Rn
1327 // A6.2.5 Miscellaneous 16-bit instructions encoding.
1328 class T1Misc<bits<7> opcode> : Encoding16 {
1329 let Inst{15-12} = 0b1011;
1330 let Inst{11-5} = opcode;
1333 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
1334 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
1335 InstrItinClass itin,
1336 string opc, string asm, string cstr, list<dag> pattern>
1337 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1338 let OutOperandList = oops;
1339 let InOperandList = !con(iops, (ins pred:$p));
1340 let AsmString = !strconcat(opc, "${p}", asm);
1341 let Pattern = pattern;
1342 list<Predicate> Predicates = [IsThumb2];
1343 let DecoderNamespace = "Thumb2";
1346 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
1347 // input operand since by default it's a zero register. It will become an
1348 // implicit def once it's "flipped".
1350 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
1352 class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
1353 InstrItinClass itin,
1354 string opc, string asm, string cstr, list<dag> pattern>
1355 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1356 bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
1359 let OutOperandList = oops;
1360 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
1361 let AsmString = !strconcat(opc, "${s}${p}", asm);
1362 let Pattern = pattern;
1363 list<Predicate> Predicates = [IsThumb2];
1364 let DecoderNamespace = "Thumb2";
1368 class Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
1369 InstrItinClass itin,
1370 string asm, string cstr, list<dag> pattern>
1371 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1372 let OutOperandList = oops;
1373 let InOperandList = iops;
1374 let AsmString = asm;
1375 let Pattern = pattern;
1376 list<Predicate> Predicates = [IsThumb2];
1377 let DecoderNamespace = "Thumb2";
1380 class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
1381 InstrItinClass itin,
1382 string asm, string cstr, list<dag> pattern>
1383 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1384 let OutOperandList = oops;
1385 let InOperandList = iops;
1386 let AsmString = asm;
1387 let Pattern = pattern;
1388 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1389 let DecoderNamespace = "Thumb";
1392 class T2I<dag oops, dag iops, InstrItinClass itin,
1393 string opc, string asm, list<dag> pattern, AddrMode am = AddrModeNone>
1394 : Thumb2I<oops, iops, am, 4, itin, opc, asm, "", pattern>;
1395 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
1396 string opc, string asm, list<dag> pattern>
1397 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
1398 class T2Ii8p<dag oops, dag iops, InstrItinClass itin,
1399 string opc, string asm, list<dag> pattern>
1400 : Thumb2I<oops, iops, AddrModeT2_i8pos, 4, itin, opc, asm, "", pattern>;
1401 class T2Ii8n<dag oops, dag iops, InstrItinClass itin,
1402 string opc, string asm, list<dag> pattern>
1403 : Thumb2I<oops, iops, AddrModeT2_i8neg, 4, itin, opc, asm, "", pattern>;
1404 class T2Iso<dag oops, dag iops, InstrItinClass itin,
1405 string opc, string asm, list<dag> pattern>
1406 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
1407 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
1408 string opc, string asm, list<dag> pattern>
1409 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
1410 class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
1411 string opc, string asm, string cstr, list<dag> pattern>
1412 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1417 let Inst{31-25} = 0b1110100;
1419 let Inst{23} = addr{8};
1422 let Inst{20} = isLoad;
1423 let Inst{19-16} = addr{12-9};
1424 let Inst{15-12} = Rt{3-0};
1425 let Inst{11-8} = Rt2{3-0};
1426 let Inst{7-0} = addr{7-0};
1428 class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
1429 InstrItinClass itin, string opc, string asm, string cstr,
1431 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
1437 let Inst{31-25} = 0b1110100;
1439 let Inst{23} = imm{8};
1442 let Inst{20} = isLoad;
1443 let Inst{19-16} = addr;
1444 let Inst{15-12} = Rt{3-0};
1445 let Inst{11-8} = Rt2{3-0};
1446 let Inst{7-0} = imm{7-0};
1449 class T2sI<dag oops, dag iops, InstrItinClass itin,
1450 string opc, string asm, list<dag> pattern>
1451 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
1453 class T2XI<dag oops, dag iops, InstrItinClass itin,
1454 string asm, list<dag> pattern>
1455 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
1456 class T2JTI<dag oops, dag iops, InstrItinClass itin,
1457 string asm, list<dag> pattern>
1458 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
1460 // Move to/from coprocessor instructions
1461 class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
1463 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
1464 let Inst{31-28} = opc;
1467 // Two-address instructions
1468 class T2XIt<dag oops, dag iops, InstrItinClass itin,
1469 string asm, string cstr, list<dag> pattern>
1470 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
1472 // T2Ipreldst - Thumb2 pre-indexed load / store instructions.
1473 class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
1475 AddrMode am, IndexMode im, InstrItinClass itin,
1476 string opc, string asm, string cstr, list<dag> pattern>
1477 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1478 let OutOperandList = oops;
1479 let InOperandList = !con(iops, (ins pred:$p));
1480 let AsmString = !strconcat(opc, "${p}", asm);
1481 let Pattern = pattern;
1482 list<Predicate> Predicates = [IsThumb2];
1483 let DecoderNamespace = "Thumb2";
1487 let Inst{31-27} = 0b11111;
1488 let Inst{26-25} = 0b00;
1489 let Inst{24} = signed;
1491 let Inst{22-21} = opcod;
1492 let Inst{20} = load;
1493 let Inst{19-16} = addr{12-9};
1494 let Inst{15-12} = Rt{3-0};
1496 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1497 let Inst{10} = pre; // The P bit.
1498 let Inst{9} = addr{8}; // Sign bit
1499 let Inst{8} = 1; // The W bit.
1500 let Inst{7-0} = addr{7-0};
1502 let DecoderMethod = "DecodeT2LdStPre";
1505 // T2Ipostldst - Thumb2 post-indexed load / store instructions.
1506 class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
1508 AddrMode am, IndexMode im, InstrItinClass itin,
1509 string opc, string asm, string cstr, list<dag> pattern>
1510 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
1511 let OutOperandList = oops;
1512 let InOperandList = !con(iops, (ins pred:$p));
1513 let AsmString = !strconcat(opc, "${p}", asm);
1514 let Pattern = pattern;
1515 list<Predicate> Predicates = [IsThumb2];
1516 let DecoderNamespace = "Thumb2";
1521 let Inst{31-27} = 0b11111;
1522 let Inst{26-25} = 0b00;
1523 let Inst{24} = signed;
1525 let Inst{22-21} = opcod;
1526 let Inst{20} = load;
1527 let Inst{19-16} = Rn;
1528 let Inst{15-12} = Rt{3-0};
1530 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
1531 let Inst{10} = pre; // The P bit.
1532 let Inst{9} = offset{8}; // Sign bit
1533 let Inst{8} = 1; // The W bit.
1534 let Inst{7-0} = offset{7-0};
1536 let DecoderMethod = "DecodeT2LdStPre";
1539 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
1540 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
1541 list<Predicate> Predicates = [IsThumb, IsThumb1Only];
1544 // T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
1545 class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
1546 list<Predicate> Predicates = [IsThumb2, HasV6T2];
1549 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
1550 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
1551 list<Predicate> Predicates = [IsThumb2];
1554 //===----------------------------------------------------------------------===//
1556 //===----------------------------------------------------------------------===//
1557 // ARM VFP Instruction templates.
1560 // Almost all VFP instructions are predicable.
1561 class VFPI<dag oops, dag iops, AddrMode am, int sz,
1562 IndexMode im, Format f, InstrItinClass itin,
1563 string opc, string asm, string cstr, list<dag> pattern>
1564 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1566 let Inst{31-28} = p;
1567 let OutOperandList = oops;
1568 let InOperandList = !con(iops, (ins pred:$p));
1569 let AsmString = !strconcat(opc, "${p}", asm);
1570 let Pattern = pattern;
1571 let PostEncoderMethod = "VFPThumb2PostEncoder";
1572 let DecoderNamespace = "VFP";
1573 list<Predicate> Predicates = [HasVFP2];
1577 class VFPXI<dag oops, dag iops, AddrMode am, int sz,
1578 IndexMode im, Format f, InstrItinClass itin,
1579 string asm, string cstr, list<dag> pattern>
1580 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
1582 let Inst{31-28} = p;
1583 let OutOperandList = oops;
1584 let InOperandList = iops;
1585 let AsmString = asm;
1586 let Pattern = pattern;
1587 let PostEncoderMethod = "VFPThumb2PostEncoder";
1588 let DecoderNamespace = "VFP";
1589 list<Predicate> Predicates = [HasVFP2];
1592 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
1593 string opc, string asm, string cstr, list<dag> pattern>
1594 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
1595 opc, asm, cstr, pattern> {
1596 let PostEncoderMethod = "VFPThumb2PostEncoder";
1599 // ARM VFP addrmode5 loads and stores
1600 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1601 InstrItinClass itin,
1602 string opc, string asm, list<dag> pattern>
1603 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1604 VFPLdStFrm, itin, opc, asm, "", pattern> {
1605 // Instruction operands.
1609 // Encode instruction operands.
1610 let Inst{23} = addr{8}; // U (add = (U == '1'))
1611 let Inst{22} = Dd{4};
1612 let Inst{19-16} = addr{12-9}; // Rn
1613 let Inst{15-12} = Dd{3-0};
1614 let Inst{7-0} = addr{7-0}; // imm8
1616 let Inst{27-24} = opcod1;
1617 let Inst{21-20} = opcod2;
1618 let Inst{11-9} = 0b101;
1619 let Inst{8} = 1; // Double precision
1621 // Loads & stores operate on both NEON and VFP pipelines.
1622 let D = VFPNeonDomain;
1625 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1626 InstrItinClass itin,
1627 string opc, string asm, list<dag> pattern>
1628 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
1629 VFPLdStFrm, itin, opc, asm, "", pattern> {
1630 // Instruction operands.
1634 // Encode instruction operands.
1635 let Inst{23} = addr{8}; // U (add = (U == '1'))
1636 let Inst{22} = Sd{0};
1637 let Inst{19-16} = addr{12-9}; // Rn
1638 let Inst{15-12} = Sd{4-1};
1639 let Inst{7-0} = addr{7-0}; // imm8
1641 let Inst{27-24} = opcod1;
1642 let Inst{21-20} = opcod2;
1643 let Inst{11-9} = 0b101;
1644 let Inst{8} = 0; // Single precision
1646 // Loads & stores operate on both NEON and VFP pipelines.
1647 let D = VFPNeonDomain;
1650 class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
1651 InstrItinClass itin,
1652 string opc, string asm, list<dag> pattern>
1653 : VFPI<oops, iops, AddrMode5FP16, 4, IndexModeNone,
1654 VFPLdStFrm, itin, opc, asm, "", pattern> {
1655 list<Predicate> Predicates = [HasFullFP16];
1657 // Instruction operands.
1661 // Encode instruction operands.
1662 let Inst{23} = addr{8}; // U (add = (U == '1'))
1663 let Inst{22} = Sd{0};
1664 let Inst{19-16} = addr{12-9}; // Rn
1665 let Inst{15-12} = Sd{4-1};
1666 let Inst{7-0} = addr{7-0}; // imm8
1668 let Inst{27-24} = opcod1;
1669 let Inst{21-20} = opcod2;
1670 let Inst{11-8} = 0b1001; // Half precision
1672 // Loads & stores operate on both NEON and VFP pipelines.
1673 let D = VFPNeonDomain;
1675 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional
1678 // VFP Load / store multiple pseudo instructions.
1679 class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
1681 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
1683 let OutOperandList = oops;
1684 let InOperandList = !con(iops, (ins pred:$p));
1685 let Pattern = pattern;
1686 list<Predicate> Predicates = [HasVFP2];
1689 // Load / store multiple
1691 // Unknown precision
1692 class AXXI4<dag oops, dag iops, IndexMode im,
1693 string asm, string cstr, list<dag> pattern>
1694 : VFPXI<oops, iops, AddrMode4, 4, im,
1695 VFPLdStFrm, NoItinerary, asm, cstr, pattern> {
1696 // Instruction operands.
1700 // Encode instruction operands.
1701 let Inst{19-16} = Rn;
1703 let Inst{15-12} = regs{11-8};
1704 let Inst{7-1} = regs{7-1};
1706 let Inst{27-25} = 0b110;
1707 let Inst{11-8} = 0b1011;
1712 class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1713 string asm, string cstr, list<dag> pattern>
1714 : VFPXI<oops, iops, AddrMode4, 4, im,
1715 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1716 // Instruction operands.
1720 // Encode instruction operands.
1721 let Inst{19-16} = Rn;
1722 let Inst{22} = regs{12};
1723 let Inst{15-12} = regs{11-8};
1724 let Inst{7-1} = regs{7-1};
1726 let Inst{27-25} = 0b110;
1727 let Inst{11-9} = 0b101;
1728 let Inst{8} = 1; // Double precision
1733 class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
1734 string asm, string cstr, list<dag> pattern>
1735 : VFPXI<oops, iops, AddrMode4, 4, im,
1736 VFPLdStMulFrm, itin, asm, cstr, pattern> {
1737 // Instruction operands.
1741 // Encode instruction operands.
1742 let Inst{19-16} = Rn;
1743 let Inst{22} = regs{8};
1744 let Inst{15-12} = regs{12-9};
1745 let Inst{7-0} = regs{7-0};
1747 let Inst{27-25} = 0b110;
1748 let Inst{11-9} = 0b101;
1749 let Inst{8} = 0; // Single precision
1752 // Double precision, unary
1753 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1754 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1755 string asm, string cstr, list<dag> pattern>
1756 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, cstr, pattern> {
1757 // Instruction operands.
1761 // Encode instruction operands.
1762 let Inst{3-0} = Dm{3-0};
1763 let Inst{5} = Dm{4};
1764 let Inst{15-12} = Dd{3-0};
1765 let Inst{22} = Dd{4};
1767 let Inst{27-23} = opcod1;
1768 let Inst{21-20} = opcod2;
1769 let Inst{19-16} = opcod3;
1770 let Inst{11-9} = 0b101;
1771 let Inst{8} = 1; // Double precision
1772 let Inst{7-6} = opcod4;
1773 let Inst{4} = opcod5;
1775 let Predicates = [HasVFP2, HasDPVFP];
1778 // Double precision, unary, not-predicated
1779 class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1780 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1781 string asm, list<dag> pattern>
1782 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> {
1783 // Instruction operands.
1787 let Inst{31-28} = 0b1111;
1789 // Encode instruction operands.
1790 let Inst{3-0} = Dm{3-0};
1791 let Inst{5} = Dm{4};
1792 let Inst{15-12} = Dd{3-0};
1793 let Inst{22} = Dd{4};
1795 let Inst{27-23} = opcod1;
1796 let Inst{21-20} = opcod2;
1797 let Inst{19-16} = opcod3;
1798 let Inst{11-9} = 0b101;
1799 let Inst{8} = 1; // Double precision
1800 let Inst{7-6} = opcod4;
1801 let Inst{4} = opcod5;
1804 // Double precision, binary
1805 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1806 dag iops, InstrItinClass itin, string opc, string asm,
1808 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> {
1809 // Instruction operands.
1814 // Encode instruction operands.
1815 let Inst{3-0} = Dm{3-0};
1816 let Inst{5} = Dm{4};
1817 let Inst{19-16} = Dn{3-0};
1818 let Inst{7} = Dn{4};
1819 let Inst{15-12} = Dd{3-0};
1820 let Inst{22} = Dd{4};
1822 let Inst{27-23} = opcod1;
1823 let Inst{21-20} = opcod2;
1824 let Inst{11-9} = 0b101;
1825 let Inst{8} = 1; // Double precision
1829 let Predicates = [HasVFP2, HasDPVFP];
1832 // FP, binary, not predicated
1833 class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1834 InstrItinClass itin, string asm, list<dag> pattern>
1835 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
1838 // Instruction operands.
1843 let Inst{31-28} = 0b1111;
1845 // Encode instruction operands.
1846 let Inst{3-0} = Dm{3-0};
1847 let Inst{5} = Dm{4};
1848 let Inst{19-16} = Dn{3-0};
1849 let Inst{7} = Dn{4};
1850 let Inst{15-12} = Dd{3-0};
1851 let Inst{22} = Dd{4};
1853 let Inst{27-23} = opcod1;
1854 let Inst{21-20} = opcod2;
1855 let Inst{11-9} = 0b101;
1856 let Inst{8} = 1; // double precision
1857 let Inst{6} = opcod3;
1860 let Predicates = [HasVFP2, HasDPVFP];
1863 // Single precision, unary, predicated
1864 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1865 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1866 string asm, string cstr, list<dag> pattern>
1867 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, cstr, pattern> {
1868 // Instruction operands.
1872 // Encode instruction operands.
1873 let Inst{3-0} = Sm{4-1};
1874 let Inst{5} = Sm{0};
1875 let Inst{15-12} = Sd{4-1};
1876 let Inst{22} = Sd{0};
1878 let Inst{27-23} = opcod1;
1879 let Inst{21-20} = opcod2;
1880 let Inst{19-16} = opcod3;
1881 let Inst{11-9} = 0b101;
1882 let Inst{8} = 0; // Single precision
1883 let Inst{7-6} = opcod4;
1884 let Inst{4} = opcod5;
1887 // Single precision, unary, non-predicated
1888 class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1889 bit opcod5, dag oops, dag iops, InstrItinClass itin,
1890 string asm, list<dag> pattern>
1891 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1892 VFPUnaryFrm, itin, asm, "", pattern> {
1893 // Instruction operands.
1897 let Inst{31-28} = 0b1111;
1899 // Encode instruction operands.
1900 let Inst{3-0} = Sm{4-1};
1901 let Inst{5} = Sm{0};
1902 let Inst{15-12} = Sd{4-1};
1903 let Inst{22} = Sd{0};
1905 let Inst{27-23} = opcod1;
1906 let Inst{21-20} = opcod2;
1907 let Inst{19-16} = opcod3;
1908 let Inst{11-9} = 0b101;
1909 let Inst{8} = 0; // Single precision
1910 let Inst{7-6} = opcod4;
1911 let Inst{4} = opcod5;
1914 // Single precision unary, if no NEON. Same as ASuI except not available if
1916 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
1917 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
1918 string asm, list<dag> pattern>
1919 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
1921 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1924 // Single precision, binary
1925 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
1926 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1927 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> {
1928 // Instruction operands.
1933 // Encode instruction operands.
1934 let Inst{3-0} = Sm{4-1};
1935 let Inst{5} = Sm{0};
1936 let Inst{19-16} = Sn{4-1};
1937 let Inst{7} = Sn{0};
1938 let Inst{15-12} = Sd{4-1};
1939 let Inst{22} = Sd{0};
1941 let Inst{27-23} = opcod1;
1942 let Inst{21-20} = opcod2;
1943 let Inst{11-9} = 0b101;
1944 let Inst{8} = 0; // Single precision
1949 // Single precision, binary, not predicated
1950 class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
1951 InstrItinClass itin, string asm, list<dag> pattern>
1952 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
1953 VFPBinaryFrm, itin, asm, "", pattern>
1955 // Instruction operands.
1960 let Inst{31-28} = 0b1111;
1962 // Encode instruction operands.
1963 let Inst{3-0} = Sm{4-1};
1964 let Inst{5} = Sm{0};
1965 let Inst{19-16} = Sn{4-1};
1966 let Inst{7} = Sn{0};
1967 let Inst{15-12} = Sd{4-1};
1968 let Inst{22} = Sd{0};
1970 let Inst{27-23} = opcod1;
1971 let Inst{21-20} = opcod2;
1972 let Inst{11-9} = 0b101;
1973 let Inst{8} = 0; // Single precision
1974 let Inst{6} = opcod3;
1978 // Single precision binary, if no NEON. Same as ASbI except not available if
1980 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
1981 dag iops, InstrItinClass itin, string opc, string asm,
1983 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
1984 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
1986 // Instruction operands.
1991 // Encode instruction operands.
1992 let Inst{3-0} = Sm{4-1};
1993 let Inst{5} = Sm{0};
1994 let Inst{19-16} = Sn{4-1};
1995 let Inst{7} = Sn{0};
1996 let Inst{15-12} = Sd{4-1};
1997 let Inst{22} = Sd{0};
2000 // Half precision, unary, predicated
2001 class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
2002 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
2003 string asm, list<dag> pattern>
2004 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, "", pattern> {
2005 list<Predicate> Predicates = [HasFullFP16];
2007 // Instruction operands.
2011 // Encode instruction operands.
2012 let Inst{3-0} = Sm{4-1};
2013 let Inst{5} = Sm{0};
2014 let Inst{15-12} = Sd{4-1};
2015 let Inst{22} = Sd{0};
2017 let Inst{27-23} = opcod1;
2018 let Inst{21-20} = opcod2;
2019 let Inst{19-16} = opcod3;
2020 let Inst{11-8} = 0b1001; // Half precision
2021 let Inst{7-6} = opcod4;
2022 let Inst{4} = opcod5;
2024 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional
2027 // Half precision, unary, non-predicated
2028 class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
2029 bit opcod5, dag oops, dag iops, InstrItinClass itin,
2030 string asm, list<dag> pattern>
2031 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
2032 VFPUnaryFrm, itin, asm, "", pattern> {
2033 list<Predicate> Predicates = [HasFullFP16];
2035 // Instruction operands.
2039 let Inst{31-28} = 0b1111;
2041 // Encode instruction operands.
2042 let Inst{3-0} = Sm{4-1};
2043 let Inst{5} = Sm{0};
2044 let Inst{15-12} = Sd{4-1};
2045 let Inst{22} = Sd{0};
2047 let Inst{27-23} = opcod1;
2048 let Inst{21-20} = opcod2;
2049 let Inst{19-16} = opcod3;
2050 let Inst{11-8} = 0b1001; // Half precision
2051 let Inst{7-6} = opcod4;
2052 let Inst{4} = opcod5;
2054 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional
2057 // Half precision, binary
2058 class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
2059 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2060 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> {
2061 list<Predicate> Predicates = [HasFullFP16];
2063 // Instruction operands.
2068 // Encode instruction operands.
2069 let Inst{3-0} = Sm{4-1};
2070 let Inst{5} = Sm{0};
2071 let Inst{19-16} = Sn{4-1};
2072 let Inst{7} = Sn{0};
2073 let Inst{15-12} = Sd{4-1};
2074 let Inst{22} = Sd{0};
2076 let Inst{27-23} = opcod1;
2077 let Inst{21-20} = opcod2;
2078 let Inst{11-8} = 0b1001; // Half precision
2082 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional
2085 // Half precision, binary, not predicated
2086 class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
2087 InstrItinClass itin, string asm, list<dag> pattern>
2088 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
2089 VFPBinaryFrm, itin, asm, "", pattern> {
2090 list<Predicate> Predicates = [HasFullFP16];
2092 // Instruction operands.
2097 let Inst{31-28} = 0b1111;
2099 // Encode instruction operands.
2100 let Inst{3-0} = Sm{4-1};
2101 let Inst{5} = Sm{0};
2102 let Inst{19-16} = Sn{4-1};
2103 let Inst{7} = Sn{0};
2104 let Inst{15-12} = Sd{4-1};
2105 let Inst{22} = Sd{0};
2107 let Inst{27-23} = opcod1;
2108 let Inst{21-20} = opcod2;
2109 let Inst{11-8} = 0b1001; // Half precision
2110 let Inst{6} = opcod3;
2113 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional
2116 // VFP conversion instructions
2117 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
2118 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
2120 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, "", pattern> {
2121 let Inst{27-23} = opcod1;
2122 let Inst{21-20} = opcod2;
2123 let Inst{19-16} = opcod3;
2124 let Inst{11-8} = opcod4;
2129 // VFP conversion between floating-point and fixed-point
2130 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
2131 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
2133 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
2135 // size (fixed-point number): sx == 0 ? 16 : 32
2136 let Inst{7} = op5; // sx
2137 let Inst{5} = fbits{0};
2138 let Inst{3-0} = fbits{4-1};
2141 // VFP conversion instructions, if no NEON
2142 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
2143 dag oops, dag iops, InstrItinClass itin,
2144 string opc, string asm, list<dag> pattern>
2145 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
2147 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
2150 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
2151 InstrItinClass itin,
2152 string opc, string asm, list<dag> pattern>
2153 : VFPAI<oops, iops, f, itin, opc, asm, "", pattern> {
2154 let Inst{27-20} = opcod1;
2155 let Inst{11-8} = opcod2;
2159 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2160 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2161 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
2163 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2164 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2165 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
2167 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2168 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2169 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
2171 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
2172 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2173 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
2175 //===----------------------------------------------------------------------===//
2177 //===----------------------------------------------------------------------===//
2178 // ARM NEON Instruction templates.
2181 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2182 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2184 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2185 let OutOperandList = oops;
2186 let InOperandList = !con(iops, (ins pred:$p));
2187 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2188 let Pattern = pattern;
2189 list<Predicate> Predicates = [HasNEON];
2190 let DecoderNamespace = "NEON";
2193 // Same as NeonI except it does not have a "data type" specifier.
2194 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2195 InstrItinClass itin, string opc, string asm, string cstr,
2197 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2198 let OutOperandList = oops;
2199 let InOperandList = !con(iops, (ins pred:$p));
2200 let AsmString = !strconcat(opc, "${p}", "\t", asm);
2201 let Pattern = pattern;
2202 list<Predicate> Predicates = [HasNEON];
2203 let DecoderNamespace = "NEON";
2206 // Same as NeonI except it is not predicated
2207 class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
2208 InstrItinClass itin, string opc, string dt, string asm, string cstr,
2210 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
2211 let OutOperandList = oops;
2212 let InOperandList = iops;
2213 let AsmString = !strconcat(opc, ".", dt, "\t", asm);
2214 let Pattern = pattern;
2215 list<Predicate> Predicates = [HasNEON];
2216 let DecoderNamespace = "NEON";
2218 let Inst{31-28} = 0b1111;
2221 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2222 dag oops, dag iops, InstrItinClass itin,
2223 string opc, string dt, string asm, string cstr, list<dag> pattern>
2224 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
2226 let Inst{31-24} = 0b11110100;
2227 let Inst{23} = op23;
2228 let Inst{21-20} = op21_20;
2229 let Inst{11-8} = op11_8;
2230 let Inst{7-4} = op7_4;
2232 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
2233 let DecoderNamespace = "NEONLoadStore";
2239 let Inst{22} = Vd{4};
2240 let Inst{15-12} = Vd{3-0};
2241 let Inst{19-16} = Rn{3-0};
2242 let Inst{3-0} = Rm{3-0};
2245 class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
2246 dag oops, dag iops, InstrItinClass itin,
2247 string opc, string dt, string asm, string cstr, list<dag> pattern>
2248 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
2249 dt, asm, cstr, pattern> {
2253 class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
2254 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2256 let OutOperandList = oops;
2257 let InOperandList = !con(iops, (ins pred:$p));
2258 list<Predicate> Predicates = [HasNEON];
2261 class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
2263 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
2265 let OutOperandList = oops;
2266 let InOperandList = !con(iops, (ins pred:$p));
2267 let Pattern = pattern;
2268 list<Predicate> Predicates = [HasNEON];
2271 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
2272 string opc, string dt, string asm, string cstr, list<dag> pattern>
2273 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
2275 let Inst{31-25} = 0b1111001;
2276 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2277 let DecoderNamespace = "NEONData";
2280 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
2281 string opc, string asm, string cstr, list<dag> pattern>
2282 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
2284 let Inst{31-25} = 0b1111001;
2285 let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
2286 let DecoderNamespace = "NEONData";
2289 // NEON "one register and a modified immediate" format.
2290 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
2292 dag oops, dag iops, InstrItinClass itin,
2293 string opc, string dt, string asm, string cstr,
2295 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
2296 let Inst{23} = op23;
2297 let Inst{21-19} = op21_19;
2298 let Inst{11-8} = op11_8;
2304 // Instruction operands.
2308 let Inst{15-12} = Vd{3-0};
2309 let Inst{22} = Vd{4};
2310 let Inst{24} = SIMM{7};
2311 let Inst{18-16} = SIMM{6-4};
2312 let Inst{3-0} = SIMM{3-0};
2313 let DecoderMethod = "DecodeVMOVModImmInstruction";
2316 // NEON 2 vector register format.
2317 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2318 bits<5> op11_7, bit op6, bit op4,
2319 dag oops, dag iops, InstrItinClass itin,
2320 string opc, string dt, string asm, string cstr, list<dag> pattern>
2321 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
2322 let Inst{24-23} = op24_23;
2323 let Inst{21-20} = op21_20;
2324 let Inst{19-18} = op19_18;
2325 let Inst{17-16} = op17_16;
2326 let Inst{11-7} = op11_7;
2330 // Instruction operands.
2334 let Inst{15-12} = Vd{3-0};
2335 let Inst{22} = Vd{4};
2336 let Inst{3-0} = Vm{3-0};
2337 let Inst{5} = Vm{4};
2340 // Same as N2V but not predicated.
2341 class N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
2342 dag oops, dag iops, InstrItinClass itin, string OpcodeStr,
2343 string Dt, list<dag> pattern>
2344 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin,
2345 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> {
2349 // Encode instruction operands
2350 let Inst{22} = Vd{4};
2351 let Inst{15-12} = Vd{3-0};
2352 let Inst{5} = Vm{4};
2353 let Inst{3-0} = Vm{3-0};
2355 // Encode constant bits
2356 let Inst{27-23} = 0b00111;
2357 let Inst{21-20} = 0b11;
2358 let Inst{19-18} = op19_18;
2359 let Inst{17-16} = op17_16;
2361 let Inst{10-8} = op10_8;
2366 let DecoderNamespace = "NEON";
2369 // Same as N2V except it doesn't have a datatype suffix.
2370 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
2371 bits<5> op11_7, bit op6, bit op4,
2372 dag oops, dag iops, InstrItinClass itin,
2373 string opc, string asm, string cstr, list<dag> pattern>
2374 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
2375 let Inst{24-23} = op24_23;
2376 let Inst{21-20} = op21_20;
2377 let Inst{19-18} = op19_18;
2378 let Inst{17-16} = op17_16;
2379 let Inst{11-7} = op11_7;
2383 // Instruction operands.
2387 let Inst{15-12} = Vd{3-0};
2388 let Inst{22} = Vd{4};
2389 let Inst{3-0} = Vm{3-0};
2390 let Inst{5} = Vm{4};
2393 // NEON 2 vector register with immediate.
2394 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
2395 dag oops, dag iops, Format f, InstrItinClass itin,
2396 string opc, string dt, string asm, string cstr, list<dag> pattern>
2397 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2398 let Inst{24} = op24;
2399 let Inst{23} = op23;
2400 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{3-0} = Vm{3-0};
2413 let Inst{5} = Vm{4};
2414 let Inst{21-16} = SIMM{5-0};
2417 // NEON 3 vector register format.
2419 class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2420 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2421 string opc, string dt, string asm, string cstr,
2423 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2424 let Inst{24} = op24;
2425 let Inst{23} = op23;
2426 let Inst{21-20} = op21_20;
2427 let Inst{11-8} = op11_8;
2432 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
2433 dag oops, dag iops, Format f, InstrItinClass itin,
2434 string opc, string dt, string asm, string cstr, list<dag> pattern>
2435 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2436 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2437 // Instruction operands.
2442 let Inst{15-12} = Vd{3-0};
2443 let Inst{22} = Vd{4};
2444 let Inst{19-16} = Vn{3-0};
2445 let Inst{7} = Vn{4};
2446 let Inst{3-0} = Vm{3-0};
2447 let Inst{5} = Vm{4};
2450 class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2451 bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2452 string OpcodeStr, string Dt, list<dag> pattern>
2453 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
2454 Dt, "$Vd, $Vn, $Vm", "", pattern> {
2459 // Encode instruction operands
2460 let Inst{22} = Vd{4};
2461 let Inst{15-12} = Vd{3-0};
2462 let Inst{19-16} = Vn{3-0};
2463 let Inst{7} = Vn{4};
2464 let Inst{5} = Vm{4};
2465 let Inst{3-0} = Vm{3-0};
2467 // Encode constant bits
2468 let Inst{27-23} = op27_23;
2469 let Inst{21-20} = op21_20;
2470 let Inst{11-8} = op11_8;
2475 class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2476 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2477 string opc, string dt, string asm, string cstr,
2479 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2480 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2482 // Instruction operands.
2488 let Inst{15-12} = Vd{3-0};
2489 let Inst{22} = Vd{4};
2490 let Inst{19-16} = Vn{3-0};
2491 let Inst{7} = Vn{4};
2492 let Inst{3-0} = Vm{3-0};
2496 class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2497 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
2498 string opc, string dt, string asm, string cstr,
2500 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
2501 oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
2503 // Instruction operands.
2509 let Inst{15-12} = Vd{3-0};
2510 let Inst{22} = Vd{4};
2511 let Inst{19-16} = Vn{3-0};
2512 let Inst{7} = Vn{4};
2513 let Inst{2-0} = Vm{2-0};
2514 let Inst{5} = lane{1};
2515 let Inst{3} = lane{0};
2518 // Same as N3V except it doesn't have a data type suffix.
2519 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
2521 dag oops, dag iops, Format f, InstrItinClass itin,
2522 string opc, string asm, string cstr, list<dag> pattern>
2523 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
2524 let Inst{24} = op24;
2525 let Inst{23} = op23;
2526 let Inst{21-20} = op21_20;
2527 let Inst{11-8} = op11_8;
2531 // Instruction operands.
2536 let Inst{15-12} = Vd{3-0};
2537 let Inst{22} = Vd{4};
2538 let Inst{19-16} = Vn{3-0};
2539 let Inst{7} = Vn{4};
2540 let Inst{3-0} = Vm{3-0};
2541 let Inst{5} = Vm{4};
2544 // NEON VMOVs between scalar and core registers.
2545 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2546 dag oops, dag iops, Format f, InstrItinClass itin,
2547 string opc, string dt, string asm, list<dag> pattern>
2548 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
2550 let Inst{27-20} = opcod1;
2551 let Inst{11-8} = opcod2;
2552 let Inst{6-5} = opcod3;
2554 // A8.6.303, A8.6.328, A8.6.329
2555 let Inst{3-0} = 0b0000;
2557 let OutOperandList = oops;
2558 let InOperandList = !con(iops, (ins pred:$p));
2559 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
2560 let Pattern = pattern;
2561 list<Predicate> Predicates = [HasNEON];
2563 let PostEncoderMethod = "NEONThumb2DupPostEncoder";
2564 let DecoderNamespace = "NEONDup";
2571 let Inst{31-28} = p{3-0};
2573 let Inst{19-16} = V{3-0};
2574 let Inst{15-12} = R{3-0};
2576 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2577 dag oops, dag iops, InstrItinClass itin,
2578 string opc, string dt, string asm, list<dag> pattern>
2579 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
2580 opc, dt, asm, pattern>;
2581 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2582 dag oops, dag iops, InstrItinClass itin,
2583 string opc, string dt, string asm, list<dag> pattern>
2584 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
2585 opc, dt, asm, pattern>;
2586 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
2587 dag oops, dag iops, InstrItinClass itin,
2588 string opc, string dt, string asm, list<dag> pattern>
2589 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
2590 opc, dt, asm, pattern>;
2592 // Vector Duplicate Lane (from scalar to all elements)
2593 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
2594 InstrItinClass itin, string opc, string dt, string asm,
2596 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
2597 let Inst{24-23} = 0b11;
2598 let Inst{21-20} = 0b11;
2599 let Inst{19-16} = op19_16;
2600 let Inst{11-7} = 0b11000;
2607 let Inst{22} = Vd{4};
2608 let Inst{15-12} = Vd{3-0};
2609 let Inst{5} = Vm{4};
2610 let Inst{3-0} = Vm{3-0};
2613 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
2614 // for single-precision FP.
2615 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
2616 list<Predicate> Predicates = [HasNEON,UseNEONForFP];
2619 // VFP/NEON Instruction aliases for type suffices.
2620 // Note: When EmitPriority == 1, the alias will be used for printing
2621 class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> :
2622 InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasFPRegs]>;
2624 // Note: When EmitPriority == 1, the alias will be used for printing
2625 multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2626 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2627 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2628 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2629 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2632 // Note: When EmitPriority == 1, the alias will be used for printing
2633 multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> {
2634 let Predicates = [HasNEON] in {
2635 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>;
2636 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>;
2637 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>;
2638 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>;
2642 // The same alias classes using AsmPseudo instead, for the more complex
2643 // stuff in NEON that InstAlias can't quite handle.
2644 // Note that we can't use anonymous defm references here like we can
2645 // above, as we care about the ultimate instruction enum names generated, unlike
2646 // for instalias defs.
2647 class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> :
2648 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>;
2650 // Extension of NEON 3-vector data processing instructions in coprocessor 8
2651 // encoding space, introduced in ARMv8.3-A.
2652 class N3VCP8<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4,
2653 dag oops, dag iops, InstrItinClass itin,
2654 string opc, string dt, string asm, string cstr, list<dag> pattern>
2655 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc,
2656 dt, asm, cstr, pattern> {
2661 let DecoderNamespace = "VFPV8";
2662 // These have the same encodings in ARM and Thumb2
2663 let PostEncoderMethod = "";
2665 let Inst{31-25} = 0b1111110;
2666 let Inst{24-23} = op24_23;
2667 let Inst{22} = Vd{4};
2668 let Inst{21-20} = op21_20;
2669 let Inst{19-16} = Vn{3-0};
2670 let Inst{15-12} = Vd{3-0};
2671 let Inst{11-8} = 0b1000;
2672 let Inst{7} = Vn{4};
2674 let Inst{5} = Vm{4};
2676 let Inst{3-0} = Vm{3-0};
2679 // Extension of NEON 2-vector-and-scalar data processing instructions in
2680 // coprocessor 8 encoding space, introduced in ARMv8.3-A.
2681 class N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4,
2682 dag oops, dag iops, InstrItinClass itin,
2683 string opc, string dt, string asm, string cstr, list<dag> pattern>
2684 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc,
2685 dt, asm, cstr, pattern> {
2690 let DecoderNamespace = "VFPV8";
2691 // These have the same encodings in ARM and Thumb2
2692 let PostEncoderMethod = "";
2694 let Inst{31-24} = 0b11111110;
2695 let Inst{23} = op23;
2696 let Inst{22} = Vd{4};
2697 let Inst{21-20} = op21_20;
2698 let Inst{19-16} = Vn{3-0};
2699 let Inst{15-12} = Vd{3-0};
2700 let Inst{11-8} = 0b1000;
2701 let Inst{7} = Vn{4};
2703 // Bit 5 set by sub-classes
2705 let Inst{3-0} = Vm{3-0};
2708 // In Armv8.2-A, some NEON instructions are added that encode Vn and Vm
2710 // if Q == ‘1’ then UInt(N:Vn) else UInt(Vn:N);
2711 // if Q == ‘1’ then UInt(M:Vm) else UInt(Vm:M);
2712 // Class N3VCP8 above describes the Q=1 case, and this class the Q=0 case.
2713 class N3VCP8Q0<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4,
2714 dag oops, dag iops, InstrItinClass itin,
2715 string opc, string dt, string asm, string cstr, list<dag> pattern>
2716 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, dt, asm, cstr, pattern> {
2721 let DecoderNamespace = "VFPV8";
2722 // These have the same encodings in ARM and Thumb2
2723 let PostEncoderMethod = "";
2725 let Inst{31-25} = 0b1111110;
2726 let Inst{24-23} = op24_23;
2727 let Inst{22} = Vd{4};
2728 let Inst{21-20} = op21_20;
2729 let Inst{19-16} = Vn{4-1};
2730 let Inst{15-12} = Vd{3-0};
2731 let Inst{11-8} = 0b1000;
2732 let Inst{7} = Vn{0};
2734 let Inst{5} = Vm{0};
2736 let Inst{3-0} = Vm{4-1};
2739 // Operand types for complex instructions
2740 class ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag>
2742 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
2743 let DiagnosticString = "complex rotation must be " # Diag;
2744 let Name = "ComplexRotation" # Type;
2746 def complexrotateop : Operand<i32> {
2747 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">;
2748 let PrintMethod = "printComplexRotationOp<90, 0>";
2750 def complexrotateopodd : Operand<i32> {
2751 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">;
2752 let PrintMethod = "printComplexRotationOp<180, 90>";
2755 def MveSaturateOperand : AsmOperandClass {
2756 let PredicateMethod = "isMveSaturateOp";
2757 let DiagnosticString = "saturate operand must be 48 or 64";
2758 let Name = "MveSaturate";
2760 def saturateop : Operand<i32> {
2761 let ParserMatchClass = MveSaturateOperand;
2762 let PrintMethod = "printMveSaturateOp";
2765 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
2766 def : TokenAlias<".s8", ".i8">;
2767 def : TokenAlias<".u8", ".i8">;
2768 def : TokenAlias<".s16", ".i16">;
2769 def : TokenAlias<".u16", ".i16">;
2770 def : TokenAlias<".s32", ".i32">;
2771 def : TokenAlias<".u32", ".i32">;
2772 def : TokenAlias<".s64", ".i64">;
2773 def : TokenAlias<".u64", ".i64">;
2775 def : TokenAlias<".i8", ".8">;
2776 def : TokenAlias<".i16", ".16">;
2777 def : TokenAlias<".i32", ".32">;
2778 def : TokenAlias<".i64", ".64">;
2780 def : TokenAlias<".p8", ".8">;
2781 def : TokenAlias<".p16", ".16">;
2783 def : TokenAlias<".f32", ".32">;
2784 def : TokenAlias<".f64", ".64">;
2785 def : TokenAlias<".f", ".f32">;
2786 def : TokenAlias<".d", ".f64">;