1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>;
62 def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
63 def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
64 def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
66 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
68 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
69 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
72 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
73 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
75 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
76 [SDNPHasChain, SDNPOutFlag]>;
77 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
78 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
80 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
81 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
83 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
84 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
86 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
87 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
90 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
91 [SDNPHasChain, SDNPOptInFlag]>;
93 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
95 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
98 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
99 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
101 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
103 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
106 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
109 def ARMand : SDNode<"ARMISD::AND", SDT_ARMAnd,
112 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
115 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
116 [SDNPOutFlag, SDNPCommutative]>;
118 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
120 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
121 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
122 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
124 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
125 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
126 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
128 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
130 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
132 def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
134 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR,
136 def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR,
139 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
141 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
142 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
145 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
147 //===----------------------------------------------------------------------===//
148 // ARM Instruction Predicate Definitions.
150 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
151 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
152 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
153 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
154 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">;
162 def HasDivide : Predicate<"Subtarget->hasDivide()">;
163 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
164 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
165 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
166 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
167 def IsThumb : Predicate<"Subtarget->isThumb()">;
168 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
169 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
170 def IsARM : Predicate<"!Subtarget->isThumb()">;
171 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
172 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
174 // FIXME: Eventually this will be just "hasV6T2Ops".
175 def UseMovt : Predicate<"Subtarget->useMovt()">;
176 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
177 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
179 //===----------------------------------------------------------------------===//
180 // ARM Flag Definitions.
182 class RegConstraint<string C> {
183 string Constraints = C;
186 //===----------------------------------------------------------------------===//
187 // ARM specific transformation functions and pattern fragments.
190 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
191 // so_imm_neg def below.
192 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
193 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
196 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
197 // so_imm_not def below.
198 def so_imm_not_XFORM : SDNodeXForm<imm, [{
199 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
202 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
203 def rot_imm : PatLeaf<(i32 imm), [{
204 int32_t v = (int32_t)N->getZExtValue();
205 return v == 8 || v == 16 || v == 24;
208 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
209 def imm1_15 : PatLeaf<(i32 imm), [{
210 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
213 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
214 def imm16_31 : PatLeaf<(i32 imm), [{
215 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
220 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
221 }], so_imm_neg_XFORM>;
225 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
226 }], so_imm_not_XFORM>;
228 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
229 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
230 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
233 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
235 def bf_inv_mask_imm : Operand<i32>,
237 return ARM::isBitFieldInvertedMask(N->getZExtValue());
239 let PrintMethod = "printBitfieldInvMaskImmOperand";
242 /// Split a 32-bit immediate into two 16 bit parts.
243 def hi16 : SDNodeXForm<imm, [{
244 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
247 def lo16AllZero : PatLeaf<(i32 imm), [{
248 // Returns true if all low 16-bits are 0.
249 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
252 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
254 def imm0_65535 : PatLeaf<(i32 imm), [{
255 return (uint32_t)N->getZExtValue() < 65536;
258 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
259 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
261 /// adde and sube predicates - True based on whether the carry flag output
262 /// will be needed or not.
263 def adde_dead_carry :
264 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
265 [{return !N->hasAnyUseOfValue(1);}]>;
266 def sube_dead_carry :
267 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
268 [{return !N->hasAnyUseOfValue(1);}]>;
269 def adde_live_carry :
270 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
271 [{return N->hasAnyUseOfValue(1);}]>;
272 def sube_live_carry :
273 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
274 [{return N->hasAnyUseOfValue(1);}]>;
276 //===----------------------------------------------------------------------===//
277 // Operand Definitions.
281 def brtarget : Operand<OtherVT>;
283 // A list of registers separated by comma. Used by load/store multiple.
284 def reglist : Operand<i32> {
285 let PrintMethod = "printRegisterList";
288 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
289 def cpinst_operand : Operand<i32> {
290 let PrintMethod = "printCPInstOperand";
293 def jtblock_operand : Operand<i32> {
294 let PrintMethod = "printJTBlockOperand";
296 def jt2block_operand : Operand<i32> {
297 let PrintMethod = "printJT2BlockOperand";
301 def pclabel : Operand<i32> {
302 let PrintMethod = "printPCLabel";
305 // shift_imm: An integer that encodes a shift amount and the type of shift
306 // (currently either asr or lsl) using the same encoding used for the
307 // immediates in so_reg operands.
308 def shift_imm : Operand<i32> {
309 let PrintMethod = "printShiftImmOperand";
312 // shifter_operand operands: so_reg and so_imm.
313 def so_reg : Operand<i32>, // reg reg imm
314 ComplexPattern<i32, 3, "SelectShifterOperandReg",
315 [shl,srl,sra,rotr]> {
316 let PrintMethod = "printSORegOperand";
317 let MIOperandInfo = (ops GPR, GPR, i32imm);
320 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
321 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
322 // represented in the imm field in the same 12-bit form that they are encoded
323 // into so_imm instructions: the 8-bit immediate is the least significant bits
324 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
325 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
326 let PrintMethod = "printSOImmOperand";
329 // Break so_imm's up into two pieces. This handles immediates with up to 16
330 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
331 // get the first/second pieces.
332 def so_imm2part : Operand<i32>,
334 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
336 let PrintMethod = "printSOImm2PartOperand";
339 def so_imm2part_1 : SDNodeXForm<imm, [{
340 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
341 return CurDAG->getTargetConstant(V, MVT::i32);
344 def so_imm2part_2 : SDNodeXForm<imm, [{
345 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
346 return CurDAG->getTargetConstant(V, MVT::i32);
349 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
350 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
352 let PrintMethod = "printSOImm2PartOperand";
355 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
356 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
357 return CurDAG->getTargetConstant(V, MVT::i32);
360 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
361 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
362 return CurDAG->getTargetConstant(V, MVT::i32);
365 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
366 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
367 return (int32_t)N->getZExtValue() < 32;
370 // Define ARM specific addressing modes.
372 // addrmode2base := reg +/- imm12
374 def addrmode2base : Operand<i32>,
375 ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
376 let PrintMethod = "printAddrMode2Operand";
377 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
379 // addrmode2shop := reg +/- reg shop imm
381 def addrmode2shop : Operand<i32>,
382 ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
383 let PrintMethod = "printAddrMode2Operand";
384 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
387 // addrmode2 := (addrmode2base || addrmode2shop)
389 def addrmode2 : Operand<i32>,
390 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
391 let PrintMethod = "printAddrMode2Operand";
392 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
395 def am2offset : Operand<i32>,
396 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
397 [], [SDNPWantRoot]> {
398 let PrintMethod = "printAddrMode2OffsetOperand";
399 let MIOperandInfo = (ops GPR, i32imm);
402 // addrmode3 := reg +/- reg
403 // addrmode3 := reg +/- imm8
405 def addrmode3 : Operand<i32>,
406 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
407 let PrintMethod = "printAddrMode3Operand";
408 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
411 def am3offset : Operand<i32>,
412 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
413 [], [SDNPWantRoot]> {
414 let PrintMethod = "printAddrMode3OffsetOperand";
415 let MIOperandInfo = (ops GPR, i32imm);
418 // addrmode4 := reg, <mode|W>
420 def addrmode4 : Operand<i32>,
421 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
422 let PrintMethod = "printAddrMode4Operand";
423 let MIOperandInfo = (ops GPR:$addr, i32imm);
426 // addrmode5 := reg +/- imm8*4
428 def addrmode5 : Operand<i32>,
429 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
430 let PrintMethod = "printAddrMode5Operand";
431 let MIOperandInfo = (ops GPR:$base, i32imm);
434 // addrmode6 := reg with optional writeback
436 def addrmode6 : Operand<i32>,
437 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
438 let PrintMethod = "printAddrMode6Operand";
439 let MIOperandInfo = (ops GPR:$addr, i32imm);
442 def am6offset : Operand<i32> {
443 let PrintMethod = "printAddrMode6OffsetOperand";
444 let MIOperandInfo = (ops GPR);
447 // addrmodepc := pc + reg
449 def addrmodepc : Operand<i32>,
450 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
451 let PrintMethod = "printAddrModePCOperand";
452 let MIOperandInfo = (ops GPR, i32imm);
455 def nohash_imm : Operand<i32> {
456 let PrintMethod = "printNoHashImmediate";
459 //===----------------------------------------------------------------------===//
461 include "ARMInstrFormats.td"
463 //===----------------------------------------------------------------------===//
464 // Multiclass helpers...
467 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
468 /// binop that produces a value.
469 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
470 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
471 PatFrag opnode, bit Commutable = 0> {
472 // The register-immediate version is re-materializable. This is useful
473 // in particular for taking the address of a local.
474 let isReMaterializable = 1 in {
475 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
476 iii, opc, "\t$dst, $a, $b",
477 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
481 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
482 iir, opc, "\t$dst, $a, $b",
483 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
484 let Inst{11-4} = 0b00000000;
486 let isCommutable = Commutable;
488 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
489 iis, opc, "\t$dst, $a, $b",
490 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
495 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
496 /// instruction modifies the CPSR register.
497 let Defs = [CPSR] in {
498 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
499 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
500 PatFrag opnode, bit Commutable = 0> {
501 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
502 iii, opc, "\t$dst, $a, $b",
503 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
507 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
508 iir, opc, "\t$dst, $a, $b",
509 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
510 let isCommutable = Commutable;
511 let Inst{11-4} = 0b00000000;
515 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
516 iis, opc, "\t$dst, $a, $b",
517 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
524 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
525 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
526 /// a explicit result, only implicitly set CPSR.
527 let isCompare = 1, Defs = [CPSR] in {
528 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
529 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
530 PatFrag opnode, bit Commutable = 0> {
531 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, iii,
533 [(opnode GPR:$a, so_imm:$b)]> {
537 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, iir,
539 [(opnode GPR:$a, GPR:$b)]> {
540 let Inst{11-4} = 0b00000000;
543 let isCommutable = Commutable;
545 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, iis,
547 [(opnode GPR:$a, so_reg:$b)]> {
554 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
555 /// register and one whose operand is a register rotated by 8/16/24.
556 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
557 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
558 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
559 IIC_iEXTr, opc, "\t$dst, $src",
560 [(set GPR:$dst, (opnode GPR:$src))]>,
561 Requires<[IsARM, HasV6]> {
562 let Inst{11-10} = 0b00;
563 let Inst{19-16} = 0b1111;
565 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
566 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
567 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
568 Requires<[IsARM, HasV6]> {
569 let Inst{19-16} = 0b1111;
573 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
574 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
575 IIC_iEXTr, opc, "\t$dst, $src",
576 [/* For disassembly only; pattern left blank */]>,
577 Requires<[IsARM, HasV6]> {
578 let Inst{11-10} = 0b00;
579 let Inst{19-16} = 0b1111;
581 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
582 IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
583 [/* For disassembly only; pattern left blank */]>,
584 Requires<[IsARM, HasV6]> {
585 let Inst{19-16} = 0b1111;
589 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
590 /// register and one whose operand is a register rotated by 8/16/24.
591 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
592 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
593 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
594 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
595 Requires<[IsARM, HasV6]> {
596 let Inst{11-10} = 0b00;
598 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
600 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
601 [(set GPR:$dst, (opnode GPR:$LHS,
602 (rotr GPR:$RHS, rot_imm:$rot)))]>,
603 Requires<[IsARM, HasV6]>;
606 // For disassembly only.
607 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
608 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
609 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
610 [/* For disassembly only; pattern left blank */]>,
611 Requires<[IsARM, HasV6]> {
612 let Inst{11-10} = 0b00;
614 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
616 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
617 [/* For disassembly only; pattern left blank */]>,
618 Requires<[IsARM, HasV6]>;
621 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
622 let Uses = [CPSR] in {
623 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
624 bit Commutable = 0> {
625 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
626 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
627 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
631 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
632 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
633 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
635 let isCommutable = Commutable;
636 let Inst{11-4} = 0b00000000;
639 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
640 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
641 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
646 // Carry setting variants
647 let Defs = [CPSR] in {
648 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
649 bit Commutable = 0> {
650 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
651 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
652 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
657 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
658 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
659 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
661 let Inst{11-4} = 0b00000000;
665 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
666 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
667 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
676 //===----------------------------------------------------------------------===//
678 //===----------------------------------------------------------------------===//
680 //===----------------------------------------------------------------------===//
681 // Miscellaneous Instructions.
684 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
685 /// the function. The first operand is the ID# for this instruction, the second
686 /// is the index into the MachineConstantPool that this is, the third is the
687 /// size in bytes of this constant pool entry.
688 let neverHasSideEffects = 1, isNotDuplicable = 1 in
689 def CONSTPOOL_ENTRY :
690 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
691 i32imm:$size), NoItinerary,
692 "${instid:label} ${cpidx:cpentry}", []>;
694 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
695 // from removing one half of the matched pairs. That breaks PEI, which assumes
696 // these will always be in pairs, and asserts if it finds otherwise. Better way?
697 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
699 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
700 "${:comment} ADJCALLSTACKUP $amt1",
701 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
703 def ADJCALLSTACKDOWN :
704 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
705 "${:comment} ADJCALLSTACKDOWN $amt",
706 [(ARMcallseq_start timm:$amt)]>;
709 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
710 [/* For disassembly only; pattern left blank */]>,
711 Requires<[IsARM, HasV6T2]> {
712 let Inst{27-16} = 0b001100100000;
713 let Inst{7-0} = 0b00000000;
716 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
717 [/* For disassembly only; pattern left blank */]>,
718 Requires<[IsARM, HasV6T2]> {
719 let Inst{27-16} = 0b001100100000;
720 let Inst{7-0} = 0b00000001;
723 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
724 [/* For disassembly only; pattern left blank */]>,
725 Requires<[IsARM, HasV6T2]> {
726 let Inst{27-16} = 0b001100100000;
727 let Inst{7-0} = 0b00000010;
730 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
731 [/* For disassembly only; pattern left blank */]>,
732 Requires<[IsARM, HasV6T2]> {
733 let Inst{27-16} = 0b001100100000;
734 let Inst{7-0} = 0b00000011;
737 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
739 [/* For disassembly only; pattern left blank */]>,
740 Requires<[IsARM, HasV6]> {
741 let Inst{27-20} = 0b01101000;
742 let Inst{7-4} = 0b1011;
745 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
746 [/* For disassembly only; pattern left blank */]>,
747 Requires<[IsARM, HasV6T2]> {
748 let Inst{27-16} = 0b001100100000;
749 let Inst{7-0} = 0b00000100;
752 // The i32imm operand $val can be used by a debugger to store more information
753 // about the breakpoint.
754 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
755 [/* For disassembly only; pattern left blank */]>,
757 let Inst{27-20} = 0b00010010;
758 let Inst{7-4} = 0b0111;
761 // Change Processor State is a system instruction -- for disassembly only.
762 // The singleton $opt operand contains the following information:
763 // opt{4-0} = mode from Inst{4-0}
764 // opt{5} = changemode from Inst{17}
765 // opt{8-6} = AIF from Inst{8-6}
766 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
767 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
768 [/* For disassembly only; pattern left blank */]>,
770 let Inst{31-28} = 0b1111;
771 let Inst{27-20} = 0b00010000;
776 // Preload signals the memory system of possible future data/instruction access.
777 // These are for disassembly only.
779 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
780 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
781 multiclass APreLoad<bit data, bit read, string opc> {
783 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
784 !strconcat(opc, "\t[$base, $imm]"), []> {
785 let Inst{31-26} = 0b111101;
786 let Inst{25} = 0; // 0 for immediate form
789 let Inst{21-20} = 0b01;
792 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
793 !strconcat(opc, "\t$addr"), []> {
794 let Inst{31-26} = 0b111101;
795 let Inst{25} = 1; // 1 for register form
798 let Inst{21-20} = 0b01;
803 defm PLD : APreLoad<1, 1, "pld">;
804 defm PLDW : APreLoad<1, 0, "pldw">;
805 defm PLI : APreLoad<0, 1, "pli">;
807 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
808 [/* For disassembly only; pattern left blank */]>,
810 let Inst{31-28} = 0b1111;
811 let Inst{27-20} = 0b00010000;
814 let Inst{7-4} = 0b0000;
817 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
818 [/* For disassembly only; pattern left blank */]>,
820 let Inst{31-28} = 0b1111;
821 let Inst{27-20} = 0b00010000;
824 let Inst{7-4} = 0b0000;
827 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
828 [/* For disassembly only; pattern left blank */]>,
829 Requires<[IsARM, HasV7]> {
830 let Inst{27-16} = 0b001100100000;
831 let Inst{7-4} = 0b1111;
834 // A5.4 Permanently UNDEFINED instructions.
835 let isBarrier = 1, isTerminator = 1 in
836 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
839 let Inst{27-25} = 0b011;
840 let Inst{24-20} = 0b11111;
841 let Inst{7-5} = 0b111;
845 // Address computation and loads and stores in PIC mode.
846 let isNotDuplicable = 1 in {
847 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
848 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
849 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
851 let AddedComplexity = 10 in {
852 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
853 Pseudo, IIC_iLoad_r, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
854 [(set GPR:$dst, (load addrmodepc:$addr))]>;
856 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
857 Pseudo, IIC_iLoad_bh_r, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
858 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
860 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
861 Pseudo, IIC_iLoad_bh_r, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
862 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
864 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
865 Pseudo, IIC_iLoad_bh_r, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
866 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
868 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
869 Pseudo, IIC_iLoad_bh_r, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
870 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
872 let AddedComplexity = 10 in {
873 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
874 Pseudo, IIC_iStore_r, "\n${addr:label}:\n\tstr$p\t$src, $addr",
875 [(store GPR:$src, addrmodepc:$addr)]>;
877 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
878 Pseudo, IIC_iStore_bh_r, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
879 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
881 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
882 Pseudo, IIC_iStore_bh_r, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
883 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
885 } // isNotDuplicable = 1
888 // LEApcrel - Load a pc-relative address into a register without offending the
890 let neverHasSideEffects = 1 in {
891 let isReMaterializable = 1 in
892 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
894 "adr$p\t$dst, #$label", []>;
896 } // neverHasSideEffects
897 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
898 (ins i32imm:$label, nohash_imm:$id, pred:$p),
900 "adr$p\t$dst, #${label}_${id}", []> {
904 //===----------------------------------------------------------------------===//
905 // Control Flow Instructions.
908 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
910 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
911 "bx", "\tlr", [(ARMretflag)]>,
912 Requires<[IsARM, HasV4T]> {
913 let Inst{3-0} = 0b1110;
914 let Inst{7-4} = 0b0001;
915 let Inst{19-8} = 0b111111111111;
916 let Inst{27-20} = 0b00010010;
920 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
921 "mov", "\tpc, lr", [(ARMretflag)]>,
922 Requires<[IsARM, NoV4T]> {
923 let Inst{11-0} = 0b000000001110;
924 let Inst{15-12} = 0b1111;
925 let Inst{19-16} = 0b0000;
926 let Inst{27-20} = 0b00011010;
931 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
933 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
935 Requires<[IsARM, HasV4T]> {
936 let Inst{7-4} = 0b0001;
937 let Inst{19-8} = 0b111111111111;
938 let Inst{27-20} = 0b00010010;
939 let Inst{31-28} = 0b1110;
943 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
945 Requires<[IsARM, NoV4T]> {
946 let Inst{11-4} = 0b00000000;
947 let Inst{15-12} = 0b1111;
948 let Inst{19-16} = 0b0000;
949 let Inst{27-20} = 0b00011010;
950 let Inst{31-28} = 0b1110;
954 // FIXME: remove when we have a way to marking a MI with these properties.
955 // FIXME: Should pc be an implicit operand like PICADD, etc?
956 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
957 hasExtraDefRegAllocReq = 1 in
958 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
959 reglist:$dsts, variable_ops),
960 IndexModeUpd, LdStMulFrm, IIC_iLoadmBr,
961 "ldm${addr:submode}${p}\t$addr!, $dsts",
962 "$addr.addr = $wb", []>;
964 // On non-Darwin platforms R9 is callee-saved.
966 Defs = [R0, R1, R2, R3, R12, LR,
967 D0, D1, D2, D3, D4, D5, D6, D7,
968 D16, D17, D18, D19, D20, D21, D22, D23,
969 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
970 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
971 IIC_Br, "bl\t${func:call}",
972 [(ARMcall tglobaladdr:$func)]>,
973 Requires<[IsARM, IsNotDarwin]> {
974 let Inst{31-28} = 0b1110;
977 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
978 IIC_Br, "bl", "\t${func:call}",
979 [(ARMcall_pred tglobaladdr:$func)]>,
980 Requires<[IsARM, IsNotDarwin]>;
983 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
984 IIC_Br, "blx\t$func",
985 [(ARMcall GPR:$func)]>,
986 Requires<[IsARM, HasV5T, IsNotDarwin]> {
987 let Inst{7-4} = 0b0011;
988 let Inst{19-8} = 0b111111111111;
989 let Inst{27-20} = 0b00010010;
993 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
994 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
995 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
996 [(ARMcall_nolink tGPR:$func)]>,
997 Requires<[IsARM, HasV4T, IsNotDarwin]> {
998 let Inst{7-4} = 0b0001;
999 let Inst{19-8} = 0b111111111111;
1000 let Inst{27-20} = 0b00010010;
1004 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1005 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1006 [(ARMcall_nolink tGPR:$func)]>,
1007 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1008 let Inst{11-4} = 0b00000000;
1009 let Inst{15-12} = 0b1111;
1010 let Inst{19-16} = 0b0000;
1011 let Inst{27-20} = 0b00011010;
1015 // On Darwin R9 is call-clobbered.
1017 Defs = [R0, R1, R2, R3, R9, R12, LR,
1018 D0, D1, D2, D3, D4, D5, D6, D7,
1019 D16, D17, D18, D19, D20, D21, D22, D23,
1020 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1021 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1022 IIC_Br, "bl\t${func:call}",
1023 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1024 let Inst{31-28} = 0b1110;
1027 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1028 IIC_Br, "bl", "\t${func:call}",
1029 [(ARMcall_pred tglobaladdr:$func)]>,
1030 Requires<[IsARM, IsDarwin]>;
1033 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1034 IIC_Br, "blx\t$func",
1035 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1036 let Inst{7-4} = 0b0011;
1037 let Inst{19-8} = 0b111111111111;
1038 let Inst{27-20} = 0b00010010;
1042 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1043 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1044 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1045 [(ARMcall_nolink tGPR:$func)]>,
1046 Requires<[IsARM, HasV4T, IsDarwin]> {
1047 let Inst{7-4} = 0b0001;
1048 let Inst{19-8} = 0b111111111111;
1049 let Inst{27-20} = 0b00010010;
1053 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1054 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1055 [(ARMcall_nolink tGPR:$func)]>,
1056 Requires<[IsARM, NoV4T, IsDarwin]> {
1057 let Inst{11-4} = 0b00000000;
1058 let Inst{15-12} = 0b1111;
1059 let Inst{19-16} = 0b0000;
1060 let Inst{27-20} = 0b00011010;
1066 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1068 let Defs = [R0, R1, R2, R3, R9, R12,
1069 D0, D1, D2, D3, D4, D5, D6, D7,
1070 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1071 D27, D28, D29, D30, D31, PC],
1073 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1075 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1077 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1079 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1081 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1082 IIC_Br, "b\t$dst @ TAILCALL",
1083 []>, Requires<[IsDarwin]>;
1085 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1086 IIC_Br, "b.w\t$dst @ TAILCALL",
1087 []>, Requires<[IsDarwin]>;
1089 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1090 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1091 []>, Requires<[IsDarwin]> {
1092 let Inst{7-4} = 0b0001;
1093 let Inst{19-8} = 0b111111111111;
1094 let Inst{27-20} = 0b00010010;
1095 let Inst{31-28} = 0b1110;
1099 // Non-Darwin versions (the difference is R9).
1100 let Defs = [R0, R1, R2, R3, R12,
1101 D0, D1, D2, D3, D4, D5, D6, D7,
1102 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1103 D27, D28, D29, D30, D31, PC],
1105 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1107 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1109 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1111 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1113 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1114 IIC_Br, "b\t$dst @ TAILCALL",
1115 []>, Requires<[IsARM, IsNotDarwin]>;
1117 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1118 IIC_Br, "b.w\t$dst @ TAILCALL",
1119 []>, Requires<[IsThumb, IsNotDarwin]>;
1121 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1122 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1123 []>, Requires<[IsNotDarwin]> {
1124 let Inst{7-4} = 0b0001;
1125 let Inst{19-8} = 0b111111111111;
1126 let Inst{27-20} = 0b00010010;
1127 let Inst{31-28} = 0b1110;
1132 let isBranch = 1, isTerminator = 1 in {
1133 // B is "predicable" since it can be xformed into a Bcc.
1134 let isBarrier = 1 in {
1135 let isPredicable = 1 in
1136 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1137 "b\t$target", [(br bb:$target)]>;
1139 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1140 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1141 IIC_Br, "mov\tpc, $target$jt",
1142 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1143 let Inst{11-4} = 0b00000000;
1144 let Inst{15-12} = 0b1111;
1145 let Inst{20} = 0; // S Bit
1146 let Inst{24-21} = 0b1101;
1147 let Inst{27-25} = 0b000;
1149 def BR_JTm : JTI<(outs),
1150 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1151 IIC_Br, "ldr\tpc, $target$jt",
1152 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1154 let Inst{15-12} = 0b1111;
1155 let Inst{20} = 1; // L bit
1156 let Inst{21} = 0; // W bit
1157 let Inst{22} = 0; // B bit
1158 let Inst{24} = 1; // P bit
1159 let Inst{27-25} = 0b011;
1161 def BR_JTadd : JTI<(outs),
1162 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1163 IIC_Br, "add\tpc, $target, $idx$jt",
1164 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1166 let Inst{15-12} = 0b1111;
1167 let Inst{20} = 0; // S bit
1168 let Inst{24-21} = 0b0100;
1169 let Inst{27-25} = 0b000;
1171 } // isNotDuplicable = 1, isIndirectBranch = 1
1174 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1175 // a two-value operand where a dag node expects two operands. :(
1176 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1177 IIC_Br, "b", "\t$target",
1178 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1181 // Branch and Exchange Jazelle -- for disassembly only
1182 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1183 [/* For disassembly only; pattern left blank */]> {
1184 let Inst{23-20} = 0b0010;
1185 //let Inst{19-8} = 0xfff;
1186 let Inst{7-4} = 0b0010;
1189 // Secure Monitor Call is a system instruction -- for disassembly only
1190 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1191 [/* For disassembly only; pattern left blank */]> {
1192 let Inst{23-20} = 0b0110;
1193 let Inst{7-4} = 0b0111;
1196 // Supervisor Call (Software Interrupt) -- for disassembly only
1198 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1199 [/* For disassembly only; pattern left blank */]>;
1202 // Store Return State is a system instruction -- for disassembly only
1203 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1204 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1205 [/* For disassembly only; pattern left blank */]> {
1206 let Inst{31-28} = 0b1111;
1207 let Inst{22-20} = 0b110; // W = 1
1210 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1211 NoItinerary, "srs${addr:submode}\tsp, $mode",
1212 [/* For disassembly only; pattern left blank */]> {
1213 let Inst{31-28} = 0b1111;
1214 let Inst{22-20} = 0b100; // W = 0
1217 // Return From Exception is a system instruction -- for disassembly only
1218 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1219 NoItinerary, "rfe${addr:submode}\t$base!",
1220 [/* For disassembly only; pattern left blank */]> {
1221 let Inst{31-28} = 0b1111;
1222 let Inst{22-20} = 0b011; // W = 1
1225 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1226 NoItinerary, "rfe${addr:submode}\t$base",
1227 [/* For disassembly only; pattern left blank */]> {
1228 let Inst{31-28} = 0b1111;
1229 let Inst{22-20} = 0b001; // W = 0
1232 //===----------------------------------------------------------------------===//
1233 // Load / store Instructions.
1237 let canFoldAsLoad = 1, isReMaterializable = 1 in
1238 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1239 "ldr", "\t$dst, $addr",
1240 [(set GPR:$dst, (load addrmode2:$addr))]>;
1242 // Special LDR for loads from non-pc-relative constpools.
1243 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1244 isReMaterializable = 1 in
1245 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r,
1246 "ldr", "\t$dst, $addr", []>;
1248 // Loads with zero extension
1249 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1250 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1251 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1253 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1254 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr",
1255 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1257 // Loads with sign extension
1258 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1259 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1260 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1262 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1263 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1264 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1266 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1268 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1269 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1270 []>, Requires<[IsARM, HasV5TE]>;
1273 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1274 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1275 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1277 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1278 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1279 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1281 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1282 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1283 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1285 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1286 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1287 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1289 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1290 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1291 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1293 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1294 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1295 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1297 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1298 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1299 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1301 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1302 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1303 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1305 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1306 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1307 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1309 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1310 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1311 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1313 // For disassembly only
1314 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1315 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1316 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1317 Requires<[IsARM, HasV5TE]>;
1319 // For disassembly only
1320 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1321 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1322 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1323 Requires<[IsARM, HasV5TE]>;
1325 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1327 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1329 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1330 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1331 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1332 let Inst{21} = 1; // overwrite
1335 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1336 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1337 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1338 let Inst{21} = 1; // overwrite
1341 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1342 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1343 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1344 let Inst{21} = 1; // overwrite
1347 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1348 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1349 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1350 let Inst{21} = 1; // overwrite
1353 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1354 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1355 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1356 let Inst{21} = 1; // overwrite
1360 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1361 "str", "\t$src, $addr",
1362 [(store GPR:$src, addrmode2:$addr)]>;
1364 // Stores with truncate
1365 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1366 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1367 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1369 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1370 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1371 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1374 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1375 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1376 StMiscFrm, IIC_iStore_d_r,
1377 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1380 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1381 (ins GPR:$src, GPR:$base, am2offset:$offset),
1382 StFrm, IIC_iStore_ru,
1383 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1385 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1387 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1388 (ins GPR:$src, GPR:$base,am2offset:$offset),
1389 StFrm, IIC_iStore_ru,
1390 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1392 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1394 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1395 (ins GPR:$src, GPR:$base,am3offset:$offset),
1396 StMiscFrm, IIC_iStore_ru,
1397 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1399 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1401 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1402 (ins GPR:$src, GPR:$base,am3offset:$offset),
1403 StMiscFrm, IIC_iStore_bh_ru,
1404 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1405 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1406 GPR:$base, am3offset:$offset))]>;
1408 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1409 (ins GPR:$src, GPR:$base,am2offset:$offset),
1410 StFrm, IIC_iStore_bh_ru,
1411 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1412 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1413 GPR:$base, am2offset:$offset))]>;
1415 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1416 (ins GPR:$src, GPR:$base,am2offset:$offset),
1417 StFrm, IIC_iStore_bh_ru,
1418 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1419 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1420 GPR:$base, am2offset:$offset))]>;
1422 // For disassembly only
1423 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1424 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1425 StMiscFrm, IIC_iStore_d_ru,
1426 "strd", "\t$src1, $src2, [$base, $offset]!",
1427 "$base = $base_wb", []>;
1429 // For disassembly only
1430 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1431 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1432 StMiscFrm, IIC_iStore_d_ru,
1433 "strd", "\t$src1, $src2, [$base], $offset",
1434 "$base = $base_wb", []>;
1436 // STRT, STRBT, and STRHT are for disassembly only.
1438 def STRT : AI2stwpo<(outs GPR:$base_wb),
1439 (ins GPR:$src, GPR:$base,am2offset:$offset),
1440 StFrm, IIC_iStore_ru,
1441 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1442 [/* For disassembly only; pattern left blank */]> {
1443 let Inst{21} = 1; // overwrite
1446 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1447 (ins GPR:$src, GPR:$base,am2offset:$offset),
1448 StFrm, IIC_iStore_bh_ru,
1449 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1450 [/* For disassembly only; pattern left blank */]> {
1451 let Inst{21} = 1; // overwrite
1454 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1455 (ins GPR:$src, GPR:$base,am3offset:$offset),
1456 StMiscFrm, IIC_iStore_bh_ru,
1457 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1458 [/* For disassembly only; pattern left blank */]> {
1459 let Inst{21} = 1; // overwrite
1462 //===----------------------------------------------------------------------===//
1463 // Load / store multiple Instructions.
1466 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1467 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1468 reglist:$dsts, variable_ops),
1469 IndexModeNone, LdStMulFrm, IIC_iLoadm,
1470 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1472 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1473 reglist:$dsts, variable_ops),
1474 IndexModeUpd, LdStMulFrm, IIC_iLoadm,
1475 "ldm${addr:submode}${p}\t$addr!, $dsts",
1476 "$addr.addr = $wb", []>;
1477 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1479 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1480 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1481 reglist:$srcs, variable_ops),
1482 IndexModeNone, LdStMulFrm, IIC_iStorem,
1483 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1485 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1486 reglist:$srcs, variable_ops),
1487 IndexModeUpd, LdStMulFrm, IIC_iStorem,
1488 "stm${addr:submode}${p}\t$addr!, $srcs",
1489 "$addr.addr = $wb", []>;
1490 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1492 //===----------------------------------------------------------------------===//
1493 // Move Instructions.
1496 let neverHasSideEffects = 1 in
1497 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1498 "mov", "\t$dst, $src", []>, UnaryDP {
1499 let Inst{11-4} = 0b00000000;
1503 // A version for the smaller set of tail call registers.
1504 let neverHasSideEffects = 1 in
1505 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$dst), (ins tcGPR:$src), DPFrm,
1506 IIC_iMOVr, "mov", "\t$dst, $src", []>, UnaryDP {
1507 let Inst{11-4} = 0b00000000;
1511 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1512 DPSoRegFrm, IIC_iMOVsr,
1513 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1517 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1518 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1519 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1523 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1524 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1526 "movw", "\t$dst, $src",
1527 [(set GPR:$dst, imm0_65535:$src)]>,
1528 Requires<[IsARM, HasV6T2]>, UnaryDP {
1533 let Constraints = "$src = $dst" in
1534 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1536 "movt", "\t$dst, $imm",
1538 (or (and GPR:$src, 0xffff),
1539 lo16AllZero:$imm))]>, UnaryDP,
1540 Requires<[IsARM, HasV6T2]> {
1545 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1546 Requires<[IsARM, HasV6T2]>;
1548 let Uses = [CPSR] in
1549 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1550 "mov", "\t$dst, $src, rrx",
1551 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1553 // These aren't really mov instructions, but we have to define them this way
1554 // due to flag operands.
1556 let Defs = [CPSR] in {
1557 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1558 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1559 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1560 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1561 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1562 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1565 //===----------------------------------------------------------------------===//
1566 // Extend Instructions.
1571 defm SXTB : AI_ext_rrot<0b01101010,
1572 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1573 defm SXTH : AI_ext_rrot<0b01101011,
1574 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1576 defm SXTAB : AI_exta_rrot<0b01101010,
1577 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1578 defm SXTAH : AI_exta_rrot<0b01101011,
1579 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1581 // For disassembly only
1582 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1584 // For disassembly only
1585 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1589 let AddedComplexity = 16 in {
1590 defm UXTB : AI_ext_rrot<0b01101110,
1591 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1592 defm UXTH : AI_ext_rrot<0b01101111,
1593 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1594 defm UXTB16 : AI_ext_rrot<0b01101100,
1595 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1597 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1598 // The transformation should probably be done as a combiner action
1599 // instead so we can include a check for masking back in the upper
1600 // eight bits of the source into the lower eight bits of the result.
1601 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1602 // (UXTB16r_rot GPR:$Src, 24)>;
1603 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1604 (UXTB16r_rot GPR:$Src, 8)>;
1606 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1607 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1608 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1609 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1612 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1613 // For disassembly only
1614 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1617 def SBFX : I<(outs GPR:$dst),
1618 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1619 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1620 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1621 Requires<[IsARM, HasV6T2]> {
1622 let Inst{27-21} = 0b0111101;
1623 let Inst{6-4} = 0b101;
1626 def UBFX : I<(outs GPR:$dst),
1627 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1628 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1629 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1630 Requires<[IsARM, HasV6T2]> {
1631 let Inst{27-21} = 0b0111111;
1632 let Inst{6-4} = 0b101;
1635 //===----------------------------------------------------------------------===//
1636 // Arithmetic Instructions.
1639 defm ADD : AsI1_bin_irs<0b0100, "add",
1640 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1641 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1642 defm SUB : AsI1_bin_irs<0b0010, "sub",
1643 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1644 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1646 // ADD and SUB with 's' bit set.
1647 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1648 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1649 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1650 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1651 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1652 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1654 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1655 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1656 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1657 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1658 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1659 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1660 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1661 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1663 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1664 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1665 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1669 // The reg/reg form is only defined for the disassembler; for codegen it is
1670 // equivalent to SUBrr.
1671 def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
1672 IIC_iALUr, "rsb", "\t$dst, $a, $b",
1673 [/* For disassembly only; pattern left blank */]> {
1675 let Inst{11-4} = 0b00000000;
1678 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1679 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1680 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1684 // RSB with 's' bit set.
1685 let Defs = [CPSR] in {
1686 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1687 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1688 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1692 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1693 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1694 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1700 let Uses = [CPSR] in {
1701 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1702 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1703 [(set GPR:$dst, (sube_dead_carry 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 RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1710 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b",
1711 [/* For disassembly only; pattern left blank */]> {
1713 let Inst{11-4} = 0b00000000;
1715 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1716 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1717 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1723 // FIXME: Allow these to be predicated.
1724 let Defs = [CPSR], Uses = [CPSR] in {
1725 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1726 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1727 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1732 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1733 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1734 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1741 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1742 // The assume-no-carry-in form uses the negation of the input since add/sub
1743 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1744 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1746 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1747 (SUBri GPR:$src, so_imm_neg:$imm)>;
1748 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1749 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1750 // The with-carry-in form matches bitwise not instead of the negation.
1751 // Effectively, the inverse interpretation of the carry flag already accounts
1752 // for part of the negation.
1753 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1754 (SBCri GPR:$src, so_imm_not:$imm)>;
1756 // Note: These are implemented in C++ code, because they have to generate
1757 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1759 // (mul X, 2^n+1) -> (add (X << n), X)
1760 // (mul X, 2^n-1) -> (rsb X, (X << n))
1762 // ARM Arithmetic Instruction -- for disassembly only
1763 // GPR:$dst = GPR:$a op GPR:$b
1764 class AAI<bits<8> op27_20, bits<4> op7_4, string opc,
1765 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
1766 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1767 opc, "\t$dst, $a, $b", pattern> {
1768 let Inst{27-20} = op27_20;
1769 let Inst{7-4} = op7_4;
1772 // Saturating add/subtract -- for disassembly only
1774 def QADD : AAI<0b00010000, 0b0101, "qadd",
1775 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>;
1776 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1777 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1778 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1779 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1780 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1781 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1782 def QSUB : AAI<0b00010010, 0b0101, "qsub",
1783 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>;
1784 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1785 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1786 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1787 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1788 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1789 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1790 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1791 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1793 // Signed/Unsigned add/subtract -- for disassembly only
1795 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1796 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1797 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1798 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1799 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1800 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1801 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1802 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1803 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1804 def USAX : AAI<0b01100101, 0b0101, "usax">;
1805 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1806 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1808 // Signed/Unsigned halving add/subtract -- for disassembly only
1810 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1811 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1812 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1813 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1814 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1815 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1816 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1817 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1818 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1819 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1820 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1821 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1823 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1825 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1826 MulFrm /* for convenience */, NoItinerary, "usad8",
1827 "\t$dst, $a, $b", []>,
1828 Requires<[IsARM, HasV6]> {
1829 let Inst{27-20} = 0b01111000;
1830 let Inst{15-12} = 0b1111;
1831 let Inst{7-4} = 0b0001;
1833 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1834 MulFrm /* for convenience */, NoItinerary, "usada8",
1835 "\t$dst, $a, $b, $acc", []>,
1836 Requires<[IsARM, HasV6]> {
1837 let Inst{27-20} = 0b01111000;
1838 let Inst{7-4} = 0b0001;
1841 // Signed/Unsigned saturate -- for disassembly only
1843 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1844 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1845 [/* For disassembly only; pattern left blank */]> {
1846 let Inst{27-21} = 0b0110101;
1847 let Inst{5-4} = 0b01;
1850 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1851 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1852 [/* For disassembly only; pattern left blank */]> {
1853 let Inst{27-20} = 0b01101010;
1854 let Inst{7-4} = 0b0011;
1857 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh),
1858 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1859 [/* For disassembly only; pattern left blank */]> {
1860 let Inst{27-21} = 0b0110111;
1861 let Inst{5-4} = 0b01;
1864 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
1865 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1866 [/* For disassembly only; pattern left blank */]> {
1867 let Inst{27-20} = 0b01101110;
1868 let Inst{7-4} = 0b0011;
1871 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1872 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
1874 //===----------------------------------------------------------------------===//
1875 // Bitwise Instructions.
1878 defm AND : AsI1_bin_irs<0b0000, "and",
1879 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1880 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1881 defm ANDS : AI1_bin_s_irs<0b0000, "and",
1882 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1883 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>;
1884 defm ORR : AsI1_bin_irs<0b1100, "orr",
1885 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1886 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1887 defm EOR : AsI1_bin_irs<0b0001, "eor",
1888 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1889 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1890 defm BIC : AsI1_bin_irs<0b1110, "bic",
1891 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
1892 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1894 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1895 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1896 "bfc", "\t$dst, $imm", "$src = $dst",
1897 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1898 Requires<[IsARM, HasV6T2]> {
1899 let Inst{27-21} = 0b0111110;
1900 let Inst{6-0} = 0b0011111;
1903 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1904 def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm),
1905 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1906 "bfi", "\t$dst, $val, $imm", "$src = $dst",
1907 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val,
1908 bf_inv_mask_imm:$imm))]>,
1909 Requires<[IsARM, HasV6T2]> {
1910 let Inst{27-21} = 0b0111110;
1911 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1914 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr,
1915 "mvn", "\t$dst, $src",
1916 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1918 let Inst{11-4} = 0b00000000;
1920 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1921 IIC_iMVNsr, "mvn", "\t$dst, $src",
1922 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1925 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1926 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1927 IIC_iMVNi, "mvn", "\t$dst, $imm",
1928 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1932 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1933 (BICri GPR:$src, so_imm_not:$imm)>;
1935 //===----------------------------------------------------------------------===//
1936 // Multiply Instructions.
1939 let isCommutable = 1 in
1940 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1941 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1942 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1944 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1945 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1946 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1948 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1949 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1950 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1951 Requires<[IsARM, HasV6T2]>;
1953 // Extra precision multiplies with low / high results
1954 let neverHasSideEffects = 1 in {
1955 let isCommutable = 1 in {
1956 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1957 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1958 "smull", "\t$ldst, $hdst, $a, $b", []>;
1960 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1961 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1962 "umull", "\t$ldst, $hdst, $a, $b", []>;
1965 // Multiply + accumulate
1966 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1967 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1968 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1970 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1971 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1972 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1974 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1975 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1976 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1977 Requires<[IsARM, HasV6]>;
1978 } // neverHasSideEffects
1980 // Most significant word multiply
1981 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1982 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1983 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1984 Requires<[IsARM, HasV6]> {
1985 let Inst{7-4} = 0b0001;
1986 let Inst{15-12} = 0b1111;
1989 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1990 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1991 [/* For disassembly only; pattern left blank */]>,
1992 Requires<[IsARM, HasV6]> {
1993 let Inst{7-4} = 0b0011; // R = 1
1994 let Inst{15-12} = 0b1111;
1997 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1998 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1999 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
2000 Requires<[IsARM, HasV6]> {
2001 let Inst{7-4} = 0b0001;
2004 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2005 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
2006 [/* For disassembly only; pattern left blank */]>,
2007 Requires<[IsARM, HasV6]> {
2008 let Inst{7-4} = 0b0011; // R = 1
2011 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2012 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
2013 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
2014 Requires<[IsARM, HasV6]> {
2015 let Inst{7-4} = 0b1101;
2018 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2019 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
2020 [/* For disassembly only; pattern left blank */]>,
2021 Requires<[IsARM, HasV6]> {
2022 let Inst{7-4} = 0b1111; // R = 1
2025 multiclass AI_smul<string opc, PatFrag opnode> {
2026 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2027 IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b",
2028 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2029 (sext_inreg GPR:$b, i16)))]>,
2030 Requires<[IsARM, HasV5TE]> {
2035 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2036 IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b",
2037 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
2038 (sra GPR:$b, (i32 16))))]>,
2039 Requires<[IsARM, HasV5TE]> {
2044 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2045 IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b",
2046 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2047 (sext_inreg GPR:$b, i16)))]>,
2048 Requires<[IsARM, HasV5TE]> {
2053 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2054 IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b",
2055 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
2056 (sra GPR:$b, (i32 16))))]>,
2057 Requires<[IsARM, HasV5TE]> {
2062 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2063 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
2064 [(set GPR:$dst, (sra (opnode GPR:$a,
2065 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
2066 Requires<[IsARM, HasV5TE]> {
2071 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2072 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
2073 [(set GPR:$dst, (sra (opnode GPR:$a,
2074 (sra GPR:$b, (i32 16))), (i32 16)))]>,
2075 Requires<[IsARM, HasV5TE]> {
2082 multiclass AI_smla<string opc, PatFrag opnode> {
2083 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2084 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2085 [(set GPR:$dst, (add GPR:$acc,
2086 (opnode (sext_inreg GPR:$a, i16),
2087 (sext_inreg GPR:$b, i16))))]>,
2088 Requires<[IsARM, HasV5TE]> {
2093 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2094 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2095 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
2096 (sra GPR:$b, (i32 16)))))]>,
2097 Requires<[IsARM, HasV5TE]> {
2102 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2103 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2104 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2105 (sext_inreg GPR:$b, i16))))]>,
2106 Requires<[IsARM, HasV5TE]> {
2111 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2112 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2113 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
2114 (sra GPR:$b, (i32 16)))))]>,
2115 Requires<[IsARM, HasV5TE]> {
2120 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2121 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2122 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2123 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
2124 Requires<[IsARM, HasV5TE]> {
2129 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2130 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2131 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
2132 (sra GPR:$b, (i32 16))), (i32 16))))]>,
2133 Requires<[IsARM, HasV5TE]> {
2139 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2140 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2142 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2143 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2144 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2145 [/* For disassembly only; pattern left blank */]>,
2146 Requires<[IsARM, HasV5TE]> {
2151 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2152 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2153 [/* For disassembly only; pattern left blank */]>,
2154 Requires<[IsARM, HasV5TE]> {
2159 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2160 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2161 [/* For disassembly only; pattern left blank */]>,
2162 Requires<[IsARM, HasV5TE]> {
2167 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2168 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2169 [/* For disassembly only; pattern left blank */]>,
2170 Requires<[IsARM, HasV5TE]> {
2175 // Helper class for AI_smld -- for disassembly only
2176 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2177 InstrItinClass itin, string opc, string asm>
2178 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2183 let Inst{21-20} = 0b00;
2184 let Inst{22} = long;
2185 let Inst{27-23} = 0b01110;
2188 multiclass AI_smld<bit sub, string opc> {
2190 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2191 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2193 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2194 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2196 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2197 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2199 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2200 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2204 defm SMLA : AI_smld<0, "smla">;
2205 defm SMLS : AI_smld<1, "smls">;
2207 multiclass AI_sdml<bit sub, string opc> {
2209 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2210 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2211 let Inst{15-12} = 0b1111;
2214 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2215 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2216 let Inst{15-12} = 0b1111;
2221 defm SMUA : AI_sdml<0, "smua">;
2222 defm SMUS : AI_sdml<1, "smus">;
2224 //===----------------------------------------------------------------------===//
2225 // Misc. Arithmetic Instructions.
2228 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2229 "clz", "\t$dst, $src",
2230 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2231 let Inst{7-4} = 0b0001;
2232 let Inst{11-8} = 0b1111;
2233 let Inst{19-16} = 0b1111;
2236 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2237 "rbit", "\t$dst, $src",
2238 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2239 Requires<[IsARM, HasV6T2]> {
2240 let Inst{7-4} = 0b0011;
2241 let Inst{11-8} = 0b1111;
2242 let Inst{19-16} = 0b1111;
2245 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2246 "rev", "\t$dst, $src",
2247 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2248 let Inst{7-4} = 0b0011;
2249 let Inst{11-8} = 0b1111;
2250 let Inst{19-16} = 0b1111;
2253 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2254 "rev16", "\t$dst, $src",
2256 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2257 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2258 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2259 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2260 Requires<[IsARM, HasV6]> {
2261 let Inst{7-4} = 0b1011;
2262 let Inst{11-8} = 0b1111;
2263 let Inst{19-16} = 0b1111;
2266 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2267 "revsh", "\t$dst, $src",
2270 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2271 (shl GPR:$src, (i32 8))), i16))]>,
2272 Requires<[IsARM, HasV6]> {
2273 let Inst{7-4} = 0b1011;
2274 let Inst{11-8} = 0b1111;
2275 let Inst{19-16} = 0b1111;
2278 def lsl_shift_imm : SDNodeXForm<imm, [{
2279 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2280 return CurDAG->getTargetConstant(Sh, MVT::i32);
2283 def lsl_amt : PatLeaf<(i32 imm), [{
2284 return (N->getZExtValue() < 32);
2287 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2288 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2289 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2290 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2291 (and (shl GPR:$src2, lsl_amt:$sh),
2293 Requires<[IsARM, HasV6]> {
2294 let Inst{6-4} = 0b001;
2297 // Alternate cases for PKHBT where identities eliminate some nodes.
2298 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2299 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2300 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
2301 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
2303 def asr_shift_imm : SDNodeXForm<imm, [{
2304 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2305 return CurDAG->getTargetConstant(Sh, MVT::i32);
2308 def asr_amt : PatLeaf<(i32 imm), [{
2309 return (N->getZExtValue() <= 32);
2312 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2313 // will match the pattern below.
2314 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2315 (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
2316 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2317 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2318 (and (sra GPR:$src2, asr_amt:$sh),
2320 Requires<[IsARM, HasV6]> {
2321 let Inst{6-4} = 0b101;
2324 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2325 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2326 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2327 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2328 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2329 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2330 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2332 //===----------------------------------------------------------------------===//
2333 // Comparison Instructions...
2336 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2337 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2338 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2340 // FIXME: We have to be careful when using the CMN instruction and comparison
2341 // with 0. One would expect these two pieces of code should give identical
2357 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2358 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2359 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2360 // value of r0 and the carry bit (because the "carry bit" parameter to
2361 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2362 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2363 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2364 // parameter to AddWithCarry is defined as 0).
2366 // When x is 0 and unsigned:
2370 // ~x + 1 = 0x1 0000 0000
2371 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2373 // Therefore, we should disable CMN when comparing against zero, until we can
2374 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2375 // when it's a comparison which doesn't look at the 'carry' flag).
2377 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2379 // This is related to <rdar://problem/7569620>.
2381 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2382 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2384 // Note that TST/TEQ don't set all the same flags that CMP does!
2385 defm TST : AI1_cmp_irs<0b1000, "tst",
2386 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2387 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2388 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2389 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2390 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2392 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2393 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2394 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2395 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2396 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2397 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2399 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2400 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2402 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2403 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2405 // Pseudo i64 compares for some floating point compares.
2406 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2408 def BCCi64 : PseudoInst<(outs),
2409 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2411 "${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, imm:$cc",
2412 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2414 def BCCZi64 : PseudoInst<(outs),
2415 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst),
2417 "${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, 0, 0, imm:$cc",
2418 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2419 } // usesCustomInserter
2422 // Conditional moves
2423 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2424 // a two-value operand where a dag node expects two operands. :(
2425 let neverHasSideEffects = 1 in {
2426 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2427 IIC_iCMOVr, "mov", "\t$dst, $true",
2428 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2429 RegConstraint<"$false = $dst">, UnaryDP {
2430 let Inst{11-4} = 0b00000000;
2434 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2435 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2436 "mov", "\t$dst, $true",
2437 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2438 RegConstraint<"$false = $dst">, UnaryDP {
2442 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2443 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2444 "mov", "\t$dst, $true",
2445 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2446 RegConstraint<"$false = $dst">, UnaryDP {
2449 } // neverHasSideEffects
2451 //===----------------------------------------------------------------------===//
2452 // Atomic operations intrinsics
2455 // memory barriers protect the atomic sequences
2456 let hasSideEffects = 1 in {
2457 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2458 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2459 let Inst{31-4} = 0xf57ff05;
2460 // FIXME: add support for options other than a full system DMB
2461 // See DMB disassembly-only variants below.
2462 let Inst{3-0} = 0b1111;
2465 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2466 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2467 let Inst{31-4} = 0xf57ff04;
2468 // FIXME: add support for options other than a full system DSB
2469 // See DSB disassembly-only variants below.
2470 let Inst{3-0} = 0b1111;
2473 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2474 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2475 [(ARMMemBarrierMCR GPR:$zero)]>,
2476 Requires<[IsARM, HasV6]> {
2477 // FIXME: add support for options other than a full system DMB
2478 // FIXME: add encoding
2481 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2482 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2483 [(ARMSyncBarrierMCR GPR:$zero)]>,
2484 Requires<[IsARM, HasV6]> {
2485 // FIXME: add support for options other than a full system DSB
2486 // FIXME: add encoding
2490 // Memory Barrier Operations Variants -- for disassembly only
2492 def memb_opt : Operand<i32> {
2493 let PrintMethod = "printMemBOption";
2496 class AMBI<bits<4> op7_4, string opc>
2497 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2498 [/* For disassembly only; pattern left blank */]>,
2499 Requires<[IsARM, HasDB]> {
2500 let Inst{31-8} = 0xf57ff0;
2501 let Inst{7-4} = op7_4;
2504 // These DMB variants are for disassembly only.
2505 def DMBvar : AMBI<0b0101, "dmb">;
2507 // These DSB variants are for disassembly only.
2508 def DSBvar : AMBI<0b0100, "dsb">;
2510 // ISB has only full system option -- for disassembly only
2511 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2512 Requires<[IsARM, HasDB]> {
2513 let Inst{31-4} = 0xf57ff06;
2514 let Inst{3-0} = 0b1111;
2517 let usesCustomInserter = 1 in {
2518 let Uses = [CPSR] in {
2519 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2520 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2521 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2522 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2523 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2524 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2525 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2526 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2527 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2528 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2529 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2530 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2531 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2532 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2533 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2534 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2535 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2536 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2537 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2538 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2539 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2540 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2541 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2542 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2543 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2544 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2545 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2546 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2547 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2548 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2549 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2550 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2551 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2552 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2553 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2554 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2555 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2556 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2557 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2558 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2559 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2560 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2561 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2562 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2563 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2564 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2565 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2566 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2567 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2568 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2569 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2570 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2571 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2572 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2573 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2574 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2575 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2576 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2577 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2578 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2579 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2580 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2581 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2582 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2583 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2584 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2585 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2586 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2587 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2588 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2589 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2590 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2592 def ATOMIC_SWAP_I8 : PseudoInst<
2593 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2594 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2595 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2596 def ATOMIC_SWAP_I16 : PseudoInst<
2597 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2598 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2599 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2600 def ATOMIC_SWAP_I32 : PseudoInst<
2601 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2602 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2603 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2605 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2606 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2607 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2608 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2609 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2610 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2611 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2612 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2613 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2614 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2615 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2616 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2620 let mayLoad = 1 in {
2621 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2622 "ldrexb", "\t$dest, [$ptr]",
2624 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2625 "ldrexh", "\t$dest, [$ptr]",
2627 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2628 "ldrex", "\t$dest, [$ptr]",
2630 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2632 "ldrexd", "\t$dest, $dest2, [$ptr]",
2636 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2637 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2639 "strexb", "\t$success, $src, [$ptr]",
2641 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2643 "strexh", "\t$success, $src, [$ptr]",
2645 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2647 "strex", "\t$success, $src, [$ptr]",
2649 def STREXD : AIstrex<0b01, (outs GPR:$success),
2650 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2652 "strexd", "\t$success, $src, $src2, [$ptr]",
2656 // Clear-Exclusive is for disassembly only.
2657 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2658 [/* For disassembly only; pattern left blank */]>,
2659 Requires<[IsARM, HasV7]> {
2660 let Inst{31-20} = 0xf57;
2661 let Inst{7-4} = 0b0001;
2664 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2665 let mayLoad = 1 in {
2666 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2667 "swp", "\t$dst, $src, [$ptr]",
2668 [/* For disassembly only; pattern left blank */]> {
2669 let Inst{27-23} = 0b00010;
2670 let Inst{22} = 0; // B = 0
2671 let Inst{21-20} = 0b00;
2672 let Inst{7-4} = 0b1001;
2675 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2676 "swpb", "\t$dst, $src, [$ptr]",
2677 [/* For disassembly only; pattern left blank */]> {
2678 let Inst{27-23} = 0b00010;
2679 let Inst{22} = 1; // B = 1
2680 let Inst{21-20} = 0b00;
2681 let Inst{7-4} = 0b1001;
2685 //===----------------------------------------------------------------------===//
2689 // __aeabi_read_tp preserves the registers r1-r3.
2691 Defs = [R0, R12, LR, CPSR] in {
2692 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2693 "bl\t__aeabi_read_tp",
2694 [(set R0, ARMthread_pointer)]>;
2697 //===----------------------------------------------------------------------===//
2698 // SJLJ Exception handling intrinsics
2699 // eh_sjlj_setjmp() is an instruction sequence to store the return
2700 // address and save #0 in R0 for the non-longjmp case.
2701 // Since by its nature we may be coming from some other function to get
2702 // here, and we're using the stack frame for the containing function to
2703 // save/restore registers, we can't keep anything live in regs across
2704 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2705 // when we get here from a longjmp(). We force everthing out of registers
2706 // except for our own input by listing the relevant registers in Defs. By
2707 // doing so, we also cause the prologue/epilogue code to actively preserve
2708 // all of the callee-saved resgisters, which is exactly what we want.
2709 // A constant value is passed in $val, and we use the location as a scratch.
2711 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2712 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2713 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2714 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2715 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2716 AddrModeNone, SizeSpecial, IndexModeNone,
2717 Pseudo, NoItinerary,
2718 "${:comment} EH.SJLJ.SETJMP PSEUDO", "",
2719 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2720 Requires<[IsARM, HasVFP2]>;
2724 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2725 hasSideEffects = 1, isBarrier = 1 in {
2726 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2727 AddrModeNone, SizeSpecial, IndexModeNone,
2728 Pseudo, NoItinerary,
2729 "${:comment} EH.SJLJ.SETJMP PSEUDO", "",
2730 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2731 Requires<[IsARM, NoVFP]>;
2734 // FIXME: Non-Darwin version(s)
2735 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
2736 Defs = [ R7, LR, SP ] in {
2737 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
2738 AddrModeNone, SizeSpecial, IndexModeNone,
2739 Pseudo, NoItinerary,
2740 "${:comment} EH.SJLJ.LONGJMP PSEUDO", "",
2741 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
2742 Requires<[IsARM, IsDarwin]>;
2745 //===----------------------------------------------------------------------===//
2746 // Non-Instruction Patterns
2749 // Large immediate handling.
2751 // Two piece so_imms.
2752 // FIXME: Expand this in ARMExpandPseudoInsts.
2753 // FIXME: Remove this when we can do generalized remat.
2754 let isReMaterializable = 1 in
2755 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2756 Pseudo, IIC_iMOVix2,
2757 "mov", "\t$dst, $src",
2758 [(set GPR:$dst, so_imm2part:$src)]>,
2759 Requires<[IsARM, NoV6T2]>;
2761 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2762 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2763 (so_imm2part_2 imm:$RHS))>;
2764 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2765 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2766 (so_imm2part_2 imm:$RHS))>;
2767 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2768 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2769 (so_imm2part_2 imm:$RHS))>;
2770 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2771 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2772 (so_neg_imm2part_2 imm:$RHS))>;
2774 // 32-bit immediate using movw + movt.
2775 // This is a single pseudo instruction, the benefit is that it can be remat'd
2776 // as a single unit instead of having to handle reg inputs.
2777 // FIXME: Remove this when we can do generalized remat.
2778 let isReMaterializable = 1 in
2779 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVix2,
2780 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2781 [(set GPR:$dst, (i32 imm:$src))]>,
2782 Requires<[IsARM, HasV6T2]>;
2784 // ConstantPool, GlobalAddress, and JumpTable
2785 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2786 Requires<[IsARM, DontUseMovt]>;
2787 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2788 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2789 Requires<[IsARM, UseMovt]>;
2790 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2791 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2793 // TODO: add,sub,and, 3-instr forms?
2796 def : ARMPat<(ARMtcret tcGPR:$dst),
2797 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
2799 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2800 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2802 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2803 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
2805 def : ARMPat<(ARMtcret tcGPR:$dst),
2806 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
2808 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
2809 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2811 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
2812 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
2815 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2816 Requires<[IsARM, IsNotDarwin]>;
2817 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2818 Requires<[IsARM, IsDarwin]>;
2820 // zextload i1 -> zextload i8
2821 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2823 // extload -> zextload
2824 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2825 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2826 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2828 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2829 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2832 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2833 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2834 (SMULBB GPR:$a, GPR:$b)>;
2835 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2836 (SMULBB GPR:$a, GPR:$b)>;
2837 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2838 (sra GPR:$b, (i32 16))),
2839 (SMULBT GPR:$a, GPR:$b)>;
2840 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2841 (SMULBT GPR:$a, GPR:$b)>;
2842 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2843 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2844 (SMULTB GPR:$a, GPR:$b)>;
2845 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2846 (SMULTB GPR:$a, GPR:$b)>;
2847 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2849 (SMULWB GPR:$a, GPR:$b)>;
2850 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2851 (SMULWB GPR:$a, GPR:$b)>;
2853 def : ARMV5TEPat<(add GPR:$acc,
2854 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2855 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2856 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2857 def : ARMV5TEPat<(add GPR:$acc,
2858 (mul sext_16_node:$a, sext_16_node:$b)),
2859 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2860 def : ARMV5TEPat<(add GPR:$acc,
2861 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2862 (sra GPR:$b, (i32 16)))),
2863 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2864 def : ARMV5TEPat<(add GPR:$acc,
2865 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2866 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2867 def : ARMV5TEPat<(add GPR:$acc,
2868 (mul (sra GPR:$a, (i32 16)),
2869 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2870 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2871 def : ARMV5TEPat<(add GPR:$acc,
2872 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2873 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2874 def : ARMV5TEPat<(add GPR:$acc,
2875 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2877 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2878 def : ARMV5TEPat<(add GPR:$acc,
2879 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2880 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2882 //===----------------------------------------------------------------------===//
2886 include "ARMInstrThumb.td"
2888 //===----------------------------------------------------------------------===//
2892 include "ARMInstrThumb2.td"
2894 //===----------------------------------------------------------------------===//
2895 // Floating Point Support
2898 include "ARMInstrVFP.td"
2900 //===----------------------------------------------------------------------===//
2901 // Advanced SIMD (NEON) Support
2904 include "ARMInstrNEON.td"
2906 //===----------------------------------------------------------------------===//
2907 // Coprocessor Instructions. For disassembly only.
2910 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2911 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2912 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2913 [/* For disassembly only; pattern left blank */]> {
2917 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2918 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2919 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2920 [/* For disassembly only; pattern left blank */]> {
2921 let Inst{31-28} = 0b1111;
2925 class ACI<dag oops, dag iops, string opc, string asm>
2926 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2927 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2928 let Inst{27-25} = 0b110;
2931 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2933 def _OFFSET : ACI<(outs),
2934 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2935 opc, "\tp$cop, cr$CRd, $addr"> {
2936 let Inst{31-28} = op31_28;
2937 let Inst{24} = 1; // P = 1
2938 let Inst{21} = 0; // W = 0
2939 let Inst{22} = 0; // D = 0
2940 let Inst{20} = load;
2943 def _PRE : ACI<(outs),
2944 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2945 opc, "\tp$cop, cr$CRd, $addr!"> {
2946 let Inst{31-28} = op31_28;
2947 let Inst{24} = 1; // P = 1
2948 let Inst{21} = 1; // W = 1
2949 let Inst{22} = 0; // D = 0
2950 let Inst{20} = load;
2953 def _POST : ACI<(outs),
2954 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2955 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2956 let Inst{31-28} = op31_28;
2957 let Inst{24} = 0; // P = 0
2958 let Inst{21} = 1; // W = 1
2959 let Inst{22} = 0; // D = 0
2960 let Inst{20} = load;
2963 def _OPTION : ACI<(outs),
2964 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2965 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2966 let Inst{31-28} = op31_28;
2967 let Inst{24} = 0; // P = 0
2968 let Inst{23} = 1; // U = 1
2969 let Inst{21} = 0; // W = 0
2970 let Inst{22} = 0; // D = 0
2971 let Inst{20} = load;
2974 def L_OFFSET : ACI<(outs),
2975 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2976 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
2977 let Inst{31-28} = op31_28;
2978 let Inst{24} = 1; // P = 1
2979 let Inst{21} = 0; // W = 0
2980 let Inst{22} = 1; // D = 1
2981 let Inst{20} = load;
2984 def L_PRE : ACI<(outs),
2985 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2986 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
2987 let Inst{31-28} = op31_28;
2988 let Inst{24} = 1; // P = 1
2989 let Inst{21} = 1; // W = 1
2990 let Inst{22} = 1; // D = 1
2991 let Inst{20} = load;
2994 def L_POST : ACI<(outs),
2995 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2996 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
2997 let Inst{31-28} = op31_28;
2998 let Inst{24} = 0; // P = 0
2999 let Inst{21} = 1; // W = 1
3000 let Inst{22} = 1; // D = 1
3001 let Inst{20} = load;
3004 def L_OPTION : ACI<(outs),
3005 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3006 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3007 let Inst{31-28} = op31_28;
3008 let Inst{24} = 0; // P = 0
3009 let Inst{23} = 1; // U = 1
3010 let Inst{21} = 0; // W = 0
3011 let Inst{22} = 1; // D = 1
3012 let Inst{20} = load;
3016 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3017 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3018 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3019 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3021 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3022 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3023 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3024 [/* For disassembly only; pattern left blank */]> {
3029 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3030 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3031 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3032 [/* For disassembly only; pattern left blank */]> {
3033 let Inst{31-28} = 0b1111;
3038 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3039 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3040 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3041 [/* For disassembly only; pattern left blank */]> {
3046 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3047 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3048 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3049 [/* For disassembly only; pattern left blank */]> {
3050 let Inst{31-28} = 0b1111;
3055 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3056 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3057 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3058 [/* For disassembly only; pattern left blank */]> {
3059 let Inst{23-20} = 0b0100;
3062 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3063 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3064 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3065 [/* For disassembly only; pattern left blank */]> {
3066 let Inst{31-28} = 0b1111;
3067 let Inst{23-20} = 0b0100;
3070 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3071 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3072 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3073 [/* For disassembly only; pattern left blank */]> {
3074 let Inst{23-20} = 0b0101;
3077 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3078 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3079 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3080 [/* For disassembly only; pattern left blank */]> {
3081 let Inst{31-28} = 0b1111;
3082 let Inst{23-20} = 0b0101;
3085 //===----------------------------------------------------------------------===//
3086 // Move between special register and ARM core register -- for disassembly only
3089 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3090 [/* For disassembly only; pattern left blank */]> {
3091 let Inst{23-20} = 0b0000;
3092 let Inst{7-4} = 0b0000;
3095 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3096 [/* For disassembly only; pattern left blank */]> {
3097 let Inst{23-20} = 0b0100;
3098 let Inst{7-4} = 0b0000;
3101 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3102 "msr", "\tcpsr$mask, $src",
3103 [/* For disassembly only; pattern left blank */]> {
3104 let Inst{23-20} = 0b0010;
3105 let Inst{7-4} = 0b0000;
3108 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3109 "msr", "\tcpsr$mask, $a",
3110 [/* For disassembly only; pattern left blank */]> {
3111 let Inst{23-20} = 0b0010;
3112 let Inst{7-4} = 0b0000;
3115 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3116 "msr", "\tspsr$mask, $src",
3117 [/* For disassembly only; pattern left blank */]> {
3118 let Inst{23-20} = 0b0110;
3119 let Inst{7-4} = 0b0000;
3122 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3123 "msr", "\tspsr$mask, $a",
3124 [/* For disassembly only; pattern left blank */]> {
3125 let Inst{23-20} = 0b0110;
3126 let Inst{7-4} = 0b0000;