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, [SDTCisInt<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_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
43 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
46 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
50 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
51 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
53 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
54 [SDNPHasChain, SDNPOutFlag]>;
55 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
56 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
58 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
59 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
60 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
61 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
62 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
63 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
65 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
66 [SDNPHasChain, SDNPOptInFlag]>;
68 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
70 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
73 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
74 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
76 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
78 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
81 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
84 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
85 [SDNPOutFlag,SDNPCommutative]>;
87 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
89 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
90 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
91 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
93 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
94 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
96 //===----------------------------------------------------------------------===//
97 // ARM Instruction Predicate Definitions.
99 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
100 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
101 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
102 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
103 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
104 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
105 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
106 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
107 def HasNEON : Predicate<"Subtarget->hasNEON()">;
108 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
109 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
110 def IsThumb : Predicate<"Subtarget->isThumb()">;
111 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
112 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
113 def IsARM : Predicate<"!Subtarget->isThumb()">;
114 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
115 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
116 def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
117 def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
119 // FIXME: Eventually this will be just "hasV6T2Ops".
120 def UseMovt : Predicate<"Subtarget->useMovt()">;
121 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
123 //===----------------------------------------------------------------------===//
124 // ARM Flag Definitions.
126 class RegConstraint<string C> {
127 string Constraints = C;
130 //===----------------------------------------------------------------------===//
131 // ARM specific transformation functions and pattern fragments.
134 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
135 // so_imm_neg def below.
136 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
137 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
140 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
141 // so_imm_not def below.
142 def so_imm_not_XFORM : SDNodeXForm<imm, [{
143 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
146 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
147 def rot_imm : PatLeaf<(i32 imm), [{
148 int32_t v = (int32_t)N->getZExtValue();
149 return v == 8 || v == 16 || v == 24;
152 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
153 def imm1_15 : PatLeaf<(i32 imm), [{
154 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
157 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
158 def imm16_31 : PatLeaf<(i32 imm), [{
159 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
164 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
165 }], so_imm_neg_XFORM>;
169 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
170 }], so_imm_not_XFORM>;
172 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
173 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
174 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
177 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
179 def bf_inv_mask_imm : Operand<i32>,
181 uint32_t v = (uint32_t)N->getZExtValue();
184 // there can be 1's on either or both "outsides", all the "inside"
186 unsigned int lsb = 0, msb = 31;
187 while (v & (1 << msb)) --msb;
188 while (v & (1 << lsb)) ++lsb;
189 for (unsigned int i = lsb; i <= msb; ++i) {
195 let PrintMethod = "printBitfieldInvMaskImmOperand";
198 /// Split a 32-bit immediate into two 16 bit parts.
199 def lo16 : SDNodeXForm<imm, [{
200 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
204 def hi16 : SDNodeXForm<imm, [{
205 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
208 def lo16AllZero : PatLeaf<(i32 imm), [{
209 // Returns true if all low 16-bits are 0.
210 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
213 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
215 def imm0_65535 : PatLeaf<(i32 imm), [{
216 return (uint32_t)N->getZExtValue() < 65536;
219 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
220 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
222 //===----------------------------------------------------------------------===//
223 // Operand Definitions.
227 def brtarget : Operand<OtherVT>;
229 // A list of registers separated by comma. Used by load/store multiple.
230 def reglist : Operand<i32> {
231 let PrintMethod = "printRegisterList";
234 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
235 def cpinst_operand : Operand<i32> {
236 let PrintMethod = "printCPInstOperand";
239 def jtblock_operand : Operand<i32> {
240 let PrintMethod = "printJTBlockOperand";
242 def jt2block_operand : Operand<i32> {
243 let PrintMethod = "printJT2BlockOperand";
247 def pclabel : Operand<i32> {
248 let PrintMethod = "printPCLabel";
251 // shifter_operand operands: so_reg and so_imm.
252 def so_reg : Operand<i32>, // reg reg imm
253 ComplexPattern<i32, 3, "SelectShifterOperandReg",
254 [shl,srl,sra,rotr]> {
255 let PrintMethod = "printSORegOperand";
256 let MIOperandInfo = (ops GPR, GPR, i32imm);
259 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
260 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
261 // represented in the imm field in the same 12-bit form that they are encoded
262 // into so_imm instructions: the 8-bit immediate is the least significant bits
263 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
264 def so_imm : Operand<i32>,
266 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
268 let PrintMethod = "printSOImmOperand";
271 // Break so_imm's up into two pieces. This handles immediates with up to 16
272 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
273 // get the first/second pieces.
274 def so_imm2part : Operand<i32>,
276 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
278 let PrintMethod = "printSOImm2PartOperand";
281 def so_imm2part_1 : SDNodeXForm<imm, [{
282 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
283 return CurDAG->getTargetConstant(V, MVT::i32);
286 def so_imm2part_2 : SDNodeXForm<imm, [{
287 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
288 return CurDAG->getTargetConstant(V, MVT::i32);
291 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
292 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
294 let PrintMethod = "printSOImm2PartOperand";
297 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
298 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
299 return CurDAG->getTargetConstant(V, MVT::i32);
302 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
303 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
304 return CurDAG->getTargetConstant(V, MVT::i32);
307 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
308 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
309 return (int32_t)N->getZExtValue() < 32;
312 // Define ARM specific addressing modes.
314 // addrmode2 := reg +/- reg shop imm
315 // addrmode2 := reg +/- imm12
317 def addrmode2 : Operand<i32>,
318 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
319 let PrintMethod = "printAddrMode2Operand";
320 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
323 def am2offset : Operand<i32>,
324 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
325 let PrintMethod = "printAddrMode2OffsetOperand";
326 let MIOperandInfo = (ops GPR, i32imm);
329 // addrmode3 := reg +/- reg
330 // addrmode3 := reg +/- imm8
332 def addrmode3 : Operand<i32>,
333 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
334 let PrintMethod = "printAddrMode3Operand";
335 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
338 def am3offset : Operand<i32>,
339 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
340 let PrintMethod = "printAddrMode3OffsetOperand";
341 let MIOperandInfo = (ops GPR, i32imm);
344 // addrmode4 := reg, <mode|W>
346 def addrmode4 : Operand<i32>,
347 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
348 let PrintMethod = "printAddrMode4Operand";
349 let MIOperandInfo = (ops GPR, i32imm);
352 // addrmode5 := reg +/- imm8*4
354 def addrmode5 : Operand<i32>,
355 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
356 let PrintMethod = "printAddrMode5Operand";
357 let MIOperandInfo = (ops GPR, i32imm);
360 // addrmode6 := reg with optional writeback
362 def addrmode6 : Operand<i32>,
363 ComplexPattern<i32, 4, "SelectAddrMode6", []> {
364 let PrintMethod = "printAddrMode6Operand";
365 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
368 // addrmodepc := pc + reg
370 def addrmodepc : Operand<i32>,
371 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
372 let PrintMethod = "printAddrModePCOperand";
373 let MIOperandInfo = (ops GPR, i32imm);
376 def nohash_imm : Operand<i32> {
377 let PrintMethod = "printNoHashImmediate";
380 //===----------------------------------------------------------------------===//
382 include "ARMInstrFormats.td"
384 //===----------------------------------------------------------------------===//
385 // Multiclass helpers...
388 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
389 /// binop that produces a value.
390 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
391 bit Commutable = 0> {
392 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
393 IIC_iALUi, opc, "\t$dst, $a, $b",
394 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
397 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
398 IIC_iALUr, opc, "\t$dst, $a, $b",
399 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
400 let Inst{11-4} = 0b00000000;
402 let isCommutable = Commutable;
404 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
405 IIC_iALUsr, opc, "\t$dst, $a, $b",
406 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
411 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
412 /// instruction modifies the CPSR register.
413 let Defs = [CPSR] in {
414 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
415 bit Commutable = 0> {
416 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
417 IIC_iALUi, opc, "\t$dst, $a, $b",
418 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
422 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
423 IIC_iALUr, opc, "\t$dst, $a, $b",
424 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
425 let isCommutable = Commutable;
426 let Inst{11-4} = 0b00000000;
430 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
431 IIC_iALUsr, opc, "\t$dst, $a, $b",
432 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
439 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
440 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
441 /// a explicit result, only implicitly set CPSR.
442 let Defs = [CPSR] in {
443 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
444 bit Commutable = 0> {
445 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
447 [(opnode GPR:$a, so_imm:$b)]> {
451 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
453 [(opnode GPR:$a, GPR:$b)]> {
454 let Inst{11-4} = 0b00000000;
457 let isCommutable = Commutable;
459 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
461 [(opnode GPR:$a, so_reg:$b)]> {
468 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
469 /// register and one whose operand is a register rotated by 8/16/24.
470 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
471 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
472 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
473 IIC_iUNAr, opc, "\t$dst, $src",
474 [(set GPR:$dst, (opnode GPR:$src))]>,
475 Requires<[IsARM, HasV6]> {
476 let Inst{11-10} = 0b00;
477 let Inst{19-16} = 0b1111;
479 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
480 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
481 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
482 Requires<[IsARM, HasV6]> {
483 let Inst{19-16} = 0b1111;
487 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
488 /// register and one whose operand is a register rotated by 8/16/24.
489 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
490 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
491 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
492 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
493 Requires<[IsARM, HasV6]> {
494 let Inst{11-10} = 0b00;
496 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
497 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
498 [(set GPR:$dst, (opnode GPR:$LHS,
499 (rotr GPR:$RHS, rot_imm:$rot)))]>,
500 Requires<[IsARM, HasV6]>;
503 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
504 let Uses = [CPSR] in {
505 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
506 bit Commutable = 0> {
507 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
508 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
509 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
510 Requires<[IsARM, CarryDefIsUnused]> {
513 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
514 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
515 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
516 Requires<[IsARM, CarryDefIsUnused]> {
517 let isCommutable = Commutable;
518 let Inst{11-4} = 0b00000000;
521 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
522 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
523 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
524 Requires<[IsARM, CarryDefIsUnused]> {
528 // Carry setting variants
529 let Defs = [CPSR] in {
530 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
531 bit Commutable = 0> {
532 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
533 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
534 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
535 Requires<[IsARM, CarryDefIsUsed]> {
540 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
541 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
542 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
543 Requires<[IsARM, CarryDefIsUsed]> {
545 let Inst{11-4} = 0b00000000;
549 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
550 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
551 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
552 Requires<[IsARM, CarryDefIsUsed]> {
561 //===----------------------------------------------------------------------===//
563 //===----------------------------------------------------------------------===//
565 //===----------------------------------------------------------------------===//
566 // Miscellaneous Instructions.
569 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
570 /// the function. The first operand is the ID# for this instruction, the second
571 /// is the index into the MachineConstantPool that this is, the third is the
572 /// size in bytes of this constant pool entry.
573 let neverHasSideEffects = 1, isNotDuplicable = 1 in
574 def CONSTPOOL_ENTRY :
575 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
576 i32imm:$size), NoItinerary,
577 "${instid:label} ${cpidx:cpentry}", []>;
579 let Defs = [SP], Uses = [SP] in {
581 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
582 "@ ADJCALLSTACKUP $amt1",
583 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
585 def ADJCALLSTACKDOWN :
586 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
587 "@ ADJCALLSTACKDOWN $amt",
588 [(ARMcallseq_start timm:$amt)]>;
591 // Address computation and loads and stores in PIC mode.
592 let isNotDuplicable = 1 in {
593 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
594 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
595 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
597 let AddedComplexity = 10 in {
598 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
599 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
600 [(set GPR:$dst, (load addrmodepc:$addr))]>;
602 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
603 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
604 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
606 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
607 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
608 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
610 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
611 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
612 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
614 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
615 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
616 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
618 let AddedComplexity = 10 in {
619 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
620 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
621 [(store GPR:$src, addrmodepc:$addr)]>;
623 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
624 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
625 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
627 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
628 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
629 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
631 } // isNotDuplicable = 1
634 // LEApcrel - Load a pc-relative address into a register without offending the
636 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
638 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
639 "${:private}PCRELL${:uid}+8))\n"),
640 !strconcat("${:private}PCRELL${:uid}:\n\t",
641 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
644 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
645 (ins i32imm:$label, nohash_imm:$id, pred:$p),
647 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
649 "${:private}PCRELL${:uid}+8))\n"),
650 !strconcat("${:private}PCRELL${:uid}:\n\t",
651 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
656 //===----------------------------------------------------------------------===//
657 // Control Flow Instructions.
660 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
661 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
662 "bx", "\tlr", [(ARMretflag)]> {
663 let Inst{3-0} = 0b1110;
664 let Inst{7-4} = 0b0001;
665 let Inst{19-8} = 0b111111111111;
666 let Inst{27-20} = 0b00010010;
670 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
671 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
672 [(brind GPR:$dst)]> {
673 let Inst{7-4} = 0b0001;
674 let Inst{19-8} = 0b111111111111;
675 let Inst{27-20} = 0b00010010;
676 let Inst{31-28} = 0b1110;
680 // FIXME: remove when we have a way to marking a MI with these properties.
681 // FIXME: Should pc be an implicit operand like PICADD, etc?
682 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
683 hasExtraDefRegAllocReq = 1 in
684 def LDM_RET : AXI4ld<(outs),
685 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
686 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
689 // On non-Darwin platforms R9 is callee-saved.
691 Defs = [R0, R1, R2, R3, R12, LR,
692 D0, D1, D2, D3, D4, D5, D6, D7,
693 D16, D17, D18, D19, D20, D21, D22, D23,
694 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
695 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
696 IIC_Br, "bl\t${func:call}",
697 [(ARMcall tglobaladdr:$func)]>,
698 Requires<[IsARM, IsNotDarwin]> {
699 let Inst{31-28} = 0b1110;
702 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
703 IIC_Br, "bl", "\t${func:call}",
704 [(ARMcall_pred tglobaladdr:$func)]>,
705 Requires<[IsARM, IsNotDarwin]>;
708 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
709 IIC_Br, "blx\t$func",
710 [(ARMcall GPR:$func)]>,
711 Requires<[IsARM, HasV5T, IsNotDarwin]> {
712 let Inst{7-4} = 0b0011;
713 let Inst{19-8} = 0b111111111111;
714 let Inst{27-20} = 0b00010010;
718 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
719 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
720 [(ARMcall_nolink GPR:$func)]>,
721 Requires<[IsARM, IsNotDarwin]> {
722 let Inst{7-4} = 0b0001;
723 let Inst{19-8} = 0b111111111111;
724 let Inst{27-20} = 0b00010010;
728 // On Darwin R9 is call-clobbered.
730 Defs = [R0, R1, R2, R3, R9, R12, LR,
731 D0, D1, D2, D3, D4, D5, D6, D7,
732 D16, D17, D18, D19, D20, D21, D22, D23,
733 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
734 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
735 IIC_Br, "bl\t${func:call}",
736 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
737 let Inst{31-28} = 0b1110;
740 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
741 IIC_Br, "bl", "\t${func:call}",
742 [(ARMcall_pred tglobaladdr:$func)]>,
743 Requires<[IsARM, IsDarwin]>;
746 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
747 IIC_Br, "blx\t$func",
748 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
749 let Inst{7-4} = 0b0011;
750 let Inst{19-8} = 0b111111111111;
751 let Inst{27-20} = 0b00010010;
755 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
756 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
757 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
758 let Inst{7-4} = 0b0001;
759 let Inst{19-8} = 0b111111111111;
760 let Inst{27-20} = 0b00010010;
764 let isBranch = 1, isTerminator = 1 in {
765 // B is "predicable" since it can be xformed into a Bcc.
766 let isBarrier = 1 in {
767 let isPredicable = 1 in
768 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
769 "b\t$target", [(br bb:$target)]>;
771 let isNotDuplicable = 1, isIndirectBranch = 1 in {
772 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
773 IIC_Br, "mov\tpc, $target \n$jt",
774 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
775 let Inst{15-12} = 0b1111;
776 let Inst{20} = 0; // S Bit
777 let Inst{24-21} = 0b1101;
778 let Inst{27-25} = 0b000;
780 def BR_JTm : JTI<(outs),
781 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
782 IIC_Br, "ldr\tpc, $target \n$jt",
783 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
785 let Inst{15-12} = 0b1111;
786 let Inst{20} = 1; // L bit
787 let Inst{21} = 0; // W bit
788 let Inst{22} = 0; // B bit
789 let Inst{24} = 1; // P bit
790 let Inst{27-25} = 0b011;
792 def BR_JTadd : JTI<(outs),
793 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
794 IIC_Br, "add\tpc, $target, $idx \n$jt",
795 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
797 let Inst{15-12} = 0b1111;
798 let Inst{20} = 0; // S bit
799 let Inst{24-21} = 0b0100;
800 let Inst{27-25} = 0b000;
802 } // isNotDuplicable = 1, isIndirectBranch = 1
805 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
806 // a two-value operand where a dag node expects two operands. :(
807 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
808 IIC_Br, "b", "\t$target",
809 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
812 //===----------------------------------------------------------------------===//
813 // Load / store Instructions.
817 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
818 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
819 "ldr", "\t$dst, $addr",
820 [(set GPR:$dst, (load addrmode2:$addr))]>;
822 // Special LDR for loads from non-pc-relative constpools.
823 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
824 mayHaveSideEffects = 1 in
825 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
826 "ldr", "\t$dst, $addr", []>;
828 // Loads with zero extension
829 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
830 IIC_iLoadr, "ldrh", "\t$dst, $addr",
831 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
833 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
834 IIC_iLoadr, "ldrb", "\t$dst, $addr",
835 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
837 // Loads with sign extension
838 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
839 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
840 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
842 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
843 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
844 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
846 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
848 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
849 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
850 []>, Requires<[IsARM, HasV5TE]>;
853 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
854 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
855 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
857 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
858 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
859 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
861 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
862 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
863 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
865 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
866 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
867 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
869 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
870 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
871 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
873 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
874 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
875 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
877 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
878 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
879 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
881 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
882 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
883 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
885 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
886 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
887 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
889 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
890 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
891 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
895 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
896 "str", "\t$src, $addr",
897 [(store GPR:$src, addrmode2:$addr)]>;
899 // Stores with truncate
900 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
901 "strh", "\t$src, $addr",
902 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
904 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
905 "strb", "\t$src, $addr",
906 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
909 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
910 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
911 StMiscFrm, IIC_iStorer,
912 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
915 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
916 (ins GPR:$src, GPR:$base, am2offset:$offset),
918 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
920 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
922 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
923 (ins GPR:$src, GPR:$base,am2offset:$offset),
925 "str", "\t$src, [$base], $offset", "$base = $base_wb",
927 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
929 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
930 (ins GPR:$src, GPR:$base,am3offset:$offset),
931 StMiscFrm, IIC_iStoreru,
932 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
934 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
936 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
937 (ins GPR:$src, GPR:$base,am3offset:$offset),
938 StMiscFrm, IIC_iStoreru,
939 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
940 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
941 GPR:$base, am3offset:$offset))]>;
943 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
944 (ins GPR:$src, GPR:$base,am2offset:$offset),
946 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
947 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
948 GPR:$base, am2offset:$offset))]>;
950 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
951 (ins GPR:$src, GPR:$base,am2offset:$offset),
953 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
954 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
955 GPR:$base, am2offset:$offset))]>;
957 //===----------------------------------------------------------------------===//
958 // Load / store multiple Instructions.
961 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
962 def LDM : AXI4ld<(outs),
963 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
964 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
967 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
968 def STM : AXI4st<(outs),
969 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
970 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
973 //===----------------------------------------------------------------------===//
974 // Move Instructions.
977 let neverHasSideEffects = 1 in
978 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
979 "mov", "\t$dst, $src", []>, UnaryDP {
980 let Inst{11-4} = 0b00000000;
984 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
985 DPSoRegFrm, IIC_iMOVsr,
986 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
990 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
991 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
992 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
996 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
997 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
999 "movw", "\t$dst, $src",
1000 [(set GPR:$dst, imm0_65535:$src)]>,
1001 Requires<[IsARM, HasV6T2]> {
1006 let Constraints = "$src = $dst" in
1007 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1009 "movt", "\t$dst, $imm",
1011 (or (and GPR:$src, 0xffff),
1012 lo16AllZero:$imm))]>, UnaryDP,
1013 Requires<[IsARM, HasV6T2]> {
1018 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1019 Requires<[IsARM, HasV6T2]>;
1021 let Uses = [CPSR] in
1022 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1023 "mov", "\t$dst, $src, rrx",
1024 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1026 // These aren't really mov instructions, but we have to define them this way
1027 // due to flag operands.
1029 let Defs = [CPSR] in {
1030 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1031 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1032 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1033 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1034 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1035 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1038 //===----------------------------------------------------------------------===//
1039 // Extend Instructions.
1044 defm SXTB : AI_unary_rrot<0b01101010,
1045 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1046 defm SXTH : AI_unary_rrot<0b01101011,
1047 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1049 defm SXTAB : AI_bin_rrot<0b01101010,
1050 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1051 defm SXTAH : AI_bin_rrot<0b01101011,
1052 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1054 // TODO: SXT(A){B|H}16
1058 let AddedComplexity = 16 in {
1059 defm UXTB : AI_unary_rrot<0b01101110,
1060 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1061 defm UXTH : AI_unary_rrot<0b01101111,
1062 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1063 defm UXTB16 : AI_unary_rrot<0b01101100,
1064 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1066 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1067 (UXTB16r_rot GPR:$Src, 24)>;
1068 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1069 (UXTB16r_rot GPR:$Src, 8)>;
1071 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1072 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1073 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1074 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1077 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1078 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1080 // TODO: UXT(A){B|H}16
1082 def SBFX : I<(outs GPR:$dst),
1083 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1084 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1085 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1086 Requires<[IsARM, HasV6T2]> {
1087 let Inst{27-21} = 0b0111101;
1088 let Inst{6-4} = 0b101;
1091 def UBFX : I<(outs GPR:$dst),
1092 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1093 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1094 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1095 Requires<[IsARM, HasV6T2]> {
1096 let Inst{27-21} = 0b0111111;
1097 let Inst{6-4} = 0b101;
1100 //===----------------------------------------------------------------------===//
1101 // Arithmetic Instructions.
1104 defm ADD : AsI1_bin_irs<0b0100, "add",
1105 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1106 defm SUB : AsI1_bin_irs<0b0010, "sub",
1107 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1109 // ADD and SUB with 's' bit set.
1110 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1111 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1112 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1113 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1115 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1116 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1117 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1118 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1119 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1120 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1121 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1122 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1124 // These don't define reg/reg forms, because they are handled above.
1125 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1126 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1127 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1131 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1132 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1133 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1137 // RSB with 's' bit set.
1138 let Defs = [CPSR] in {
1139 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1140 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1141 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1145 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1146 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1147 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1153 let Uses = [CPSR] in {
1154 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1155 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1156 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1157 Requires<[IsARM, CarryDefIsUnused]> {
1160 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1161 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1162 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1163 Requires<[IsARM, CarryDefIsUnused]> {
1168 // FIXME: Allow these to be predicated.
1169 let Defs = [CPSR], Uses = [CPSR] in {
1170 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1171 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1172 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1173 Requires<[IsARM, CarryDefIsUnused]> {
1177 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1178 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1179 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1180 Requires<[IsARM, CarryDefIsUnused]> {
1186 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1187 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1188 (SUBri GPR:$src, so_imm_neg:$imm)>;
1190 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1191 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1192 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1193 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1195 // Note: These are implemented in C++ code, because they have to generate
1196 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1198 // (mul X, 2^n+1) -> (add (X << n), X)
1199 // (mul X, 2^n-1) -> (rsb X, (X << n))
1202 //===----------------------------------------------------------------------===//
1203 // Bitwise Instructions.
1206 defm AND : AsI1_bin_irs<0b0000, "and",
1207 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1208 defm ORR : AsI1_bin_irs<0b1100, "orr",
1209 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1210 defm EOR : AsI1_bin_irs<0b0001, "eor",
1211 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1212 defm BIC : AsI1_bin_irs<0b1110, "bic",
1213 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1215 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1216 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1217 "bfc", "\t$dst, $imm", "$src = $dst",
1218 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1219 Requires<[IsARM, HasV6T2]> {
1220 let Inst{27-21} = 0b0111110;
1221 let Inst{6-0} = 0b0011111;
1224 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1225 "mvn", "\t$dst, $src",
1226 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1227 let Inst{11-4} = 0b00000000;
1229 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1230 IIC_iMOVsr, "mvn", "\t$dst, $src",
1231 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
1232 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1233 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1234 IIC_iMOVi, "mvn", "\t$dst, $imm",
1235 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1239 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1240 (BICri GPR:$src, so_imm_not:$imm)>;
1242 //===----------------------------------------------------------------------===//
1243 // Multiply Instructions.
1246 let isCommutable = 1 in
1247 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1248 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1249 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1251 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1252 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1253 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1255 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1256 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1257 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1258 Requires<[IsARM, HasV6T2]>;
1260 // Extra precision multiplies with low / high results
1261 let neverHasSideEffects = 1 in {
1262 let isCommutable = 1 in {
1263 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1264 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1265 "smull", "\t$ldst, $hdst, $a, $b", []>;
1267 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1268 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1269 "umull", "\t$ldst, $hdst, $a, $b", []>;
1272 // Multiply + accumulate
1273 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1274 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1275 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1277 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1278 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1279 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1281 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1282 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1283 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1284 Requires<[IsARM, HasV6]>;
1285 } // neverHasSideEffects
1287 // Most significant word multiply
1288 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1289 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1290 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1291 Requires<[IsARM, HasV6]> {
1292 let Inst{7-4} = 0b0001;
1293 let Inst{15-12} = 0b1111;
1296 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1297 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1298 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1299 Requires<[IsARM, HasV6]> {
1300 let Inst{7-4} = 0b0001;
1304 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1305 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1306 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1307 Requires<[IsARM, HasV6]> {
1308 let Inst{7-4} = 0b1101;
1311 multiclass AI_smul<string opc, PatFrag opnode> {
1312 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1313 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1314 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1315 (sext_inreg GPR:$b, i16)))]>,
1316 Requires<[IsARM, HasV5TE]> {
1321 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1322 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1323 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1324 (sra GPR:$b, (i32 16))))]>,
1325 Requires<[IsARM, HasV5TE]> {
1330 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1331 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1332 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1333 (sext_inreg GPR:$b, i16)))]>,
1334 Requires<[IsARM, HasV5TE]> {
1339 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1340 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1341 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1342 (sra GPR:$b, (i32 16))))]>,
1343 Requires<[IsARM, HasV5TE]> {
1348 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1349 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1350 [(set GPR:$dst, (sra (opnode GPR:$a,
1351 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1352 Requires<[IsARM, HasV5TE]> {
1357 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1358 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1359 [(set GPR:$dst, (sra (opnode GPR:$a,
1360 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1361 Requires<[IsARM, HasV5TE]> {
1368 multiclass AI_smla<string opc, PatFrag opnode> {
1369 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1370 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1371 [(set GPR:$dst, (add GPR:$acc,
1372 (opnode (sext_inreg GPR:$a, i16),
1373 (sext_inreg GPR:$b, i16))))]>,
1374 Requires<[IsARM, HasV5TE]> {
1379 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1380 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1381 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1382 (sra GPR:$b, (i32 16)))))]>,
1383 Requires<[IsARM, HasV5TE]> {
1388 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1389 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1390 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1391 (sext_inreg GPR:$b, i16))))]>,
1392 Requires<[IsARM, HasV5TE]> {
1397 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1398 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1399 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1400 (sra GPR:$b, (i32 16)))))]>,
1401 Requires<[IsARM, HasV5TE]> {
1406 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1407 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1408 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1409 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1410 Requires<[IsARM, HasV5TE]> {
1415 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1416 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1417 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1418 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1419 Requires<[IsARM, HasV5TE]> {
1425 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1426 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1428 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1429 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1431 //===----------------------------------------------------------------------===//
1432 // Misc. Arithmetic Instructions.
1435 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1436 "clz", "\t$dst, $src",
1437 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1438 let Inst{7-4} = 0b0001;
1439 let Inst{11-8} = 0b1111;
1440 let Inst{19-16} = 0b1111;
1443 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1444 "rev", "\t$dst, $src",
1445 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1446 let Inst{7-4} = 0b0011;
1447 let Inst{11-8} = 0b1111;
1448 let Inst{19-16} = 0b1111;
1451 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1452 "rev16", "\t$dst, $src",
1454 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1455 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1456 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1457 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1458 Requires<[IsARM, HasV6]> {
1459 let Inst{7-4} = 0b1011;
1460 let Inst{11-8} = 0b1111;
1461 let Inst{19-16} = 0b1111;
1464 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1465 "revsh", "\t$dst, $src",
1468 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1469 (shl GPR:$src, (i32 8))), i16))]>,
1470 Requires<[IsARM, HasV6]> {
1471 let Inst{7-4} = 0b1011;
1472 let Inst{11-8} = 0b1111;
1473 let Inst{19-16} = 0b1111;
1476 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1477 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1478 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1479 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1480 (and (shl GPR:$src2, (i32 imm:$shamt)),
1482 Requires<[IsARM, HasV6]> {
1483 let Inst{6-4} = 0b001;
1486 // Alternate cases for PKHBT where identities eliminate some nodes.
1487 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1488 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1489 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1490 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1493 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1494 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1495 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1496 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1497 (and (sra GPR:$src2, imm16_31:$shamt),
1498 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1499 let Inst{6-4} = 0b101;
1502 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
1503 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1504 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1505 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1506 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1507 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1508 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1510 //===----------------------------------------------------------------------===//
1511 // Comparison Instructions...
1514 defm CMP : AI1_cmp_irs<0b1010, "cmp",
1515 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1516 defm CMN : AI1_cmp_irs<0b1011, "cmn",
1517 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1519 // Note that TST/TEQ don't set all the same flags that CMP does!
1520 defm TST : AI1_cmp_irs<0b1000, "tst",
1521 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1522 defm TEQ : AI1_cmp_irs<0b1001, "teq",
1523 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1525 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1526 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1527 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1528 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1530 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1531 (CMNri GPR:$src, so_imm_neg:$imm)>;
1533 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1534 (CMNri GPR:$src, so_imm_neg:$imm)>;
1537 // Conditional moves
1538 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1539 // a two-value operand where a dag node expects two operands. :(
1540 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1541 IIC_iCMOVr, "mov", "\t$dst, $true",
1542 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1543 RegConstraint<"$false = $dst">, UnaryDP {
1544 let Inst{11-4} = 0b00000000;
1548 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1549 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1550 "mov", "\t$dst, $true",
1551 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1552 RegConstraint<"$false = $dst">, UnaryDP {
1556 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1557 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1558 "mov", "\t$dst, $true",
1559 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1560 RegConstraint<"$false = $dst">, UnaryDP {
1565 //===----------------------------------------------------------------------===//
1569 // __aeabi_read_tp preserves the registers r1-r3.
1571 Defs = [R0, R12, LR, CPSR] in {
1572 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1573 "bl\t__aeabi_read_tp",
1574 [(set R0, ARMthread_pointer)]>;
1577 //===----------------------------------------------------------------------===//
1578 // SJLJ Exception handling intrinsics
1579 // eh_sjlj_setjmp() is an instruction sequence to store the return
1580 // address and save #0 in R0 for the non-longjmp case.
1581 // Since by its nature we may be coming from some other function to get
1582 // here, and we're using the stack frame for the containing function to
1583 // save/restore registers, we can't keep anything live in regs across
1584 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1585 // when we get here from a longjmp(). We force everthing out of registers
1586 // except for our own input by listing the relevant registers in Defs. By
1587 // doing so, we also cause the prologue/epilogue code to actively preserve
1588 // all of the callee-saved resgisters, which is exactly what we want.
1590 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
1591 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1592 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1594 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
1595 AddrModeNone, SizeSpecial, IndexModeNone,
1596 Pseudo, NoItinerary,
1597 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1598 "add\tr12, pc, #8\n\t"
1599 "str\tr12, [$src, #+4]\n\t"
1601 "add\tpc, pc, #0\n\t"
1602 "mov\tr0, #1 @ eh_setjmp end", "",
1603 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1606 //===----------------------------------------------------------------------===//
1607 // Non-Instruction Patterns
1610 // Large immediate handling.
1612 // Two piece so_imms.
1613 let isReMaterializable = 1 in
1614 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
1616 "mov", "\t$dst, $src",
1617 [(set GPR:$dst, so_imm2part:$src)]>,
1618 Requires<[IsARM, NoV6T2]>;
1620 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1621 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1622 (so_imm2part_2 imm:$RHS))>;
1623 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1624 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1625 (so_imm2part_2 imm:$RHS))>;
1626 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1627 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1628 (so_imm2part_2 imm:$RHS))>;
1629 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1630 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1631 (so_neg_imm2part_2 imm:$RHS))>;
1633 // 32-bit immediate using movw + movt.
1634 // This is a single pseudo instruction, the benefit is that it can be remat'd
1635 // as a single unit instead of having to handle reg inputs.
1636 // FIXME: Remove this when we can do generalized remat.
1637 let isReMaterializable = 1 in
1638 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1639 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1640 [(set GPR:$dst, (i32 imm:$src))]>,
1641 Requires<[IsARM, HasV6T2]>;
1643 // ConstantPool, GlobalAddress, and JumpTable
1644 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1645 Requires<[IsARM, DontUseMovt]>;
1646 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1647 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1648 Requires<[IsARM, UseMovt]>;
1649 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1650 (LEApcrelJT tjumptable:$dst, imm:$id)>;
1652 // TODO: add,sub,and, 3-instr forms?
1656 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1657 Requires<[IsARM, IsNotDarwin]>;
1658 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1659 Requires<[IsARM, IsDarwin]>;
1661 // zextload i1 -> zextload i8
1662 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1664 // extload -> zextload
1665 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1666 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1667 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
1669 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1670 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1673 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1674 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1675 (SMULBB GPR:$a, GPR:$b)>;
1676 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1677 (SMULBB GPR:$a, GPR:$b)>;
1678 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1679 (sra GPR:$b, (i32 16))),
1680 (SMULBT GPR:$a, GPR:$b)>;
1681 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
1682 (SMULBT GPR:$a, GPR:$b)>;
1683 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1684 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1685 (SMULTB GPR:$a, GPR:$b)>;
1686 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
1687 (SMULTB GPR:$a, GPR:$b)>;
1688 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1690 (SMULWB GPR:$a, GPR:$b)>;
1691 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
1692 (SMULWB GPR:$a, GPR:$b)>;
1694 def : ARMV5TEPat<(add GPR:$acc,
1695 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1696 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1697 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1698 def : ARMV5TEPat<(add GPR:$acc,
1699 (mul sext_16_node:$a, sext_16_node:$b)),
1700 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1701 def : ARMV5TEPat<(add GPR:$acc,
1702 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1703 (sra GPR:$b, (i32 16)))),
1704 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1705 def : ARMV5TEPat<(add GPR:$acc,
1706 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
1707 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1708 def : ARMV5TEPat<(add GPR:$acc,
1709 (mul (sra GPR:$a, (i32 16)),
1710 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1711 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1712 def : ARMV5TEPat<(add GPR:$acc,
1713 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
1714 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1715 def : ARMV5TEPat<(add GPR:$acc,
1716 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1718 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1719 def : ARMV5TEPat<(add GPR:$acc,
1720 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
1721 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1723 //===----------------------------------------------------------------------===//
1727 include "ARMInstrThumb.td"
1729 //===----------------------------------------------------------------------===//
1733 include "ARMInstrThumb2.td"
1735 //===----------------------------------------------------------------------===//
1736 // Floating Point Support
1739 include "ARMInstrVFP.td"
1741 //===----------------------------------------------------------------------===//
1742 // Advanced SIMD (NEON) Support
1745 include "ARMInstrNEON.td"