1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>;
62 def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
63 def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
64 def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
66 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
68 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
69 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
72 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
73 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
75 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
76 [SDNPHasChain, SDNPOutFlag]>;
77 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
78 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
80 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
81 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
83 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
84 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
86 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
87 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
90 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
91 [SDNPHasChain, SDNPOptInFlag]>;
93 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
95 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
98 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
99 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
101 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
103 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
106 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
109 def ARMand : SDNode<"ARMISD::AND", SDT_ARMAnd,
112 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
115 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
116 [SDNPOutFlag, SDNPCommutative]>;
118 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
120 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
121 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
122 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
124 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
125 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
126 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
128 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
130 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
132 def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
134 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR,
136 def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR,
139 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
141 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
142 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
145 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
147 //===----------------------------------------------------------------------===//
148 // ARM Instruction Predicate Definitions.
150 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
151 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
152 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
153 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
154 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">;
162 def HasDivide : Predicate<"Subtarget->hasDivide()">;
163 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
164 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
165 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
166 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
167 def IsThumb : Predicate<"Subtarget->isThumb()">;
168 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
169 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
170 def IsARM : Predicate<"!Subtarget->isThumb()">;
171 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
172 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
174 // FIXME: Eventually this will be just "hasV6T2Ops".
175 def UseMovt : Predicate<"Subtarget->useMovt()">;
176 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
177 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
179 //===----------------------------------------------------------------------===//
180 // ARM Flag Definitions.
182 class RegConstraint<string C> {
183 string Constraints = C;
186 //===----------------------------------------------------------------------===//
187 // ARM specific transformation functions and pattern fragments.
190 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
191 // so_imm_neg def below.
192 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
193 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
196 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
197 // so_imm_not def below.
198 def so_imm_not_XFORM : SDNodeXForm<imm, [{
199 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
202 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
203 def rot_imm : PatLeaf<(i32 imm), [{
204 int32_t v = (int32_t)N->getZExtValue();
205 return v == 8 || v == 16 || v == 24;
208 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
209 def imm1_15 : PatLeaf<(i32 imm), [{
210 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
213 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
214 def imm16_31 : PatLeaf<(i32 imm), [{
215 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
220 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
221 }], so_imm_neg_XFORM>;
225 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
226 }], so_imm_not_XFORM>;
228 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
229 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
230 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
233 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
235 def bf_inv_mask_imm : Operand<i32>,
237 return ARM::isBitFieldInvertedMask(N->getZExtValue());
239 let PrintMethod = "printBitfieldInvMaskImmOperand";
242 /// Split a 32-bit immediate into two 16 bit parts.
243 def hi16 : SDNodeXForm<imm, [{
244 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
247 def lo16AllZero : PatLeaf<(i32 imm), [{
248 // Returns true if all low 16-bits are 0.
249 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
252 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
254 def imm0_65535 : PatLeaf<(i32 imm), [{
255 return (uint32_t)N->getZExtValue() < 65536;
258 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
259 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
261 /// adde and sube predicates - True based on whether the carry flag output
262 /// will be needed or not.
263 def adde_dead_carry :
264 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
265 [{return !N->hasAnyUseOfValue(1);}]>;
266 def sube_dead_carry :
267 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
268 [{return !N->hasAnyUseOfValue(1);}]>;
269 def adde_live_carry :
270 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
271 [{return N->hasAnyUseOfValue(1);}]>;
272 def sube_live_carry :
273 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
274 [{return N->hasAnyUseOfValue(1);}]>;
276 //===----------------------------------------------------------------------===//
277 // Operand Definitions.
281 def brtarget : Operand<OtherVT>;
283 // A list of registers separated by comma. Used by load/store multiple.
284 def reglist : Operand<i32> {
285 let PrintMethod = "printRegisterList";
288 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
289 def cpinst_operand : Operand<i32> {
290 let PrintMethod = "printCPInstOperand";
293 def jtblock_operand : Operand<i32> {
294 let PrintMethod = "printJTBlockOperand";
296 def jt2block_operand : Operand<i32> {
297 let PrintMethod = "printJT2BlockOperand";
301 def pclabel : Operand<i32> {
302 let PrintMethod = "printPCLabel";
305 // shift_imm: An integer that encodes a shift amount and the type of shift
306 // (currently either asr or lsl) using the same encoding used for the
307 // immediates in so_reg operands.
308 def shift_imm : Operand<i32> {
309 let PrintMethod = "printShiftImmOperand";
312 // shifter_operand operands: so_reg and so_imm.
313 def so_reg : Operand<i32>, // reg reg imm
314 ComplexPattern<i32, 3, "SelectShifterOperandReg",
315 [shl,srl,sra,rotr]> {
316 let PrintMethod = "printSORegOperand";
317 let MIOperandInfo = (ops GPR, GPR, i32imm);
320 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
321 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
322 // represented in the imm field in the same 12-bit form that they are encoded
323 // into so_imm instructions: the 8-bit immediate is the least significant bits
324 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
325 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
326 let PrintMethod = "printSOImmOperand";
329 // Break so_imm's up into two pieces. This handles immediates with up to 16
330 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
331 // get the first/second pieces.
332 def so_imm2part : Operand<i32>,
334 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
336 let PrintMethod = "printSOImm2PartOperand";
339 def so_imm2part_1 : SDNodeXForm<imm, [{
340 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
341 return CurDAG->getTargetConstant(V, MVT::i32);
344 def so_imm2part_2 : SDNodeXForm<imm, [{
345 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
346 return CurDAG->getTargetConstant(V, MVT::i32);
349 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
350 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
352 let PrintMethod = "printSOImm2PartOperand";
355 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
356 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
357 return CurDAG->getTargetConstant(V, MVT::i32);
360 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
361 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
362 return CurDAG->getTargetConstant(V, MVT::i32);
365 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
366 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
367 return (int32_t)N->getZExtValue() < 32;
370 // Define ARM specific addressing modes.
372 // addrmode2base := reg +/- imm12
374 def addrmode2base : Operand<i32>,
375 ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
376 let PrintMethod = "printAddrMode2Operand";
377 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
379 // addrmode2shop := reg +/- reg shop imm
381 def addrmode2shop : Operand<i32>,
382 ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
383 let PrintMethod = "printAddrMode2Operand";
384 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
387 // addrmode2 := (addrmode2base || addrmode2shop)
389 def addrmode2 : Operand<i32>,
390 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
391 let PrintMethod = "printAddrMode2Operand";
392 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
395 def am2offset : Operand<i32>,
396 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
397 [], [SDNPWantRoot]> {
398 let PrintMethod = "printAddrMode2OffsetOperand";
399 let MIOperandInfo = (ops GPR, i32imm);
402 // addrmode3 := reg +/- reg
403 // addrmode3 := reg +/- imm8
405 def addrmode3 : Operand<i32>,
406 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
407 let PrintMethod = "printAddrMode3Operand";
408 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
411 def am3offset : Operand<i32>,
412 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
413 [], [SDNPWantRoot]> {
414 let PrintMethod = "printAddrMode3OffsetOperand";
415 let MIOperandInfo = (ops GPR, i32imm);
418 // addrmode4 := reg, <mode|W>
420 def addrmode4 : Operand<i32>,
421 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
422 let PrintMethod = "printAddrMode4Operand";
423 let MIOperandInfo = (ops GPR:$addr, i32imm);
426 // addrmode5 := reg +/- imm8*4
428 def addrmode5 : Operand<i32>,
429 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
430 let PrintMethod = "printAddrMode5Operand";
431 let MIOperandInfo = (ops GPR:$base, i32imm);
434 // addrmode6 := reg with optional writeback
436 def addrmode6 : Operand<i32>,
437 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
438 let PrintMethod = "printAddrMode6Operand";
439 let MIOperandInfo = (ops GPR:$addr, i32imm);
442 def am6offset : Operand<i32> {
443 let PrintMethod = "printAddrMode6OffsetOperand";
444 let MIOperandInfo = (ops GPR);
447 // addrmodepc := pc + reg
449 def addrmodepc : Operand<i32>,
450 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
451 let PrintMethod = "printAddrModePCOperand";
452 let MIOperandInfo = (ops GPR, i32imm);
455 def nohash_imm : Operand<i32> {
456 let PrintMethod = "printNoHashImmediate";
459 //===----------------------------------------------------------------------===//
461 include "ARMInstrFormats.td"
463 //===----------------------------------------------------------------------===//
464 // Multiclass helpers...
467 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
468 /// binop that produces a value.
469 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
470 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
471 PatFrag opnode, bit Commutable = 0> {
472 // The register-immediate version is re-materializable. This is useful
473 // in particular for taking the address of a local.
474 let isReMaterializable = 1 in {
475 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
476 iii, opc, "\t$dst, $a, $b",
477 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
481 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
482 iir, opc, "\t$dst, $a, $b",
483 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
484 let Inst{11-4} = 0b00000000;
486 let isCommutable = Commutable;
488 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
489 iis, opc, "\t$dst, $a, $b",
490 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
495 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
496 /// instruction modifies the CPSR register.
497 let Defs = [CPSR] in {
498 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
499 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
500 PatFrag opnode, bit Commutable = 0> {
501 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
502 iii, opc, "\t$dst, $a, $b",
503 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
507 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
508 iir, opc, "\t$dst, $a, $b",
509 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
510 let isCommutable = Commutable;
511 let Inst{11-4} = 0b00000000;
515 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
516 iis, opc, "\t$dst, $a, $b",
517 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
524 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
525 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
526 /// a explicit result, only implicitly set CPSR.
527 let isCompare = 1, Defs = [CPSR] in {
528 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
529 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
530 PatFrag opnode, bit Commutable = 0> {
531 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, iii,
533 [(opnode GPR:$a, so_imm:$b)]> {
537 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, iir,
539 [(opnode GPR:$a, GPR:$b)]> {
540 let Inst{11-4} = 0b00000000;
543 let isCommutable = Commutable;
545 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, iis,
547 [(opnode GPR:$a, so_reg:$b)]> {
554 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
555 /// register and one whose operand is a register rotated by 8/16/24.
556 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
557 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
558 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
559 IIC_iEXTr, opc, "\t$dst, $src",
560 [(set GPR:$dst, (opnode GPR:$src))]>,
561 Requires<[IsARM, HasV6]> {
562 let Inst{11-10} = 0b00;
563 let Inst{19-16} = 0b1111;
565 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
566 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
567 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
568 Requires<[IsARM, HasV6]> {
569 let Inst{19-16} = 0b1111;
573 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
574 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
575 IIC_iEXTr, opc, "\t$dst, $src",
576 [/* For disassembly only; pattern left blank */]>,
577 Requires<[IsARM, HasV6]> {
578 let Inst{11-10} = 0b00;
579 let Inst{19-16} = 0b1111;
581 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
582 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
583 [/* For disassembly only; pattern left blank */]>,
584 Requires<[IsARM, HasV6]> {
585 let Inst{19-16} = 0b1111;
589 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
590 /// register and one whose operand is a register rotated by 8/16/24.
591 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
592 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
593 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
594 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
595 Requires<[IsARM, HasV6]> {
596 let Inst{11-10} = 0b00;
598 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
600 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
601 [(set GPR:$dst, (opnode GPR:$LHS,
602 (rotr GPR:$RHS, rot_imm:$rot)))]>,
603 Requires<[IsARM, HasV6]>;
606 // For disassembly only.
607 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
608 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
609 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
610 [/* For disassembly only; pattern left blank */]>,
611 Requires<[IsARM, HasV6]> {
612 let Inst{11-10} = 0b00;
614 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
616 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
617 [/* For disassembly only; pattern left blank */]>,
618 Requires<[IsARM, HasV6]>;
621 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
622 let Uses = [CPSR] in {
623 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
624 bit Commutable = 0> {
625 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
626 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
627 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
631 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
632 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
633 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
635 let isCommutable = Commutable;
636 let Inst{11-4} = 0b00000000;
639 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
640 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
641 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
646 // Carry setting variants
647 let Defs = [CPSR] in {
648 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
649 bit Commutable = 0> {
650 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
651 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
652 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
657 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
658 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
659 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
661 let Inst{11-4} = 0b00000000;
665 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
666 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
667 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
676 //===----------------------------------------------------------------------===//
678 //===----------------------------------------------------------------------===//
680 //===----------------------------------------------------------------------===//
681 // Miscellaneous Instructions.
684 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
685 /// the function. The first operand is the ID# for this instruction, the second
686 /// is the index into the MachineConstantPool that this is, the third is the
687 /// size in bytes of this constant pool entry.
688 let neverHasSideEffects = 1, isNotDuplicable = 1 in
689 def CONSTPOOL_ENTRY :
690 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
691 i32imm:$size), NoItinerary, "", []>;
693 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
694 // from removing one half of the matched pairs. That breaks PEI, which assumes
695 // these will always be in pairs, and asserts if it finds otherwise. Better way?
696 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
698 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
699 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
701 def ADJCALLSTACKDOWN :
702 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
703 [(ARMcallseq_start timm:$amt)]>;
706 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
707 [/* For disassembly only; pattern left blank */]>,
708 Requires<[IsARM, HasV6T2]> {
709 let Inst{27-16} = 0b001100100000;
710 let Inst{7-0} = 0b00000000;
713 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
714 [/* For disassembly only; pattern left blank */]>,
715 Requires<[IsARM, HasV6T2]> {
716 let Inst{27-16} = 0b001100100000;
717 let Inst{7-0} = 0b00000001;
720 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
721 [/* For disassembly only; pattern left blank */]>,
722 Requires<[IsARM, HasV6T2]> {
723 let Inst{27-16} = 0b001100100000;
724 let Inst{7-0} = 0b00000010;
727 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
728 [/* For disassembly only; pattern left blank */]>,
729 Requires<[IsARM, HasV6T2]> {
730 let Inst{27-16} = 0b001100100000;
731 let Inst{7-0} = 0b00000011;
734 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
736 [/* For disassembly only; pattern left blank */]>,
737 Requires<[IsARM, HasV6]> {
738 let Inst{27-20} = 0b01101000;
739 let Inst{7-4} = 0b1011;
742 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
743 [/* For disassembly only; pattern left blank */]>,
744 Requires<[IsARM, HasV6T2]> {
745 let Inst{27-16} = 0b001100100000;
746 let Inst{7-0} = 0b00000100;
749 // The i32imm operand $val can be used by a debugger to store more information
750 // about the breakpoint.
751 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
752 [/* For disassembly only; pattern left blank */]>,
754 let Inst{27-20} = 0b00010010;
755 let Inst{7-4} = 0b0111;
758 // Change Processor State is a system instruction -- for disassembly only.
759 // The singleton $opt operand contains the following information:
760 // opt{4-0} = mode from Inst{4-0}
761 // opt{5} = changemode from Inst{17}
762 // opt{8-6} = AIF from Inst{8-6}
763 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
764 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
765 [/* For disassembly only; pattern left blank */]>,
767 let Inst{31-28} = 0b1111;
768 let Inst{27-20} = 0b00010000;
773 // Preload signals the memory system of possible future data/instruction access.
774 // These are for disassembly only.
776 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
777 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
778 multiclass APreLoad<bit data, bit read, string opc> {
780 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
781 !strconcat(opc, "\t[$base, $imm]"), []> {
782 let Inst{31-26} = 0b111101;
783 let Inst{25} = 0; // 0 for immediate form
786 let Inst{21-20} = 0b01;
789 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
790 !strconcat(opc, "\t$addr"), []> {
791 let Inst{31-26} = 0b111101;
792 let Inst{25} = 1; // 1 for register form
795 let Inst{21-20} = 0b01;
800 defm PLD : APreLoad<1, 1, "pld">;
801 defm PLDW : APreLoad<1, 0, "pldw">;
802 defm PLI : APreLoad<0, 1, "pli">;
804 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
805 [/* For disassembly only; pattern left blank */]>,
807 let Inst{31-28} = 0b1111;
808 let Inst{27-20} = 0b00010000;
811 let Inst{7-4} = 0b0000;
814 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
815 [/* For disassembly only; pattern left blank */]>,
817 let Inst{31-28} = 0b1111;
818 let Inst{27-20} = 0b00010000;
821 let Inst{7-4} = 0b0000;
824 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
825 [/* For disassembly only; pattern left blank */]>,
826 Requires<[IsARM, HasV7]> {
827 let Inst{27-16} = 0b001100100000;
828 let Inst{7-4} = 0b1111;
831 // A5.4 Permanently UNDEFINED instructions.
832 let isBarrier = 1, isTerminator = 1 in
833 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
836 let Inst{27-25} = 0b011;
837 let Inst{24-20} = 0b11111;
838 let Inst{7-5} = 0b111;
842 // Address computation and loads and stores in PIC mode.
843 let isNotDuplicable = 1 in {
844 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
845 Pseudo, IIC_iALUr, "",
846 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
848 let AddedComplexity = 10 in {
849 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
850 Pseudo, IIC_iLoad_r, "",
851 [(set GPR:$dst, (load addrmodepc:$addr))]>;
853 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
854 Pseudo, IIC_iLoad_bh_r, "",
855 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
857 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
858 Pseudo, IIC_iLoad_bh_r, "",
859 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
861 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
862 Pseudo, IIC_iLoad_bh_r, "",
863 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
865 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
866 Pseudo, IIC_iLoad_bh_r, "",
867 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
869 let AddedComplexity = 10 in {
870 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
871 Pseudo, IIC_iStore_r, "",
872 [(store GPR:$src, addrmodepc:$addr)]>;
874 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
875 Pseudo, IIC_iStore_bh_r, "",
876 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
878 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
879 Pseudo, IIC_iStore_bh_r, "",
880 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
882 } // isNotDuplicable = 1
885 // LEApcrel - Load a pc-relative address into a register without offending the
887 let neverHasSideEffects = 1 in {
888 let isReMaterializable = 1 in
889 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
891 "adr$p\t$dst, #$label", []>;
893 } // neverHasSideEffects
894 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
895 (ins i32imm:$label, nohash_imm:$id, pred:$p),
897 "adr$p\t$dst, #${label}_${id}", []> {
901 //===----------------------------------------------------------------------===//
902 // Control Flow Instructions.
905 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
907 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
908 "bx", "\tlr", [(ARMretflag)]>,
909 Requires<[IsARM, HasV4T]> {
910 let Inst{3-0} = 0b1110;
911 let Inst{7-4} = 0b0001;
912 let Inst{19-8} = 0b111111111111;
913 let Inst{27-20} = 0b00010010;
917 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
918 "mov", "\tpc, lr", [(ARMretflag)]>,
919 Requires<[IsARM, NoV4T]> {
920 let Inst{11-0} = 0b000000001110;
921 let Inst{15-12} = 0b1111;
922 let Inst{19-16} = 0b0000;
923 let Inst{27-20} = 0b00011010;
928 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
930 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
932 Requires<[IsARM, HasV4T]> {
933 let Inst{7-4} = 0b0001;
934 let Inst{19-8} = 0b111111111111;
935 let Inst{27-20} = 0b00010010;
936 let Inst{31-28} = 0b1110;
940 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
942 Requires<[IsARM, NoV4T]> {
943 let Inst{11-4} = 0b00000000;
944 let Inst{15-12} = 0b1111;
945 let Inst{19-16} = 0b0000;
946 let Inst{27-20} = 0b00011010;
947 let Inst{31-28} = 0b1110;
951 // FIXME: remove when we have a way to marking a MI with these properties.
952 // FIXME: Should pc be an implicit operand like PICADD, etc?
953 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
954 hasExtraDefRegAllocReq = 1 in
955 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
956 reglist:$dsts, variable_ops),
957 IndexModeUpd, LdStMulFrm, IIC_iLoadmBr,
958 "ldm${addr:submode}${p}\t$addr!, $dsts",
959 "$addr.addr = $wb", []>;
961 // On non-Darwin platforms R9 is callee-saved.
963 Defs = [R0, R1, R2, R3, R12, LR,
964 D0, D1, D2, D3, D4, D5, D6, D7,
965 D16, D17, D18, D19, D20, D21, D22, D23,
966 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
967 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
968 IIC_Br, "bl\t${func:call}",
969 [(ARMcall tglobaladdr:$func)]>,
970 Requires<[IsARM, IsNotDarwin]> {
971 let Inst{31-28} = 0b1110;
974 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
975 IIC_Br, "bl", "\t${func:call}",
976 [(ARMcall_pred tglobaladdr:$func)]>,
977 Requires<[IsARM, IsNotDarwin]>;
980 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
981 IIC_Br, "blx\t$func",
982 [(ARMcall GPR:$func)]>,
983 Requires<[IsARM, HasV5T, IsNotDarwin]> {
984 let Inst{7-4} = 0b0011;
985 let Inst{19-8} = 0b111111111111;
986 let Inst{27-20} = 0b00010010;
990 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
991 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
992 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
993 [(ARMcall_nolink tGPR:$func)]>,
994 Requires<[IsARM, HasV4T, IsNotDarwin]> {
995 let Inst{7-4} = 0b0001;
996 let Inst{19-8} = 0b111111111111;
997 let Inst{27-20} = 0b00010010;
1001 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1002 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1003 [(ARMcall_nolink tGPR:$func)]>,
1004 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1005 let Inst{11-4} = 0b00000000;
1006 let Inst{15-12} = 0b1111;
1007 let Inst{19-16} = 0b0000;
1008 let Inst{27-20} = 0b00011010;
1012 // On Darwin R9 is call-clobbered.
1014 Defs = [R0, R1, R2, R3, R9, R12, LR,
1015 D0, D1, D2, D3, D4, D5, D6, D7,
1016 D16, D17, D18, D19, D20, D21, D22, D23,
1017 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1018 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1019 IIC_Br, "bl\t${func:call}",
1020 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1021 let Inst{31-28} = 0b1110;
1024 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1025 IIC_Br, "bl", "\t${func:call}",
1026 [(ARMcall_pred tglobaladdr:$func)]>,
1027 Requires<[IsARM, IsDarwin]>;
1030 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1031 IIC_Br, "blx\t$func",
1032 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1033 let Inst{7-4} = 0b0011;
1034 let Inst{19-8} = 0b111111111111;
1035 let Inst{27-20} = 0b00010010;
1039 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1040 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1041 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1042 [(ARMcall_nolink tGPR:$func)]>,
1043 Requires<[IsARM, HasV4T, IsDarwin]> {
1044 let Inst{7-4} = 0b0001;
1045 let Inst{19-8} = 0b111111111111;
1046 let Inst{27-20} = 0b00010010;
1050 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1051 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1052 [(ARMcall_nolink tGPR:$func)]>,
1053 Requires<[IsARM, NoV4T, IsDarwin]> {
1054 let Inst{11-4} = 0b00000000;
1055 let Inst{15-12} = 0b1111;
1056 let Inst{19-16} = 0b0000;
1057 let Inst{27-20} = 0b00011010;
1063 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1065 let Defs = [R0, R1, R2, R3, R9, R12,
1066 D0, D1, D2, D3, D4, D5, D6, D7,
1067 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1068 D27, D28, D29, D30, D31, PC],
1070 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1072 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1074 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1076 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1078 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1079 IIC_Br, "b\t$dst @ TAILCALL",
1080 []>, Requires<[IsDarwin]>;
1082 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1083 IIC_Br, "b.w\t$dst @ TAILCALL",
1084 []>, Requires<[IsDarwin]>;
1086 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1087 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1088 []>, Requires<[IsDarwin]> {
1089 let Inst{7-4} = 0b0001;
1090 let Inst{19-8} = 0b111111111111;
1091 let Inst{27-20} = 0b00010010;
1092 let Inst{31-28} = 0b1110;
1096 // Non-Darwin versions (the difference is R9).
1097 let Defs = [R0, R1, R2, R3, R12,
1098 D0, D1, D2, D3, D4, D5, D6, D7,
1099 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1100 D27, D28, D29, D30, D31, PC],
1102 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1104 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1106 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1108 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1110 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1111 IIC_Br, "b\t$dst @ TAILCALL",
1112 []>, Requires<[IsARM, IsNotDarwin]>;
1114 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1115 IIC_Br, "b.w\t$dst @ TAILCALL",
1116 []>, Requires<[IsThumb, IsNotDarwin]>;
1118 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1119 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1120 []>, Requires<[IsNotDarwin]> {
1121 let Inst{7-4} = 0b0001;
1122 let Inst{19-8} = 0b111111111111;
1123 let Inst{27-20} = 0b00010010;
1124 let Inst{31-28} = 0b1110;
1129 let isBranch = 1, isTerminator = 1 in {
1130 // B is "predicable" since it can be xformed into a Bcc.
1131 let isBarrier = 1 in {
1132 let isPredicable = 1 in
1133 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1134 "b\t$target", [(br bb:$target)]>;
1136 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1137 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1138 IIC_Br, "mov\tpc, $target$jt",
1139 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1140 let Inst{11-4} = 0b00000000;
1141 let Inst{15-12} = 0b1111;
1142 let Inst{20} = 0; // S Bit
1143 let Inst{24-21} = 0b1101;
1144 let Inst{27-25} = 0b000;
1146 def BR_JTm : JTI<(outs),
1147 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1148 IIC_Br, "ldr\tpc, $target$jt",
1149 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1151 let Inst{15-12} = 0b1111;
1152 let Inst{20} = 1; // L bit
1153 let Inst{21} = 0; // W bit
1154 let Inst{22} = 0; // B bit
1155 let Inst{24} = 1; // P bit
1156 let Inst{27-25} = 0b011;
1158 def BR_JTadd : JTI<(outs),
1159 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1160 IIC_Br, "add\tpc, $target, $idx$jt",
1161 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1163 let Inst{15-12} = 0b1111;
1164 let Inst{20} = 0; // S bit
1165 let Inst{24-21} = 0b0100;
1166 let Inst{27-25} = 0b000;
1168 } // isNotDuplicable = 1, isIndirectBranch = 1
1171 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1172 // a two-value operand where a dag node expects two operands. :(
1173 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1174 IIC_Br, "b", "\t$target",
1175 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1178 // Branch and Exchange Jazelle -- for disassembly only
1179 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1180 [/* For disassembly only; pattern left blank */]> {
1181 let Inst{23-20} = 0b0010;
1182 //let Inst{19-8} = 0xfff;
1183 let Inst{7-4} = 0b0010;
1186 // Secure Monitor Call is a system instruction -- for disassembly only
1187 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1188 [/* For disassembly only; pattern left blank */]> {
1189 let Inst{23-20} = 0b0110;
1190 let Inst{7-4} = 0b0111;
1193 // Supervisor Call (Software Interrupt) -- for disassembly only
1195 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1196 [/* For disassembly only; pattern left blank */]>;
1199 // Store Return State is a system instruction -- for disassembly only
1200 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1201 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1202 [/* For disassembly only; pattern left blank */]> {
1203 let Inst{31-28} = 0b1111;
1204 let Inst{22-20} = 0b110; // W = 1
1207 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1208 NoItinerary, "srs${addr:submode}\tsp, $mode",
1209 [/* For disassembly only; pattern left blank */]> {
1210 let Inst{31-28} = 0b1111;
1211 let Inst{22-20} = 0b100; // W = 0
1214 // Return From Exception is a system instruction -- for disassembly only
1215 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1216 NoItinerary, "rfe${addr:submode}\t$base!",
1217 [/* For disassembly only; pattern left blank */]> {
1218 let Inst{31-28} = 0b1111;
1219 let Inst{22-20} = 0b011; // W = 1
1222 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1223 NoItinerary, "rfe${addr:submode}\t$base",
1224 [/* For disassembly only; pattern left blank */]> {
1225 let Inst{31-28} = 0b1111;
1226 let Inst{22-20} = 0b001; // W = 0
1229 //===----------------------------------------------------------------------===//
1230 // Load / store Instructions.
1234 let canFoldAsLoad = 1, isReMaterializable = 1 in
1235 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1236 "ldr", "\t$dst, $addr",
1237 [(set GPR:$dst, (load addrmode2:$addr))]>;
1239 // Special LDR for loads from non-pc-relative constpools.
1240 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1241 isReMaterializable = 1 in
1242 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1243 "ldr", "\t$dst, $addr", []>;
1245 // Loads with zero extension
1246 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1247 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1248 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1250 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1251 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr",
1252 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1254 // Loads with sign extension
1255 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1256 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1257 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1259 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1260 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1261 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1263 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1265 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1266 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1267 []>, Requires<[IsARM, HasV5TE]>;
1270 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1271 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1272 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1274 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1275 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1276 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1278 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1279 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1280 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1282 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1283 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1284 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1286 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1287 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1288 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1290 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1291 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1292 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1294 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1295 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1296 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1298 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1299 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1300 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1302 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1303 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1304 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1306 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1307 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1308 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1310 // For disassembly only
1311 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1312 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1313 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1314 Requires<[IsARM, HasV5TE]>;
1316 // For disassembly only
1317 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1318 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1319 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1320 Requires<[IsARM, HasV5TE]>;
1322 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1324 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1326 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1327 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1328 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1329 let Inst{21} = 1; // overwrite
1332 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1333 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1334 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1335 let Inst{21} = 1; // overwrite
1338 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1339 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1340 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1341 let Inst{21} = 1; // overwrite
1344 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1345 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1346 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1347 let Inst{21} = 1; // overwrite
1350 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1351 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1352 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1353 let Inst{21} = 1; // overwrite
1357 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1358 "str", "\t$src, $addr",
1359 [(store GPR:$src, addrmode2:$addr)]>;
1361 // Stores with truncate
1362 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1363 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1364 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1366 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1367 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1368 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1371 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1372 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1373 StMiscFrm, IIC_iStore_d_r,
1374 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1377 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1378 (ins GPR:$src, GPR:$base, am2offset:$offset),
1379 StFrm, IIC_iStore_ru,
1380 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1382 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1384 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1385 (ins GPR:$src, GPR:$base,am2offset:$offset),
1386 StFrm, IIC_iStore_ru,
1387 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1389 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1391 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1392 (ins GPR:$src, GPR:$base,am3offset:$offset),
1393 StMiscFrm, IIC_iStore_ru,
1394 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1396 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1398 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1399 (ins GPR:$src, GPR:$base,am3offset:$offset),
1400 StMiscFrm, IIC_iStore_bh_ru,
1401 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1402 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1403 GPR:$base, am3offset:$offset))]>;
1405 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1406 (ins GPR:$src, GPR:$base,am2offset:$offset),
1407 StFrm, IIC_iStore_bh_ru,
1408 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1409 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1410 GPR:$base, am2offset:$offset))]>;
1412 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1413 (ins GPR:$src, GPR:$base,am2offset:$offset),
1414 StFrm, IIC_iStore_bh_ru,
1415 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1416 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1417 GPR:$base, am2offset:$offset))]>;
1419 // For disassembly only
1420 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1421 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1422 StMiscFrm, IIC_iStore_d_ru,
1423 "strd", "\t$src1, $src2, [$base, $offset]!",
1424 "$base = $base_wb", []>;
1426 // For disassembly only
1427 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1428 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1429 StMiscFrm, IIC_iStore_d_ru,
1430 "strd", "\t$src1, $src2, [$base], $offset",
1431 "$base = $base_wb", []>;
1433 // STRT, STRBT, and STRHT are for disassembly only.
1435 def STRT : AI2stwpo<(outs GPR:$base_wb),
1436 (ins GPR:$src, GPR:$base,am2offset:$offset),
1437 StFrm, IIC_iStore_ru,
1438 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1439 [/* For disassembly only; pattern left blank */]> {
1440 let Inst{21} = 1; // overwrite
1443 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1444 (ins GPR:$src, GPR:$base,am2offset:$offset),
1445 StFrm, IIC_iStore_bh_ru,
1446 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1447 [/* For disassembly only; pattern left blank */]> {
1448 let Inst{21} = 1; // overwrite
1451 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1452 (ins GPR:$src, GPR:$base,am3offset:$offset),
1453 StMiscFrm, IIC_iStore_bh_ru,
1454 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1455 [/* For disassembly only; pattern left blank */]> {
1456 let Inst{21} = 1; // overwrite
1459 //===----------------------------------------------------------------------===//
1460 // Load / store multiple Instructions.
1463 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1464 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1465 reglist:$dsts, variable_ops),
1466 IndexModeNone, LdStMulFrm, IIC_iLoadm,
1467 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1469 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1470 reglist:$dsts, variable_ops),
1471 IndexModeUpd, LdStMulFrm, IIC_iLoadm,
1472 "ldm${addr:submode}${p}\t$addr!, $dsts",
1473 "$addr.addr = $wb", []>;
1474 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1476 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1477 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1478 reglist:$srcs, variable_ops),
1479 IndexModeNone, LdStMulFrm, IIC_iStorem,
1480 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1482 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1483 reglist:$srcs, variable_ops),
1484 IndexModeUpd, LdStMulFrm, IIC_iStorem,
1485 "stm${addr:submode}${p}\t$addr!, $srcs",
1486 "$addr.addr = $wb", []>;
1487 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1489 //===----------------------------------------------------------------------===//
1490 // Move Instructions.
1493 let neverHasSideEffects = 1 in
1494 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1495 "mov", "\t$dst, $src", []>, UnaryDP {
1496 let Inst{11-4} = 0b00000000;
1500 // A version for the smaller set of tail call registers.
1501 let neverHasSideEffects = 1 in
1502 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$dst), (ins tcGPR:$src), DPFrm,
1503 IIC_iMOVr, "mov", "\t$dst, $src", []>, UnaryDP {
1504 let Inst{11-4} = 0b00000000;
1508 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1509 DPSoRegFrm, IIC_iMOVsr,
1510 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1514 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1515 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1516 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1520 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1521 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1523 "movw", "\t$dst, $src",
1524 [(set GPR:$dst, imm0_65535:$src)]>,
1525 Requires<[IsARM, HasV6T2]>, UnaryDP {
1530 let Constraints = "$src = $dst" in
1531 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1533 "movt", "\t$dst, $imm",
1535 (or (and GPR:$src, 0xffff),
1536 lo16AllZero:$imm))]>, UnaryDP,
1537 Requires<[IsARM, HasV6T2]> {
1542 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1543 Requires<[IsARM, HasV6T2]>;
1545 let Uses = [CPSR] in
1546 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1547 "mov", "\t$dst, $src, rrx",
1548 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1550 // These aren't really mov instructions, but we have to define them this way
1551 // due to flag operands.
1553 let Defs = [CPSR] in {
1554 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1555 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1556 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1557 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1558 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1559 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1562 //===----------------------------------------------------------------------===//
1563 // Extend Instructions.
1568 defm SXTB : AI_ext_rrot<0b01101010,
1569 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1570 defm SXTH : AI_ext_rrot<0b01101011,
1571 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1573 defm SXTAB : AI_exta_rrot<0b01101010,
1574 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1575 defm SXTAH : AI_exta_rrot<0b01101011,
1576 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1578 // For disassembly only
1579 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1581 // For disassembly only
1582 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1586 let AddedComplexity = 16 in {
1587 defm UXTB : AI_ext_rrot<0b01101110,
1588 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1589 defm UXTH : AI_ext_rrot<0b01101111,
1590 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1591 defm UXTB16 : AI_ext_rrot<0b01101100,
1592 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1594 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1595 // The transformation should probably be done as a combiner action
1596 // instead so we can include a check for masking back in the upper
1597 // eight bits of the source into the lower eight bits of the result.
1598 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1599 // (UXTB16r_rot GPR:$Src, 24)>;
1600 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1601 (UXTB16r_rot GPR:$Src, 8)>;
1603 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1604 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1605 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1606 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1609 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1610 // For disassembly only
1611 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1614 def SBFX : I<(outs GPR:$dst),
1615 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1616 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1617 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1618 Requires<[IsARM, HasV6T2]> {
1619 let Inst{27-21} = 0b0111101;
1620 let Inst{6-4} = 0b101;
1623 def UBFX : I<(outs GPR:$dst),
1624 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1625 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1626 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1627 Requires<[IsARM, HasV6T2]> {
1628 let Inst{27-21} = 0b0111111;
1629 let Inst{6-4} = 0b101;
1632 //===----------------------------------------------------------------------===//
1633 // Arithmetic Instructions.
1636 defm ADD : AsI1_bin_irs<0b0100, "add",
1637 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1638 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1639 defm SUB : AsI1_bin_irs<0b0010, "sub",
1640 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1641 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1643 // ADD and SUB with 's' bit set.
1644 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1645 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1646 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1647 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1648 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1649 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1651 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1652 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1653 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1654 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1655 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1656 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1657 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1658 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1660 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1661 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1662 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1666 // The reg/reg form is only defined for the disassembler; for codegen it is
1667 // equivalent to SUBrr.
1668 def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
1669 IIC_iALUr, "rsb", "\t$dst, $a, $b",
1670 [/* For disassembly only; pattern left blank */]> {
1672 let Inst{11-4} = 0b00000000;
1675 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1676 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1677 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1681 // RSB with 's' bit set.
1682 let Defs = [CPSR] in {
1683 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1684 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1685 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1689 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1690 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1691 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1697 let Uses = [CPSR] in {
1698 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1699 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1700 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1704 // The reg/reg form is only defined for the disassembler; for codegen it is
1705 // equivalent to SUBrr.
1706 def RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1707 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b",
1708 [/* For disassembly only; pattern left blank */]> {
1710 let Inst{11-4} = 0b00000000;
1712 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1713 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1714 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1720 // FIXME: Allow these to be predicated.
1721 let Defs = [CPSR], Uses = [CPSR] in {
1722 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1723 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1724 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1729 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1730 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1731 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1738 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1739 // The assume-no-carry-in form uses the negation of the input since add/sub
1740 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1741 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1743 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1744 (SUBri GPR:$src, so_imm_neg:$imm)>;
1745 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1746 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1747 // The with-carry-in form matches bitwise not instead of the negation.
1748 // Effectively, the inverse interpretation of the carry flag already accounts
1749 // for part of the negation.
1750 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1751 (SBCri GPR:$src, so_imm_not:$imm)>;
1753 // Note: These are implemented in C++ code, because they have to generate
1754 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1756 // (mul X, 2^n+1) -> (add (X << n), X)
1757 // (mul X, 2^n-1) -> (rsb X, (X << n))
1759 // ARM Arithmetic Instruction -- for disassembly only
1760 // GPR:$dst = GPR:$a op GPR:$b
1761 class AAI<bits<8> op27_20, bits<4> op7_4, string opc,
1762 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
1763 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1764 opc, "\t$dst, $a, $b", pattern> {
1765 let Inst{27-20} = op27_20;
1766 let Inst{7-4} = op7_4;
1769 // Saturating add/subtract -- for disassembly only
1771 def QADD : AAI<0b00010000, 0b0101, "qadd",
1772 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>;
1773 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1774 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1775 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1776 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1777 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1778 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1779 def QSUB : AAI<0b00010010, 0b0101, "qsub",
1780 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>;
1781 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1782 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1783 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1784 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1785 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1786 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1787 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1788 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1790 // Signed/Unsigned add/subtract -- for disassembly only
1792 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1793 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1794 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1795 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1796 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1797 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1798 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1799 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1800 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1801 def USAX : AAI<0b01100101, 0b0101, "usax">;
1802 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1803 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1805 // Signed/Unsigned halving add/subtract -- for disassembly only
1807 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1808 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1809 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1810 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1811 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1812 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1813 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1814 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1815 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1816 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1817 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1818 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1820 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1822 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1823 MulFrm /* for convenience */, NoItinerary, "usad8",
1824 "\t$dst, $a, $b", []>,
1825 Requires<[IsARM, HasV6]> {
1826 let Inst{27-20} = 0b01111000;
1827 let Inst{15-12} = 0b1111;
1828 let Inst{7-4} = 0b0001;
1830 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1831 MulFrm /* for convenience */, NoItinerary, "usada8",
1832 "\t$dst, $a, $b, $acc", []>,
1833 Requires<[IsARM, HasV6]> {
1834 let Inst{27-20} = 0b01111000;
1835 let Inst{7-4} = 0b0001;
1838 // Signed/Unsigned saturate -- for disassembly only
1840 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1841 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1842 [/* For disassembly only; pattern left blank */]> {
1843 let Inst{27-21} = 0b0110101;
1844 let Inst{5-4} = 0b01;
1847 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1848 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1849 [/* For disassembly only; pattern left blank */]> {
1850 let Inst{27-20} = 0b01101010;
1851 let Inst{7-4} = 0b0011;
1854 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1855 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1856 [/* For disassembly only; pattern left blank */]> {
1857 let Inst{27-21} = 0b0110111;
1858 let Inst{5-4} = 0b01;
1861 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1862 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1863 [/* For disassembly only; pattern left blank */]> {
1864 let Inst{27-20} = 0b01101110;
1865 let Inst{7-4} = 0b0011;
1868 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1869 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
1871 //===----------------------------------------------------------------------===//
1872 // Bitwise Instructions.
1875 defm AND : AsI1_bin_irs<0b0000, "and",
1876 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1877 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1878 defm ANDS : AI1_bin_s_irs<0b0000, "and",
1879 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1880 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>;
1881 defm ORR : AsI1_bin_irs<0b1100, "orr",
1882 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1883 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1884 defm EOR : AsI1_bin_irs<0b0001, "eor",
1885 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1886 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1887 defm BIC : AsI1_bin_irs<0b1110, "bic",
1888 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1889 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1891 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1892 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1893 "bfc", "\t$dst, $imm", "$src = $dst",
1894 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1895 Requires<[IsARM, HasV6T2]> {
1896 let Inst{27-21} = 0b0111110;
1897 let Inst{6-0} = 0b0011111;
1900 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1901 def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm),
1902 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1903 "bfi", "\t$dst, $val, $imm", "$src = $dst",
1904 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val,
1905 bf_inv_mask_imm:$imm))]>,
1906 Requires<[IsARM, HasV6T2]> {
1907 let Inst{27-21} = 0b0111110;
1908 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1911 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr,
1912 "mvn", "\t$dst, $src",
1913 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1915 let Inst{11-4} = 0b00000000;
1917 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1918 IIC_iMVNsr, "mvn", "\t$dst, $src",
1919 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1922 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1923 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1924 IIC_iMVNi, "mvn", "\t$dst, $imm",
1925 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1929 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1930 (BICri GPR:$src, so_imm_not:$imm)>;
1932 //===----------------------------------------------------------------------===//
1933 // Multiply Instructions.
1936 let isCommutable = 1 in
1937 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1938 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1939 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1941 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1942 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1943 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1945 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1946 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1947 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1948 Requires<[IsARM, HasV6T2]>;
1950 // Extra precision multiplies with low / high results
1951 let neverHasSideEffects = 1 in {
1952 let isCommutable = 1 in {
1953 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1954 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1955 "smull", "\t$ldst, $hdst, $a, $b", []>;
1957 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1958 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1959 "umull", "\t$ldst, $hdst, $a, $b", []>;
1962 // Multiply + accumulate
1963 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1964 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1965 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1967 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1968 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1969 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1971 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1972 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1973 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1974 Requires<[IsARM, HasV6]>;
1975 } // neverHasSideEffects
1977 // Most significant word multiply
1978 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1979 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1980 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1981 Requires<[IsARM, HasV6]> {
1982 let Inst{7-4} = 0b0001;
1983 let Inst{15-12} = 0b1111;
1986 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1987 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1988 [/* For disassembly only; pattern left blank */]>,
1989 Requires<[IsARM, HasV6]> {
1990 let Inst{7-4} = 0b0011; // R = 1
1991 let Inst{15-12} = 0b1111;
1994 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1995 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1996 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1997 Requires<[IsARM, HasV6]> {
1998 let Inst{7-4} = 0b0001;
2001 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2002 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
2003 [/* For disassembly only; pattern left blank */]>,
2004 Requires<[IsARM, HasV6]> {
2005 let Inst{7-4} = 0b0011; // R = 1
2008 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2009 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
2010 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
2011 Requires<[IsARM, HasV6]> {
2012 let Inst{7-4} = 0b1101;
2015 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2016 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
2017 [/* For disassembly only; pattern left blank */]>,
2018 Requires<[IsARM, HasV6]> {
2019 let Inst{7-4} = 0b1111; // R = 1
2022 multiclass AI_smul<string opc, PatFrag opnode> {
2023 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2024 IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b",
2025 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2026 (sext_inreg GPR:$b, i16)))]>,
2027 Requires<[IsARM, HasV5TE]> {
2032 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2033 IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b",
2034 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2035 (sra GPR:$b, (i32 16))))]>,
2036 Requires<[IsARM, HasV5TE]> {
2041 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2042 IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b",
2043 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2044 (sext_inreg GPR:$b, i16)))]>,
2045 Requires<[IsARM, HasV5TE]> {
2050 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2051 IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b",
2052 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2053 (sra GPR:$b, (i32 16))))]>,
2054 Requires<[IsARM, HasV5TE]> {
2059 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2060 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
2061 [(set GPR:$dst, (sra (opnode GPR:$a,
2062 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
2063 Requires<[IsARM, HasV5TE]> {
2068 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2069 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
2070 [(set GPR:$dst, (sra (opnode GPR:$a,
2071 (sra GPR:$b, (i32 16))), (i32 16)))]>,
2072 Requires<[IsARM, HasV5TE]> {
2079 multiclass AI_smla<string opc, PatFrag opnode> {
2080 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2081 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2082 [(set GPR:$dst, (add GPR:$acc,
2083 (opnode (sext_inreg GPR:$a, i16),
2084 (sext_inreg GPR:$b, i16))))]>,
2085 Requires<[IsARM, HasV5TE]> {
2090 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2091 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2092 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
2093 (sra GPR:$b, (i32 16)))))]>,
2094 Requires<[IsARM, HasV5TE]> {
2099 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2100 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2101 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2102 (sext_inreg GPR:$b, i16))))]>,
2103 Requires<[IsARM, HasV5TE]> {
2108 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2109 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2110 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2111 (sra GPR:$b, (i32 16)))))]>,
2112 Requires<[IsARM, HasV5TE]> {
2117 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2118 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2119 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2120 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
2121 Requires<[IsARM, HasV5TE]> {
2126 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2127 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2128 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2129 (sra GPR:$b, (i32 16))), (i32 16))))]>,
2130 Requires<[IsARM, HasV5TE]> {
2136 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2137 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2139 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2140 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2141 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2142 [/* For disassembly only; pattern left blank */]>,
2143 Requires<[IsARM, HasV5TE]> {
2148 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2149 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2150 [/* For disassembly only; pattern left blank */]>,
2151 Requires<[IsARM, HasV5TE]> {
2156 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2157 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2158 [/* For disassembly only; pattern left blank */]>,
2159 Requires<[IsARM, HasV5TE]> {
2164 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2165 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2166 [/* For disassembly only; pattern left blank */]>,
2167 Requires<[IsARM, HasV5TE]> {
2172 // Helper class for AI_smld -- for disassembly only
2173 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2174 InstrItinClass itin, string opc, string asm>
2175 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2180 let Inst{21-20} = 0b00;
2181 let Inst{22} = long;
2182 let Inst{27-23} = 0b01110;
2185 multiclass AI_smld<bit sub, string opc> {
2187 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2188 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2190 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2191 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2193 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2194 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2196 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2197 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2201 defm SMLA : AI_smld<0, "smla">;
2202 defm SMLS : AI_smld<1, "smls">;
2204 multiclass AI_sdml<bit sub, string opc> {
2206 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2207 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2208 let Inst{15-12} = 0b1111;
2211 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2212 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2213 let Inst{15-12} = 0b1111;
2218 defm SMUA : AI_sdml<0, "smua">;
2219 defm SMUS : AI_sdml<1, "smus">;
2221 //===----------------------------------------------------------------------===//
2222 // Misc. Arithmetic Instructions.
2225 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2226 "clz", "\t$dst, $src",
2227 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2228 let Inst{7-4} = 0b0001;
2229 let Inst{11-8} = 0b1111;
2230 let Inst{19-16} = 0b1111;
2233 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2234 "rbit", "\t$dst, $src",
2235 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2236 Requires<[IsARM, HasV6T2]> {
2237 let Inst{7-4} = 0b0011;
2238 let Inst{11-8} = 0b1111;
2239 let Inst{19-16} = 0b1111;
2242 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2243 "rev", "\t$dst, $src",
2244 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2245 let Inst{7-4} = 0b0011;
2246 let Inst{11-8} = 0b1111;
2247 let Inst{19-16} = 0b1111;
2250 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2251 "rev16", "\t$dst, $src",
2253 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2254 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2255 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2256 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2257 Requires<[IsARM, HasV6]> {
2258 let Inst{7-4} = 0b1011;
2259 let Inst{11-8} = 0b1111;
2260 let Inst{19-16} = 0b1111;
2263 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2264 "revsh", "\t$dst, $src",
2267 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2268 (shl GPR:$src, (i32 8))), i16))]>,
2269 Requires<[IsARM, HasV6]> {
2270 let Inst{7-4} = 0b1011;
2271 let Inst{11-8} = 0b1111;
2272 let Inst{19-16} = 0b1111;
2275 def lsl_shift_imm : SDNodeXForm<imm, [{
2276 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2277 return CurDAG->getTargetConstant(Sh, MVT::i32);
2280 def lsl_amt : PatLeaf<(i32 imm), [{
2281 return (N->getZExtValue() < 32);
2284 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2285 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2286 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2287 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2288 (and (shl GPR:$src2, lsl_amt:$sh),
2290 Requires<[IsARM, HasV6]> {
2291 let Inst{6-4} = 0b001;
2294 // Alternate cases for PKHBT where identities eliminate some nodes.
2295 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2296 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2297 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
2298 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
2300 def asr_shift_imm : SDNodeXForm<imm, [{
2301 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2302 return CurDAG->getTargetConstant(Sh, MVT::i32);
2305 def asr_amt : PatLeaf<(i32 imm), [{
2306 return (N->getZExtValue() <= 32);
2309 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2310 // will match the pattern below.
2311 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2312 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2313 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2314 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2315 (and (sra GPR:$src2, asr_amt:$sh),
2317 Requires<[IsARM, HasV6]> {
2318 let Inst{6-4} = 0b101;
2321 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2322 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2323 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2324 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2325 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2326 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2327 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2329 //===----------------------------------------------------------------------===//
2330 // Comparison Instructions...
2333 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2334 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2335 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2337 // FIXME: We have to be careful when using the CMN instruction and comparison
2338 // with 0. One would expect these two pieces of code should give identical
2354 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2355 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2356 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2357 // value of r0 and the carry bit (because the "carry bit" parameter to
2358 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2359 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2360 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2361 // parameter to AddWithCarry is defined as 0).
2363 // When x is 0 and unsigned:
2367 // ~x + 1 = 0x1 0000 0000
2368 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2370 // Therefore, we should disable CMN when comparing against zero, until we can
2371 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2372 // when it's a comparison which doesn't look at the 'carry' flag).
2374 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2376 // This is related to <rdar://problem/7569620>.
2378 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2379 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2381 // Note that TST/TEQ don't set all the same flags that CMP does!
2382 defm TST : AI1_cmp_irs<0b1000, "tst",
2383 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2384 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2385 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2386 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2387 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2389 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2390 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2391 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2392 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2393 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2394 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2396 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2397 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2399 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2400 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2402 // Pseudo i64 compares for some floating point compares.
2403 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2405 def BCCi64 : PseudoInst<(outs),
2406 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2408 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2410 def BCCZi64 : PseudoInst<(outs),
2411 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2412 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2413 } // usesCustomInserter
2416 // Conditional moves
2417 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2418 // a two-value operand where a dag node expects two operands. :(
2419 let neverHasSideEffects = 1 in {
2420 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2421 IIC_iCMOVr, "mov", "\t$dst, $true",
2422 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2423 RegConstraint<"$false = $dst">, UnaryDP {
2424 let Inst{11-4} = 0b00000000;
2428 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2429 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2430 "mov", "\t$dst, $true",
2431 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2432 RegConstraint<"$false = $dst">, UnaryDP {
2436 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2437 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2438 "mov", "\t$dst, $true",
2439 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2440 RegConstraint<"$false = $dst">, UnaryDP {
2443 } // neverHasSideEffects
2445 //===----------------------------------------------------------------------===//
2446 // Atomic operations intrinsics
2449 // memory barriers protect the atomic sequences
2450 let hasSideEffects = 1 in {
2451 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2452 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2453 let Inst{31-4} = 0xf57ff05;
2454 // FIXME: add support for options other than a full system DMB
2455 // See DMB disassembly-only variants below.
2456 let Inst{3-0} = 0b1111;
2459 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2460 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2461 let Inst{31-4} = 0xf57ff04;
2462 // FIXME: add support for options other than a full system DSB
2463 // See DSB disassembly-only variants below.
2464 let Inst{3-0} = 0b1111;
2467 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2468 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2469 [(ARMMemBarrierMCR GPR:$zero)]>,
2470 Requires<[IsARM, HasV6]> {
2471 // FIXME: add support for options other than a full system DMB
2472 // FIXME: add encoding
2475 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2476 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2477 [(ARMSyncBarrierMCR GPR:$zero)]>,
2478 Requires<[IsARM, HasV6]> {
2479 // FIXME: add support for options other than a full system DSB
2480 // FIXME: add encoding
2484 // Memory Barrier Operations Variants -- for disassembly only
2486 def memb_opt : Operand<i32> {
2487 let PrintMethod = "printMemBOption";
2490 class AMBI<bits<4> op7_4, string opc>
2491 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2492 [/* For disassembly only; pattern left blank */]>,
2493 Requires<[IsARM, HasDB]> {
2494 let Inst{31-8} = 0xf57ff0;
2495 let Inst{7-4} = op7_4;
2498 // These DMB variants are for disassembly only.
2499 def DMBvar : AMBI<0b0101, "dmb">;
2501 // These DSB variants are for disassembly only.
2502 def DSBvar : AMBI<0b0100, "dsb">;
2504 // ISB has only full system option -- for disassembly only
2505 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2506 Requires<[IsARM, HasDB]> {
2507 let Inst{31-4} = 0xf57ff06;
2508 let Inst{3-0} = 0b1111;
2511 let usesCustomInserter = 1 in {
2512 let Uses = [CPSR] in {
2513 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2514 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2515 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2516 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2517 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2518 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2519 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2520 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2521 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2522 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2523 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2524 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2525 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2526 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2527 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2528 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2529 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2530 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2531 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2532 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2533 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2534 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2535 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2536 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2537 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2538 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2539 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2540 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2541 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2542 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2543 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2544 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2545 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2546 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2547 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2548 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2549 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2550 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2551 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2552 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2553 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2554 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2555 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2556 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2557 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2558 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2559 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2560 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2561 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2562 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2563 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2564 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2565 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2566 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2568 def ATOMIC_SWAP_I8 : PseudoInst<
2569 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2570 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2571 def ATOMIC_SWAP_I16 : PseudoInst<
2572 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2573 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2574 def ATOMIC_SWAP_I32 : PseudoInst<
2575 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2576 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2578 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2579 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2580 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2581 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2582 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2583 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2584 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2585 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2586 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2590 let mayLoad = 1 in {
2591 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2592 "ldrexb", "\t$dest, [$ptr]",
2594 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2595 "ldrexh", "\t$dest, [$ptr]",
2597 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2598 "ldrex", "\t$dest, [$ptr]",
2600 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2602 "ldrexd", "\t$dest, $dest2, [$ptr]",
2606 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2607 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2609 "strexb", "\t$success, $src, [$ptr]",
2611 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2613 "strexh", "\t$success, $src, [$ptr]",
2615 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2617 "strex", "\t$success, $src, [$ptr]",
2619 def STREXD : AIstrex<0b01, (outs GPR:$success),
2620 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2622 "strexd", "\t$success, $src, $src2, [$ptr]",
2626 // Clear-Exclusive is for disassembly only.
2627 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2628 [/* For disassembly only; pattern left blank */]>,
2629 Requires<[IsARM, HasV7]> {
2630 let Inst{31-20} = 0xf57;
2631 let Inst{7-4} = 0b0001;
2634 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2635 let mayLoad = 1 in {
2636 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2637 "swp", "\t$dst, $src, [$ptr]",
2638 [/* For disassembly only; pattern left blank */]> {
2639 let Inst{27-23} = 0b00010;
2640 let Inst{22} = 0; // B = 0
2641 let Inst{21-20} = 0b00;
2642 let Inst{7-4} = 0b1001;
2645 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2646 "swpb", "\t$dst, $src, [$ptr]",
2647 [/* For disassembly only; pattern left blank */]> {
2648 let Inst{27-23} = 0b00010;
2649 let Inst{22} = 1; // B = 1
2650 let Inst{21-20} = 0b00;
2651 let Inst{7-4} = 0b1001;
2655 //===----------------------------------------------------------------------===//
2659 // __aeabi_read_tp preserves the registers r1-r3.
2661 Defs = [R0, R12, LR, CPSR] in {
2662 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2663 "bl\t__aeabi_read_tp",
2664 [(set R0, ARMthread_pointer)]>;
2667 //===----------------------------------------------------------------------===//
2668 // SJLJ Exception handling intrinsics
2669 // eh_sjlj_setjmp() is an instruction sequence to store the return
2670 // address and save #0 in R0 for the non-longjmp case.
2671 // Since by its nature we may be coming from some other function to get
2672 // here, and we're using the stack frame for the containing function to
2673 // save/restore registers, we can't keep anything live in regs across
2674 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2675 // when we get here from a longjmp(). We force everthing out of registers
2676 // except for our own input by listing the relevant registers in Defs. By
2677 // doing so, we also cause the prologue/epilogue code to actively preserve
2678 // all of the callee-saved resgisters, which is exactly what we want.
2679 // A constant value is passed in $val, and we use the location as a scratch.
2681 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2682 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2683 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2684 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2685 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2686 AddrModeNone, SizeSpecial, IndexModeNone,
2687 Pseudo, NoItinerary, "", "",
2688 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2689 Requires<[IsARM, HasVFP2]>;
2693 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2694 hasSideEffects = 1, isBarrier = 1 in {
2695 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2696 AddrModeNone, SizeSpecial, IndexModeNone,
2697 Pseudo, NoItinerary, "", "",
2698 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2699 Requires<[IsARM, NoVFP]>;
2702 // FIXME: Non-Darwin version(s)
2703 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
2704 Defs = [ R7, LR, SP ] in {
2705 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
2706 AddrModeNone, SizeSpecial, IndexModeNone,
2707 Pseudo, NoItinerary, "", "",
2708 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
2709 Requires<[IsARM, IsDarwin]>;
2712 //===----------------------------------------------------------------------===//
2713 // Non-Instruction Patterns
2716 // Large immediate handling.
2718 // Two piece so_imms.
2719 // FIXME: Expand this in ARMExpandPseudoInsts.
2720 // FIXME: Remove this when we can do generalized remat.
2721 let isReMaterializable = 1 in
2722 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2723 Pseudo, IIC_iMOVix2,
2724 "mov", "\t$dst, $src",
2725 [(set GPR:$dst, so_imm2part:$src)]>,
2726 Requires<[IsARM, NoV6T2]>;
2728 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2729 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2730 (so_imm2part_2 imm:$RHS))>;
2731 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2732 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2733 (so_imm2part_2 imm:$RHS))>;
2734 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2735 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2736 (so_imm2part_2 imm:$RHS))>;
2737 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2738 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2739 (so_neg_imm2part_2 imm:$RHS))>;
2741 // 32-bit immediate using movw + movt.
2742 // This is a single pseudo instruction, the benefit is that it can be remat'd
2743 // as a single unit instead of having to handle reg inputs.
2744 // FIXME: Remove this when we can do generalized remat.
2745 let isReMaterializable = 1 in
2746 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVix2,
2747 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2748 [(set GPR:$dst, (i32 imm:$src))]>,
2749 Requires<[IsARM, HasV6T2]>;
2751 // ConstantPool, GlobalAddress, and JumpTable
2752 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2753 Requires<[IsARM, DontUseMovt]>;
2754 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2755 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2756 Requires<[IsARM, UseMovt]>;
2757 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2758 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2760 // TODO: add,sub,and, 3-instr forms?
2763 def : ARMPat<(ARMtcret tcGPR:$dst),
2764 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
2766 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2767 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2769 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2770 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2772 def : ARMPat<(ARMtcret tcGPR:$dst),
2773 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
2775 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2776 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2778 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2779 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2782 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2783 Requires<[IsARM, IsNotDarwin]>;
2784 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2785 Requires<[IsARM, IsDarwin]>;
2787 // zextload i1 -> zextload i8
2788 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2790 // extload -> zextload
2791 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2792 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2793 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2795 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2796 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2799 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2800 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2801 (SMULBB GPR:$a, GPR:$b)>;
2802 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2803 (SMULBB GPR:$a, GPR:$b)>;
2804 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2805 (sra GPR:$b, (i32 16))),
2806 (SMULBT GPR:$a, GPR:$b)>;
2807 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2808 (SMULBT GPR:$a, GPR:$b)>;
2809 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2810 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2811 (SMULTB GPR:$a, GPR:$b)>;
2812 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2813 (SMULTB GPR:$a, GPR:$b)>;
2814 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2816 (SMULWB GPR:$a, GPR:$b)>;
2817 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2818 (SMULWB GPR:$a, GPR:$b)>;
2820 def : ARMV5TEPat<(add GPR:$acc,
2821 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2822 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2823 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2824 def : ARMV5TEPat<(add GPR:$acc,
2825 (mul sext_16_node:$a, sext_16_node:$b)),
2826 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2827 def : ARMV5TEPat<(add GPR:$acc,
2828 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2829 (sra GPR:$b, (i32 16)))),
2830 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2831 def : ARMV5TEPat<(add GPR:$acc,
2832 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2833 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2834 def : ARMV5TEPat<(add GPR:$acc,
2835 (mul (sra GPR:$a, (i32 16)),
2836 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2837 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2838 def : ARMV5TEPat<(add GPR:$acc,
2839 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2840 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2841 def : ARMV5TEPat<(add GPR:$acc,
2842 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2844 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2845 def : ARMV5TEPat<(add GPR:$acc,
2846 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2847 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2849 //===----------------------------------------------------------------------===//
2853 include "ARMInstrThumb.td"
2855 //===----------------------------------------------------------------------===//
2859 include "ARMInstrThumb2.td"
2861 //===----------------------------------------------------------------------===//
2862 // Floating Point Support
2865 include "ARMInstrVFP.td"
2867 //===----------------------------------------------------------------------===//
2868 // Advanced SIMD (NEON) Support
2871 include "ARMInstrNEON.td"
2873 //===----------------------------------------------------------------------===//
2874 // Coprocessor Instructions. For disassembly only.
2877 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2878 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2879 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2880 [/* For disassembly only; pattern left blank */]> {
2884 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2885 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2886 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2887 [/* For disassembly only; pattern left blank */]> {
2888 let Inst{31-28} = 0b1111;
2892 class ACI<dag oops, dag iops, string opc, string asm>
2893 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2894 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2895 let Inst{27-25} = 0b110;
2898 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2900 def _OFFSET : ACI<(outs),
2901 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2902 opc, "\tp$cop, cr$CRd, $addr"> {
2903 let Inst{31-28} = op31_28;
2904 let Inst{24} = 1; // P = 1
2905 let Inst{21} = 0; // W = 0
2906 let Inst{22} = 0; // D = 0
2907 let Inst{20} = load;
2910 def _PRE : ACI<(outs),
2911 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2912 opc, "\tp$cop, cr$CRd, $addr!"> {
2913 let Inst{31-28} = op31_28;
2914 let Inst{24} = 1; // P = 1
2915 let Inst{21} = 1; // W = 1
2916 let Inst{22} = 0; // D = 0
2917 let Inst{20} = load;
2920 def _POST : ACI<(outs),
2921 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2922 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2923 let Inst{31-28} = op31_28;
2924 let Inst{24} = 0; // P = 0
2925 let Inst{21} = 1; // W = 1
2926 let Inst{22} = 0; // D = 0
2927 let Inst{20} = load;
2930 def _OPTION : ACI<(outs),
2931 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2932 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2933 let Inst{31-28} = op31_28;
2934 let Inst{24} = 0; // P = 0
2935 let Inst{23} = 1; // U = 1
2936 let Inst{21} = 0; // W = 0
2937 let Inst{22} = 0; // D = 0
2938 let Inst{20} = load;
2941 def L_OFFSET : ACI<(outs),
2942 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2943 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
2944 let Inst{31-28} = op31_28;
2945 let Inst{24} = 1; // P = 1
2946 let Inst{21} = 0; // W = 0
2947 let Inst{22} = 1; // D = 1
2948 let Inst{20} = load;
2951 def L_PRE : ACI<(outs),
2952 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2953 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
2954 let Inst{31-28} = op31_28;
2955 let Inst{24} = 1; // P = 1
2956 let Inst{21} = 1; // W = 1
2957 let Inst{22} = 1; // D = 1
2958 let Inst{20} = load;
2961 def L_POST : ACI<(outs),
2962 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2963 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
2964 let Inst{31-28} = op31_28;
2965 let Inst{24} = 0; // P = 0
2966 let Inst{21} = 1; // W = 1
2967 let Inst{22} = 1; // D = 1
2968 let Inst{20} = load;
2971 def L_OPTION : ACI<(outs),
2972 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2973 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
2974 let Inst{31-28} = op31_28;
2975 let Inst{24} = 0; // P = 0
2976 let Inst{23} = 1; // U = 1
2977 let Inst{21} = 0; // W = 0
2978 let Inst{22} = 1; // D = 1
2979 let Inst{20} = load;
2983 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2984 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2985 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2986 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2988 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2989 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2990 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2991 [/* For disassembly only; pattern left blank */]> {
2996 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2997 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2998 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2999 [/* For disassembly only; pattern left blank */]> {
3000 let Inst{31-28} = 0b1111;
3005 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3006 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3007 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3008 [/* For disassembly only; pattern left blank */]> {
3013 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3014 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3015 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3016 [/* For disassembly only; pattern left blank */]> {
3017 let Inst{31-28} = 0b1111;
3022 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3023 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3024 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3025 [/* For disassembly only; pattern left blank */]> {
3026 let Inst{23-20} = 0b0100;
3029 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3030 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3031 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3032 [/* For disassembly only; pattern left blank */]> {
3033 let Inst{31-28} = 0b1111;
3034 let Inst{23-20} = 0b0100;
3037 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3038 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3039 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3040 [/* For disassembly only; pattern left blank */]> {
3041 let Inst{23-20} = 0b0101;
3044 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3045 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3046 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3047 [/* For disassembly only; pattern left blank */]> {
3048 let Inst{31-28} = 0b1111;
3049 let Inst{23-20} = 0b0101;
3052 //===----------------------------------------------------------------------===//
3053 // Move between special register and ARM core register -- for disassembly only
3056 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3057 [/* For disassembly only; pattern left blank */]> {
3058 let Inst{23-20} = 0b0000;
3059 let Inst{7-4} = 0b0000;
3062 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3063 [/* For disassembly only; pattern left blank */]> {
3064 let Inst{23-20} = 0b0100;
3065 let Inst{7-4} = 0b0000;
3068 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3069 "msr", "\tcpsr$mask, $src",
3070 [/* For disassembly only; pattern left blank */]> {
3071 let Inst{23-20} = 0b0010;
3072 let Inst{7-4} = 0b0000;
3075 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3076 "msr", "\tcpsr$mask, $a",
3077 [/* For disassembly only; pattern left blank */]> {
3078 let Inst{23-20} = 0b0010;
3079 let Inst{7-4} = 0b0000;
3082 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3083 "msr", "\tspsr$mask, $src",
3084 [/* For disassembly only; pattern left blank */]> {
3085 let Inst{23-20} = 0b0110;
3086 let Inst{7-4} = 0b0000;
3089 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3090 "msr", "\tspsr$mask, $a",
3091 [/* For disassembly only; pattern left blank */]> {
3092 let Inst{23-20} = 0b0110;
3093 let Inst{7-4} = 0b0000;