1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>;
62 def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
63 def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
64 def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
66 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
68 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
69 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
72 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
73 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
75 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
76 [SDNPHasChain, SDNPOutFlag]>;
77 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
78 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
80 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
81 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
83 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
84 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
86 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
87 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
90 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
91 [SDNPHasChain, SDNPOptInFlag]>;
93 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
95 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
98 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
99 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
101 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
103 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
106 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
109 def ARMand : SDNode<"ARMISD::AND", SDT_ARMAnd,
112 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
115 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
116 [SDNPOutFlag, SDNPCommutative]>;
118 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
120 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
121 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
122 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
124 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
125 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
126 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
128 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
130 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
132 def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
134 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR,
136 def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR,
139 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
141 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
142 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
145 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
147 //===----------------------------------------------------------------------===//
148 // ARM Instruction Predicate Definitions.
150 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
151 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
152 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
153 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
154 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">;
162 def HasDivide : Predicate<"Subtarget->hasDivide()">;
163 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
164 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
165 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
166 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
167 def IsThumb : Predicate<"Subtarget->isThumb()">;
168 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
169 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
170 def IsARM : Predicate<"!Subtarget->isThumb()">;
171 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
172 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
174 // FIXME: Eventually this will be just "hasV6T2Ops".
175 def UseMovt : Predicate<"Subtarget->useMovt()">;
176 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
177 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
179 //===----------------------------------------------------------------------===//
180 // ARM Flag Definitions.
182 class RegConstraint<string C> {
183 string Constraints = C;
186 //===----------------------------------------------------------------------===//
187 // ARM specific transformation functions and pattern fragments.
190 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
191 // so_imm_neg def below.
192 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
193 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
196 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
197 // so_imm_not def below.
198 def so_imm_not_XFORM : SDNodeXForm<imm, [{
199 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
202 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
203 def rot_imm : PatLeaf<(i32 imm), [{
204 int32_t v = (int32_t)N->getZExtValue();
205 return v == 8 || v == 16 || v == 24;
208 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
209 def imm1_15 : PatLeaf<(i32 imm), [{
210 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
213 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
214 def imm16_31 : PatLeaf<(i32 imm), [{
215 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
220 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
221 }], so_imm_neg_XFORM>;
225 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
226 }], so_imm_not_XFORM>;
228 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
229 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
230 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
233 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
235 def bf_inv_mask_imm : Operand<i32>,
237 return ARM::isBitFieldInvertedMask(N->getZExtValue());
239 let PrintMethod = "printBitfieldInvMaskImmOperand";
242 /// Split a 32-bit immediate into two 16 bit parts.
243 def hi16 : SDNodeXForm<imm, [{
244 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
247 def lo16AllZero : PatLeaf<(i32 imm), [{
248 // Returns true if all low 16-bits are 0.
249 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
252 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
254 def imm0_65535 : PatLeaf<(i32 imm), [{
255 return (uint32_t)N->getZExtValue() < 65536;
258 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
259 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
261 /// adde and sube predicates - True based on whether the carry flag output
262 /// will be needed or not.
263 def adde_dead_carry :
264 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
265 [{return !N->hasAnyUseOfValue(1);}]>;
266 def sube_dead_carry :
267 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
268 [{return !N->hasAnyUseOfValue(1);}]>;
269 def adde_live_carry :
270 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
271 [{return N->hasAnyUseOfValue(1);}]>;
272 def sube_live_carry :
273 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
274 [{return N->hasAnyUseOfValue(1);}]>;
276 //===----------------------------------------------------------------------===//
277 // Operand Definitions.
281 def brtarget : Operand<OtherVT>;
283 // A list of registers separated by comma. Used by load/store multiple.
284 def reglist : Operand<i32> {
285 let PrintMethod = "printRegisterList";
288 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
289 def cpinst_operand : Operand<i32> {
290 let PrintMethod = "printCPInstOperand";
293 def jtblock_operand : Operand<i32> {
294 let PrintMethod = "printJTBlockOperand";
296 def jt2block_operand : Operand<i32> {
297 let PrintMethod = "printJT2BlockOperand";
301 def pclabel : Operand<i32> {
302 let PrintMethod = "printPCLabel";
305 // shift_imm: An integer that encodes a shift amount and the type of shift
306 // (currently either asr or lsl) using the same encoding used for the
307 // immediates in so_reg operands.
308 def shift_imm : Operand<i32> {
309 let PrintMethod = "printShiftImmOperand";
312 // shifter_operand operands: so_reg and so_imm.
313 def so_reg : Operand<i32>, // reg reg imm
314 ComplexPattern<i32, 3, "SelectShifterOperandReg",
315 [shl,srl,sra,rotr]> {
316 string EncoderMethod = "getSORegOpValue";
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 string EncoderMethod = "getSOImmOpValue";
328 let PrintMethod = "printSOImmOperand";
331 // Break so_imm's up into two pieces. This handles immediates with up to 16
332 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
333 // get the first/second pieces.
334 def so_imm2part : Operand<i32>,
336 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
338 let PrintMethod = "printSOImm2PartOperand";
341 def so_imm2part_1 : SDNodeXForm<imm, [{
342 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
343 return CurDAG->getTargetConstant(V, MVT::i32);
346 def so_imm2part_2 : SDNodeXForm<imm, [{
347 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
348 return CurDAG->getTargetConstant(V, MVT::i32);
351 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
352 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
354 let PrintMethod = "printSOImm2PartOperand";
357 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
358 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
359 return CurDAG->getTargetConstant(V, MVT::i32);
362 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
363 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
364 return CurDAG->getTargetConstant(V, MVT::i32);
367 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
368 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
369 return (int32_t)N->getZExtValue() < 32;
372 // Define ARM specific addressing modes.
374 // addrmode2base := reg +/- imm12
376 def addrmode2base : Operand<i32>,
377 ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
378 let PrintMethod = "printAddrMode2Operand";
379 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
381 // addrmode2shop := reg +/- reg shop imm
383 def addrmode2shop : Operand<i32>,
384 ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
385 let PrintMethod = "printAddrMode2Operand";
386 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
389 // addrmode2 := (addrmode2base || addrmode2shop)
391 def addrmode2 : Operand<i32>,
392 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
393 let PrintMethod = "printAddrMode2Operand";
394 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
397 def am2offset : Operand<i32>,
398 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
399 [], [SDNPWantRoot]> {
400 let PrintMethod = "printAddrMode2OffsetOperand";
401 let MIOperandInfo = (ops GPR, i32imm);
404 // addrmode3 := reg +/- reg
405 // addrmode3 := reg +/- imm8
407 def addrmode3 : Operand<i32>,
408 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
409 let PrintMethod = "printAddrMode3Operand";
410 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
413 def am3offset : Operand<i32>,
414 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
415 [], [SDNPWantRoot]> {
416 let PrintMethod = "printAddrMode3OffsetOperand";
417 let MIOperandInfo = (ops GPR, i32imm);
420 // addrmode4 := reg, <mode|W>
422 def addrmode4 : Operand<i32>,
423 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
424 let PrintMethod = "printAddrMode4Operand";
425 let MIOperandInfo = (ops GPR:$addr, i32imm);
428 // addrmode5 := reg +/- imm8*4
430 def addrmode5 : Operand<i32>,
431 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
432 let PrintMethod = "printAddrMode5Operand";
433 let MIOperandInfo = (ops GPR:$base, i32imm);
436 // addrmode6 := reg with optional writeback
438 def addrmode6 : Operand<i32>,
439 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
440 let PrintMethod = "printAddrMode6Operand";
441 let MIOperandInfo = (ops GPR:$addr, i32imm);
444 def am6offset : Operand<i32> {
445 let PrintMethod = "printAddrMode6OffsetOperand";
446 let MIOperandInfo = (ops GPR);
449 // addrmodepc := pc + reg
451 def addrmodepc : Operand<i32>,
452 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
453 let PrintMethod = "printAddrModePCOperand";
454 let MIOperandInfo = (ops GPR, i32imm);
457 def nohash_imm : Operand<i32> {
458 let PrintMethod = "printNoHashImmediate";
461 //===----------------------------------------------------------------------===//
463 include "ARMInstrFormats.td"
465 //===----------------------------------------------------------------------===//
466 // Multiclass helpers...
469 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
470 /// binop that produces a value.
471 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
472 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
473 PatFrag opnode, bit Commutable = 0> {
474 // The register-immediate version is re-materializable. This is useful
475 // in particular for taking the address of a local.
476 let isReMaterializable = 1 in {
477 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
478 iii, opc, "\t$Rd, $Rn, $imm",
479 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
484 let Inst{15-12} = Rd;
485 let Inst{19-16} = Rn;
486 let Inst{11-0} = imm;
489 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
490 iir, opc, "\t$Rd, $Rn, $Rm",
491 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
495 let Inst{11-4} = 0b00000000;
497 let isCommutable = Commutable;
499 let Inst{15-12} = Rd;
500 let Inst{19-16} = Rn;
502 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
503 iis, opc, "\t$Rd, $Rn, $shift",
504 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
509 let Inst{11-0} = shift;
510 let Inst{15-12} = Rd;
511 let Inst{19-16} = Rn;
515 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
516 /// instruction modifies the CPSR register.
517 let Defs = [CPSR] in {
518 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
519 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
520 PatFrag opnode, bit Commutable = 0> {
521 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
522 iii, opc, "\t$Rd, $Rn, $imm",
523 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
528 let Inst{15-12} = Rd;
529 let Inst{19-16} = Rn;
530 let Inst{11-0} = imm;
533 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
534 iir, opc, "\t$Rd, $Rn, $Rm",
535 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
539 let Inst{11-4} = 0b00000000;
541 let isCommutable = Commutable;
543 let Inst{15-12} = Rd;
544 let Inst{19-16} = Rn;
547 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
548 iis, opc, "\t$Rd, $Rn, $shift",
549 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
554 let Inst{11-0} = shift;
555 let Inst{15-12} = Rd;
556 let Inst{19-16} = Rn;
562 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
563 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
564 /// a explicit result, only implicitly set CPSR.
565 let isCompare = 1, Defs = [CPSR] in {
566 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
567 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
568 PatFrag opnode, bit Commutable = 0> {
569 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
571 [(opnode GPR:$Rn, so_imm:$imm)]> {
576 let Inst{15-12} = Rd;
577 let Inst{19-16} = Rn;
578 let Inst{11-0} = imm;
582 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
584 [(opnode GPR:$Rn, GPR:$Rm)]> {
588 let Inst{11-4} = 0b00000000;
590 let isCommutable = Commutable;
592 let Inst{15-12} = Rd;
593 let Inst{19-16} = Rn;
596 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
597 opc, "\t$Rn, $shift",
598 [(opnode GPR:$Rn, so_reg:$shift)]> {
603 let Inst{11-0} = shift;
604 let Inst{15-12} = Rd;
605 let Inst{19-16} = Rn;
611 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
612 /// register and one whose operand is a register rotated by 8/16/24.
613 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
614 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
615 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
616 IIC_iEXTr, opc, "\t$dst, $src",
617 [(set GPR:$dst, (opnode GPR:$src))]>,
618 Requires<[IsARM, HasV6]> {
619 let Inst{11-10} = 0b00;
620 let Inst{19-16} = 0b1111;
622 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
623 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
624 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
625 Requires<[IsARM, HasV6]> {
626 let Inst{19-16} = 0b1111;
630 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
631 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
632 IIC_iEXTr, opc, "\t$dst, $src",
633 [/* For disassembly only; pattern left blank */]>,
634 Requires<[IsARM, HasV6]> {
635 let Inst{11-10} = 0b00;
636 let Inst{19-16} = 0b1111;
638 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
639 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
640 [/* For disassembly only; pattern left blank */]>,
641 Requires<[IsARM, HasV6]> {
642 let Inst{19-16} = 0b1111;
646 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
647 /// register and one whose operand is a register rotated by 8/16/24.
648 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
649 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
650 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
651 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
652 Requires<[IsARM, HasV6]> {
653 let Inst{11-10} = 0b00;
655 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
657 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
658 [(set GPR:$dst, (opnode GPR:$LHS,
659 (rotr GPR:$RHS, rot_imm:$rot)))]>,
660 Requires<[IsARM, HasV6]>;
663 // For disassembly only.
664 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
665 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
666 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
667 [/* For disassembly only; pattern left blank */]>,
668 Requires<[IsARM, HasV6]> {
669 let Inst{11-10} = 0b00;
671 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
673 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
674 [/* For disassembly only; pattern left blank */]>,
675 Requires<[IsARM, HasV6]>;
678 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
679 let Uses = [CPSR] in {
680 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
681 bit Commutable = 0> {
682 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
683 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
684 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
690 let Inst{15-12} = Rd;
691 let Inst{19-16} = Rn;
692 let Inst{11-0} = imm;
694 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
695 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
696 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
701 let Inst{11-4} = 0b00000000;
703 let isCommutable = Commutable;
705 let Inst{15-12} = Rd;
706 let Inst{19-16} = Rn;
708 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
709 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
710 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
716 let Inst{11-0} = shift;
717 let Inst{15-12} = Rd;
718 let Inst{19-16} = Rn;
721 // Carry setting variants
722 let Defs = [CPSR] in {
723 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
724 bit Commutable = 0> {
725 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
726 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
727 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
732 let Inst{15-12} = Rd;
733 let Inst{19-16} = Rn;
734 let Inst{11-0} = imm;
738 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
739 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
740 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
745 let Inst{11-4} = 0b00000000;
746 let isCommutable = Commutable;
748 let Inst{15-12} = Rd;
749 let Inst{19-16} = Rn;
753 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
754 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
755 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
760 let Inst{11-0} = shift;
761 let Inst{15-12} = Rd;
762 let Inst{19-16} = Rn;
770 //===----------------------------------------------------------------------===//
772 //===----------------------------------------------------------------------===//
774 //===----------------------------------------------------------------------===//
775 // Miscellaneous Instructions.
778 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
779 /// the function. The first operand is the ID# for this instruction, the second
780 /// is the index into the MachineConstantPool that this is, the third is the
781 /// size in bytes of this constant pool entry.
782 let neverHasSideEffects = 1, isNotDuplicable = 1 in
783 def CONSTPOOL_ENTRY :
784 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
785 i32imm:$size), NoItinerary, "", []>;
787 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
788 // from removing one half of the matched pairs. That breaks PEI, which assumes
789 // these will always be in pairs, and asserts if it finds otherwise. Better way?
790 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
792 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
793 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
795 def ADJCALLSTACKDOWN :
796 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
797 [(ARMcallseq_start timm:$amt)]>;
800 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
801 [/* For disassembly only; pattern left blank */]>,
802 Requires<[IsARM, HasV6T2]> {
803 let Inst{27-16} = 0b001100100000;
804 let Inst{7-0} = 0b00000000;
807 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
808 [/* For disassembly only; pattern left blank */]>,
809 Requires<[IsARM, HasV6T2]> {
810 let Inst{27-16} = 0b001100100000;
811 let Inst{7-0} = 0b00000001;
814 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
815 [/* For disassembly only; pattern left blank */]>,
816 Requires<[IsARM, HasV6T2]> {
817 let Inst{27-16} = 0b001100100000;
818 let Inst{7-0} = 0b00000010;
821 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
822 [/* For disassembly only; pattern left blank */]>,
823 Requires<[IsARM, HasV6T2]> {
824 let Inst{27-16} = 0b001100100000;
825 let Inst{7-0} = 0b00000011;
828 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
830 [/* For disassembly only; pattern left blank */]>,
831 Requires<[IsARM, HasV6]> {
832 let Inst{27-20} = 0b01101000;
833 let Inst{7-4} = 0b1011;
836 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
837 [/* For disassembly only; pattern left blank */]>,
838 Requires<[IsARM, HasV6T2]> {
839 let Inst{27-16} = 0b001100100000;
840 let Inst{7-0} = 0b00000100;
843 // The i32imm operand $val can be used by a debugger to store more information
844 // about the breakpoint.
845 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
846 [/* For disassembly only; pattern left blank */]>,
848 let Inst{27-20} = 0b00010010;
849 let Inst{7-4} = 0b0111;
852 // Change Processor State is a system instruction -- for disassembly only.
853 // The singleton $opt operand contains the following information:
854 // opt{4-0} = mode from Inst{4-0}
855 // opt{5} = changemode from Inst{17}
856 // opt{8-6} = AIF from Inst{8-6}
857 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
858 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
859 [/* For disassembly only; pattern left blank */]>,
861 let Inst{31-28} = 0b1111;
862 let Inst{27-20} = 0b00010000;
867 // Preload signals the memory system of possible future data/instruction access.
868 // These are for disassembly only.
870 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
871 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
872 multiclass APreLoad<bit data, bit read, string opc> {
874 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
875 !strconcat(opc, "\t[$base, $imm]"), []> {
876 let Inst{31-26} = 0b111101;
877 let Inst{25} = 0; // 0 for immediate form
880 let Inst{21-20} = 0b01;
883 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
884 !strconcat(opc, "\t$addr"), []> {
885 let Inst{31-26} = 0b111101;
886 let Inst{25} = 1; // 1 for register form
889 let Inst{21-20} = 0b01;
894 defm PLD : APreLoad<1, 1, "pld">;
895 defm PLDW : APreLoad<1, 0, "pldw">;
896 defm PLI : APreLoad<0, 1, "pli">;
898 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
899 [/* For disassembly only; pattern left blank */]>,
901 let Inst{31-28} = 0b1111;
902 let Inst{27-20} = 0b00010000;
905 let Inst{7-4} = 0b0000;
908 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
909 [/* For disassembly only; pattern left blank */]>,
911 let Inst{31-28} = 0b1111;
912 let Inst{27-20} = 0b00010000;
915 let Inst{7-4} = 0b0000;
918 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
919 [/* For disassembly only; pattern left blank */]>,
920 Requires<[IsARM, HasV7]> {
921 let Inst{27-16} = 0b001100100000;
922 let Inst{7-4} = 0b1111;
925 // A5.4 Permanently UNDEFINED instructions.
926 let isBarrier = 1, isTerminator = 1 in
927 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
930 let Inst{27-25} = 0b011;
931 let Inst{24-20} = 0b11111;
932 let Inst{7-5} = 0b111;
936 // Address computation and loads and stores in PIC mode.
937 let isNotDuplicable = 1 in {
938 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
939 Pseudo, IIC_iALUr, "",
940 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
942 let AddedComplexity = 10 in {
943 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
944 Pseudo, IIC_iLoad_r, "",
945 [(set GPR:$dst, (load addrmodepc:$addr))]>;
947 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
948 Pseudo, IIC_iLoad_bh_r, "",
949 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
951 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
952 Pseudo, IIC_iLoad_bh_r, "",
953 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
955 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
956 Pseudo, IIC_iLoad_bh_r, "",
957 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
959 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
960 Pseudo, IIC_iLoad_bh_r, "",
961 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
963 let AddedComplexity = 10 in {
964 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
965 Pseudo, IIC_iStore_r, "",
966 [(store GPR:$src, addrmodepc:$addr)]>;
968 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
969 Pseudo, IIC_iStore_bh_r, "",
970 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
972 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
973 Pseudo, IIC_iStore_bh_r, "",
974 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
976 } // isNotDuplicable = 1
979 // LEApcrel - Load a pc-relative address into a register without offending the
981 let neverHasSideEffects = 1 in {
982 let isReMaterializable = 1 in
983 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
985 "adr$p\t$dst, #$label", []>;
987 } // neverHasSideEffects
988 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
989 (ins i32imm:$label, nohash_imm:$id, pred:$p),
991 "adr$p\t$dst, #${label}_${id}", []> {
995 //===----------------------------------------------------------------------===//
996 // Control Flow Instructions.
999 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1001 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1002 "bx", "\tlr", [(ARMretflag)]>,
1003 Requires<[IsARM, HasV4T]> {
1004 let Inst{3-0} = 0b1110;
1005 let Inst{7-4} = 0b0001;
1006 let Inst{19-8} = 0b111111111111;
1007 let Inst{27-20} = 0b00010010;
1011 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1012 "mov", "\tpc, lr", [(ARMretflag)]>,
1013 Requires<[IsARM, NoV4T]> {
1014 let Inst{11-0} = 0b000000001110;
1015 let Inst{15-12} = 0b1111;
1016 let Inst{19-16} = 0b0000;
1017 let Inst{27-20} = 0b00011010;
1021 // Indirect branches
1022 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1024 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1025 [(brind GPR:$dst)]>,
1026 Requires<[IsARM, HasV4T]> {
1028 let Inst{7-4} = 0b0001;
1029 let Inst{19-8} = 0b111111111111;
1030 let Inst{27-20} = 0b00010010;
1031 let Inst{31-28} = 0b1110;
1032 let Inst{3-0} = dst;
1036 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1037 [(brind GPR:$dst)]>,
1038 Requires<[IsARM, NoV4T]> {
1040 let Inst{11-4} = 0b00000000;
1041 let Inst{15-12} = 0b1111;
1042 let Inst{19-16} = 0b0000;
1043 let Inst{27-20} = 0b00011010;
1044 let Inst{31-28} = 0b1110;
1045 let Inst{3-0} = dst;
1049 // FIXME: remove when we have a way to marking a MI with these properties.
1050 // FIXME: Should pc be an implicit operand like PICADD, etc?
1051 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1052 hasExtraDefRegAllocReq = 1 in
1053 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1054 reglist:$dsts, variable_ops),
1055 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1056 "ldm${addr:submode}${p}\t$addr!, $dsts",
1057 "$addr.addr = $wb", []>;
1059 // On non-Darwin platforms R9 is callee-saved.
1061 Defs = [R0, R1, R2, R3, R12, LR,
1062 D0, D1, D2, D3, D4, D5, D6, D7,
1063 D16, D17, D18, D19, D20, D21, D22, D23,
1064 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1065 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1066 IIC_Br, "bl\t$func",
1067 [(ARMcall tglobaladdr:$func)]>,
1068 Requires<[IsARM, IsNotDarwin]> {
1069 let Inst{31-28} = 0b1110;
1072 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1073 IIC_Br, "bl", "\t$func",
1074 [(ARMcall_pred tglobaladdr:$func)]>,
1075 Requires<[IsARM, IsNotDarwin]>;
1078 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1079 IIC_Br, "blx\t$func",
1080 [(ARMcall GPR:$func)]>,
1081 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1083 let Inst{7-4} = 0b0011;
1084 let Inst{19-8} = 0b111111111111;
1085 let Inst{27-20} = 0b00010010;
1086 let Inst{3-0} = func;
1090 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1091 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1092 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1093 [(ARMcall_nolink tGPR:$func)]>,
1094 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1095 let Inst{7-4} = 0b0001;
1096 let Inst{19-8} = 0b111111111111;
1097 let Inst{27-20} = 0b00010010;
1101 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1102 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1103 [(ARMcall_nolink tGPR:$func)]>,
1104 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1105 let Inst{11-4} = 0b00000000;
1106 let Inst{15-12} = 0b1111;
1107 let Inst{19-16} = 0b0000;
1108 let Inst{27-20} = 0b00011010;
1112 // On Darwin R9 is call-clobbered.
1114 Defs = [R0, R1, R2, R3, R9, R12, LR,
1115 D0, D1, D2, D3, D4, D5, D6, D7,
1116 D16, D17, D18, D19, D20, D21, D22, D23,
1117 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1118 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1119 IIC_Br, "bl\t$func",
1120 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1121 let Inst{31-28} = 0b1110;
1124 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1125 IIC_Br, "bl", "\t$func",
1126 [(ARMcall_pred tglobaladdr:$func)]>,
1127 Requires<[IsARM, IsDarwin]>;
1130 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1131 IIC_Br, "blx\t$func",
1132 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1133 let Inst{7-4} = 0b0011;
1134 let Inst{19-8} = 0b111111111111;
1135 let Inst{27-20} = 0b00010010;
1139 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1140 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1141 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1142 [(ARMcall_nolink tGPR:$func)]>,
1143 Requires<[IsARM, HasV4T, IsDarwin]> {
1144 let Inst{7-4} = 0b0001;
1145 let Inst{19-8} = 0b111111111111;
1146 let Inst{27-20} = 0b00010010;
1150 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1151 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1152 [(ARMcall_nolink tGPR:$func)]>,
1153 Requires<[IsARM, NoV4T, IsDarwin]> {
1154 let Inst{11-4} = 0b00000000;
1155 let Inst{15-12} = 0b1111;
1156 let Inst{19-16} = 0b0000;
1157 let Inst{27-20} = 0b00011010;
1163 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1165 let Defs = [R0, R1, R2, R3, R9, R12,
1166 D0, D1, D2, D3, D4, D5, D6, D7,
1167 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1168 D27, D28, D29, D30, D31, PC],
1170 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1172 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1174 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1176 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1178 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1179 IIC_Br, "b\t$dst @ TAILCALL",
1180 []>, Requires<[IsDarwin]>;
1182 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1183 IIC_Br, "b.w\t$dst @ TAILCALL",
1184 []>, Requires<[IsDarwin]>;
1186 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1187 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1188 []>, Requires<[IsDarwin]> {
1189 let Inst{7-4} = 0b0001;
1190 let Inst{19-8} = 0b111111111111;
1191 let Inst{27-20} = 0b00010010;
1192 let Inst{31-28} = 0b1110;
1196 // Non-Darwin versions (the difference is R9).
1197 let Defs = [R0, R1, R2, R3, R12,
1198 D0, D1, D2, D3, D4, D5, D6, D7,
1199 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1200 D27, D28, D29, D30, D31, PC],
1202 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1204 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1206 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1208 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1210 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1211 IIC_Br, "b\t$dst @ TAILCALL",
1212 []>, Requires<[IsARM, IsNotDarwin]>;
1214 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1215 IIC_Br, "b.w\t$dst @ TAILCALL",
1216 []>, Requires<[IsThumb, IsNotDarwin]>;
1218 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1219 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1220 []>, Requires<[IsNotDarwin]> {
1221 let Inst{7-4} = 0b0001;
1222 let Inst{19-8} = 0b111111111111;
1223 let Inst{27-20} = 0b00010010;
1224 let Inst{31-28} = 0b1110;
1229 let isBranch = 1, isTerminator = 1 in {
1230 // B is "predicable" since it can be xformed into a Bcc.
1231 let isBarrier = 1 in {
1232 let isPredicable = 1 in
1233 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1234 "b\t$target", [(br bb:$target)]>;
1236 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1237 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1238 IIC_Br, "mov\tpc, $target$jt",
1239 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1240 let Inst{11-4} = 0b00000000;
1241 let Inst{15-12} = 0b1111;
1242 let Inst{20} = 0; // S Bit
1243 let Inst{24-21} = 0b1101;
1244 let Inst{27-25} = 0b000;
1246 def BR_JTm : JTI<(outs),
1247 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1248 IIC_Br, "ldr\tpc, $target$jt",
1249 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1251 let Inst{15-12} = 0b1111;
1252 let Inst{20} = 1; // L bit
1253 let Inst{21} = 0; // W bit
1254 let Inst{22} = 0; // B bit
1255 let Inst{24} = 1; // P bit
1256 let Inst{27-25} = 0b011;
1258 def BR_JTadd : JTI<(outs),
1259 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1260 IIC_Br, "add\tpc, $target, $idx$jt",
1261 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1263 let Inst{15-12} = 0b1111;
1264 let Inst{20} = 0; // S bit
1265 let Inst{24-21} = 0b0100;
1266 let Inst{27-25} = 0b000;
1268 } // isNotDuplicable = 1, isIndirectBranch = 1
1271 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1272 // a two-value operand where a dag node expects two operands. :(
1273 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1274 IIC_Br, "b", "\t$target",
1275 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1278 // Branch and Exchange Jazelle -- for disassembly only
1279 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1280 [/* For disassembly only; pattern left blank */]> {
1281 let Inst{23-20} = 0b0010;
1282 //let Inst{19-8} = 0xfff;
1283 let Inst{7-4} = 0b0010;
1286 // Secure Monitor Call is a system instruction -- for disassembly only
1287 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1288 [/* For disassembly only; pattern left blank */]> {
1289 let Inst{23-20} = 0b0110;
1290 let Inst{7-4} = 0b0111;
1293 // Supervisor Call (Software Interrupt) -- for disassembly only
1295 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1296 [/* For disassembly only; pattern left blank */]>;
1299 // Store Return State is a system instruction -- for disassembly only
1300 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1301 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1302 [/* For disassembly only; pattern left blank */]> {
1303 let Inst{31-28} = 0b1111;
1304 let Inst{22-20} = 0b110; // W = 1
1307 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1308 NoItinerary, "srs${addr:submode}\tsp, $mode",
1309 [/* For disassembly only; pattern left blank */]> {
1310 let Inst{31-28} = 0b1111;
1311 let Inst{22-20} = 0b100; // W = 0
1314 // Return From Exception is a system instruction -- for disassembly only
1315 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1316 NoItinerary, "rfe${addr:submode}\t$base!",
1317 [/* For disassembly only; pattern left blank */]> {
1318 let Inst{31-28} = 0b1111;
1319 let Inst{22-20} = 0b011; // W = 1
1322 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1323 NoItinerary, "rfe${addr:submode}\t$base",
1324 [/* For disassembly only; pattern left blank */]> {
1325 let Inst{31-28} = 0b1111;
1326 let Inst{22-20} = 0b001; // W = 0
1329 //===----------------------------------------------------------------------===//
1330 // Load / store Instructions.
1334 let canFoldAsLoad = 1, isReMaterializable = 1 in
1335 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1336 "ldr", "\t$dst, $addr",
1337 [(set GPR:$dst, (load addrmode2:$addr))]>;
1339 // Special LDR for loads from non-pc-relative constpools.
1340 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1341 isReMaterializable = 1 in
1342 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1343 "ldr", "\t$dst, $addr", []>;
1345 // Loads with zero extension
1346 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1347 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1348 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1350 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1351 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr",
1352 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1354 // Loads with sign extension
1355 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1356 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1357 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1359 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1360 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1361 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1363 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1365 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1366 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1367 []>, Requires<[IsARM, HasV5TE]>;
1370 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1371 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1372 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1374 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1375 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1376 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1378 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1379 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1380 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1382 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1383 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1384 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1386 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1387 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1388 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1390 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1391 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1392 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1394 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1395 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1396 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1398 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1399 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1400 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1402 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1403 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1404 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1406 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1407 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1408 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1410 // For disassembly only
1411 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1412 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1413 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1414 Requires<[IsARM, HasV5TE]>;
1416 // For disassembly only
1417 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1418 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1419 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1420 Requires<[IsARM, HasV5TE]>;
1422 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1424 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1426 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1427 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1428 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1429 let Inst{21} = 1; // overwrite
1432 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1433 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1434 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1435 let Inst{21} = 1; // overwrite
1438 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1439 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1440 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1441 let Inst{21} = 1; // overwrite
1444 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1445 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1446 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1447 let Inst{21} = 1; // overwrite
1450 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1451 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1452 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1453 let Inst{21} = 1; // overwrite
1457 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1458 "str", "\t$src, $addr",
1459 [(store GPR:$src, addrmode2:$addr)]>;
1461 // Stores with truncate
1462 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1463 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1464 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1466 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1467 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1468 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1471 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1472 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1473 StMiscFrm, IIC_iStore_d_r,
1474 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1477 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1478 (ins GPR:$src, GPR:$base, am2offset:$offset),
1479 StFrm, IIC_iStore_ru,
1480 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1482 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1484 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1485 (ins GPR:$src, GPR:$base,am2offset:$offset),
1486 StFrm, IIC_iStore_ru,
1487 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1489 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1491 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1492 (ins GPR:$src, GPR:$base,am3offset:$offset),
1493 StMiscFrm, IIC_iStore_ru,
1494 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1496 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1498 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1499 (ins GPR:$src, GPR:$base,am3offset:$offset),
1500 StMiscFrm, IIC_iStore_bh_ru,
1501 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1502 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1503 GPR:$base, am3offset:$offset))]>;
1505 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1506 (ins GPR:$src, GPR:$base,am2offset:$offset),
1507 StFrm, IIC_iStore_bh_ru,
1508 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1509 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1510 GPR:$base, am2offset:$offset))]>;
1512 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1513 (ins GPR:$src, GPR:$base,am2offset:$offset),
1514 StFrm, IIC_iStore_bh_ru,
1515 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1516 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1517 GPR:$base, am2offset:$offset))]>;
1519 // For disassembly only
1520 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1521 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1522 StMiscFrm, IIC_iStore_d_ru,
1523 "strd", "\t$src1, $src2, [$base, $offset]!",
1524 "$base = $base_wb", []>;
1526 // For disassembly only
1527 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1528 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1529 StMiscFrm, IIC_iStore_d_ru,
1530 "strd", "\t$src1, $src2, [$base], $offset",
1531 "$base = $base_wb", []>;
1533 // STRT, STRBT, and STRHT are for disassembly only.
1535 def STRT : AI2stwpo<(outs GPR:$base_wb),
1536 (ins GPR:$src, GPR:$base,am2offset:$offset),
1537 StFrm, IIC_iStore_ru,
1538 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1539 [/* For disassembly only; pattern left blank */]> {
1540 let Inst{21} = 1; // overwrite
1543 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1544 (ins GPR:$src, GPR:$base,am2offset:$offset),
1545 StFrm, IIC_iStore_bh_ru,
1546 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1547 [/* For disassembly only; pattern left blank */]> {
1548 let Inst{21} = 1; // overwrite
1551 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1552 (ins GPR:$src, GPR:$base,am3offset:$offset),
1553 StMiscFrm, IIC_iStore_bh_ru,
1554 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1555 [/* For disassembly only; pattern left blank */]> {
1556 let Inst{21} = 1; // overwrite
1559 //===----------------------------------------------------------------------===//
1560 // Load / store multiple Instructions.
1563 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1564 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1565 reglist:$dsts, variable_ops),
1566 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1567 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1569 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1570 reglist:$dsts, variable_ops),
1571 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1572 "ldm${addr:submode}${p}\t$addr!, $dsts",
1573 "$addr.addr = $wb", []>;
1574 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1576 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1577 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1578 reglist:$srcs, variable_ops),
1579 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1580 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1582 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1583 reglist:$srcs, variable_ops),
1584 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1585 "stm${addr:submode}${p}\t$addr!, $srcs",
1586 "$addr.addr = $wb", []>;
1587 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1589 //===----------------------------------------------------------------------===//
1590 // Move Instructions.
1593 let neverHasSideEffects = 1 in
1594 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1595 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1599 let Inst{11-4} = 0b00000000;
1602 let Inst{15-12} = Rd;
1605 // A version for the smaller set of tail call registers.
1606 let neverHasSideEffects = 1 in
1607 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1608 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1612 let Inst{11-4} = 0b00000000;
1615 let Inst{15-12} = Rd;
1618 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins so_reg:$src),
1619 DPSoRegFrm, IIC_iMOVsr,
1620 "mov", "\t$Rd, $src", [(set GPR:$Rd, so_reg:$src)]>, UnaryDP {
1624 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1625 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1626 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1630 let Inst{15-12} = Rd;
1631 let Inst{19-16} = 0b0000;
1632 let Inst{11-0} = imm;
1635 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1636 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1638 "movw", "\t$dst, $src",
1639 [(set GPR:$dst, imm0_65535:$src)]>,
1640 Requires<[IsARM, HasV6T2]>, UnaryDP {
1645 let Constraints = "$src = $dst" in
1646 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1648 "movt", "\t$dst, $imm",
1650 (or (and GPR:$src, 0xffff),
1651 lo16AllZero:$imm))]>, UnaryDP,
1652 Requires<[IsARM, HasV6T2]> {
1657 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1658 Requires<[IsARM, HasV6T2]>;
1660 let Uses = [CPSR] in
1661 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1662 "mov", "\t$dst, $src, rrx",
1663 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1665 // These aren't really mov instructions, but we have to define them this way
1666 // due to flag operands.
1668 let Defs = [CPSR] in {
1669 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1670 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1671 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1672 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1673 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1674 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1677 //===----------------------------------------------------------------------===//
1678 // Extend Instructions.
1683 defm SXTB : AI_ext_rrot<0b01101010,
1684 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1685 defm SXTH : AI_ext_rrot<0b01101011,
1686 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1688 defm SXTAB : AI_exta_rrot<0b01101010,
1689 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1690 defm SXTAH : AI_exta_rrot<0b01101011,
1691 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1693 // For disassembly only
1694 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1696 // For disassembly only
1697 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1701 let AddedComplexity = 16 in {
1702 defm UXTB : AI_ext_rrot<0b01101110,
1703 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1704 defm UXTH : AI_ext_rrot<0b01101111,
1705 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1706 defm UXTB16 : AI_ext_rrot<0b01101100,
1707 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1709 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1710 // The transformation should probably be done as a combiner action
1711 // instead so we can include a check for masking back in the upper
1712 // eight bits of the source into the lower eight bits of the result.
1713 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1714 // (UXTB16r_rot GPR:$Src, 24)>;
1715 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1716 (UXTB16r_rot GPR:$Src, 8)>;
1718 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1719 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1720 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1721 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1724 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1725 // For disassembly only
1726 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1729 def SBFX : I<(outs GPR:$dst),
1730 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1731 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1732 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1733 Requires<[IsARM, HasV6T2]> {
1734 let Inst{27-21} = 0b0111101;
1735 let Inst{6-4} = 0b101;
1738 def UBFX : I<(outs GPR:$dst),
1739 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1740 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1741 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1742 Requires<[IsARM, HasV6T2]> {
1743 let Inst{27-21} = 0b0111111;
1744 let Inst{6-4} = 0b101;
1747 //===----------------------------------------------------------------------===//
1748 // Arithmetic Instructions.
1751 defm ADD : AsI1_bin_irs<0b0100, "add",
1752 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1753 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1754 defm SUB : AsI1_bin_irs<0b0010, "sub",
1755 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1756 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1758 // ADD and SUB with 's' bit set.
1759 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1760 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1761 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1762 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1763 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1764 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1766 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1767 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1768 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1769 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1770 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1771 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1772 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1773 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1775 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1776 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1777 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1781 // The reg/reg form is only defined for the disassembler; for codegen it is
1782 // equivalent to SUBrr.
1783 def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
1784 IIC_iALUr, "rsb", "\t$dst, $a, $b",
1785 [/* For disassembly only; pattern left blank */]> {
1787 let Inst{11-4} = 0b00000000;
1790 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1791 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1792 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1796 // RSB with 's' bit set.
1797 let Defs = [CPSR] in {
1798 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1799 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1800 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1804 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1805 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1806 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1812 let Uses = [CPSR] in {
1813 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1814 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1815 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1819 // The reg/reg form is only defined for the disassembler; for codegen it is
1820 // equivalent to SUBrr.
1821 def RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1822 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b",
1823 [/* For disassembly only; pattern left blank */]> {
1825 let Inst{11-4} = 0b00000000;
1827 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1828 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1829 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1835 // FIXME: Allow these to be predicated.
1836 let Defs = [CPSR], Uses = [CPSR] in {
1837 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1838 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1839 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1844 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1845 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1846 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1853 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1854 // The assume-no-carry-in form uses the negation of the input since add/sub
1855 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1856 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1858 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1859 (SUBri GPR:$src, so_imm_neg:$imm)>;
1860 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1861 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1862 // The with-carry-in form matches bitwise not instead of the negation.
1863 // Effectively, the inverse interpretation of the carry flag already accounts
1864 // for part of the negation.
1865 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1866 (SBCri GPR:$src, so_imm_not:$imm)>;
1868 // Note: These are implemented in C++ code, because they have to generate
1869 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1871 // (mul X, 2^n+1) -> (add (X << n), X)
1872 // (mul X, 2^n-1) -> (rsb X, (X << n))
1874 // ARM Arithmetic Instruction -- for disassembly only
1875 // GPR:$dst = GPR:$a op GPR:$b
1876 class AAI<bits<8> op27_20, bits<4> op7_4, string opc,
1877 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
1878 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1879 opc, "\t$dst, $a, $b", pattern> {
1880 let Inst{27-20} = op27_20;
1881 let Inst{7-4} = op7_4;
1884 // Saturating add/subtract -- for disassembly only
1886 def QADD : AAI<0b00010000, 0b0101, "qadd",
1887 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>;
1888 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1889 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1890 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1891 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1892 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1893 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1894 def QSUB : AAI<0b00010010, 0b0101, "qsub",
1895 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>;
1896 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1897 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1898 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1899 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1900 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1901 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1902 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1903 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1905 // Signed/Unsigned add/subtract -- for disassembly only
1907 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1908 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1909 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1910 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1911 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1912 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1913 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1914 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1915 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1916 def USAX : AAI<0b01100101, 0b0101, "usax">;
1917 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1918 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1920 // Signed/Unsigned halving add/subtract -- for disassembly only
1922 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1923 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1924 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1925 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1926 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1927 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1928 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1929 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1930 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1931 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1932 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1933 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1935 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1937 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1938 MulFrm /* for convenience */, NoItinerary, "usad8",
1939 "\t$dst, $a, $b", []>,
1940 Requires<[IsARM, HasV6]> {
1941 let Inst{27-20} = 0b01111000;
1942 let Inst{15-12} = 0b1111;
1943 let Inst{7-4} = 0b0001;
1945 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1946 MulFrm /* for convenience */, NoItinerary, "usada8",
1947 "\t$dst, $a, $b, $acc", []>,
1948 Requires<[IsARM, HasV6]> {
1949 let Inst{27-20} = 0b01111000;
1950 let Inst{7-4} = 0b0001;
1953 // Signed/Unsigned saturate -- for disassembly only
1955 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1956 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1957 [/* For disassembly only; pattern left blank */]> {
1958 let Inst{27-21} = 0b0110101;
1959 let Inst{5-4} = 0b01;
1962 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1963 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1964 [/* For disassembly only; pattern left blank */]> {
1965 let Inst{27-20} = 0b01101010;
1966 let Inst{7-4} = 0b0011;
1969 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1970 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1971 [/* For disassembly only; pattern left blank */]> {
1972 let Inst{27-21} = 0b0110111;
1973 let Inst{5-4} = 0b01;
1976 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1977 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1978 [/* For disassembly only; pattern left blank */]> {
1979 let Inst{27-20} = 0b01101110;
1980 let Inst{7-4} = 0b0011;
1983 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1984 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
1986 //===----------------------------------------------------------------------===//
1987 // Bitwise Instructions.
1990 defm AND : AsI1_bin_irs<0b0000, "and",
1991 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1992 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1993 defm ANDS : AI1_bin_s_irs<0b0000, "and",
1994 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1995 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>;
1996 defm ORR : AsI1_bin_irs<0b1100, "orr",
1997 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1998 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1999 defm EOR : AsI1_bin_irs<0b0001, "eor",
2000 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2001 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2002 defm BIC : AsI1_bin_irs<0b1110, "bic",
2003 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2004 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2006 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
2007 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2008 "bfc", "\t$dst, $imm", "$src = $dst",
2009 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2010 Requires<[IsARM, HasV6T2]> {
2011 let Inst{27-21} = 0b0111110;
2012 let Inst{6-0} = 0b0011111;
2015 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2016 def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm),
2017 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2018 "bfi", "\t$dst, $val, $imm", "$src = $dst",
2019 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val,
2020 bf_inv_mask_imm:$imm))]>,
2021 Requires<[IsARM, HasV6T2]> {
2022 let Inst{27-21} = 0b0111110;
2023 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2026 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr,
2027 "mvn", "\t$dst, $src",
2028 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
2030 let Inst{11-4} = 0b00000000;
2032 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
2033 IIC_iMVNsr, "mvn", "\t$dst, $src",
2034 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
2037 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2038 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
2039 IIC_iMVNi, "mvn", "\t$dst, $imm",
2040 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
2044 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2045 (BICri GPR:$src, so_imm_not:$imm)>;
2047 //===----------------------------------------------------------------------===//
2048 // Multiply Instructions.
2051 let isCommutable = 1 in
2052 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2053 IIC_iMUL32, "mul", "\t$dst, $a, $b",
2054 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
2056 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2057 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
2058 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
2060 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2061 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2062 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2063 Requires<[IsARM, HasV6T2]>;
2065 // Extra precision multiplies with low / high results
2066 let neverHasSideEffects = 1 in {
2067 let isCommutable = 1 in {
2068 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
2069 (ins GPR:$a, GPR:$b), IIC_iMUL64,
2070 "smull", "\t$ldst, $hdst, $a, $b", []>;
2072 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
2073 (ins GPR:$a, GPR:$b), IIC_iMUL64,
2074 "umull", "\t$ldst, $hdst, $a, $b", []>;
2077 // Multiply + accumulate
2078 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
2079 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2080 "smlal", "\t$ldst, $hdst, $a, $b", []>;
2082 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
2083 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2084 "umlal", "\t$ldst, $hdst, $a, $b", []>;
2086 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
2087 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2088 "umaal", "\t$ldst, $hdst, $a, $b", []>,
2089 Requires<[IsARM, HasV6]>;
2090 } // neverHasSideEffects
2092 // Most significant word multiply
2093 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2094 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
2095 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
2096 Requires<[IsARM, HasV6]> {
2097 let Inst{7-4} = 0b0001;
2098 let Inst{15-12} = 0b1111;
2101 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2102 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
2103 [/* For disassembly only; pattern left blank */]>,
2104 Requires<[IsARM, HasV6]> {
2105 let Inst{7-4} = 0b0011; // R = 1
2106 let Inst{15-12} = 0b1111;
2109 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2110 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
2111 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
2112 Requires<[IsARM, HasV6]> {
2113 let Inst{7-4} = 0b0001;
2116 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2117 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
2118 [/* For disassembly only; pattern left blank */]>,
2119 Requires<[IsARM, HasV6]> {
2120 let Inst{7-4} = 0b0011; // R = 1
2123 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2124 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
2125 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
2126 Requires<[IsARM, HasV6]> {
2127 let Inst{7-4} = 0b1101;
2130 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2131 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
2132 [/* For disassembly only; pattern left blank */]>,
2133 Requires<[IsARM, HasV6]> {
2134 let Inst{7-4} = 0b1111; // R = 1
2137 multiclass AI_smul<string opc, PatFrag opnode> {
2138 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2139 IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b",
2140 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2141 (sext_inreg GPR:$b, i16)))]>,
2142 Requires<[IsARM, HasV5TE]> {
2147 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2148 IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b",
2149 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2150 (sra GPR:$b, (i32 16))))]>,
2151 Requires<[IsARM, HasV5TE]> {
2156 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2157 IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b",
2158 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2159 (sext_inreg GPR:$b, i16)))]>,
2160 Requires<[IsARM, HasV5TE]> {
2165 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2166 IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b",
2167 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2168 (sra GPR:$b, (i32 16))))]>,
2169 Requires<[IsARM, HasV5TE]> {
2174 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2175 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
2176 [(set GPR:$dst, (sra (opnode GPR:$a,
2177 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
2178 Requires<[IsARM, HasV5TE]> {
2183 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2184 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
2185 [(set GPR:$dst, (sra (opnode GPR:$a,
2186 (sra GPR:$b, (i32 16))), (i32 16)))]>,
2187 Requires<[IsARM, HasV5TE]> {
2194 multiclass AI_smla<string opc, PatFrag opnode> {
2195 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2196 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2197 [(set GPR:$dst, (add GPR:$acc,
2198 (opnode (sext_inreg GPR:$a, i16),
2199 (sext_inreg GPR:$b, i16))))]>,
2200 Requires<[IsARM, HasV5TE]> {
2205 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2206 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2207 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
2208 (sra GPR:$b, (i32 16)))))]>,
2209 Requires<[IsARM, HasV5TE]> {
2214 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2215 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2216 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2217 (sext_inreg GPR:$b, i16))))]>,
2218 Requires<[IsARM, HasV5TE]> {
2223 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2224 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2225 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2226 (sra GPR:$b, (i32 16)))))]>,
2227 Requires<[IsARM, HasV5TE]> {
2232 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2233 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2234 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2235 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
2236 Requires<[IsARM, HasV5TE]> {
2241 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2242 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2243 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2244 (sra GPR:$b, (i32 16))), (i32 16))))]>,
2245 Requires<[IsARM, HasV5TE]> {
2251 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2252 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2254 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2255 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2256 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2257 [/* For disassembly only; pattern left blank */]>,
2258 Requires<[IsARM, HasV5TE]> {
2263 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2264 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2265 [/* For disassembly only; pattern left blank */]>,
2266 Requires<[IsARM, HasV5TE]> {
2271 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2272 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2273 [/* For disassembly only; pattern left blank */]>,
2274 Requires<[IsARM, HasV5TE]> {
2279 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2280 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2281 [/* For disassembly only; pattern left blank */]>,
2282 Requires<[IsARM, HasV5TE]> {
2287 // Helper class for AI_smld -- for disassembly only
2288 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2289 InstrItinClass itin, string opc, string asm>
2290 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2295 let Inst{21-20} = 0b00;
2296 let Inst{22} = long;
2297 let Inst{27-23} = 0b01110;
2300 multiclass AI_smld<bit sub, string opc> {
2302 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2303 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2305 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2306 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2308 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2309 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2311 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2312 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2316 defm SMLA : AI_smld<0, "smla">;
2317 defm SMLS : AI_smld<1, "smls">;
2319 multiclass AI_sdml<bit sub, string opc> {
2321 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2322 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2323 let Inst{15-12} = 0b1111;
2326 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2327 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2328 let Inst{15-12} = 0b1111;
2333 defm SMUA : AI_sdml<0, "smua">;
2334 defm SMUS : AI_sdml<1, "smus">;
2336 //===----------------------------------------------------------------------===//
2337 // Misc. Arithmetic Instructions.
2340 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2341 "clz", "\t$dst, $src",
2342 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2343 let Inst{7-4} = 0b0001;
2344 let Inst{11-8} = 0b1111;
2345 let Inst{19-16} = 0b1111;
2348 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2349 "rbit", "\t$dst, $src",
2350 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2351 Requires<[IsARM, HasV6T2]> {
2352 let Inst{7-4} = 0b0011;
2353 let Inst{11-8} = 0b1111;
2354 let Inst{19-16} = 0b1111;
2357 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2358 "rev", "\t$dst, $src",
2359 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2360 let Inst{7-4} = 0b0011;
2361 let Inst{11-8} = 0b1111;
2362 let Inst{19-16} = 0b1111;
2365 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2366 "rev16", "\t$dst, $src",
2368 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2369 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2370 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2371 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2372 Requires<[IsARM, HasV6]> {
2373 let Inst{7-4} = 0b1011;
2374 let Inst{11-8} = 0b1111;
2375 let Inst{19-16} = 0b1111;
2378 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2379 "revsh", "\t$dst, $src",
2382 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2383 (shl GPR:$src, (i32 8))), i16))]>,
2384 Requires<[IsARM, HasV6]> {
2385 let Inst{7-4} = 0b1011;
2386 let Inst{11-8} = 0b1111;
2387 let Inst{19-16} = 0b1111;
2390 def lsl_shift_imm : SDNodeXForm<imm, [{
2391 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2392 return CurDAG->getTargetConstant(Sh, MVT::i32);
2395 def lsl_amt : PatLeaf<(i32 imm), [{
2396 return (N->getZExtValue() < 32);
2399 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2400 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2401 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2402 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2403 (and (shl GPR:$src2, lsl_amt:$sh),
2405 Requires<[IsARM, HasV6]> {
2406 let Inst{6-4} = 0b001;
2409 // Alternate cases for PKHBT where identities eliminate some nodes.
2410 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2411 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2412 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
2413 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
2415 def asr_shift_imm : SDNodeXForm<imm, [{
2416 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2417 return CurDAG->getTargetConstant(Sh, MVT::i32);
2420 def asr_amt : PatLeaf<(i32 imm), [{
2421 return (N->getZExtValue() <= 32);
2424 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2425 // will match the pattern below.
2426 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2427 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2428 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2429 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2430 (and (sra GPR:$src2, asr_amt:$sh),
2432 Requires<[IsARM, HasV6]> {
2433 let Inst{6-4} = 0b101;
2436 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2437 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2438 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2439 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2440 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2441 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2442 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2444 //===----------------------------------------------------------------------===//
2445 // Comparison Instructions...
2448 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2449 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2450 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2452 // FIXME: We have to be careful when using the CMN instruction and comparison
2453 // with 0. One would expect these two pieces of code should give identical
2469 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2470 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2471 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2472 // value of r0 and the carry bit (because the "carry bit" parameter to
2473 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2474 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2475 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2476 // parameter to AddWithCarry is defined as 0).
2478 // When x is 0 and unsigned:
2482 // ~x + 1 = 0x1 0000 0000
2483 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2485 // Therefore, we should disable CMN when comparing against zero, until we can
2486 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2487 // when it's a comparison which doesn't look at the 'carry' flag).
2489 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2491 // This is related to <rdar://problem/7569620>.
2493 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2494 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2496 // Note that TST/TEQ don't set all the same flags that CMP does!
2497 defm TST : AI1_cmp_irs<0b1000, "tst",
2498 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2499 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2500 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2501 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2502 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2504 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2505 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2506 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2507 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2508 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2509 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2511 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2512 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2514 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2515 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2517 // Pseudo i64 compares for some floating point compares.
2518 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2520 def BCCi64 : PseudoInst<(outs),
2521 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2523 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2525 def BCCZi64 : PseudoInst<(outs),
2526 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2527 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2528 } // usesCustomInserter
2531 // Conditional moves
2532 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2533 // a two-value operand where a dag node expects two operands. :(
2534 // FIXME: These should all be pseudo-instructions that get expanded to
2535 // the normal MOV instructions. That would fix the dependency on
2536 // special casing them in tblgen.
2537 let neverHasSideEffects = 1 in {
2538 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2539 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2540 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2541 RegConstraint<"$false = $Rd">, UnaryDP {
2545 let Inst{11-4} = 0b00000000;
2548 let Inst{15-12} = Rd;
2549 let Inst{11-4} = 0b00000000;
2553 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2554 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2555 "mov", "\t$dst, $true",
2556 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2557 RegConstraint<"$false = $dst">, UnaryDP {
2561 def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src),
2563 "movw", "\t$dst, $src",
2565 RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>,
2571 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2572 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2573 "mov", "\t$dst, $true",
2574 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2575 RegConstraint<"$false = $dst">, UnaryDP {
2578 } // neverHasSideEffects
2580 //===----------------------------------------------------------------------===//
2581 // Atomic operations intrinsics
2584 // memory barriers protect the atomic sequences
2585 let hasSideEffects = 1 in {
2586 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2587 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2588 let Inst{31-4} = 0xf57ff05;
2589 // FIXME: add support for options other than a full system DMB
2590 // See DMB disassembly-only variants below.
2591 let Inst{3-0} = 0b1111;
2594 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2595 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2596 let Inst{31-4} = 0xf57ff04;
2597 // FIXME: add support for options other than a full system DSB
2598 // See DSB disassembly-only variants below.
2599 let Inst{3-0} = 0b1111;
2602 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2603 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2604 [(ARMMemBarrierMCR GPR:$zero)]>,
2605 Requires<[IsARM, HasV6]> {
2606 // FIXME: add support for options other than a full system DMB
2607 // FIXME: add encoding
2610 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2611 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2612 [(ARMSyncBarrierMCR GPR:$zero)]>,
2613 Requires<[IsARM, HasV6]> {
2614 // FIXME: add support for options other than a full system DSB
2615 // FIXME: add encoding
2619 // Memory Barrier Operations Variants -- for disassembly only
2621 def memb_opt : Operand<i32> {
2622 let PrintMethod = "printMemBOption";
2625 class AMBI<bits<4> op7_4, string opc>
2626 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2627 [/* For disassembly only; pattern left blank */]>,
2628 Requires<[IsARM, HasDB]> {
2629 let Inst{31-8} = 0xf57ff0;
2630 let Inst{7-4} = op7_4;
2633 // These DMB variants are for disassembly only.
2634 def DMBvar : AMBI<0b0101, "dmb">;
2636 // These DSB variants are for disassembly only.
2637 def DSBvar : AMBI<0b0100, "dsb">;
2639 // ISB has only full system option -- for disassembly only
2640 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2641 Requires<[IsARM, HasDB]> {
2642 let Inst{31-4} = 0xf57ff06;
2643 let Inst{3-0} = 0b1111;
2646 let usesCustomInserter = 1 in {
2647 let Uses = [CPSR] in {
2648 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2649 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2650 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2651 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2652 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2653 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2654 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2655 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2656 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2657 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2658 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2659 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2660 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2661 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2662 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2663 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2664 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2665 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2666 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2667 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2668 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2669 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2670 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2671 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2672 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2673 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2674 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2675 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2676 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2677 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2678 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2679 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2680 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2681 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2682 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2683 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2684 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2685 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2686 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2687 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2688 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2689 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2690 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2691 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2692 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2693 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2694 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2695 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2696 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2697 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2698 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2699 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2700 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2701 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2703 def ATOMIC_SWAP_I8 : PseudoInst<
2704 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2705 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2706 def ATOMIC_SWAP_I16 : PseudoInst<
2707 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2708 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2709 def ATOMIC_SWAP_I32 : PseudoInst<
2710 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2711 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2713 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2714 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2715 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2716 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2717 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2718 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2719 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2720 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2721 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2725 let mayLoad = 1 in {
2726 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2727 "ldrexb", "\t$dest, [$ptr]",
2729 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2730 "ldrexh", "\t$dest, [$ptr]",
2732 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2733 "ldrex", "\t$dest, [$ptr]",
2735 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2737 "ldrexd", "\t$dest, $dest2, [$ptr]",
2741 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2742 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2744 "strexb", "\t$success, $src, [$ptr]",
2746 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2748 "strexh", "\t$success, $src, [$ptr]",
2750 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2752 "strex", "\t$success, $src, [$ptr]",
2754 def STREXD : AIstrex<0b01, (outs GPR:$success),
2755 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2757 "strexd", "\t$success, $src, $src2, [$ptr]",
2761 // Clear-Exclusive is for disassembly only.
2762 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2763 [/* For disassembly only; pattern left blank */]>,
2764 Requires<[IsARM, HasV7]> {
2765 let Inst{31-20} = 0xf57;
2766 let Inst{7-4} = 0b0001;
2769 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2770 let mayLoad = 1 in {
2771 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2772 "swp", "\t$dst, $src, [$ptr]",
2773 [/* For disassembly only; pattern left blank */]> {
2774 let Inst{27-23} = 0b00010;
2775 let Inst{22} = 0; // B = 0
2776 let Inst{21-20} = 0b00;
2777 let Inst{7-4} = 0b1001;
2780 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2781 "swpb", "\t$dst, $src, [$ptr]",
2782 [/* For disassembly only; pattern left blank */]> {
2783 let Inst{27-23} = 0b00010;
2784 let Inst{22} = 1; // B = 1
2785 let Inst{21-20} = 0b00;
2786 let Inst{7-4} = 0b1001;
2790 //===----------------------------------------------------------------------===//
2794 // __aeabi_read_tp preserves the registers r1-r3.
2796 Defs = [R0, R12, LR, CPSR] in {
2797 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2798 "bl\t__aeabi_read_tp",
2799 [(set R0, ARMthread_pointer)]>;
2802 //===----------------------------------------------------------------------===//
2803 // SJLJ Exception handling intrinsics
2804 // eh_sjlj_setjmp() is an instruction sequence to store the return
2805 // address and save #0 in R0 for the non-longjmp case.
2806 // Since by its nature we may be coming from some other function to get
2807 // here, and we're using the stack frame for the containing function to
2808 // save/restore registers, we can't keep anything live in regs across
2809 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2810 // when we get here from a longjmp(). We force everthing out of registers
2811 // except for our own input by listing the relevant registers in Defs. By
2812 // doing so, we also cause the prologue/epilogue code to actively preserve
2813 // all of the callee-saved resgisters, which is exactly what we want.
2814 // A constant value is passed in $val, and we use the location as a scratch.
2816 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2817 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2818 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2819 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2820 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2821 AddrModeNone, SizeSpecial, IndexModeNone,
2822 Pseudo, NoItinerary, "", "",
2823 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2824 Requires<[IsARM, HasVFP2]>;
2828 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2829 hasSideEffects = 1, isBarrier = 1 in {
2830 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2831 AddrModeNone, SizeSpecial, IndexModeNone,
2832 Pseudo, NoItinerary, "", "",
2833 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2834 Requires<[IsARM, NoVFP]>;
2837 // FIXME: Non-Darwin version(s)
2838 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
2839 Defs = [ R7, LR, SP ] in {
2840 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
2841 AddrModeNone, SizeSpecial, IndexModeNone,
2842 Pseudo, NoItinerary, "", "",
2843 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
2844 Requires<[IsARM, IsDarwin]>;
2847 //===----------------------------------------------------------------------===//
2848 // Non-Instruction Patterns
2851 // Large immediate handling.
2853 // Two piece so_imms.
2854 // FIXME: Expand this in ARMExpandPseudoInsts.
2855 // FIXME: Remove this when we can do generalized remat.
2856 let isReMaterializable = 1 in
2857 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2858 Pseudo, IIC_iMOVix2,
2859 "mov", "\t$dst, $src",
2860 [(set GPR:$dst, so_imm2part:$src)]>,
2861 Requires<[IsARM, NoV6T2]>;
2863 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2864 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2865 (so_imm2part_2 imm:$RHS))>;
2866 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2867 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2868 (so_imm2part_2 imm:$RHS))>;
2869 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2870 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2871 (so_imm2part_2 imm:$RHS))>;
2872 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2873 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2874 (so_neg_imm2part_2 imm:$RHS))>;
2876 // 32-bit immediate using movw + movt.
2877 // This is a single pseudo instruction, the benefit is that it can be remat'd
2878 // as a single unit instead of having to handle reg inputs.
2879 // FIXME: Remove this when we can do generalized remat.
2880 let isReMaterializable = 1 in
2881 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
2882 [(set GPR:$dst, (i32 imm:$src))]>,
2883 Requires<[IsARM, HasV6T2]>;
2885 // ConstantPool, GlobalAddress, and JumpTable
2886 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2887 Requires<[IsARM, DontUseMovt]>;
2888 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2889 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2890 Requires<[IsARM, UseMovt]>;
2891 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2892 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2894 // TODO: add,sub,and, 3-instr forms?
2897 def : ARMPat<(ARMtcret tcGPR:$dst),
2898 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
2900 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2901 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2903 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2904 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2906 def : ARMPat<(ARMtcret tcGPR:$dst),
2907 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
2909 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2910 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2912 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2913 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2916 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2917 Requires<[IsARM, IsNotDarwin]>;
2918 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2919 Requires<[IsARM, IsDarwin]>;
2921 // zextload i1 -> zextload i8
2922 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2924 // extload -> zextload
2925 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2926 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2927 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2929 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2930 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2933 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2934 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2935 (SMULBB GPR:$a, GPR:$b)>;
2936 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2937 (SMULBB GPR:$a, GPR:$b)>;
2938 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2939 (sra GPR:$b, (i32 16))),
2940 (SMULBT GPR:$a, GPR:$b)>;
2941 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2942 (SMULBT GPR:$a, GPR:$b)>;
2943 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2944 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2945 (SMULTB GPR:$a, GPR:$b)>;
2946 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2947 (SMULTB GPR:$a, GPR:$b)>;
2948 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2950 (SMULWB GPR:$a, GPR:$b)>;
2951 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2952 (SMULWB GPR:$a, GPR:$b)>;
2954 def : ARMV5TEPat<(add GPR:$acc,
2955 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2956 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2957 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2958 def : ARMV5TEPat<(add GPR:$acc,
2959 (mul sext_16_node:$a, sext_16_node:$b)),
2960 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2961 def : ARMV5TEPat<(add GPR:$acc,
2962 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2963 (sra GPR:$b, (i32 16)))),
2964 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2965 def : ARMV5TEPat<(add GPR:$acc,
2966 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2967 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2968 def : ARMV5TEPat<(add GPR:$acc,
2969 (mul (sra GPR:$a, (i32 16)),
2970 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2971 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2972 def : ARMV5TEPat<(add GPR:$acc,
2973 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2974 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2975 def : ARMV5TEPat<(add GPR:$acc,
2976 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2978 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2979 def : ARMV5TEPat<(add GPR:$acc,
2980 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2981 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2983 //===----------------------------------------------------------------------===//
2987 include "ARMInstrThumb.td"
2989 //===----------------------------------------------------------------------===//
2993 include "ARMInstrThumb2.td"
2995 //===----------------------------------------------------------------------===//
2996 // Floating Point Support
2999 include "ARMInstrVFP.td"
3001 //===----------------------------------------------------------------------===//
3002 // Advanced SIMD (NEON) Support
3005 include "ARMInstrNEON.td"
3007 //===----------------------------------------------------------------------===//
3008 // Coprocessor Instructions. For disassembly only.
3011 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3012 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3013 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3014 [/* For disassembly only; pattern left blank */]> {
3018 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3019 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3020 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3021 [/* For disassembly only; pattern left blank */]> {
3022 let Inst{31-28} = 0b1111;
3026 class ACI<dag oops, dag iops, string opc, string asm>
3027 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3028 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3029 let Inst{27-25} = 0b110;
3032 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3034 def _OFFSET : ACI<(outs),
3035 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3036 opc, "\tp$cop, cr$CRd, $addr"> {
3037 let Inst{31-28} = op31_28;
3038 let Inst{24} = 1; // P = 1
3039 let Inst{21} = 0; // W = 0
3040 let Inst{22} = 0; // D = 0
3041 let Inst{20} = load;
3044 def _PRE : ACI<(outs),
3045 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3046 opc, "\tp$cop, cr$CRd, $addr!"> {
3047 let Inst{31-28} = op31_28;
3048 let Inst{24} = 1; // P = 1
3049 let Inst{21} = 1; // W = 1
3050 let Inst{22} = 0; // D = 0
3051 let Inst{20} = load;
3054 def _POST : ACI<(outs),
3055 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3056 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3057 let Inst{31-28} = op31_28;
3058 let Inst{24} = 0; // P = 0
3059 let Inst{21} = 1; // W = 1
3060 let Inst{22} = 0; // D = 0
3061 let Inst{20} = load;
3064 def _OPTION : ACI<(outs),
3065 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3066 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3067 let Inst{31-28} = op31_28;
3068 let Inst{24} = 0; // P = 0
3069 let Inst{23} = 1; // U = 1
3070 let Inst{21} = 0; // W = 0
3071 let Inst{22} = 0; // D = 0
3072 let Inst{20} = load;
3075 def L_OFFSET : ACI<(outs),
3076 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3077 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3078 let Inst{31-28} = op31_28;
3079 let Inst{24} = 1; // P = 1
3080 let Inst{21} = 0; // W = 0
3081 let Inst{22} = 1; // D = 1
3082 let Inst{20} = load;
3085 def L_PRE : ACI<(outs),
3086 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3087 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3088 let Inst{31-28} = op31_28;
3089 let Inst{24} = 1; // P = 1
3090 let Inst{21} = 1; // W = 1
3091 let Inst{22} = 1; // D = 1
3092 let Inst{20} = load;
3095 def L_POST : ACI<(outs),
3096 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3097 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3098 let Inst{31-28} = op31_28;
3099 let Inst{24} = 0; // P = 0
3100 let Inst{21} = 1; // W = 1
3101 let Inst{22} = 1; // D = 1
3102 let Inst{20} = load;
3105 def L_OPTION : ACI<(outs),
3106 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3107 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3108 let Inst{31-28} = op31_28;
3109 let Inst{24} = 0; // P = 0
3110 let Inst{23} = 1; // U = 1
3111 let Inst{21} = 0; // W = 0
3112 let Inst{22} = 1; // D = 1
3113 let Inst{20} = load;
3117 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3118 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3119 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3120 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3122 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3123 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3124 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3125 [/* For disassembly only; pattern left blank */]> {
3130 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3131 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3132 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3133 [/* For disassembly only; pattern left blank */]> {
3134 let Inst{31-28} = 0b1111;
3139 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3140 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3141 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3142 [/* For disassembly only; pattern left blank */]> {
3147 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3148 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3149 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3150 [/* For disassembly only; pattern left blank */]> {
3151 let Inst{31-28} = 0b1111;
3156 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3157 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3158 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3159 [/* For disassembly only; pattern left blank */]> {
3160 let Inst{23-20} = 0b0100;
3163 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3164 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3165 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3166 [/* For disassembly only; pattern left blank */]> {
3167 let Inst{31-28} = 0b1111;
3168 let Inst{23-20} = 0b0100;
3171 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3172 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3173 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3174 [/* For disassembly only; pattern left blank */]> {
3175 let Inst{23-20} = 0b0101;
3178 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3179 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3180 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3181 [/* For disassembly only; pattern left blank */]> {
3182 let Inst{31-28} = 0b1111;
3183 let Inst{23-20} = 0b0101;
3186 //===----------------------------------------------------------------------===//
3187 // Move between special register and ARM core register -- for disassembly only
3190 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3191 [/* For disassembly only; pattern left blank */]> {
3192 let Inst{23-20} = 0b0000;
3193 let Inst{7-4} = 0b0000;
3196 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3197 [/* For disassembly only; pattern left blank */]> {
3198 let Inst{23-20} = 0b0100;
3199 let Inst{7-4} = 0b0000;
3202 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3203 "msr", "\tcpsr$mask, $src",
3204 [/* For disassembly only; pattern left blank */]> {
3205 let Inst{23-20} = 0b0010;
3206 let Inst{7-4} = 0b0000;
3209 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3210 "msr", "\tcpsr$mask, $a",
3211 [/* For disassembly only; pattern left blank */]> {
3212 let Inst{23-20} = 0b0010;
3213 let Inst{7-4} = 0b0000;
3216 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3217 "msr", "\tspsr$mask, $src",
3218 [/* For disassembly only; pattern left blank */]> {
3219 let Inst{23-20} = 0b0110;
3220 let Inst{7-4} = 0b0000;
3223 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3224 "msr", "\tspsr$mask, $a",
3225 [/* For disassembly only; pattern left blank */]> {
3226 let Inst{23-20} = 0b0110;
3227 let Inst{7-4} = 0b0000;