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()">;
178 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
180 //===----------------------------------------------------------------------===//
181 // ARM Flag Definitions.
183 class RegConstraint<string C> {
184 string Constraints = C;
187 //===----------------------------------------------------------------------===//
188 // ARM specific transformation functions and pattern fragments.
191 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
192 // so_imm_neg def below.
193 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
194 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
197 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
198 // so_imm_not def below.
199 def so_imm_not_XFORM : SDNodeXForm<imm, [{
200 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
203 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
204 def rot_imm : PatLeaf<(i32 imm), [{
205 int32_t v = (int32_t)N->getZExtValue();
206 return v == 8 || v == 16 || v == 24;
209 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
210 def imm1_15 : PatLeaf<(i32 imm), [{
211 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
214 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
215 def imm16_31 : PatLeaf<(i32 imm), [{
216 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
221 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
222 }], so_imm_neg_XFORM>;
226 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
227 }], so_imm_not_XFORM>;
229 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
230 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
231 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
234 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
236 def bf_inv_mask_imm : Operand<i32>,
238 return ARM::isBitFieldInvertedMask(N->getZExtValue());
240 let PrintMethod = "printBitfieldInvMaskImmOperand";
243 /// Split a 32-bit immediate into two 16 bit parts.
244 def hi16 : SDNodeXForm<imm, [{
245 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
248 def lo16AllZero : PatLeaf<(i32 imm), [{
249 // Returns true if all low 16-bits are 0.
250 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
253 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
255 def imm0_65535 : PatLeaf<(i32 imm), [{
256 return (uint32_t)N->getZExtValue() < 65536;
259 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
260 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
262 /// adde and sube predicates - True based on whether the carry flag output
263 /// will be needed or not.
264 def adde_dead_carry :
265 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
266 [{return !N->hasAnyUseOfValue(1);}]>;
267 def sube_dead_carry :
268 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
269 [{return !N->hasAnyUseOfValue(1);}]>;
270 def adde_live_carry :
271 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
272 [{return N->hasAnyUseOfValue(1);}]>;
273 def sube_live_carry :
274 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
275 [{return N->hasAnyUseOfValue(1);}]>;
277 //===----------------------------------------------------------------------===//
278 // Operand Definitions.
282 def brtarget : Operand<OtherVT>;
284 // A list of registers separated by comma. Used by load/store multiple.
285 def reglist : Operand<i32> {
286 let PrintMethod = "printRegisterList";
289 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
290 def cpinst_operand : Operand<i32> {
291 let PrintMethod = "printCPInstOperand";
294 def jtblock_operand : Operand<i32> {
295 let PrintMethod = "printJTBlockOperand";
297 def jt2block_operand : Operand<i32> {
298 let PrintMethod = "printJT2BlockOperand";
302 def pclabel : Operand<i32> {
303 let PrintMethod = "printPCLabel";
306 // shift_imm: An integer that encodes a shift amount and the type of shift
307 // (currently either asr or lsl) using the same encoding used for the
308 // immediates in so_reg operands.
309 def shift_imm : Operand<i32> {
310 let PrintMethod = "printShiftImmOperand";
313 // shifter_operand operands: so_reg and so_imm.
314 def so_reg : Operand<i32>, // reg reg imm
315 ComplexPattern<i32, 3, "SelectShifterOperandReg",
316 [shl,srl,sra,rotr]> {
317 let PrintMethod = "printSORegOperand";
318 let MIOperandInfo = (ops GPR, GPR, i32imm);
321 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
322 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
323 // represented in the imm field in the same 12-bit form that they are encoded
324 // into so_imm instructions: the 8-bit immediate is the least significant bits
325 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
326 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
327 let PrintMethod = "printSOImmOperand";
330 // Break so_imm's up into two pieces. This handles immediates with up to 16
331 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
332 // get the first/second pieces.
333 def so_imm2part : Operand<i32>,
335 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
337 let PrintMethod = "printSOImm2PartOperand";
340 def so_imm2part_1 : SDNodeXForm<imm, [{
341 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
342 return CurDAG->getTargetConstant(V, MVT::i32);
345 def so_imm2part_2 : SDNodeXForm<imm, [{
346 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
347 return CurDAG->getTargetConstant(V, MVT::i32);
350 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
351 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
353 let PrintMethod = "printSOImm2PartOperand";
356 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
357 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
358 return CurDAG->getTargetConstant(V, MVT::i32);
361 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
362 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
363 return CurDAG->getTargetConstant(V, MVT::i32);
366 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
367 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
368 return (int32_t)N->getZExtValue() < 32;
371 // Define ARM specific addressing modes.
373 // addrmode2 := reg +/- reg shop imm
374 // addrmode2 := reg +/- imm12
376 def addrmode2 : Operand<i32>,
377 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
378 let PrintMethod = "printAddrMode2Operand";
379 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
382 def am2offset : Operand<i32>,
383 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
384 let PrintMethod = "printAddrMode2OffsetOperand";
385 let MIOperandInfo = (ops GPR, i32imm);
388 // addrmode3 := reg +/- reg
389 // addrmode3 := reg +/- imm8
391 def addrmode3 : Operand<i32>,
392 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
393 let PrintMethod = "printAddrMode3Operand";
394 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
397 def am3offset : Operand<i32>,
398 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
399 let PrintMethod = "printAddrMode3OffsetOperand";
400 let MIOperandInfo = (ops GPR, i32imm);
403 // addrmode4 := reg, <mode|W>
405 def addrmode4 : Operand<i32>,
406 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
407 let PrintMethod = "printAddrMode4Operand";
408 let MIOperandInfo = (ops GPR:$addr, i32imm);
411 // addrmode5 := reg +/- imm8*4
413 def addrmode5 : Operand<i32>,
414 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
415 let PrintMethod = "printAddrMode5Operand";
416 let MIOperandInfo = (ops GPR:$base, i32imm);
419 // addrmode6 := reg with optional writeback
421 def addrmode6 : Operand<i32>,
422 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
423 let PrintMethod = "printAddrMode6Operand";
424 let MIOperandInfo = (ops GPR:$addr, i32imm);
427 def am6offset : Operand<i32> {
428 let PrintMethod = "printAddrMode6OffsetOperand";
429 let MIOperandInfo = (ops GPR);
432 // addrmodepc := pc + reg
434 def addrmodepc : Operand<i32>,
435 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
436 let PrintMethod = "printAddrModePCOperand";
437 let MIOperandInfo = (ops GPR, i32imm);
440 def nohash_imm : Operand<i32> {
441 let PrintMethod = "printNoHashImmediate";
444 //===----------------------------------------------------------------------===//
446 include "ARMInstrFormats.td"
448 //===----------------------------------------------------------------------===//
449 // Multiclass helpers...
452 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
453 /// binop that produces a value.
454 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
455 bit Commutable = 0> {
456 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
457 IIC_iALUi, opc, "\t$dst, $a, $b",
458 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
461 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
462 IIC_iALUr, opc, "\t$dst, $a, $b",
463 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
464 let Inst{11-4} = 0b00000000;
466 let isCommutable = Commutable;
468 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
469 IIC_iALUsr, opc, "\t$dst, $a, $b",
470 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
475 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
476 /// instruction modifies the CPSR register.
477 let Defs = [CPSR] in {
478 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
479 bit Commutable = 0> {
480 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
481 IIC_iALUi, opc, "\t$dst, $a, $b",
482 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
486 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
487 IIC_iALUr, opc, "\t$dst, $a, $b",
488 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
489 let isCommutable = Commutable;
490 let Inst{11-4} = 0b00000000;
494 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
495 IIC_iALUsr, opc, "\t$dst, $a, $b",
496 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
503 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
504 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
505 /// a explicit result, only implicitly set CPSR.
506 let isCompare = 1, Defs = [CPSR] in {
507 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
508 bit Commutable = 0> {
509 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
511 [(opnode GPR:$a, so_imm:$b)]> {
515 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
517 [(opnode GPR:$a, GPR:$b)]> {
518 let Inst{11-4} = 0b00000000;
521 let isCommutable = Commutable;
523 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
525 [(opnode GPR:$a, so_reg:$b)]> {
532 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
533 /// register and one whose operand is a register rotated by 8/16/24.
534 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
535 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
536 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
537 IIC_iUNAr, opc, "\t$dst, $src",
538 [(set GPR:$dst, (opnode GPR:$src))]>,
539 Requires<[IsARM, HasV6]> {
540 let Inst{11-10} = 0b00;
541 let Inst{19-16} = 0b1111;
543 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
544 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
545 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
546 Requires<[IsARM, HasV6]> {
547 let Inst{19-16} = 0b1111;
551 multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
552 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
553 IIC_iUNAr, opc, "\t$dst, $src",
554 [/* For disassembly only; pattern left blank */]>,
555 Requires<[IsARM, HasV6]> {
556 let Inst{11-10} = 0b00;
557 let Inst{19-16} = 0b1111;
559 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
560 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
561 [/* For disassembly only; pattern left blank */]>,
562 Requires<[IsARM, HasV6]> {
563 let Inst{19-16} = 0b1111;
567 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
568 /// register and one whose operand is a register rotated by 8/16/24.
569 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
570 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
571 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
572 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
573 Requires<[IsARM, HasV6]> {
574 let Inst{11-10} = 0b00;
576 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
578 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
579 [(set GPR:$dst, (opnode GPR:$LHS,
580 (rotr GPR:$RHS, rot_imm:$rot)))]>,
581 Requires<[IsARM, HasV6]>;
584 // For disassembly only.
585 multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
586 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
587 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
588 [/* For disassembly only; pattern left blank */]>,
589 Requires<[IsARM, HasV6]> {
590 let Inst{11-10} = 0b00;
592 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
594 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
595 [/* For disassembly only; pattern left blank */]>,
596 Requires<[IsARM, HasV6]>;
599 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
600 let Uses = [CPSR] in {
601 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
602 bit Commutable = 0> {
603 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
604 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
605 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
609 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
610 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
611 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
613 let isCommutable = Commutable;
614 let Inst{11-4} = 0b00000000;
617 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
618 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
619 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
624 // Carry setting variants
625 let Defs = [CPSR] in {
626 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
627 bit Commutable = 0> {
628 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
629 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
630 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
635 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
636 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
637 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
639 let Inst{11-4} = 0b00000000;
643 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
644 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
645 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
654 //===----------------------------------------------------------------------===//
656 //===----------------------------------------------------------------------===//
658 //===----------------------------------------------------------------------===//
659 // Miscellaneous Instructions.
662 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
663 /// the function. The first operand is the ID# for this instruction, the second
664 /// is the index into the MachineConstantPool that this is, the third is the
665 /// size in bytes of this constant pool entry.
666 let neverHasSideEffects = 1, isNotDuplicable = 1 in
667 def CONSTPOOL_ENTRY :
668 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
669 i32imm:$size), NoItinerary,
670 "${instid:label} ${cpidx:cpentry}", []>;
672 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
673 // from removing one half of the matched pairs. That breaks PEI, which assumes
674 // these will always be in pairs, and asserts if it finds otherwise. Better way?
675 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
677 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
678 "${:comment} ADJCALLSTACKUP $amt1",
679 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
681 def ADJCALLSTACKDOWN :
682 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
683 "${:comment} ADJCALLSTACKDOWN $amt",
684 [(ARMcallseq_start timm:$amt)]>;
687 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
688 [/* For disassembly only; pattern left blank */]>,
689 Requires<[IsARM, HasV6T2]> {
690 let Inst{27-16} = 0b001100100000;
691 let Inst{7-0} = 0b00000000;
694 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
695 [/* For disassembly only; pattern left blank */]>,
696 Requires<[IsARM, HasV6T2]> {
697 let Inst{27-16} = 0b001100100000;
698 let Inst{7-0} = 0b00000001;
701 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
702 [/* For disassembly only; pattern left blank */]>,
703 Requires<[IsARM, HasV6T2]> {
704 let Inst{27-16} = 0b001100100000;
705 let Inst{7-0} = 0b00000010;
708 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
709 [/* For disassembly only; pattern left blank */]>,
710 Requires<[IsARM, HasV6T2]> {
711 let Inst{27-16} = 0b001100100000;
712 let Inst{7-0} = 0b00000011;
715 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
717 [/* For disassembly only; pattern left blank */]>,
718 Requires<[IsARM, HasV6]> {
719 let Inst{27-20} = 0b01101000;
720 let Inst{7-4} = 0b1011;
723 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
724 [/* For disassembly only; pattern left blank */]>,
725 Requires<[IsARM, HasV6T2]> {
726 let Inst{27-16} = 0b001100100000;
727 let Inst{7-0} = 0b00000100;
730 // The i32imm operand $val can be used by a debugger to store more information
731 // about the breakpoint.
732 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
733 [/* For disassembly only; pattern left blank */]>,
735 let Inst{27-20} = 0b00010010;
736 let Inst{7-4} = 0b0111;
739 // Change Processor State is a system instruction -- for disassembly only.
740 // The singleton $opt operand contains the following information:
741 // opt{4-0} = mode from Inst{4-0}
742 // opt{5} = changemode from Inst{17}
743 // opt{8-6} = AIF from Inst{8-6}
744 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
745 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
746 [/* For disassembly only; pattern left blank */]>,
748 let Inst{31-28} = 0b1111;
749 let Inst{27-20} = 0b00010000;
754 // Preload signals the memory system of possible future data/instruction access.
755 // These are for disassembly only.
757 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
758 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
759 multiclass APreLoad<bit data, bit read, string opc> {
761 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
762 !strconcat(opc, "\t[$base, $imm]"), []> {
763 let Inst{31-26} = 0b111101;
764 let Inst{25} = 0; // 0 for immediate form
767 let Inst{21-20} = 0b01;
770 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
771 !strconcat(opc, "\t$addr"), []> {
772 let Inst{31-26} = 0b111101;
773 let Inst{25} = 1; // 1 for register form
776 let Inst{21-20} = 0b01;
781 defm PLD : APreLoad<1, 1, "pld">;
782 defm PLDW : APreLoad<1, 0, "pldw">;
783 defm PLI : APreLoad<0, 1, "pli">;
785 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
786 [/* For disassembly only; pattern left blank */]>,
788 let Inst{31-28} = 0b1111;
789 let Inst{27-20} = 0b00010000;
792 let Inst{7-4} = 0b0000;
795 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
796 [/* For disassembly only; pattern left blank */]>,
798 let Inst{31-28} = 0b1111;
799 let Inst{27-20} = 0b00010000;
802 let Inst{7-4} = 0b0000;
805 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
806 [/* For disassembly only; pattern left blank */]>,
807 Requires<[IsARM, HasV7]> {
808 let Inst{27-16} = 0b001100100000;
809 let Inst{7-4} = 0b1111;
812 // A5.4 Permanently UNDEFINED instructions.
813 // FIXME: Temporary emitted as raw bytes until this pseudo-op will be added to
815 let isBarrier = 1, isTerminator = 1 in
816 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
817 ".long 0xe7ffdefe ${:comment} trap", [(trap)]>,
819 let Inst{27-25} = 0b011;
820 let Inst{24-20} = 0b11111;
821 let Inst{7-5} = 0b111;
825 // Address computation and loads and stores in PIC mode.
826 let isNotDuplicable = 1 in {
827 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
828 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
829 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
831 let AddedComplexity = 10 in {
832 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
833 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
834 [(set GPR:$dst, (load addrmodepc:$addr))]>;
836 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
837 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
838 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
840 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
841 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
842 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
844 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
845 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
846 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
848 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
849 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
850 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
852 let AddedComplexity = 10 in {
853 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
854 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
855 [(store GPR:$src, addrmodepc:$addr)]>;
857 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
858 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
859 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
861 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
862 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
863 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
865 } // isNotDuplicable = 1
868 // LEApcrel - Load a pc-relative address into a register without offending the
870 let neverHasSideEffects = 1 in {
871 let isReMaterializable = 1 in
872 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
874 "adr$p\t$dst, #$label", []>;
876 } // neverHasSideEffects
877 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
878 (ins i32imm:$label, nohash_imm:$id, pred:$p),
880 "adr$p\t$dst, #${label}_${id}", []> {
884 //===----------------------------------------------------------------------===//
885 // Control Flow Instructions.
888 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
890 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
891 "bx", "\tlr", [(ARMretflag)]>,
892 Requires<[IsARM, HasV4T]> {
893 let Inst{3-0} = 0b1110;
894 let Inst{7-4} = 0b0001;
895 let Inst{19-8} = 0b111111111111;
896 let Inst{27-20} = 0b00010010;
900 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
901 "mov", "\tpc, lr", [(ARMretflag)]>,
902 Requires<[IsARM, NoV4T]> {
903 let Inst{11-0} = 0b000000001110;
904 let Inst{15-12} = 0b1111;
905 let Inst{19-16} = 0b0000;
906 let Inst{27-20} = 0b00011010;
911 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
913 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
915 Requires<[IsARM, HasV4T]> {
916 let Inst{7-4} = 0b0001;
917 let Inst{19-8} = 0b111111111111;
918 let Inst{27-20} = 0b00010010;
919 let Inst{31-28} = 0b1110;
923 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
925 Requires<[IsARM, NoV4T]> {
926 let Inst{11-4} = 0b00000000;
927 let Inst{15-12} = 0b1111;
928 let Inst{19-16} = 0b0000;
929 let Inst{27-20} = 0b00011010;
930 let Inst{31-28} = 0b1110;
934 // FIXME: remove when we have a way to marking a MI with these properties.
935 // FIXME: Should pc be an implicit operand like PICADD, etc?
936 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
937 hasExtraDefRegAllocReq = 1 in
938 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
939 reglist:$dsts, variable_ops),
940 IndexModeUpd, LdStMulFrm, IIC_Br,
941 "ldm${addr:submode}${p}\t$addr!, $dsts",
942 "$addr.addr = $wb", []>;
944 // On non-Darwin platforms R9 is callee-saved.
946 Defs = [R0, R1, R2, R3, R12, LR,
947 D0, D1, D2, D3, D4, D5, D6, D7,
948 D16, D17, D18, D19, D20, D21, D22, D23,
949 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
950 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
951 IIC_Br, "bl\t${func:call}",
952 [(ARMcall tglobaladdr:$func)]>,
953 Requires<[IsARM, IsNotDarwin]> {
954 let Inst{31-28} = 0b1110;
957 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
958 IIC_Br, "bl", "\t${func:call}",
959 [(ARMcall_pred tglobaladdr:$func)]>,
960 Requires<[IsARM, IsNotDarwin]>;
963 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
964 IIC_Br, "blx\t$func",
965 [(ARMcall GPR:$func)]>,
966 Requires<[IsARM, HasV5T, IsNotDarwin]> {
967 let Inst{7-4} = 0b0011;
968 let Inst{19-8} = 0b111111111111;
969 let Inst{27-20} = 0b00010010;
973 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
974 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
975 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
976 [(ARMcall_nolink tGPR:$func)]>,
977 Requires<[IsARM, HasV4T, IsNotDarwin]> {
978 let Inst{7-4} = 0b0001;
979 let Inst{19-8} = 0b111111111111;
980 let Inst{27-20} = 0b00010010;
984 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
985 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
986 [(ARMcall_nolink tGPR:$func)]>,
987 Requires<[IsARM, NoV4T, IsNotDarwin]> {
988 let Inst{11-4} = 0b00000000;
989 let Inst{15-12} = 0b1111;
990 let Inst{19-16} = 0b0000;
991 let Inst{27-20} = 0b00011010;
995 // On Darwin R9 is call-clobbered.
997 Defs = [R0, R1, R2, R3, R9, R12, LR,
998 D0, D1, D2, D3, D4, D5, D6, D7,
999 D16, D17, D18, D19, D20, D21, D22, D23,
1000 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1001 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1002 IIC_Br, "bl\t${func:call}",
1003 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1004 let Inst{31-28} = 0b1110;
1007 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1008 IIC_Br, "bl", "\t${func:call}",
1009 [(ARMcall_pred tglobaladdr:$func)]>,
1010 Requires<[IsARM, IsDarwin]>;
1013 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1014 IIC_Br, "blx\t$func",
1015 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1016 let Inst{7-4} = 0b0011;
1017 let Inst{19-8} = 0b111111111111;
1018 let Inst{27-20} = 0b00010010;
1022 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1023 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1024 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1025 [(ARMcall_nolink tGPR:$func)]>,
1026 Requires<[IsARM, HasV4T, IsDarwin]> {
1027 let Inst{7-4} = 0b0001;
1028 let Inst{19-8} = 0b111111111111;
1029 let Inst{27-20} = 0b00010010;
1033 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1034 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1035 [(ARMcall_nolink tGPR:$func)]>,
1036 Requires<[IsARM, NoV4T, IsDarwin]> {
1037 let Inst{11-4} = 0b00000000;
1038 let Inst{15-12} = 0b1111;
1039 let Inst{19-16} = 0b0000;
1040 let Inst{27-20} = 0b00011010;
1046 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1048 let Defs = [R0, R1, R2, R3, R9, R12,
1049 D0, D1, D2, D3, D4, D5, D6, D7,
1050 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1051 D27, D28, D29, D30, D31, PC],
1053 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1055 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1057 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1059 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1061 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1062 IIC_Br, "b\t$dst @ TAILCALL",
1063 []>, Requires<[IsDarwin]>;
1065 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1066 IIC_Br, "b.w\t$dst @ TAILCALL",
1067 []>, Requires<[IsDarwin]>;
1069 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1070 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1071 []>, Requires<[IsDarwin]> {
1072 let Inst{7-4} = 0b0001;
1073 let Inst{19-8} = 0b111111111111;
1074 let Inst{27-20} = 0b00010010;
1075 let Inst{31-28} = 0b1110;
1079 // Non-Darwin versions (the difference is R9).
1080 let Defs = [R0, R1, R2, R3, R12,
1081 D0, D1, D2, D3, D4, D5, D6, D7,
1082 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1083 D27, D28, D29, D30, D31, PC],
1085 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1087 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1089 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1091 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1093 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1094 IIC_Br, "b\t$dst @ TAILCALL",
1095 []>, Requires<[IsARM, IsNotDarwin]>;
1097 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1098 IIC_Br, "b.w\t$dst @ TAILCALL",
1099 []>, Requires<[IsThumb, IsNotDarwin]>;
1101 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1102 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1103 []>, Requires<[IsNotDarwin]> {
1104 let Inst{7-4} = 0b0001;
1105 let Inst{19-8} = 0b111111111111;
1106 let Inst{27-20} = 0b00010010;
1107 let Inst{31-28} = 0b1110;
1112 let isBranch = 1, isTerminator = 1 in {
1113 // B is "predicable" since it can be xformed into a Bcc.
1114 let isBarrier = 1 in {
1115 let isPredicable = 1 in
1116 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1117 "b\t$target", [(br bb:$target)]>;
1119 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1120 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1121 IIC_Br, "mov\tpc, $target$jt",
1122 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1123 let Inst{11-4} = 0b00000000;
1124 let Inst{15-12} = 0b1111;
1125 let Inst{20} = 0; // S Bit
1126 let Inst{24-21} = 0b1101;
1127 let Inst{27-25} = 0b000;
1129 def BR_JTm : JTI<(outs),
1130 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1131 IIC_Br, "ldr\tpc, $target$jt",
1132 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1134 let Inst{15-12} = 0b1111;
1135 let Inst{20} = 1; // L bit
1136 let Inst{21} = 0; // W bit
1137 let Inst{22} = 0; // B bit
1138 let Inst{24} = 1; // P bit
1139 let Inst{27-25} = 0b011;
1141 def BR_JTadd : JTI<(outs),
1142 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1143 IIC_Br, "add\tpc, $target, $idx$jt",
1144 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1146 let Inst{15-12} = 0b1111;
1147 let Inst{20} = 0; // S bit
1148 let Inst{24-21} = 0b0100;
1149 let Inst{27-25} = 0b000;
1151 } // isNotDuplicable = 1, isIndirectBranch = 1
1154 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1155 // a two-value operand where a dag node expects two operands. :(
1156 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1157 IIC_Br, "b", "\t$target",
1158 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1161 // Branch and Exchange Jazelle -- for disassembly only
1162 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1163 [/* For disassembly only; pattern left blank */]> {
1164 let Inst{23-20} = 0b0010;
1165 //let Inst{19-8} = 0xfff;
1166 let Inst{7-4} = 0b0010;
1169 // Secure Monitor Call is a system instruction -- for disassembly only
1170 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1171 [/* For disassembly only; pattern left blank */]> {
1172 let Inst{23-20} = 0b0110;
1173 let Inst{7-4} = 0b0111;
1176 // Supervisor Call (Software Interrupt) -- for disassembly only
1178 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1179 [/* For disassembly only; pattern left blank */]>;
1182 // Store Return State is a system instruction -- for disassembly only
1183 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1184 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1185 [/* For disassembly only; pattern left blank */]> {
1186 let Inst{31-28} = 0b1111;
1187 let Inst{22-20} = 0b110; // W = 1
1190 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1191 NoItinerary, "srs${addr:submode}\tsp, $mode",
1192 [/* For disassembly only; pattern left blank */]> {
1193 let Inst{31-28} = 0b1111;
1194 let Inst{22-20} = 0b100; // W = 0
1197 // Return From Exception is a system instruction -- for disassembly only
1198 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1199 NoItinerary, "rfe${addr:submode}\t$base!",
1200 [/* For disassembly only; pattern left blank */]> {
1201 let Inst{31-28} = 0b1111;
1202 let Inst{22-20} = 0b011; // W = 1
1205 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1206 NoItinerary, "rfe${addr:submode}\t$base",
1207 [/* For disassembly only; pattern left blank */]> {
1208 let Inst{31-28} = 0b1111;
1209 let Inst{22-20} = 0b001; // W = 0
1212 //===----------------------------------------------------------------------===//
1213 // Load / store Instructions.
1217 let canFoldAsLoad = 1, isReMaterializable = 1 in
1218 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1219 "ldr", "\t$dst, $addr",
1220 [(set GPR:$dst, (load addrmode2:$addr))]>;
1222 // Special LDR for loads from non-pc-relative constpools.
1223 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1224 isReMaterializable = 1 in
1225 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1226 "ldr", "\t$dst, $addr", []>;
1228 // Loads with zero extension
1229 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1230 IIC_iLoadr, "ldrh", "\t$dst, $addr",
1231 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1233 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1234 IIC_iLoadr, "ldrb", "\t$dst, $addr",
1235 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1237 // Loads with sign extension
1238 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1239 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1240 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1242 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1243 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1244 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1246 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1248 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1249 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1250 []>, Requires<[IsARM, HasV5TE]>;
1253 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1254 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1255 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1257 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1258 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1259 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1261 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1262 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1263 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1265 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1266 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1267 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1269 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1270 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1271 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1273 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1274 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1275 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1277 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1278 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1279 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1281 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1282 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1283 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1285 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1286 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1287 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1289 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1290 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1291 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1293 // For disassembly only
1294 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1295 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1296 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1297 Requires<[IsARM, HasV5TE]>;
1299 // For disassembly only
1300 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1301 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1302 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1303 Requires<[IsARM, HasV5TE]>;
1305 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1307 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1309 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1310 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1311 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1312 let Inst{21} = 1; // overwrite
1315 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1316 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1317 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1318 let Inst{21} = 1; // overwrite
1321 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1322 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1323 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1324 let Inst{21} = 1; // overwrite
1327 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1328 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1329 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1330 let Inst{21} = 1; // overwrite
1333 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1334 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1335 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1336 let Inst{21} = 1; // overwrite
1340 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1341 "str", "\t$src, $addr",
1342 [(store GPR:$src, addrmode2:$addr)]>;
1344 // Stores with truncate
1345 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1346 IIC_iStorer, "strh", "\t$src, $addr",
1347 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1349 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1350 "strb", "\t$src, $addr",
1351 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1354 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1355 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1356 StMiscFrm, IIC_iStorer,
1357 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1360 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1361 (ins GPR:$src, GPR:$base, am2offset:$offset),
1362 StFrm, IIC_iStoreru,
1363 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1365 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1367 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1368 (ins GPR:$src, GPR:$base,am2offset:$offset),
1369 StFrm, IIC_iStoreru,
1370 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1372 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1374 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1375 (ins GPR:$src, GPR:$base,am3offset:$offset),
1376 StMiscFrm, IIC_iStoreru,
1377 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1379 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1381 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1382 (ins GPR:$src, GPR:$base,am3offset:$offset),
1383 StMiscFrm, IIC_iStoreru,
1384 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1385 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1386 GPR:$base, am3offset:$offset))]>;
1388 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1389 (ins GPR:$src, GPR:$base,am2offset:$offset),
1390 StFrm, IIC_iStoreru,
1391 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1392 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1393 GPR:$base, am2offset:$offset))]>;
1395 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1396 (ins GPR:$src, GPR:$base,am2offset:$offset),
1397 StFrm, IIC_iStoreru,
1398 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1399 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1400 GPR:$base, am2offset:$offset))]>;
1402 // For disassembly only
1403 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1404 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1405 StMiscFrm, IIC_iStoreru,
1406 "strd", "\t$src1, $src2, [$base, $offset]!",
1407 "$base = $base_wb", []>;
1409 // For disassembly only
1410 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1411 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1412 StMiscFrm, IIC_iStoreru,
1413 "strd", "\t$src1, $src2, [$base], $offset",
1414 "$base = $base_wb", []>;
1416 // STRT, STRBT, and STRHT are for disassembly only.
1418 def STRT : AI2stwpo<(outs GPR:$base_wb),
1419 (ins GPR:$src, GPR:$base,am2offset:$offset),
1420 StFrm, IIC_iStoreru,
1421 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1422 [/* For disassembly only; pattern left blank */]> {
1423 let Inst{21} = 1; // overwrite
1426 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1427 (ins GPR:$src, GPR:$base,am2offset:$offset),
1428 StFrm, IIC_iStoreru,
1429 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1430 [/* For disassembly only; pattern left blank */]> {
1431 let Inst{21} = 1; // overwrite
1434 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1435 (ins GPR:$src, GPR:$base,am3offset:$offset),
1436 StMiscFrm, IIC_iStoreru,
1437 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1438 [/* For disassembly only; pattern left blank */]> {
1439 let Inst{21} = 1; // overwrite
1442 //===----------------------------------------------------------------------===//
1443 // Load / store multiple Instructions.
1446 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1447 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1448 reglist:$dsts, variable_ops),
1449 IndexModeNone, LdStMulFrm, IIC_iLoadm,
1450 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1452 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1453 reglist:$dsts, variable_ops),
1454 IndexModeUpd, LdStMulFrm, IIC_iLoadm,
1455 "ldm${addr:submode}${p}\t$addr!, $dsts",
1456 "$addr.addr = $wb", []>;
1457 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1459 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1460 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1461 reglist:$srcs, variable_ops),
1462 IndexModeNone, LdStMulFrm, IIC_iStorem,
1463 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1465 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1466 reglist:$srcs, variable_ops),
1467 IndexModeUpd, LdStMulFrm, IIC_iStorem,
1468 "stm${addr:submode}${p}\t$addr!, $srcs",
1469 "$addr.addr = $wb", []>;
1470 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1472 //===----------------------------------------------------------------------===//
1473 // Move Instructions.
1476 let neverHasSideEffects = 1 in
1477 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1478 "mov", "\t$dst, $src", []>, UnaryDP {
1479 let Inst{11-4} = 0b00000000;
1483 // A version for the smaller set of tail call registers.
1484 let neverHasSideEffects = 1 in
1485 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$dst), (ins tcGPR:$src), DPFrm,
1486 IIC_iMOVr, "mov", "\t$dst, $src", []>, UnaryDP {
1487 let Inst{11-4} = 0b00000000;
1491 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1492 DPSoRegFrm, IIC_iMOVsr,
1493 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1497 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1498 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1499 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1503 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1504 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1506 "movw", "\t$dst, $src",
1507 [(set GPR:$dst, imm0_65535:$src)]>,
1508 Requires<[IsARM, HasV6T2]>, UnaryDP {
1513 let Constraints = "$src = $dst" in
1514 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1516 "movt", "\t$dst, $imm",
1518 (or (and GPR:$src, 0xffff),
1519 lo16AllZero:$imm))]>, UnaryDP,
1520 Requires<[IsARM, HasV6T2]> {
1525 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1526 Requires<[IsARM, HasV6T2]>;
1528 let Uses = [CPSR] in
1529 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1530 "mov", "\t$dst, $src, rrx",
1531 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1533 // These aren't really mov instructions, but we have to define them this way
1534 // due to flag operands.
1536 let Defs = [CPSR] in {
1537 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1538 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1539 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1540 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1541 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1542 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1545 //===----------------------------------------------------------------------===//
1546 // Extend Instructions.
1551 defm SXTB : AI_unary_rrot<0b01101010,
1552 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1553 defm SXTH : AI_unary_rrot<0b01101011,
1554 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1556 defm SXTAB : AI_bin_rrot<0b01101010,
1557 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1558 defm SXTAH : AI_bin_rrot<0b01101011,
1559 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1561 // For disassembly only
1562 defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
1564 // For disassembly only
1565 defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1569 let AddedComplexity = 16 in {
1570 defm UXTB : AI_unary_rrot<0b01101110,
1571 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1572 defm UXTH : AI_unary_rrot<0b01101111,
1573 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1574 defm UXTB16 : AI_unary_rrot<0b01101100,
1575 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1577 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1578 // The transformation should probably be done as a combiner action
1579 // instead so we can include a check for masking back in the upper
1580 // eight bits of the source into the lower eight bits of the result.
1581 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1582 // (UXTB16r_rot GPR:$Src, 24)>;
1583 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1584 (UXTB16r_rot GPR:$Src, 8)>;
1586 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1587 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1588 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1589 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1592 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1593 // For disassembly only
1594 defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1597 def SBFX : I<(outs GPR:$dst),
1598 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1599 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1600 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1601 Requires<[IsARM, HasV6T2]> {
1602 let Inst{27-21} = 0b0111101;
1603 let Inst{6-4} = 0b101;
1606 def UBFX : I<(outs GPR:$dst),
1607 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1608 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1609 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1610 Requires<[IsARM, HasV6T2]> {
1611 let Inst{27-21} = 0b0111111;
1612 let Inst{6-4} = 0b101;
1615 //===----------------------------------------------------------------------===//
1616 // Arithmetic Instructions.
1619 defm ADD : AsI1_bin_irs<0b0100, "add",
1620 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1621 defm SUB : AsI1_bin_irs<0b0010, "sub",
1622 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1624 // ADD and SUB with 's' bit set.
1625 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1626 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1627 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1628 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1630 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1631 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1632 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1633 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1634 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1635 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1636 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1637 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1639 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1640 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1641 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1645 // The reg/reg form is only defined for the disassembler; for codegen it is
1646 // equivalent to SUBrr.
1647 def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
1648 IIC_iALUr, "rsb", "\t$dst, $a, $b",
1649 [/* For disassembly only; pattern left blank */]> {
1651 let Inst{11-4} = 0b00000000;
1654 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1655 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1656 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1660 // RSB with 's' bit set.
1661 let Defs = [CPSR] in {
1662 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1663 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1664 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1668 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1669 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1670 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1676 let Uses = [CPSR] in {
1677 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1678 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1679 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1683 // The reg/reg form is only defined for the disassembler; for codegen it is
1684 // equivalent to SUBrr.
1685 def RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1686 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b",
1687 [/* For disassembly only; pattern left blank */]> {
1689 let Inst{11-4} = 0b00000000;
1691 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1692 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1693 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1699 // FIXME: Allow these to be predicated.
1700 let Defs = [CPSR], Uses = [CPSR] in {
1701 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1702 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1703 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1708 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1709 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1710 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1717 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1718 // The assume-no-carry-in form uses the negation of the input since add/sub
1719 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1720 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1722 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1723 (SUBri GPR:$src, so_imm_neg:$imm)>;
1724 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1725 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1726 // The with-carry-in form matches bitwise not instead of the negation.
1727 // Effectively, the inverse interpretation of the carry flag already accounts
1728 // for part of the negation.
1729 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1730 (SBCri GPR:$src, so_imm_not:$imm)>;
1732 // Note: These are implemented in C++ code, because they have to generate
1733 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1735 // (mul X, 2^n+1) -> (add (X << n), X)
1736 // (mul X, 2^n-1) -> (rsb X, (X << n))
1738 // ARM Arithmetic Instruction -- for disassembly only
1739 // GPR:$dst = GPR:$a op GPR:$b
1740 class AAI<bits<8> op27_20, bits<4> op7_4, string opc,
1741 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
1742 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1743 opc, "\t$dst, $a, $b", pattern> {
1744 let Inst{27-20} = op27_20;
1745 let Inst{7-4} = op7_4;
1748 // Saturating add/subtract -- for disassembly only
1750 def QADD : AAI<0b00010000, 0b0101, "qadd",
1751 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>;
1752 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1753 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1754 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1755 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1756 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1757 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1758 def QSUB : AAI<0b00010010, 0b0101, "qsub",
1759 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>;
1760 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1761 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1762 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1763 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1764 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1765 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1766 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1767 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1769 // Signed/Unsigned add/subtract -- for disassembly only
1771 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1772 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1773 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1774 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1775 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1776 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1777 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1778 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1779 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1780 def USAX : AAI<0b01100101, 0b0101, "usax">;
1781 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1782 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1784 // Signed/Unsigned halving add/subtract -- for disassembly only
1786 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1787 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1788 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1789 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1790 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1791 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1792 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1793 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1794 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1795 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1796 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1797 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1799 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1801 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1802 MulFrm /* for convenience */, NoItinerary, "usad8",
1803 "\t$dst, $a, $b", []>,
1804 Requires<[IsARM, HasV6]> {
1805 let Inst{27-20} = 0b01111000;
1806 let Inst{15-12} = 0b1111;
1807 let Inst{7-4} = 0b0001;
1809 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1810 MulFrm /* for convenience */, NoItinerary, "usada8",
1811 "\t$dst, $a, $b, $acc", []>,
1812 Requires<[IsARM, HasV6]> {
1813 let Inst{27-20} = 0b01111000;
1814 let Inst{7-4} = 0b0001;
1817 // Signed/Unsigned saturate -- for disassembly only
1819 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1820 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1821 [/* For disassembly only; pattern left blank */]> {
1822 let Inst{27-21} = 0b0110101;
1823 let Inst{5-4} = 0b01;
1826 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1827 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1828 [/* For disassembly only; pattern left blank */]> {
1829 let Inst{27-20} = 0b01101010;
1830 let Inst{7-4} = 0b0011;
1833 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1834 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1835 [/* For disassembly only; pattern left blank */]> {
1836 let Inst{27-21} = 0b0110111;
1837 let Inst{5-4} = 0b01;
1840 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1841 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1842 [/* For disassembly only; pattern left blank */]> {
1843 let Inst{27-20} = 0b01101110;
1844 let Inst{7-4} = 0b0011;
1847 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1848 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
1850 //===----------------------------------------------------------------------===//
1851 // Bitwise Instructions.
1854 defm AND : AsI1_bin_irs<0b0000, "and",
1855 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1856 defm ORR : AsI1_bin_irs<0b1100, "orr",
1857 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1858 defm EOR : AsI1_bin_irs<0b0001, "eor",
1859 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1860 defm BIC : AsI1_bin_irs<0b1110, "bic",
1861 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1863 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1864 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1865 "bfc", "\t$dst, $imm", "$src = $dst",
1866 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1867 Requires<[IsARM, HasV6T2]> {
1868 let Inst{27-21} = 0b0111110;
1869 let Inst{6-0} = 0b0011111;
1872 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1873 def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm),
1874 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1875 "bfi", "\t$dst, $val, $imm", "$src = $dst",
1876 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val,
1877 bf_inv_mask_imm:$imm))]>,
1878 Requires<[IsARM, HasV6T2]> {
1879 let Inst{27-21} = 0b0111110;
1880 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1883 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1884 "mvn", "\t$dst, $src",
1885 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1887 let Inst{11-4} = 0b00000000;
1889 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1890 IIC_iMOVsr, "mvn", "\t$dst, $src",
1891 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1894 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1895 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1896 IIC_iMOVi, "mvn", "\t$dst, $imm",
1897 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1901 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1902 (BICri GPR:$src, so_imm_not:$imm)>;
1904 //===----------------------------------------------------------------------===//
1905 // Multiply Instructions.
1908 let isCommutable = 1 in
1909 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1910 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1911 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1913 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1914 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1915 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1917 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1918 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1919 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1920 Requires<[IsARM, HasV6T2]>;
1922 // Extra precision multiplies with low / high results
1923 let neverHasSideEffects = 1 in {
1924 let isCommutable = 1 in {
1925 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1926 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1927 "smull", "\t$ldst, $hdst, $a, $b", []>;
1929 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1930 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1931 "umull", "\t$ldst, $hdst, $a, $b", []>;
1934 // Multiply + accumulate
1935 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1936 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1937 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1939 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1940 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1941 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1943 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1944 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1945 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1946 Requires<[IsARM, HasV6]>;
1947 } // neverHasSideEffects
1949 // Most significant word multiply
1950 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1951 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1952 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1953 Requires<[IsARM, HasV6]> {
1954 let Inst{7-4} = 0b0001;
1955 let Inst{15-12} = 0b1111;
1958 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1959 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1960 [/* For disassembly only; pattern left blank */]>,
1961 Requires<[IsARM, HasV6]> {
1962 let Inst{7-4} = 0b0011; // R = 1
1963 let Inst{15-12} = 0b1111;
1966 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1967 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1968 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1969 Requires<[IsARM, HasV6]> {
1970 let Inst{7-4} = 0b0001;
1973 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1974 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1975 [/* For disassembly only; pattern left blank */]>,
1976 Requires<[IsARM, HasV6]> {
1977 let Inst{7-4} = 0b0011; // R = 1
1980 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1981 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1982 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1983 Requires<[IsARM, HasV6]> {
1984 let Inst{7-4} = 0b1101;
1987 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1988 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1989 [/* For disassembly only; pattern left blank */]>,
1990 Requires<[IsARM, HasV6]> {
1991 let Inst{7-4} = 0b1111; // R = 1
1994 multiclass AI_smul<string opc, PatFrag opnode> {
1995 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1996 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1997 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1998 (sext_inreg GPR:$b, i16)))]>,
1999 Requires<[IsARM, HasV5TE]> {
2004 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2005 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
2006 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2007 (sra GPR:$b, (i32 16))))]>,
2008 Requires<[IsARM, HasV5TE]> {
2013 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2014 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
2015 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2016 (sext_inreg GPR:$b, i16)))]>,
2017 Requires<[IsARM, HasV5TE]> {
2022 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2023 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
2024 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2025 (sra GPR:$b, (i32 16))))]>,
2026 Requires<[IsARM, HasV5TE]> {
2031 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2032 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
2033 [(set GPR:$dst, (sra (opnode GPR:$a,
2034 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
2035 Requires<[IsARM, HasV5TE]> {
2040 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2041 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
2042 [(set GPR:$dst, (sra (opnode GPR:$a,
2043 (sra GPR:$b, (i32 16))), (i32 16)))]>,
2044 Requires<[IsARM, HasV5TE]> {
2051 multiclass AI_smla<string opc, PatFrag opnode> {
2052 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2053 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2054 [(set GPR:$dst, (add GPR:$acc,
2055 (opnode (sext_inreg GPR:$a, i16),
2056 (sext_inreg GPR:$b, i16))))]>,
2057 Requires<[IsARM, HasV5TE]> {
2062 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2063 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2064 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
2065 (sra GPR:$b, (i32 16)))))]>,
2066 Requires<[IsARM, HasV5TE]> {
2071 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2072 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2073 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2074 (sext_inreg GPR:$b, i16))))]>,
2075 Requires<[IsARM, HasV5TE]> {
2080 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2081 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2082 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2083 (sra GPR:$b, (i32 16)))))]>,
2084 Requires<[IsARM, HasV5TE]> {
2089 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2090 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2091 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2092 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
2093 Requires<[IsARM, HasV5TE]> {
2098 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2099 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2100 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2101 (sra GPR:$b, (i32 16))), (i32 16))))]>,
2102 Requires<[IsARM, HasV5TE]> {
2108 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2109 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2111 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2112 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2113 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2114 [/* For disassembly only; pattern left blank */]>,
2115 Requires<[IsARM, HasV5TE]> {
2120 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2121 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2122 [/* For disassembly only; pattern left blank */]>,
2123 Requires<[IsARM, HasV5TE]> {
2128 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2129 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2130 [/* For disassembly only; pattern left blank */]>,
2131 Requires<[IsARM, HasV5TE]> {
2136 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2137 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2138 [/* For disassembly only; pattern left blank */]>,
2139 Requires<[IsARM, HasV5TE]> {
2144 // Helper class for AI_smld -- for disassembly only
2145 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2146 InstrItinClass itin, string opc, string asm>
2147 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2152 let Inst{21-20} = 0b00;
2153 let Inst{22} = long;
2154 let Inst{27-23} = 0b01110;
2157 multiclass AI_smld<bit sub, string opc> {
2159 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2160 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2162 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2163 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2165 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2166 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2168 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2169 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2173 defm SMLA : AI_smld<0, "smla">;
2174 defm SMLS : AI_smld<1, "smls">;
2176 multiclass AI_sdml<bit sub, string opc> {
2178 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2179 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2180 let Inst{15-12} = 0b1111;
2183 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2184 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2185 let Inst{15-12} = 0b1111;
2190 defm SMUA : AI_sdml<0, "smua">;
2191 defm SMUS : AI_sdml<1, "smus">;
2193 //===----------------------------------------------------------------------===//
2194 // Misc. Arithmetic Instructions.
2197 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2198 "clz", "\t$dst, $src",
2199 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2200 let Inst{7-4} = 0b0001;
2201 let Inst{11-8} = 0b1111;
2202 let Inst{19-16} = 0b1111;
2205 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2206 "rbit", "\t$dst, $src",
2207 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2208 Requires<[IsARM, HasV6T2]> {
2209 let Inst{7-4} = 0b0011;
2210 let Inst{11-8} = 0b1111;
2211 let Inst{19-16} = 0b1111;
2214 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2215 "rev", "\t$dst, $src",
2216 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2217 let Inst{7-4} = 0b0011;
2218 let Inst{11-8} = 0b1111;
2219 let Inst{19-16} = 0b1111;
2222 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2223 "rev16", "\t$dst, $src",
2225 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2226 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2227 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2228 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2229 Requires<[IsARM, HasV6]> {
2230 let Inst{7-4} = 0b1011;
2231 let Inst{11-8} = 0b1111;
2232 let Inst{19-16} = 0b1111;
2235 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2236 "revsh", "\t$dst, $src",
2239 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2240 (shl GPR:$src, (i32 8))), i16))]>,
2241 Requires<[IsARM, HasV6]> {
2242 let Inst{7-4} = 0b1011;
2243 let Inst{11-8} = 0b1111;
2244 let Inst{19-16} = 0b1111;
2247 def lsl_shift_imm : SDNodeXForm<imm, [{
2248 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2249 return CurDAG->getTargetConstant(Sh, MVT::i32);
2252 def lsl_amt : PatLeaf<(i32 imm), [{
2253 return (N->getZExtValue() < 32);
2256 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2257 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2258 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2259 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2260 (and (shl GPR:$src2, lsl_amt:$sh),
2262 Requires<[IsARM, HasV6]> {
2263 let Inst{6-4} = 0b001;
2266 // Alternate cases for PKHBT where identities eliminate some nodes.
2267 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2268 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2269 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
2270 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
2272 def asr_shift_imm : SDNodeXForm<imm, [{
2273 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2274 return CurDAG->getTargetConstant(Sh, MVT::i32);
2277 def asr_amt : PatLeaf<(i32 imm), [{
2278 return (N->getZExtValue() <= 32);
2281 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2282 // will match the pattern below.
2283 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2284 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2285 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2286 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2287 (and (sra GPR:$src2, asr_amt:$sh),
2289 Requires<[IsARM, HasV6]> {
2290 let Inst{6-4} = 0b101;
2293 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2294 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2295 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2296 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2297 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2298 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2299 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2301 //===----------------------------------------------------------------------===//
2302 // Comparison Instructions...
2305 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2306 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2308 // FIXME: There seems to be a (potential) hardware bug with the CMN instruction
2309 // and comparison with 0. These two pieces of code should give identical
2325 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2326 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2327 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2328 // value of r0 and the carry bit (because the "carry bit" parameter to
2329 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2330 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2331 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2332 // parameter to AddWithCarry is defined as 0).
2334 // The AddWithCarry in the CMP case seems to be relying upon the identity:
2338 // However when x is 0 and unsigned, this doesn't hold:
2342 // ~x + 1 = 0x1 0000 0000
2343 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2345 // Therefore, we should disable *all* versions of CMN, especially when comparing
2346 // against zero, until we can limit when the CMN instruction is used (when we
2347 // know that the RHS is not 0) or when we have a hardware fix for this.
2349 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2351 // This is related to <rdar://problem/7569620>.
2353 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2354 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2356 // Note that TST/TEQ don't set all the same flags that CMP does!
2357 defm TST : AI1_cmp_irs<0b1000, "tst",
2358 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2359 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2360 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2362 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2363 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2364 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2365 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2367 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2368 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2370 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2371 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2373 // Pseudo i64 compares for some floating point compares.
2374 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2376 def BCCi64 : PseudoInst<(outs),
2377 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2379 "${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, imm:$cc",
2380 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2382 def BCCZi64 : PseudoInst<(outs),
2383 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst),
2385 "${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, 0, 0, imm:$cc",
2386 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2387 } // usesCustomInserter
2390 // Conditional moves
2391 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2392 // a two-value operand where a dag node expects two operands. :(
2393 let neverHasSideEffects = 1 in {
2394 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2395 IIC_iCMOVr, "mov", "\t$dst, $true",
2396 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2397 RegConstraint<"$false = $dst">, UnaryDP {
2398 let Inst{11-4} = 0b00000000;
2402 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2403 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2404 "mov", "\t$dst, $true",
2405 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2406 RegConstraint<"$false = $dst">, UnaryDP {
2410 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2411 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2412 "mov", "\t$dst, $true",
2413 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2414 RegConstraint<"$false = $dst">, UnaryDP {
2417 } // neverHasSideEffects
2419 //===----------------------------------------------------------------------===//
2420 // Atomic operations intrinsics
2423 // memory barriers protect the atomic sequences
2424 let hasSideEffects = 1 in {
2425 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2426 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2427 let Inst{31-4} = 0xf57ff05;
2428 // FIXME: add support for options other than a full system DMB
2429 // See DMB disassembly-only variants below.
2430 let Inst{3-0} = 0b1111;
2433 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2434 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2435 let Inst{31-4} = 0xf57ff04;
2436 // FIXME: add support for options other than a full system DSB
2437 // See DSB disassembly-only variants below.
2438 let Inst{3-0} = 0b1111;
2441 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2442 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2443 [(ARMMemBarrierMCR GPR:$zero)]>,
2444 Requires<[IsARM, HasV6]> {
2445 // FIXME: add support for options other than a full system DMB
2446 // FIXME: add encoding
2449 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2450 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2451 [(ARMSyncBarrierMCR GPR:$zero)]>,
2452 Requires<[IsARM, HasV6]> {
2453 // FIXME: add support for options other than a full system DSB
2454 // FIXME: add encoding
2458 // Memory Barrier Operations Variants -- for disassembly only
2460 def memb_opt : Operand<i32> {
2461 let PrintMethod = "printMemBOption";
2464 class AMBI<bits<4> op7_4, string opc>
2465 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2466 [/* For disassembly only; pattern left blank */]>,
2467 Requires<[IsARM, HasDB]> {
2468 let Inst{31-8} = 0xf57ff0;
2469 let Inst{7-4} = op7_4;
2472 // These DMB variants are for disassembly only.
2473 def DMBvar : AMBI<0b0101, "dmb">;
2475 // These DSB variants are for disassembly only.
2476 def DSBvar : AMBI<0b0100, "dsb">;
2478 // ISB has only full system option -- for disassembly only
2479 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2480 Requires<[IsARM, HasDB]> {
2481 let Inst{31-4} = 0xf57ff06;
2482 let Inst{3-0} = 0b1111;
2485 let usesCustomInserter = 1 in {
2486 let Uses = [CPSR] in {
2487 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2488 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2489 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2490 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2491 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2492 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2493 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2494 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2495 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2496 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2497 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2498 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2499 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2500 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2501 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2502 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2503 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2504 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2505 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2506 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2507 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2508 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2509 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2510 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2511 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2512 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2513 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2514 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2515 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2516 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2517 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2518 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2519 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2520 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2521 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2522 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2523 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2524 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2525 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2526 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2527 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2528 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2529 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2530 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2531 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2532 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2533 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2534 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2535 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2536 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2537 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2538 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2539 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2540 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2541 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2542 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2543 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2544 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2545 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2546 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2547 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2548 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2549 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2550 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2551 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2552 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2553 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2554 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2555 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2556 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2557 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2558 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2560 def ATOMIC_SWAP_I8 : PseudoInst<
2561 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2562 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2563 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2564 def ATOMIC_SWAP_I16 : PseudoInst<
2565 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2566 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2567 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2568 def ATOMIC_SWAP_I32 : PseudoInst<
2569 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2570 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2571 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2573 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2574 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2575 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2576 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2577 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2578 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2579 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2580 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2581 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2582 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2583 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2584 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2588 let mayLoad = 1 in {
2589 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2590 "ldrexb", "\t$dest, [$ptr]",
2592 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2593 "ldrexh", "\t$dest, [$ptr]",
2595 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2596 "ldrex", "\t$dest, [$ptr]",
2598 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2600 "ldrexd", "\t$dest, $dest2, [$ptr]",
2604 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2605 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2607 "strexb", "\t$success, $src, [$ptr]",
2609 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2611 "strexh", "\t$success, $src, [$ptr]",
2613 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2615 "strex", "\t$success, $src, [$ptr]",
2617 def STREXD : AIstrex<0b01, (outs GPR:$success),
2618 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2620 "strexd", "\t$success, $src, $src2, [$ptr]",
2624 // Clear-Exclusive is for disassembly only.
2625 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2626 [/* For disassembly only; pattern left blank */]>,
2627 Requires<[IsARM, HasV7]> {
2628 let Inst{31-20} = 0xf57;
2629 let Inst{7-4} = 0b0001;
2632 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2633 let mayLoad = 1 in {
2634 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2635 "swp", "\t$dst, $src, [$ptr]",
2636 [/* For disassembly only; pattern left blank */]> {
2637 let Inst{27-23} = 0b00010;
2638 let Inst{22} = 0; // B = 0
2639 let Inst{21-20} = 0b00;
2640 let Inst{7-4} = 0b1001;
2643 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2644 "swpb", "\t$dst, $src, [$ptr]",
2645 [/* For disassembly only; pattern left blank */]> {
2646 let Inst{27-23} = 0b00010;
2647 let Inst{22} = 1; // B = 1
2648 let Inst{21-20} = 0b00;
2649 let Inst{7-4} = 0b1001;
2653 //===----------------------------------------------------------------------===//
2657 // __aeabi_read_tp preserves the registers r1-r3.
2659 Defs = [R0, R12, LR, CPSR] in {
2660 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2661 "bl\t__aeabi_read_tp",
2662 [(set R0, ARMthread_pointer)]>;
2665 //===----------------------------------------------------------------------===//
2666 // SJLJ Exception handling intrinsics
2667 // eh_sjlj_setjmp() is an instruction sequence to store the return
2668 // address and save #0 in R0 for the non-longjmp case.
2669 // Since by its nature we may be coming from some other function to get
2670 // here, and we're using the stack frame for the containing function to
2671 // save/restore registers, we can't keep anything live in regs across
2672 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2673 // when we get here from a longjmp(). We force everthing out of registers
2674 // except for our own input by listing the relevant registers in Defs. By
2675 // doing so, we also cause the prologue/epilogue code to actively preserve
2676 // all of the callee-saved resgisters, which is exactly what we want.
2677 // A constant value is passed in $val, and we use the location as a scratch.
2679 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2680 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2681 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2682 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2683 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2684 AddrModeNone, SizeSpecial, IndexModeNone,
2685 Pseudo, NoItinerary,
2686 "add\t$val, pc, #8\t${:comment} eh_setjmp begin\n\t"
2687 "str\t$val, [$src, #+4]\n\t"
2689 "add\tpc, pc, #0\n\t"
2690 "mov\tr0, #1 ${:comment} eh_setjmp end", "",
2691 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2692 Requires<[IsARM, HasVFP2]>;
2696 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2697 hasSideEffects = 1, isBarrier = 1 in {
2698 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2699 AddrModeNone, SizeSpecial, IndexModeNone,
2700 Pseudo, NoItinerary,
2701 "add\t$val, pc, #8\n ${:comment} eh_setjmp begin\n\t"
2702 "str\t$val, [$src, #+4]\n\t"
2704 "add\tpc, pc, #0\n\t"
2705 "mov\tr0, #1 ${:comment} eh_setjmp end", "",
2706 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2707 Requires<[IsARM, NoVFP]>;
2710 // FIXME: Non-Darwin version(s)
2711 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
2712 Defs = [ R7, LR, SP ] in {
2713 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
2714 AddrModeNone, SizeSpecial, IndexModeNone,
2715 Pseudo, NoItinerary,
2716 "ldr\tsp, [$src, #8]\n\t"
2717 "ldr\t$scratch, [$src, #4]\n\t"
2718 "ldr\tr7, [$src]\n\t"
2720 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
2721 Requires<[IsARM, IsDarwin]>;
2724 //===----------------------------------------------------------------------===//
2725 // Non-Instruction Patterns
2728 // Large immediate handling.
2730 // Two piece so_imms.
2731 let isReMaterializable = 1 in
2732 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2734 "mov", "\t$dst, $src",
2735 [(set GPR:$dst, so_imm2part:$src)]>,
2736 Requires<[IsARM, NoV6T2]>;
2738 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2739 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2740 (so_imm2part_2 imm:$RHS))>;
2741 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2742 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2743 (so_imm2part_2 imm:$RHS))>;
2744 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2745 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2746 (so_imm2part_2 imm:$RHS))>;
2747 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2748 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2749 (so_neg_imm2part_2 imm:$RHS))>;
2751 // 32-bit immediate using movw + movt.
2752 // This is a single pseudo instruction, the benefit is that it can be remat'd
2753 // as a single unit instead of having to handle reg inputs.
2754 // FIXME: Remove this when we can do generalized remat.
2755 let isReMaterializable = 1 in
2756 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2757 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2758 [(set GPR:$dst, (i32 imm:$src))]>,
2759 Requires<[IsARM, HasV6T2]>;
2761 // ConstantPool, GlobalAddress, and JumpTable
2762 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2763 Requires<[IsARM, DontUseMovt]>;
2764 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2765 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2766 Requires<[IsARM, UseMovt]>;
2767 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2768 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2770 // TODO: add,sub,and, 3-instr forms?
2773 def : ARMPat<(ARMtcret tcGPR:$dst),
2774 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
2776 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2777 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2779 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2780 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2782 def : ARMPat<(ARMtcret tcGPR:$dst),
2783 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
2785 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2786 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2788 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2789 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2792 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2793 Requires<[IsARM, IsNotDarwin]>;
2794 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2795 Requires<[IsARM, IsDarwin]>;
2797 // zextload i1 -> zextload i8
2798 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2800 // extload -> zextload
2801 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2802 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2803 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2805 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2806 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2809 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2810 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2811 (SMULBB GPR:$a, GPR:$b)>;
2812 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2813 (SMULBB GPR:$a, GPR:$b)>;
2814 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2815 (sra GPR:$b, (i32 16))),
2816 (SMULBT GPR:$a, GPR:$b)>;
2817 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2818 (SMULBT GPR:$a, GPR:$b)>;
2819 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2820 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2821 (SMULTB GPR:$a, GPR:$b)>;
2822 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2823 (SMULTB GPR:$a, GPR:$b)>;
2824 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2826 (SMULWB GPR:$a, GPR:$b)>;
2827 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2828 (SMULWB GPR:$a, GPR:$b)>;
2830 def : ARMV5TEPat<(add GPR:$acc,
2831 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2832 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2833 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2834 def : ARMV5TEPat<(add GPR:$acc,
2835 (mul sext_16_node:$a, sext_16_node:$b)),
2836 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2837 def : ARMV5TEPat<(add GPR:$acc,
2838 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2839 (sra GPR:$b, (i32 16)))),
2840 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2841 def : ARMV5TEPat<(add GPR:$acc,
2842 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2843 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2844 def : ARMV5TEPat<(add GPR:$acc,
2845 (mul (sra GPR:$a, (i32 16)),
2846 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2847 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2848 def : ARMV5TEPat<(add GPR:$acc,
2849 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2850 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2851 def : ARMV5TEPat<(add GPR:$acc,
2852 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2854 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2855 def : ARMV5TEPat<(add GPR:$acc,
2856 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2857 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2859 //===----------------------------------------------------------------------===//
2863 include "ARMInstrThumb.td"
2865 //===----------------------------------------------------------------------===//
2869 include "ARMInstrThumb2.td"
2871 //===----------------------------------------------------------------------===//
2872 // Floating Point Support
2875 include "ARMInstrVFP.td"
2877 //===----------------------------------------------------------------------===//
2878 // Advanced SIMD (NEON) Support
2881 include "ARMInstrNEON.td"
2883 //===----------------------------------------------------------------------===//
2884 // Coprocessor Instructions. For disassembly only.
2887 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2888 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2889 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2890 [/* For disassembly only; pattern left blank */]> {
2894 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2895 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2896 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2897 [/* For disassembly only; pattern left blank */]> {
2898 let Inst{31-28} = 0b1111;
2902 class ACI<dag oops, dag iops, string opc, string asm>
2903 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2904 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2905 let Inst{27-25} = 0b110;
2908 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2910 def _OFFSET : 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} = 0; // W = 0
2916 let Inst{22} = 0; // D = 0
2917 let Inst{20} = load;
2920 def _PRE : ACI<(outs),
2921 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2922 opc, "\tp$cop, cr$CRd, $addr!"> {
2923 let Inst{31-28} = op31_28;
2924 let Inst{24} = 1; // P = 1
2925 let Inst{21} = 1; // W = 1
2926 let Inst{22} = 0; // D = 0
2927 let Inst{20} = load;
2930 def _POST : ACI<(outs),
2931 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2932 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2933 let Inst{31-28} = op31_28;
2934 let Inst{24} = 0; // P = 0
2935 let Inst{21} = 1; // W = 1
2936 let Inst{22} = 0; // D = 0
2937 let Inst{20} = load;
2940 def _OPTION : ACI<(outs),
2941 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2942 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2943 let Inst{31-28} = op31_28;
2944 let Inst{24} = 0; // P = 0
2945 let Inst{23} = 1; // U = 1
2946 let Inst{21} = 0; // W = 0
2947 let Inst{22} = 0; // D = 0
2948 let Inst{20} = load;
2951 def L_OFFSET : 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} = 0; // W = 0
2957 let Inst{22} = 1; // D = 1
2958 let Inst{20} = load;
2961 def L_PRE : ACI<(outs),
2962 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2963 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
2964 let Inst{31-28} = op31_28;
2965 let Inst{24} = 1; // P = 1
2966 let Inst{21} = 1; // W = 1
2967 let Inst{22} = 1; // D = 1
2968 let Inst{20} = load;
2971 def L_POST : ACI<(outs),
2972 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2973 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
2974 let Inst{31-28} = op31_28;
2975 let Inst{24} = 0; // P = 0
2976 let Inst{21} = 1; // W = 1
2977 let Inst{22} = 1; // D = 1
2978 let Inst{20} = load;
2981 def L_OPTION : ACI<(outs),
2982 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2983 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
2984 let Inst{31-28} = op31_28;
2985 let Inst{24} = 0; // P = 0
2986 let Inst{23} = 1; // U = 1
2987 let Inst{21} = 0; // W = 0
2988 let Inst{22} = 1; // D = 1
2989 let Inst{20} = load;
2993 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2994 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2995 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2996 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2998 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2999 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3000 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3001 [/* For disassembly only; pattern left blank */]> {
3006 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3007 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3008 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3009 [/* For disassembly only; pattern left blank */]> {
3010 let Inst{31-28} = 0b1111;
3015 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3016 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3017 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3018 [/* For disassembly only; pattern left blank */]> {
3023 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3024 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3025 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3026 [/* For disassembly only; pattern left blank */]> {
3027 let Inst{31-28} = 0b1111;
3032 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3033 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3034 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3035 [/* For disassembly only; pattern left blank */]> {
3036 let Inst{23-20} = 0b0100;
3039 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3040 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3041 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3042 [/* For disassembly only; pattern left blank */]> {
3043 let Inst{31-28} = 0b1111;
3044 let Inst{23-20} = 0b0100;
3047 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3048 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3049 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3050 [/* For disassembly only; pattern left blank */]> {
3051 let Inst{23-20} = 0b0101;
3054 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3055 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3056 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3057 [/* For disassembly only; pattern left blank */]> {
3058 let Inst{31-28} = 0b1111;
3059 let Inst{23-20} = 0b0101;
3062 //===----------------------------------------------------------------------===//
3063 // Move between special register and ARM core register -- for disassembly only
3066 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3067 [/* For disassembly only; pattern left blank */]> {
3068 let Inst{23-20} = 0b0000;
3069 let Inst{7-4} = 0b0000;
3072 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3073 [/* For disassembly only; pattern left blank */]> {
3074 let Inst{23-20} = 0b0100;
3075 let Inst{7-4} = 0b0000;
3078 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3079 "msr", "\tcpsr$mask, $src",
3080 [/* For disassembly only; pattern left blank */]> {
3081 let Inst{23-20} = 0b0010;
3082 let Inst{7-4} = 0b0000;
3085 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3086 "msr", "\tcpsr$mask, $a",
3087 [/* For disassembly only; pattern left blank */]> {
3088 let Inst{23-20} = 0b0010;
3089 let Inst{7-4} = 0b0000;
3092 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3093 "msr", "\tspsr$mask, $src",
3094 [/* For disassembly only; pattern left blank */]> {
3095 let Inst{23-20} = 0b0110;
3096 let Inst{7-4} = 0b0000;
3099 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3100 "msr", "\tspsr$mask, $a",
3101 [/* For disassembly only; pattern left blank */]> {
3102 let Inst{23-20} = 0b0110;
3103 let Inst{7-4} = 0b0000;