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:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
522 iii, opc, "\t$dst, $a, $b",
523 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
527 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
528 iir, opc, "\t$dst, $a, $b",
529 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
530 let isCommutable = Commutable;
531 let Inst{11-4} = 0b00000000;
535 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
536 iis, opc, "\t$dst, $a, $b",
537 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
544 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
545 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
546 /// a explicit result, only implicitly set CPSR.
547 let isCompare = 1, Defs = [CPSR] in {
548 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
549 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
550 PatFrag opnode, bit Commutable = 0> {
551 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, iii,
553 [(opnode GPR:$a, so_imm:$b)]> {
557 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, iir,
559 [(opnode GPR:$a, GPR:$b)]> {
560 let Inst{11-4} = 0b00000000;
563 let isCommutable = Commutable;
565 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, iis,
567 [(opnode GPR:$a, so_reg:$b)]> {
574 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
575 /// register and one whose operand is a register rotated by 8/16/24.
576 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
577 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
578 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
579 IIC_iEXTr, opc, "\t$dst, $src",
580 [(set GPR:$dst, (opnode GPR:$src))]>,
581 Requires<[IsARM, HasV6]> {
582 let Inst{11-10} = 0b00;
583 let Inst{19-16} = 0b1111;
585 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
586 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
587 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
588 Requires<[IsARM, HasV6]> {
589 let Inst{19-16} = 0b1111;
593 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
594 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
595 IIC_iEXTr, opc, "\t$dst, $src",
596 [/* For disassembly only; pattern left blank */]>,
597 Requires<[IsARM, HasV6]> {
598 let Inst{11-10} = 0b00;
599 let Inst{19-16} = 0b1111;
601 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
602 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
603 [/* For disassembly only; pattern left blank */]>,
604 Requires<[IsARM, HasV6]> {
605 let Inst{19-16} = 0b1111;
609 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
610 /// register and one whose operand is a register rotated by 8/16/24.
611 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
612 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
613 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
614 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
615 Requires<[IsARM, HasV6]> {
616 let Inst{11-10} = 0b00;
618 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
620 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
621 [(set GPR:$dst, (opnode GPR:$LHS,
622 (rotr GPR:$RHS, rot_imm:$rot)))]>,
623 Requires<[IsARM, HasV6]>;
626 // For disassembly only.
627 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
628 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
629 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
630 [/* For disassembly only; pattern left blank */]>,
631 Requires<[IsARM, HasV6]> {
632 let Inst{11-10} = 0b00;
634 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
636 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
637 [/* For disassembly only; pattern left blank */]>,
638 Requires<[IsARM, HasV6]>;
641 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
642 let Uses = [CPSR] in {
643 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
644 bit Commutable = 0> {
645 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
646 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
647 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
651 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
652 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
653 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
655 let isCommutable = Commutable;
656 let Inst{11-4} = 0b00000000;
659 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
660 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
661 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
666 // Carry setting variants
667 let Defs = [CPSR] in {
668 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
669 bit Commutable = 0> {
670 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
671 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
672 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
677 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
678 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
679 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
681 let Inst{11-4} = 0b00000000;
685 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
686 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
687 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
696 //===----------------------------------------------------------------------===//
698 //===----------------------------------------------------------------------===//
700 //===----------------------------------------------------------------------===//
701 // Miscellaneous Instructions.
704 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
705 /// the function. The first operand is the ID# for this instruction, the second
706 /// is the index into the MachineConstantPool that this is, the third is the
707 /// size in bytes of this constant pool entry.
708 let neverHasSideEffects = 1, isNotDuplicable = 1 in
709 def CONSTPOOL_ENTRY :
710 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
711 i32imm:$size), NoItinerary, "", []>;
713 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
714 // from removing one half of the matched pairs. That breaks PEI, which assumes
715 // these will always be in pairs, and asserts if it finds otherwise. Better way?
716 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
718 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
719 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
721 def ADJCALLSTACKDOWN :
722 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
723 [(ARMcallseq_start timm:$amt)]>;
726 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
727 [/* For disassembly only; pattern left blank */]>,
728 Requires<[IsARM, HasV6T2]> {
729 let Inst{27-16} = 0b001100100000;
730 let Inst{7-0} = 0b00000000;
733 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
734 [/* For disassembly only; pattern left blank */]>,
735 Requires<[IsARM, HasV6T2]> {
736 let Inst{27-16} = 0b001100100000;
737 let Inst{7-0} = 0b00000001;
740 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
741 [/* For disassembly only; pattern left blank */]>,
742 Requires<[IsARM, HasV6T2]> {
743 let Inst{27-16} = 0b001100100000;
744 let Inst{7-0} = 0b00000010;
747 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
748 [/* For disassembly only; pattern left blank */]>,
749 Requires<[IsARM, HasV6T2]> {
750 let Inst{27-16} = 0b001100100000;
751 let Inst{7-0} = 0b00000011;
754 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
756 [/* For disassembly only; pattern left blank */]>,
757 Requires<[IsARM, HasV6]> {
758 let Inst{27-20} = 0b01101000;
759 let Inst{7-4} = 0b1011;
762 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
763 [/* For disassembly only; pattern left blank */]>,
764 Requires<[IsARM, HasV6T2]> {
765 let Inst{27-16} = 0b001100100000;
766 let Inst{7-0} = 0b00000100;
769 // The i32imm operand $val can be used by a debugger to store more information
770 // about the breakpoint.
771 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
772 [/* For disassembly only; pattern left blank */]>,
774 let Inst{27-20} = 0b00010010;
775 let Inst{7-4} = 0b0111;
778 // Change Processor State is a system instruction -- for disassembly only.
779 // The singleton $opt operand contains the following information:
780 // opt{4-0} = mode from Inst{4-0}
781 // opt{5} = changemode from Inst{17}
782 // opt{8-6} = AIF from Inst{8-6}
783 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
784 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
785 [/* For disassembly only; pattern left blank */]>,
787 let Inst{31-28} = 0b1111;
788 let Inst{27-20} = 0b00010000;
793 // Preload signals the memory system of possible future data/instruction access.
794 // These are for disassembly only.
796 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
797 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
798 multiclass APreLoad<bit data, bit read, string opc> {
800 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
801 !strconcat(opc, "\t[$base, $imm]"), []> {
802 let Inst{31-26} = 0b111101;
803 let Inst{25} = 0; // 0 for immediate form
806 let Inst{21-20} = 0b01;
809 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
810 !strconcat(opc, "\t$addr"), []> {
811 let Inst{31-26} = 0b111101;
812 let Inst{25} = 1; // 1 for register form
815 let Inst{21-20} = 0b01;
820 defm PLD : APreLoad<1, 1, "pld">;
821 defm PLDW : APreLoad<1, 0, "pldw">;
822 defm PLI : APreLoad<0, 1, "pli">;
824 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
825 [/* For disassembly only; pattern left blank */]>,
827 let Inst{31-28} = 0b1111;
828 let Inst{27-20} = 0b00010000;
831 let Inst{7-4} = 0b0000;
834 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
835 [/* For disassembly only; pattern left blank */]>,
837 let Inst{31-28} = 0b1111;
838 let Inst{27-20} = 0b00010000;
841 let Inst{7-4} = 0b0000;
844 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
845 [/* For disassembly only; pattern left blank */]>,
846 Requires<[IsARM, HasV7]> {
847 let Inst{27-16} = 0b001100100000;
848 let Inst{7-4} = 0b1111;
851 // A5.4 Permanently UNDEFINED instructions.
852 let isBarrier = 1, isTerminator = 1 in
853 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
856 let Inst{27-25} = 0b011;
857 let Inst{24-20} = 0b11111;
858 let Inst{7-5} = 0b111;
862 // Address computation and loads and stores in PIC mode.
863 let isNotDuplicable = 1 in {
864 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
865 Pseudo, IIC_iALUr, "",
866 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
868 let AddedComplexity = 10 in {
869 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
870 Pseudo, IIC_iLoad_r, "",
871 [(set GPR:$dst, (load addrmodepc:$addr))]>;
873 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
874 Pseudo, IIC_iLoad_bh_r, "",
875 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
877 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
878 Pseudo, IIC_iLoad_bh_r, "",
879 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
881 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
882 Pseudo, IIC_iLoad_bh_r, "",
883 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
885 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
886 Pseudo, IIC_iLoad_bh_r, "",
887 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
889 let AddedComplexity = 10 in {
890 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
891 Pseudo, IIC_iStore_r, "",
892 [(store GPR:$src, addrmodepc:$addr)]>;
894 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
895 Pseudo, IIC_iStore_bh_r, "",
896 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
898 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
899 Pseudo, IIC_iStore_bh_r, "",
900 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
902 } // isNotDuplicable = 1
905 // LEApcrel - Load a pc-relative address into a register without offending the
907 let neverHasSideEffects = 1 in {
908 let isReMaterializable = 1 in
909 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
911 "adr$p\t$dst, #$label", []>;
913 } // neverHasSideEffects
914 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
915 (ins i32imm:$label, nohash_imm:$id, pred:$p),
917 "adr$p\t$dst, #${label}_${id}", []> {
921 //===----------------------------------------------------------------------===//
922 // Control Flow Instructions.
925 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
927 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
928 "bx", "\tlr", [(ARMretflag)]>,
929 Requires<[IsARM, HasV4T]> {
930 let Inst{3-0} = 0b1110;
931 let Inst{7-4} = 0b0001;
932 let Inst{19-8} = 0b111111111111;
933 let Inst{27-20} = 0b00010010;
937 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
938 "mov", "\tpc, lr", [(ARMretflag)]>,
939 Requires<[IsARM, NoV4T]> {
940 let Inst{11-0} = 0b000000001110;
941 let Inst{15-12} = 0b1111;
942 let Inst{19-16} = 0b0000;
943 let Inst{27-20} = 0b00011010;
948 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
950 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
952 Requires<[IsARM, HasV4T]> {
954 let Inst{7-4} = 0b0001;
955 let Inst{19-8} = 0b111111111111;
956 let Inst{27-20} = 0b00010010;
957 let Inst{31-28} = 0b1110;
962 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
964 Requires<[IsARM, NoV4T]> {
966 let Inst{11-4} = 0b00000000;
967 let Inst{15-12} = 0b1111;
968 let Inst{19-16} = 0b0000;
969 let Inst{27-20} = 0b00011010;
970 let Inst{31-28} = 0b1110;
975 // FIXME: remove when we have a way to marking a MI with these properties.
976 // FIXME: Should pc be an implicit operand like PICADD, etc?
977 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
978 hasExtraDefRegAllocReq = 1 in
979 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
980 reglist:$dsts, variable_ops),
981 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
982 "ldm${addr:submode}${p}\t$addr!, $dsts",
983 "$addr.addr = $wb", []>;
985 // On non-Darwin platforms R9 is callee-saved.
987 Defs = [R0, R1, R2, R3, R12, LR,
988 D0, D1, D2, D3, D4, D5, D6, D7,
989 D16, D17, D18, D19, D20, D21, D22, D23,
990 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
991 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
993 [(ARMcall tglobaladdr:$func)]>,
994 Requires<[IsARM, IsNotDarwin]> {
995 let Inst{31-28} = 0b1110;
998 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
999 IIC_Br, "bl", "\t$func",
1000 [(ARMcall_pred tglobaladdr:$func)]>,
1001 Requires<[IsARM, IsNotDarwin]>;
1004 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1005 IIC_Br, "blx\t$func",
1006 [(ARMcall GPR:$func)]>,
1007 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1009 let Inst{7-4} = 0b0011;
1010 let Inst{19-8} = 0b111111111111;
1011 let Inst{27-20} = 0b00010010;
1012 let Inst{3-0} = func;
1016 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1017 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1018 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1019 [(ARMcall_nolink tGPR:$func)]>,
1020 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1021 let Inst{7-4} = 0b0001;
1022 let Inst{19-8} = 0b111111111111;
1023 let Inst{27-20} = 0b00010010;
1027 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1028 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1029 [(ARMcall_nolink tGPR:$func)]>,
1030 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1031 let Inst{11-4} = 0b00000000;
1032 let Inst{15-12} = 0b1111;
1033 let Inst{19-16} = 0b0000;
1034 let Inst{27-20} = 0b00011010;
1038 // On Darwin R9 is call-clobbered.
1040 Defs = [R0, R1, R2, R3, R9, R12, LR,
1041 D0, D1, D2, D3, D4, D5, D6, D7,
1042 D16, D17, D18, D19, D20, D21, D22, D23,
1043 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1044 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1045 IIC_Br, "bl\t$func",
1046 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1047 let Inst{31-28} = 0b1110;
1050 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1051 IIC_Br, "bl", "\t$func",
1052 [(ARMcall_pred tglobaladdr:$func)]>,
1053 Requires<[IsARM, IsDarwin]>;
1056 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1057 IIC_Br, "blx\t$func",
1058 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1059 let Inst{7-4} = 0b0011;
1060 let Inst{19-8} = 0b111111111111;
1061 let Inst{27-20} = 0b00010010;
1065 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1066 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1067 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1068 [(ARMcall_nolink tGPR:$func)]>,
1069 Requires<[IsARM, HasV4T, IsDarwin]> {
1070 let Inst{7-4} = 0b0001;
1071 let Inst{19-8} = 0b111111111111;
1072 let Inst{27-20} = 0b00010010;
1076 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1077 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1078 [(ARMcall_nolink tGPR:$func)]>,
1079 Requires<[IsARM, NoV4T, IsDarwin]> {
1080 let Inst{11-4} = 0b00000000;
1081 let Inst{15-12} = 0b1111;
1082 let Inst{19-16} = 0b0000;
1083 let Inst{27-20} = 0b00011010;
1089 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1091 let Defs = [R0, R1, R2, R3, R9, R12,
1092 D0, D1, D2, D3, D4, D5, D6, D7,
1093 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1094 D27, D28, D29, D30, D31, PC],
1096 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1098 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1100 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1102 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1104 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1105 IIC_Br, "b\t$dst @ TAILCALL",
1106 []>, Requires<[IsDarwin]>;
1108 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1109 IIC_Br, "b.w\t$dst @ TAILCALL",
1110 []>, Requires<[IsDarwin]>;
1112 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1113 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1114 []>, Requires<[IsDarwin]> {
1115 let Inst{7-4} = 0b0001;
1116 let Inst{19-8} = 0b111111111111;
1117 let Inst{27-20} = 0b00010010;
1118 let Inst{31-28} = 0b1110;
1122 // Non-Darwin versions (the difference is R9).
1123 let Defs = [R0, R1, R2, R3, R12,
1124 D0, D1, D2, D3, D4, D5, D6, D7,
1125 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1126 D27, D28, D29, D30, D31, PC],
1128 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1130 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1132 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1134 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1136 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1137 IIC_Br, "b\t$dst @ TAILCALL",
1138 []>, Requires<[IsARM, IsNotDarwin]>;
1140 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1141 IIC_Br, "b.w\t$dst @ TAILCALL",
1142 []>, Requires<[IsThumb, IsNotDarwin]>;
1144 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1145 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1146 []>, Requires<[IsNotDarwin]> {
1147 let Inst{7-4} = 0b0001;
1148 let Inst{19-8} = 0b111111111111;
1149 let Inst{27-20} = 0b00010010;
1150 let Inst{31-28} = 0b1110;
1155 let isBranch = 1, isTerminator = 1 in {
1156 // B is "predicable" since it can be xformed into a Bcc.
1157 let isBarrier = 1 in {
1158 let isPredicable = 1 in
1159 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1160 "b\t$target", [(br bb:$target)]>;
1162 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1163 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1164 IIC_Br, "mov\tpc, $target$jt",
1165 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1166 let Inst{11-4} = 0b00000000;
1167 let Inst{15-12} = 0b1111;
1168 let Inst{20} = 0; // S Bit
1169 let Inst{24-21} = 0b1101;
1170 let Inst{27-25} = 0b000;
1172 def BR_JTm : JTI<(outs),
1173 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1174 IIC_Br, "ldr\tpc, $target$jt",
1175 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1177 let Inst{15-12} = 0b1111;
1178 let Inst{20} = 1; // L bit
1179 let Inst{21} = 0; // W bit
1180 let Inst{22} = 0; // B bit
1181 let Inst{24} = 1; // P bit
1182 let Inst{27-25} = 0b011;
1184 def BR_JTadd : JTI<(outs),
1185 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1186 IIC_Br, "add\tpc, $target, $idx$jt",
1187 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1189 let Inst{15-12} = 0b1111;
1190 let Inst{20} = 0; // S bit
1191 let Inst{24-21} = 0b0100;
1192 let Inst{27-25} = 0b000;
1194 } // isNotDuplicable = 1, isIndirectBranch = 1
1197 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1198 // a two-value operand where a dag node expects two operands. :(
1199 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1200 IIC_Br, "b", "\t$target",
1201 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1204 // Branch and Exchange Jazelle -- for disassembly only
1205 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1206 [/* For disassembly only; pattern left blank */]> {
1207 let Inst{23-20} = 0b0010;
1208 //let Inst{19-8} = 0xfff;
1209 let Inst{7-4} = 0b0010;
1212 // Secure Monitor Call is a system instruction -- for disassembly only
1213 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1214 [/* For disassembly only; pattern left blank */]> {
1215 let Inst{23-20} = 0b0110;
1216 let Inst{7-4} = 0b0111;
1219 // Supervisor Call (Software Interrupt) -- for disassembly only
1221 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1222 [/* For disassembly only; pattern left blank */]>;
1225 // Store Return State is a system instruction -- for disassembly only
1226 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1227 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1228 [/* For disassembly only; pattern left blank */]> {
1229 let Inst{31-28} = 0b1111;
1230 let Inst{22-20} = 0b110; // W = 1
1233 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1234 NoItinerary, "srs${addr:submode}\tsp, $mode",
1235 [/* For disassembly only; pattern left blank */]> {
1236 let Inst{31-28} = 0b1111;
1237 let Inst{22-20} = 0b100; // W = 0
1240 // Return From Exception is a system instruction -- for disassembly only
1241 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1242 NoItinerary, "rfe${addr:submode}\t$base!",
1243 [/* For disassembly only; pattern left blank */]> {
1244 let Inst{31-28} = 0b1111;
1245 let Inst{22-20} = 0b011; // W = 1
1248 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1249 NoItinerary, "rfe${addr:submode}\t$base",
1250 [/* For disassembly only; pattern left blank */]> {
1251 let Inst{31-28} = 0b1111;
1252 let Inst{22-20} = 0b001; // W = 0
1255 //===----------------------------------------------------------------------===//
1256 // Load / store Instructions.
1260 let canFoldAsLoad = 1, isReMaterializable = 1 in
1261 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1262 "ldr", "\t$dst, $addr",
1263 [(set GPR:$dst, (load addrmode2:$addr))]>;
1265 // Special LDR for loads from non-pc-relative constpools.
1266 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1267 isReMaterializable = 1 in
1268 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1269 "ldr", "\t$dst, $addr", []>;
1271 // Loads with zero extension
1272 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1273 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1274 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1276 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1277 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr",
1278 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1280 // Loads with sign extension
1281 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1282 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1283 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1285 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1286 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1287 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1289 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1291 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1292 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1293 []>, Requires<[IsARM, HasV5TE]>;
1296 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1297 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1298 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1300 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1301 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1302 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1304 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1305 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1306 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1308 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1309 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1310 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1312 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1313 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1314 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1316 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1317 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1318 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1320 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1321 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1322 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1324 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1325 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1326 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1328 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1329 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1330 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1332 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1333 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1334 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1336 // For disassembly only
1337 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1338 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1339 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1340 Requires<[IsARM, HasV5TE]>;
1342 // For disassembly only
1343 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1344 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1345 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1346 Requires<[IsARM, HasV5TE]>;
1348 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1350 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1352 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1353 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1354 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1355 let Inst{21} = 1; // overwrite
1358 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1359 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1360 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1361 let Inst{21} = 1; // overwrite
1364 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1365 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1366 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1367 let Inst{21} = 1; // overwrite
1370 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1371 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1372 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1373 let Inst{21} = 1; // overwrite
1376 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1377 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1378 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1379 let Inst{21} = 1; // overwrite
1383 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1384 "str", "\t$src, $addr",
1385 [(store GPR:$src, addrmode2:$addr)]>;
1387 // Stores with truncate
1388 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1389 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1390 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1392 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1393 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1394 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1397 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1398 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1399 StMiscFrm, IIC_iStore_d_r,
1400 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1403 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1404 (ins GPR:$src, GPR:$base, am2offset:$offset),
1405 StFrm, IIC_iStore_ru,
1406 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1408 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1410 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1411 (ins GPR:$src, GPR:$base,am2offset:$offset),
1412 StFrm, IIC_iStore_ru,
1413 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1415 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1417 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1418 (ins GPR:$src, GPR:$base,am3offset:$offset),
1419 StMiscFrm, IIC_iStore_ru,
1420 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1422 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1424 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1425 (ins GPR:$src, GPR:$base,am3offset:$offset),
1426 StMiscFrm, IIC_iStore_bh_ru,
1427 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1428 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1429 GPR:$base, am3offset:$offset))]>;
1431 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1432 (ins GPR:$src, GPR:$base,am2offset:$offset),
1433 StFrm, IIC_iStore_bh_ru,
1434 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1435 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1436 GPR:$base, am2offset:$offset))]>;
1438 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1439 (ins GPR:$src, GPR:$base,am2offset:$offset),
1440 StFrm, IIC_iStore_bh_ru,
1441 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1442 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1443 GPR:$base, am2offset:$offset))]>;
1445 // For disassembly only
1446 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1447 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1448 StMiscFrm, IIC_iStore_d_ru,
1449 "strd", "\t$src1, $src2, [$base, $offset]!",
1450 "$base = $base_wb", []>;
1452 // For disassembly only
1453 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1454 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1455 StMiscFrm, IIC_iStore_d_ru,
1456 "strd", "\t$src1, $src2, [$base], $offset",
1457 "$base = $base_wb", []>;
1459 // STRT, STRBT, and STRHT are for disassembly only.
1461 def STRT : AI2stwpo<(outs GPR:$base_wb),
1462 (ins GPR:$src, GPR:$base,am2offset:$offset),
1463 StFrm, IIC_iStore_ru,
1464 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1465 [/* For disassembly only; pattern left blank */]> {
1466 let Inst{21} = 1; // overwrite
1469 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1470 (ins GPR:$src, GPR:$base,am2offset:$offset),
1471 StFrm, IIC_iStore_bh_ru,
1472 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1473 [/* For disassembly only; pattern left blank */]> {
1474 let Inst{21} = 1; // overwrite
1477 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1478 (ins GPR:$src, GPR:$base,am3offset:$offset),
1479 StMiscFrm, IIC_iStore_bh_ru,
1480 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1481 [/* For disassembly only; pattern left blank */]> {
1482 let Inst{21} = 1; // overwrite
1485 //===----------------------------------------------------------------------===//
1486 // Load / store multiple Instructions.
1489 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1490 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1491 reglist:$dsts, variable_ops),
1492 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1493 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1495 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1496 reglist:$dsts, variable_ops),
1497 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1498 "ldm${addr:submode}${p}\t$addr!, $dsts",
1499 "$addr.addr = $wb", []>;
1500 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1502 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1503 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1504 reglist:$srcs, variable_ops),
1505 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1506 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1508 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1509 reglist:$srcs, variable_ops),
1510 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1511 "stm${addr:submode}${p}\t$addr!, $srcs",
1512 "$addr.addr = $wb", []>;
1513 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1515 //===----------------------------------------------------------------------===//
1516 // Move Instructions.
1519 let neverHasSideEffects = 1 in
1520 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1521 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1525 let Inst{11-4} = 0b00000000;
1528 let Inst{15-12} = Rd;
1531 // A version for the smaller set of tail call registers.
1532 let neverHasSideEffects = 1 in
1533 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1534 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1538 let Inst{11-4} = 0b00000000;
1541 let Inst{15-12} = Rd;
1544 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins so_reg:$src),
1545 DPSoRegFrm, IIC_iMOVsr,
1546 "mov", "\t$Rd, $src", [(set GPR:$Rd, so_reg:$src)]>, UnaryDP {
1550 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1551 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1552 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1556 let Inst{15-12} = Rd;
1557 let Inst{19-16} = 0b0000;
1558 let Inst{11-0} = imm;
1561 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1562 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1564 "movw", "\t$dst, $src",
1565 [(set GPR:$dst, imm0_65535:$src)]>,
1566 Requires<[IsARM, HasV6T2]>, UnaryDP {
1571 let Constraints = "$src = $dst" in
1572 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1574 "movt", "\t$dst, $imm",
1576 (or (and GPR:$src, 0xffff),
1577 lo16AllZero:$imm))]>, UnaryDP,
1578 Requires<[IsARM, HasV6T2]> {
1583 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1584 Requires<[IsARM, HasV6T2]>;
1586 let Uses = [CPSR] in
1587 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1588 "mov", "\t$dst, $src, rrx",
1589 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1591 // These aren't really mov instructions, but we have to define them this way
1592 // due to flag operands.
1594 let Defs = [CPSR] in {
1595 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1596 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1597 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1598 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1599 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1600 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1603 //===----------------------------------------------------------------------===//
1604 // Extend Instructions.
1609 defm SXTB : AI_ext_rrot<0b01101010,
1610 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1611 defm SXTH : AI_ext_rrot<0b01101011,
1612 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1614 defm SXTAB : AI_exta_rrot<0b01101010,
1615 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1616 defm SXTAH : AI_exta_rrot<0b01101011,
1617 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1619 // For disassembly only
1620 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1622 // For disassembly only
1623 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1627 let AddedComplexity = 16 in {
1628 defm UXTB : AI_ext_rrot<0b01101110,
1629 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1630 defm UXTH : AI_ext_rrot<0b01101111,
1631 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1632 defm UXTB16 : AI_ext_rrot<0b01101100,
1633 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1635 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1636 // The transformation should probably be done as a combiner action
1637 // instead so we can include a check for masking back in the upper
1638 // eight bits of the source into the lower eight bits of the result.
1639 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1640 // (UXTB16r_rot GPR:$Src, 24)>;
1641 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1642 (UXTB16r_rot GPR:$Src, 8)>;
1644 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1645 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1646 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1647 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1650 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1651 // For disassembly only
1652 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1655 def SBFX : I<(outs GPR:$dst),
1656 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1657 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1658 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1659 Requires<[IsARM, HasV6T2]> {
1660 let Inst{27-21} = 0b0111101;
1661 let Inst{6-4} = 0b101;
1664 def UBFX : I<(outs GPR:$dst),
1665 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1666 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1667 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1668 Requires<[IsARM, HasV6T2]> {
1669 let Inst{27-21} = 0b0111111;
1670 let Inst{6-4} = 0b101;
1673 //===----------------------------------------------------------------------===//
1674 // Arithmetic Instructions.
1677 defm ADD : AsI1_bin_irs<0b0100, "add",
1678 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1679 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1680 defm SUB : AsI1_bin_irs<0b0010, "sub",
1681 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1682 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1684 // ADD and SUB with 's' bit set.
1685 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1686 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1687 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1688 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1689 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1690 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1692 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1693 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1694 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1695 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1696 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1697 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1698 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1699 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1701 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1702 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1703 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1707 // The reg/reg form is only defined for the disassembler; for codegen it is
1708 // equivalent to SUBrr.
1709 def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
1710 IIC_iALUr, "rsb", "\t$dst, $a, $b",
1711 [/* For disassembly only; pattern left blank */]> {
1713 let Inst{11-4} = 0b00000000;
1716 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1717 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1718 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1722 // RSB with 's' bit set.
1723 let Defs = [CPSR] in {
1724 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1725 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1726 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1730 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1731 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1732 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1738 let Uses = [CPSR] in {
1739 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1740 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1741 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1745 // The reg/reg form is only defined for the disassembler; for codegen it is
1746 // equivalent to SUBrr.
1747 def RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1748 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b",
1749 [/* For disassembly only; pattern left blank */]> {
1751 let Inst{11-4} = 0b00000000;
1753 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1754 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1755 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1761 // FIXME: Allow these to be predicated.
1762 let Defs = [CPSR], Uses = [CPSR] in {
1763 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1764 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1765 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1770 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1771 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1772 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1779 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1780 // The assume-no-carry-in form uses the negation of the input since add/sub
1781 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1782 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1784 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1785 (SUBri GPR:$src, so_imm_neg:$imm)>;
1786 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1787 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1788 // The with-carry-in form matches bitwise not instead of the negation.
1789 // Effectively, the inverse interpretation of the carry flag already accounts
1790 // for part of the negation.
1791 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1792 (SBCri GPR:$src, so_imm_not:$imm)>;
1794 // Note: These are implemented in C++ code, because they have to generate
1795 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1797 // (mul X, 2^n+1) -> (add (X << n), X)
1798 // (mul X, 2^n-1) -> (rsb X, (X << n))
1800 // ARM Arithmetic Instruction -- for disassembly only
1801 // GPR:$dst = GPR:$a op GPR:$b
1802 class AAI<bits<8> op27_20, bits<4> op7_4, string opc,
1803 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
1804 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1805 opc, "\t$dst, $a, $b", pattern> {
1806 let Inst{27-20} = op27_20;
1807 let Inst{7-4} = op7_4;
1810 // Saturating add/subtract -- for disassembly only
1812 def QADD : AAI<0b00010000, 0b0101, "qadd",
1813 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>;
1814 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1815 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1816 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1817 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1818 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1819 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1820 def QSUB : AAI<0b00010010, 0b0101, "qsub",
1821 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>;
1822 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1823 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1824 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1825 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1826 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1827 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1828 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1829 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1831 // Signed/Unsigned add/subtract -- for disassembly only
1833 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1834 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1835 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1836 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1837 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1838 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1839 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1840 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1841 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1842 def USAX : AAI<0b01100101, 0b0101, "usax">;
1843 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1844 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1846 // Signed/Unsigned halving add/subtract -- for disassembly only
1848 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1849 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1850 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1851 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1852 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1853 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1854 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1855 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1856 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1857 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1858 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1859 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1861 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1863 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1864 MulFrm /* for convenience */, NoItinerary, "usad8",
1865 "\t$dst, $a, $b", []>,
1866 Requires<[IsARM, HasV6]> {
1867 let Inst{27-20} = 0b01111000;
1868 let Inst{15-12} = 0b1111;
1869 let Inst{7-4} = 0b0001;
1871 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1872 MulFrm /* for convenience */, NoItinerary, "usada8",
1873 "\t$dst, $a, $b, $acc", []>,
1874 Requires<[IsARM, HasV6]> {
1875 let Inst{27-20} = 0b01111000;
1876 let Inst{7-4} = 0b0001;
1879 // Signed/Unsigned saturate -- for disassembly only
1881 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1882 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1883 [/* For disassembly only; pattern left blank */]> {
1884 let Inst{27-21} = 0b0110101;
1885 let Inst{5-4} = 0b01;
1888 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1889 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1890 [/* For disassembly only; pattern left blank */]> {
1891 let Inst{27-20} = 0b01101010;
1892 let Inst{7-4} = 0b0011;
1895 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1896 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1897 [/* For disassembly only; pattern left blank */]> {
1898 let Inst{27-21} = 0b0110111;
1899 let Inst{5-4} = 0b01;
1902 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1903 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1904 [/* For disassembly only; pattern left blank */]> {
1905 let Inst{27-20} = 0b01101110;
1906 let Inst{7-4} = 0b0011;
1909 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1910 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
1912 //===----------------------------------------------------------------------===//
1913 // Bitwise Instructions.
1916 defm AND : AsI1_bin_irs<0b0000, "and",
1917 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1918 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1919 defm ANDS : AI1_bin_s_irs<0b0000, "and",
1920 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1921 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>;
1922 defm ORR : AsI1_bin_irs<0b1100, "orr",
1923 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1924 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1925 defm EOR : AsI1_bin_irs<0b0001, "eor",
1926 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1927 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1928 defm BIC : AsI1_bin_irs<0b1110, "bic",
1929 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1930 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1932 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1933 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1934 "bfc", "\t$dst, $imm", "$src = $dst",
1935 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1936 Requires<[IsARM, HasV6T2]> {
1937 let Inst{27-21} = 0b0111110;
1938 let Inst{6-0} = 0b0011111;
1941 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1942 def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm),
1943 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1944 "bfi", "\t$dst, $val, $imm", "$src = $dst",
1945 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val,
1946 bf_inv_mask_imm:$imm))]>,
1947 Requires<[IsARM, HasV6T2]> {
1948 let Inst{27-21} = 0b0111110;
1949 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1952 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr,
1953 "mvn", "\t$dst, $src",
1954 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1956 let Inst{11-4} = 0b00000000;
1958 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1959 IIC_iMVNsr, "mvn", "\t$dst, $src",
1960 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1963 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1964 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1965 IIC_iMVNi, "mvn", "\t$dst, $imm",
1966 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1970 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1971 (BICri GPR:$src, so_imm_not:$imm)>;
1973 //===----------------------------------------------------------------------===//
1974 // Multiply Instructions.
1977 let isCommutable = 1 in
1978 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1979 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1980 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1982 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1983 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1984 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1986 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1987 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1988 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1989 Requires<[IsARM, HasV6T2]>;
1991 // Extra precision multiplies with low / high results
1992 let neverHasSideEffects = 1 in {
1993 let isCommutable = 1 in {
1994 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1995 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1996 "smull", "\t$ldst, $hdst, $a, $b", []>;
1998 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1999 (ins GPR:$a, GPR:$b), IIC_iMUL64,
2000 "umull", "\t$ldst, $hdst, $a, $b", []>;
2003 // Multiply + accumulate
2004 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
2005 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2006 "smlal", "\t$ldst, $hdst, $a, $b", []>;
2008 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
2009 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2010 "umlal", "\t$ldst, $hdst, $a, $b", []>;
2012 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
2013 (ins GPR:$a, GPR:$b), IIC_iMAC64,
2014 "umaal", "\t$ldst, $hdst, $a, $b", []>,
2015 Requires<[IsARM, HasV6]>;
2016 } // neverHasSideEffects
2018 // Most significant word multiply
2019 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2020 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
2021 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
2022 Requires<[IsARM, HasV6]> {
2023 let Inst{7-4} = 0b0001;
2024 let Inst{15-12} = 0b1111;
2027 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2028 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
2029 [/* For disassembly only; pattern left blank */]>,
2030 Requires<[IsARM, HasV6]> {
2031 let Inst{7-4} = 0b0011; // R = 1
2032 let Inst{15-12} = 0b1111;
2035 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2036 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
2037 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
2038 Requires<[IsARM, HasV6]> {
2039 let Inst{7-4} = 0b0001;
2042 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2043 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
2044 [/* For disassembly only; pattern left blank */]>,
2045 Requires<[IsARM, HasV6]> {
2046 let Inst{7-4} = 0b0011; // R = 1
2049 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2050 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
2051 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
2052 Requires<[IsARM, HasV6]> {
2053 let Inst{7-4} = 0b1101;
2056 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2057 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
2058 [/* For disassembly only; pattern left blank */]>,
2059 Requires<[IsARM, HasV6]> {
2060 let Inst{7-4} = 0b1111; // R = 1
2063 multiclass AI_smul<string opc, PatFrag opnode> {
2064 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2065 IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b",
2066 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2067 (sext_inreg GPR:$b, i16)))]>,
2068 Requires<[IsARM, HasV5TE]> {
2073 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2074 IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b",
2075 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2076 (sra GPR:$b, (i32 16))))]>,
2077 Requires<[IsARM, HasV5TE]> {
2082 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2083 IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b",
2084 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2085 (sext_inreg GPR:$b, i16)))]>,
2086 Requires<[IsARM, HasV5TE]> {
2091 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2092 IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b",
2093 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2094 (sra GPR:$b, (i32 16))))]>,
2095 Requires<[IsARM, HasV5TE]> {
2100 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2101 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
2102 [(set GPR:$dst, (sra (opnode GPR:$a,
2103 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
2104 Requires<[IsARM, HasV5TE]> {
2109 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2110 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
2111 [(set GPR:$dst, (sra (opnode GPR:$a,
2112 (sra GPR:$b, (i32 16))), (i32 16)))]>,
2113 Requires<[IsARM, HasV5TE]> {
2120 multiclass AI_smla<string opc, PatFrag opnode> {
2121 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2122 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2123 [(set GPR:$dst, (add GPR:$acc,
2124 (opnode (sext_inreg GPR:$a, i16),
2125 (sext_inreg GPR:$b, i16))))]>,
2126 Requires<[IsARM, HasV5TE]> {
2131 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2132 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2133 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
2134 (sra GPR:$b, (i32 16)))))]>,
2135 Requires<[IsARM, HasV5TE]> {
2140 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2141 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2142 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2143 (sext_inreg GPR:$b, i16))))]>,
2144 Requires<[IsARM, HasV5TE]> {
2149 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2150 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2151 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2152 (sra GPR:$b, (i32 16)))))]>,
2153 Requires<[IsARM, HasV5TE]> {
2158 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2159 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2160 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2161 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
2162 Requires<[IsARM, HasV5TE]> {
2167 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2168 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2169 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2170 (sra GPR:$b, (i32 16))), (i32 16))))]>,
2171 Requires<[IsARM, HasV5TE]> {
2177 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2178 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2180 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2181 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2182 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2183 [/* For disassembly only; pattern left blank */]>,
2184 Requires<[IsARM, HasV5TE]> {
2189 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2190 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2191 [/* For disassembly only; pattern left blank */]>,
2192 Requires<[IsARM, HasV5TE]> {
2197 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2198 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2199 [/* For disassembly only; pattern left blank */]>,
2200 Requires<[IsARM, HasV5TE]> {
2205 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2206 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2207 [/* For disassembly only; pattern left blank */]>,
2208 Requires<[IsARM, HasV5TE]> {
2213 // Helper class for AI_smld -- for disassembly only
2214 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2215 InstrItinClass itin, string opc, string asm>
2216 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2221 let Inst{21-20} = 0b00;
2222 let Inst{22} = long;
2223 let Inst{27-23} = 0b01110;
2226 multiclass AI_smld<bit sub, string opc> {
2228 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2229 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2231 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2232 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2234 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2235 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2237 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2238 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2242 defm SMLA : AI_smld<0, "smla">;
2243 defm SMLS : AI_smld<1, "smls">;
2245 multiclass AI_sdml<bit sub, string opc> {
2247 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2248 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2249 let Inst{15-12} = 0b1111;
2252 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2253 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2254 let Inst{15-12} = 0b1111;
2259 defm SMUA : AI_sdml<0, "smua">;
2260 defm SMUS : AI_sdml<1, "smus">;
2262 //===----------------------------------------------------------------------===//
2263 // Misc. Arithmetic Instructions.
2266 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2267 "clz", "\t$dst, $src",
2268 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2269 let Inst{7-4} = 0b0001;
2270 let Inst{11-8} = 0b1111;
2271 let Inst{19-16} = 0b1111;
2274 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2275 "rbit", "\t$dst, $src",
2276 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2277 Requires<[IsARM, HasV6T2]> {
2278 let Inst{7-4} = 0b0011;
2279 let Inst{11-8} = 0b1111;
2280 let Inst{19-16} = 0b1111;
2283 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2284 "rev", "\t$dst, $src",
2285 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2286 let Inst{7-4} = 0b0011;
2287 let Inst{11-8} = 0b1111;
2288 let Inst{19-16} = 0b1111;
2291 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2292 "rev16", "\t$dst, $src",
2294 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2295 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2296 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2297 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2298 Requires<[IsARM, HasV6]> {
2299 let Inst{7-4} = 0b1011;
2300 let Inst{11-8} = 0b1111;
2301 let Inst{19-16} = 0b1111;
2304 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2305 "revsh", "\t$dst, $src",
2308 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2309 (shl GPR:$src, (i32 8))), i16))]>,
2310 Requires<[IsARM, HasV6]> {
2311 let Inst{7-4} = 0b1011;
2312 let Inst{11-8} = 0b1111;
2313 let Inst{19-16} = 0b1111;
2316 def lsl_shift_imm : SDNodeXForm<imm, [{
2317 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2318 return CurDAG->getTargetConstant(Sh, MVT::i32);
2321 def lsl_amt : PatLeaf<(i32 imm), [{
2322 return (N->getZExtValue() < 32);
2325 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2326 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2327 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2328 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2329 (and (shl GPR:$src2, lsl_amt:$sh),
2331 Requires<[IsARM, HasV6]> {
2332 let Inst{6-4} = 0b001;
2335 // Alternate cases for PKHBT where identities eliminate some nodes.
2336 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2337 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2338 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
2339 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
2341 def asr_shift_imm : SDNodeXForm<imm, [{
2342 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2343 return CurDAG->getTargetConstant(Sh, MVT::i32);
2346 def asr_amt : PatLeaf<(i32 imm), [{
2347 return (N->getZExtValue() <= 32);
2350 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2351 // will match the pattern below.
2352 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2353 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2354 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2355 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2356 (and (sra GPR:$src2, asr_amt:$sh),
2358 Requires<[IsARM, HasV6]> {
2359 let Inst{6-4} = 0b101;
2362 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2363 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2364 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2365 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2366 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2367 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2368 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2370 //===----------------------------------------------------------------------===//
2371 // Comparison Instructions...
2374 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2375 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2376 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2378 // FIXME: We have to be careful when using the CMN instruction and comparison
2379 // with 0. One would expect these two pieces of code should give identical
2395 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2396 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2397 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2398 // value of r0 and the carry bit (because the "carry bit" parameter to
2399 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2400 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2401 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2402 // parameter to AddWithCarry is defined as 0).
2404 // When x is 0 and unsigned:
2408 // ~x + 1 = 0x1 0000 0000
2409 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2411 // Therefore, we should disable CMN when comparing against zero, until we can
2412 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2413 // when it's a comparison which doesn't look at the 'carry' flag).
2415 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2417 // This is related to <rdar://problem/7569620>.
2419 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2420 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2422 // Note that TST/TEQ don't set all the same flags that CMP does!
2423 defm TST : AI1_cmp_irs<0b1000, "tst",
2424 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2425 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2426 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2427 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2428 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2430 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2431 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2432 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2433 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2434 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2435 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2437 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2438 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2440 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2441 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2443 // Pseudo i64 compares for some floating point compares.
2444 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2446 def BCCi64 : PseudoInst<(outs),
2447 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2449 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2451 def BCCZi64 : PseudoInst<(outs),
2452 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2453 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2454 } // usesCustomInserter
2457 // Conditional moves
2458 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2459 // a two-value operand where a dag node expects two operands. :(
2460 // FIXME: These should all be pseudo-instructions that get expanded to
2461 // the normal MOV instructions. That would fix the dependency on
2462 // special casing them in tblgen.
2463 let neverHasSideEffects = 1 in {
2464 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2465 IIC_iCMOVr, "mov", "\t$dst, $true",
2466 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2467 RegConstraint<"$false = $dst">, UnaryDP {
2468 let Inst{11-4} = 0b00000000;
2472 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2473 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2474 "mov", "\t$dst, $true",
2475 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2476 RegConstraint<"$false = $dst">, UnaryDP {
2480 def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src),
2482 "movw", "\t$dst, $src",
2484 RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>,
2490 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2491 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2492 "mov", "\t$dst, $true",
2493 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2494 RegConstraint<"$false = $dst">, UnaryDP {
2497 } // neverHasSideEffects
2499 //===----------------------------------------------------------------------===//
2500 // Atomic operations intrinsics
2503 // memory barriers protect the atomic sequences
2504 let hasSideEffects = 1 in {
2505 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2506 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2507 let Inst{31-4} = 0xf57ff05;
2508 // FIXME: add support for options other than a full system DMB
2509 // See DMB disassembly-only variants below.
2510 let Inst{3-0} = 0b1111;
2513 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2514 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2515 let Inst{31-4} = 0xf57ff04;
2516 // FIXME: add support for options other than a full system DSB
2517 // See DSB disassembly-only variants below.
2518 let Inst{3-0} = 0b1111;
2521 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2522 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2523 [(ARMMemBarrierMCR GPR:$zero)]>,
2524 Requires<[IsARM, HasV6]> {
2525 // FIXME: add support for options other than a full system DMB
2526 // FIXME: add encoding
2529 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2530 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2531 [(ARMSyncBarrierMCR GPR:$zero)]>,
2532 Requires<[IsARM, HasV6]> {
2533 // FIXME: add support for options other than a full system DSB
2534 // FIXME: add encoding
2538 // Memory Barrier Operations Variants -- for disassembly only
2540 def memb_opt : Operand<i32> {
2541 let PrintMethod = "printMemBOption";
2544 class AMBI<bits<4> op7_4, string opc>
2545 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2546 [/* For disassembly only; pattern left blank */]>,
2547 Requires<[IsARM, HasDB]> {
2548 let Inst{31-8} = 0xf57ff0;
2549 let Inst{7-4} = op7_4;
2552 // These DMB variants are for disassembly only.
2553 def DMBvar : AMBI<0b0101, "dmb">;
2555 // These DSB variants are for disassembly only.
2556 def DSBvar : AMBI<0b0100, "dsb">;
2558 // ISB has only full system option -- for disassembly only
2559 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2560 Requires<[IsARM, HasDB]> {
2561 let Inst{31-4} = 0xf57ff06;
2562 let Inst{3-0} = 0b1111;
2565 let usesCustomInserter = 1 in {
2566 let Uses = [CPSR] in {
2567 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2568 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2569 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2570 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2571 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2572 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2573 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2574 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2575 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2576 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2577 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2578 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2579 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2580 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2581 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2582 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2583 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2584 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2585 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2586 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2587 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2588 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2589 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2590 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2591 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2592 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2593 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2594 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2595 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2596 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2597 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2598 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2599 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2600 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2601 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2602 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2603 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2604 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2605 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2606 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2607 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2608 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2609 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2610 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2611 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2612 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2613 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2614 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2615 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2616 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2617 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2618 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2619 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2620 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2622 def ATOMIC_SWAP_I8 : PseudoInst<
2623 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2624 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2625 def ATOMIC_SWAP_I16 : PseudoInst<
2626 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2627 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2628 def ATOMIC_SWAP_I32 : PseudoInst<
2629 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2630 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2632 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2633 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2634 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2635 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2636 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2637 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2638 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2639 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2640 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2644 let mayLoad = 1 in {
2645 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2646 "ldrexb", "\t$dest, [$ptr]",
2648 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2649 "ldrexh", "\t$dest, [$ptr]",
2651 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2652 "ldrex", "\t$dest, [$ptr]",
2654 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2656 "ldrexd", "\t$dest, $dest2, [$ptr]",
2660 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2661 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2663 "strexb", "\t$success, $src, [$ptr]",
2665 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2667 "strexh", "\t$success, $src, [$ptr]",
2669 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2671 "strex", "\t$success, $src, [$ptr]",
2673 def STREXD : AIstrex<0b01, (outs GPR:$success),
2674 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2676 "strexd", "\t$success, $src, $src2, [$ptr]",
2680 // Clear-Exclusive is for disassembly only.
2681 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2682 [/* For disassembly only; pattern left blank */]>,
2683 Requires<[IsARM, HasV7]> {
2684 let Inst{31-20} = 0xf57;
2685 let Inst{7-4} = 0b0001;
2688 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2689 let mayLoad = 1 in {
2690 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2691 "swp", "\t$dst, $src, [$ptr]",
2692 [/* For disassembly only; pattern left blank */]> {
2693 let Inst{27-23} = 0b00010;
2694 let Inst{22} = 0; // B = 0
2695 let Inst{21-20} = 0b00;
2696 let Inst{7-4} = 0b1001;
2699 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2700 "swpb", "\t$dst, $src, [$ptr]",
2701 [/* For disassembly only; pattern left blank */]> {
2702 let Inst{27-23} = 0b00010;
2703 let Inst{22} = 1; // B = 1
2704 let Inst{21-20} = 0b00;
2705 let Inst{7-4} = 0b1001;
2709 //===----------------------------------------------------------------------===//
2713 // __aeabi_read_tp preserves the registers r1-r3.
2715 Defs = [R0, R12, LR, CPSR] in {
2716 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2717 "bl\t__aeabi_read_tp",
2718 [(set R0, ARMthread_pointer)]>;
2721 //===----------------------------------------------------------------------===//
2722 // SJLJ Exception handling intrinsics
2723 // eh_sjlj_setjmp() is an instruction sequence to store the return
2724 // address and save #0 in R0 for the non-longjmp case.
2725 // Since by its nature we may be coming from some other function to get
2726 // here, and we're using the stack frame for the containing function to
2727 // save/restore registers, we can't keep anything live in regs across
2728 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2729 // when we get here from a longjmp(). We force everthing out of registers
2730 // except for our own input by listing the relevant registers in Defs. By
2731 // doing so, we also cause the prologue/epilogue code to actively preserve
2732 // all of the callee-saved resgisters, which is exactly what we want.
2733 // A constant value is passed in $val, and we use the location as a scratch.
2735 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2736 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2737 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2738 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2739 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2740 AddrModeNone, SizeSpecial, IndexModeNone,
2741 Pseudo, NoItinerary, "", "",
2742 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2743 Requires<[IsARM, HasVFP2]>;
2747 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2748 hasSideEffects = 1, isBarrier = 1 in {
2749 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2750 AddrModeNone, SizeSpecial, IndexModeNone,
2751 Pseudo, NoItinerary, "", "",
2752 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2753 Requires<[IsARM, NoVFP]>;
2756 // FIXME: Non-Darwin version(s)
2757 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
2758 Defs = [ R7, LR, SP ] in {
2759 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
2760 AddrModeNone, SizeSpecial, IndexModeNone,
2761 Pseudo, NoItinerary, "", "",
2762 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
2763 Requires<[IsARM, IsDarwin]>;
2766 //===----------------------------------------------------------------------===//
2767 // Non-Instruction Patterns
2770 // Large immediate handling.
2772 // Two piece so_imms.
2773 // FIXME: Expand this in ARMExpandPseudoInsts.
2774 // FIXME: Remove this when we can do generalized remat.
2775 let isReMaterializable = 1 in
2776 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2777 Pseudo, IIC_iMOVix2,
2778 "mov", "\t$dst, $src",
2779 [(set GPR:$dst, so_imm2part:$src)]>,
2780 Requires<[IsARM, NoV6T2]>;
2782 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2783 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2784 (so_imm2part_2 imm:$RHS))>;
2785 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2786 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2787 (so_imm2part_2 imm:$RHS))>;
2788 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2789 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2790 (so_imm2part_2 imm:$RHS))>;
2791 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2792 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2793 (so_neg_imm2part_2 imm:$RHS))>;
2795 // 32-bit immediate using movw + movt.
2796 // This is a single pseudo instruction, the benefit is that it can be remat'd
2797 // as a single unit instead of having to handle reg inputs.
2798 // FIXME: Remove this when we can do generalized remat.
2799 let isReMaterializable = 1 in
2800 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
2801 [(set GPR:$dst, (i32 imm:$src))]>,
2802 Requires<[IsARM, HasV6T2]>;
2804 // ConstantPool, GlobalAddress, and JumpTable
2805 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2806 Requires<[IsARM, DontUseMovt]>;
2807 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2808 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2809 Requires<[IsARM, UseMovt]>;
2810 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2811 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2813 // TODO: add,sub,and, 3-instr forms?
2816 def : ARMPat<(ARMtcret tcGPR:$dst),
2817 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
2819 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2820 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2822 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2823 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2825 def : ARMPat<(ARMtcret tcGPR:$dst),
2826 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
2828 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2829 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2831 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2832 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2835 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2836 Requires<[IsARM, IsNotDarwin]>;
2837 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2838 Requires<[IsARM, IsDarwin]>;
2840 // zextload i1 -> zextload i8
2841 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2843 // extload -> zextload
2844 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2845 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2846 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2848 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2849 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2852 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2853 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2854 (SMULBB GPR:$a, GPR:$b)>;
2855 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2856 (SMULBB GPR:$a, GPR:$b)>;
2857 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2858 (sra GPR:$b, (i32 16))),
2859 (SMULBT GPR:$a, GPR:$b)>;
2860 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2861 (SMULBT GPR:$a, GPR:$b)>;
2862 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2863 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2864 (SMULTB GPR:$a, GPR:$b)>;
2865 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2866 (SMULTB GPR:$a, GPR:$b)>;
2867 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2869 (SMULWB GPR:$a, GPR:$b)>;
2870 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2871 (SMULWB GPR:$a, GPR:$b)>;
2873 def : ARMV5TEPat<(add GPR:$acc,
2874 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2875 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2876 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2877 def : ARMV5TEPat<(add GPR:$acc,
2878 (mul sext_16_node:$a, sext_16_node:$b)),
2879 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2880 def : ARMV5TEPat<(add GPR:$acc,
2881 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2882 (sra GPR:$b, (i32 16)))),
2883 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2884 def : ARMV5TEPat<(add GPR:$acc,
2885 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2886 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2887 def : ARMV5TEPat<(add GPR:$acc,
2888 (mul (sra GPR:$a, (i32 16)),
2889 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2890 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2891 def : ARMV5TEPat<(add GPR:$acc,
2892 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2893 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2894 def : ARMV5TEPat<(add GPR:$acc,
2895 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2897 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2898 def : ARMV5TEPat<(add GPR:$acc,
2899 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2900 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2902 //===----------------------------------------------------------------------===//
2906 include "ARMInstrThumb.td"
2908 //===----------------------------------------------------------------------===//
2912 include "ARMInstrThumb2.td"
2914 //===----------------------------------------------------------------------===//
2915 // Floating Point Support
2918 include "ARMInstrVFP.td"
2920 //===----------------------------------------------------------------------===//
2921 // Advanced SIMD (NEON) Support
2924 include "ARMInstrNEON.td"
2926 //===----------------------------------------------------------------------===//
2927 // Coprocessor Instructions. For disassembly only.
2930 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2931 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2932 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2933 [/* For disassembly only; pattern left blank */]> {
2937 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2938 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2939 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2940 [/* For disassembly only; pattern left blank */]> {
2941 let Inst{31-28} = 0b1111;
2945 class ACI<dag oops, dag iops, string opc, string asm>
2946 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2947 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2948 let Inst{27-25} = 0b110;
2951 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2953 def _OFFSET : ACI<(outs),
2954 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2955 opc, "\tp$cop, cr$CRd, $addr"> {
2956 let Inst{31-28} = op31_28;
2957 let Inst{24} = 1; // P = 1
2958 let Inst{21} = 0; // W = 0
2959 let Inst{22} = 0; // D = 0
2960 let Inst{20} = load;
2963 def _PRE : ACI<(outs),
2964 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2965 opc, "\tp$cop, cr$CRd, $addr!"> {
2966 let Inst{31-28} = op31_28;
2967 let Inst{24} = 1; // P = 1
2968 let Inst{21} = 1; // W = 1
2969 let Inst{22} = 0; // D = 0
2970 let Inst{20} = load;
2973 def _POST : ACI<(outs),
2974 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2975 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2976 let Inst{31-28} = op31_28;
2977 let Inst{24} = 0; // P = 0
2978 let Inst{21} = 1; // W = 1
2979 let Inst{22} = 0; // D = 0
2980 let Inst{20} = load;
2983 def _OPTION : ACI<(outs),
2984 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2985 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2986 let Inst{31-28} = op31_28;
2987 let Inst{24} = 0; // P = 0
2988 let Inst{23} = 1; // U = 1
2989 let Inst{21} = 0; // W = 0
2990 let Inst{22} = 0; // D = 0
2991 let Inst{20} = load;
2994 def L_OFFSET : ACI<(outs),
2995 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2996 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
2997 let Inst{31-28} = op31_28;
2998 let Inst{24} = 1; // P = 1
2999 let Inst{21} = 0; // W = 0
3000 let Inst{22} = 1; // D = 1
3001 let Inst{20} = load;
3004 def L_PRE : ACI<(outs),
3005 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3006 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3007 let Inst{31-28} = op31_28;
3008 let Inst{24} = 1; // P = 1
3009 let Inst{21} = 1; // W = 1
3010 let Inst{22} = 1; // D = 1
3011 let Inst{20} = load;
3014 def L_POST : ACI<(outs),
3015 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3016 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3017 let Inst{31-28} = op31_28;
3018 let Inst{24} = 0; // P = 0
3019 let Inst{21} = 1; // W = 1
3020 let Inst{22} = 1; // D = 1
3021 let Inst{20} = load;
3024 def L_OPTION : ACI<(outs),
3025 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3026 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3027 let Inst{31-28} = op31_28;
3028 let Inst{24} = 0; // P = 0
3029 let Inst{23} = 1; // U = 1
3030 let Inst{21} = 0; // W = 0
3031 let Inst{22} = 1; // D = 1
3032 let Inst{20} = load;
3036 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3037 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3038 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3039 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3041 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3042 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3043 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3044 [/* For disassembly only; pattern left blank */]> {
3049 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3050 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3051 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3052 [/* For disassembly only; pattern left blank */]> {
3053 let Inst{31-28} = 0b1111;
3058 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3059 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3060 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3061 [/* For disassembly only; pattern left blank */]> {
3066 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3067 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3068 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3069 [/* For disassembly only; pattern left blank */]> {
3070 let Inst{31-28} = 0b1111;
3075 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3076 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3077 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3078 [/* For disassembly only; pattern left blank */]> {
3079 let Inst{23-20} = 0b0100;
3082 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3083 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3084 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3085 [/* For disassembly only; pattern left blank */]> {
3086 let Inst{31-28} = 0b1111;
3087 let Inst{23-20} = 0b0100;
3090 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3091 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3092 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3093 [/* For disassembly only; pattern left blank */]> {
3094 let Inst{23-20} = 0b0101;
3097 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3098 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3099 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3100 [/* For disassembly only; pattern left blank */]> {
3101 let Inst{31-28} = 0b1111;
3102 let Inst{23-20} = 0b0101;
3105 //===----------------------------------------------------------------------===//
3106 // Move between special register and ARM core register -- for disassembly only
3109 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3110 [/* For disassembly only; pattern left blank */]> {
3111 let Inst{23-20} = 0b0000;
3112 let Inst{7-4} = 0b0000;
3115 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3116 [/* For disassembly only; pattern left blank */]> {
3117 let Inst{23-20} = 0b0100;
3118 let Inst{7-4} = 0b0000;
3121 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3122 "msr", "\tcpsr$mask, $src",
3123 [/* For disassembly only; pattern left blank */]> {
3124 let Inst{23-20} = 0b0010;
3125 let Inst{7-4} = 0b0000;
3128 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3129 "msr", "\tcpsr$mask, $a",
3130 [/* For disassembly only; pattern left blank */]> {
3131 let Inst{23-20} = 0b0010;
3132 let Inst{7-4} = 0b0000;
3135 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3136 "msr", "\tspsr$mask, $src",
3137 [/* For disassembly only; pattern left blank */]> {
3138 let Inst{23-20} = 0b0110;
3139 let Inst{7-4} = 0b0000;
3142 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3143 "msr", "\tspsr$mask, $a",
3144 [/* For disassembly only; pattern left blank */]> {
3145 let Inst{23-20} = 0b0110;
3146 let Inst{7-4} = 0b0000;