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>]>;
49 def SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>;
50 def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
51 def SDT_ARMMEMBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
52 def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
55 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
56 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
58 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
59 [SDNPHasChain, SDNPOutFlag]>;
60 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
61 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
63 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
64 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
65 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
66 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
67 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
68 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
70 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
71 [SDNPHasChain, SDNPOptInFlag]>;
73 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
75 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
78 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
79 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
81 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
83 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
86 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
89 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
90 [SDNPOutFlag,SDNPCommutative]>;
92 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
94 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
95 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
98 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
99 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
101 def ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
103 def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
105 def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
107 def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
110 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
112 //===----------------------------------------------------------------------===//
113 // ARM Instruction Predicate Definitions.
115 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
116 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
117 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
118 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
119 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
120 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
121 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
122 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
123 def HasNEON : Predicate<"Subtarget->hasNEON()">;
124 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
125 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
126 def IsThumb : Predicate<"Subtarget->isThumb()">;
127 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
128 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
129 def IsARM : Predicate<"!Subtarget->isThumb()">;
130 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
131 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
132 def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
133 def CarryDefIsUsed : Predicate<"N->hasAnyUseOfValue(1)">;
135 // FIXME: Eventually this will be just "hasV6T2Ops".
136 def UseMovt : Predicate<"Subtarget->useMovt()">;
137 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
139 //===----------------------------------------------------------------------===//
140 // ARM Flag Definitions.
142 class RegConstraint<string C> {
143 string Constraints = C;
146 //===----------------------------------------------------------------------===//
147 // ARM specific transformation functions and pattern fragments.
150 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
151 // so_imm_neg def below.
152 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
153 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
156 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
157 // so_imm_not def below.
158 def so_imm_not_XFORM : SDNodeXForm<imm, [{
159 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
162 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
163 def rot_imm : PatLeaf<(i32 imm), [{
164 int32_t v = (int32_t)N->getZExtValue();
165 return v == 8 || v == 16 || v == 24;
168 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
169 def imm1_15 : PatLeaf<(i32 imm), [{
170 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
173 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
174 def imm16_31 : PatLeaf<(i32 imm), [{
175 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
180 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
181 }], so_imm_neg_XFORM>;
185 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
186 }], so_imm_not_XFORM>;
188 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
189 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
190 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
193 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
195 def bf_inv_mask_imm : Operand<i32>,
197 uint32_t v = (uint32_t)N->getZExtValue();
200 // there can be 1's on either or both "outsides", all the "inside"
202 unsigned int lsb = 0, msb = 31;
203 while (v & (1 << msb)) --msb;
204 while (v & (1 << lsb)) ++lsb;
205 for (unsigned int i = lsb; i <= msb; ++i) {
211 let PrintMethod = "printBitfieldInvMaskImmOperand";
214 /// Split a 32-bit immediate into two 16 bit parts.
215 def lo16 : SDNodeXForm<imm, [{
216 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
220 def hi16 : SDNodeXForm<imm, [{
221 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
224 def lo16AllZero : PatLeaf<(i32 imm), [{
225 // Returns true if all low 16-bits are 0.
226 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
229 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
231 def imm0_65535 : PatLeaf<(i32 imm), [{
232 return (uint32_t)N->getZExtValue() < 65536;
235 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
236 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
238 //===----------------------------------------------------------------------===//
239 // Operand Definitions.
243 def brtarget : Operand<OtherVT>;
245 // A list of registers separated by comma. Used by load/store multiple.
246 def reglist : Operand<i32> {
247 let PrintMethod = "printRegisterList";
250 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
251 def cpinst_operand : Operand<i32> {
252 let PrintMethod = "printCPInstOperand";
255 def jtblock_operand : Operand<i32> {
256 let PrintMethod = "printJTBlockOperand";
258 def jt2block_operand : Operand<i32> {
259 let PrintMethod = "printJT2BlockOperand";
263 def pclabel : Operand<i32> {
264 let PrintMethod = "printPCLabel";
267 // shifter_operand operands: so_reg and so_imm.
268 def so_reg : Operand<i32>, // reg reg imm
269 ComplexPattern<i32, 3, "SelectShifterOperandReg",
270 [shl,srl,sra,rotr]> {
271 let PrintMethod = "printSORegOperand";
272 let MIOperandInfo = (ops GPR, GPR, i32imm);
275 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
276 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
277 // represented in the imm field in the same 12-bit form that they are encoded
278 // into so_imm instructions: the 8-bit immediate is the least significant bits
279 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
280 def so_imm : Operand<i32>,
282 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
284 let PrintMethod = "printSOImmOperand";
287 // Break so_imm's up into two pieces. This handles immediates with up to 16
288 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
289 // get the first/second pieces.
290 def so_imm2part : Operand<i32>,
292 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
294 let PrintMethod = "printSOImm2PartOperand";
297 def so_imm2part_1 : SDNodeXForm<imm, [{
298 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
299 return CurDAG->getTargetConstant(V, MVT::i32);
302 def so_imm2part_2 : SDNodeXForm<imm, [{
303 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
304 return CurDAG->getTargetConstant(V, MVT::i32);
307 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
308 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
310 let PrintMethod = "printSOImm2PartOperand";
313 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
314 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
315 return CurDAG->getTargetConstant(V, MVT::i32);
318 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
319 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
320 return CurDAG->getTargetConstant(V, MVT::i32);
323 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
324 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
325 return (int32_t)N->getZExtValue() < 32;
328 // Define ARM specific addressing modes.
330 // addrmode2 := reg +/- reg shop imm
331 // addrmode2 := reg +/- imm12
333 def addrmode2 : Operand<i32>,
334 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
335 let PrintMethod = "printAddrMode2Operand";
336 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
339 def am2offset : Operand<i32>,
340 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
341 let PrintMethod = "printAddrMode2OffsetOperand";
342 let MIOperandInfo = (ops GPR, i32imm);
345 // addrmode3 := reg +/- reg
346 // addrmode3 := reg +/- imm8
348 def addrmode3 : Operand<i32>,
349 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
350 let PrintMethod = "printAddrMode3Operand";
351 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
354 def am3offset : Operand<i32>,
355 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
356 let PrintMethod = "printAddrMode3OffsetOperand";
357 let MIOperandInfo = (ops GPR, i32imm);
360 // addrmode4 := reg, <mode|W>
362 def addrmode4 : Operand<i32>,
363 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
364 let PrintMethod = "printAddrMode4Operand";
365 let MIOperandInfo = (ops GPR, i32imm);
368 // addrmode5 := reg +/- imm8*4
370 def addrmode5 : Operand<i32>,
371 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
372 let PrintMethod = "printAddrMode5Operand";
373 let MIOperandInfo = (ops GPR, i32imm);
376 // addrmode6 := reg with optional writeback
378 def addrmode6 : Operand<i32>,
379 ComplexPattern<i32, 4, "SelectAddrMode6", []> {
380 let PrintMethod = "printAddrMode6Operand";
381 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
384 // addrmodepc := pc + reg
386 def addrmodepc : Operand<i32>,
387 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
388 let PrintMethod = "printAddrModePCOperand";
389 let MIOperandInfo = (ops GPR, i32imm);
392 def nohash_imm : Operand<i32> {
393 let PrintMethod = "printNoHashImmediate";
396 //===----------------------------------------------------------------------===//
398 include "ARMInstrFormats.td"
400 //===----------------------------------------------------------------------===//
401 // Multiclass helpers...
404 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
405 /// binop that produces a value.
406 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
407 bit Commutable = 0> {
408 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
409 IIC_iALUi, opc, "\t$dst, $a, $b",
410 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
413 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
414 IIC_iALUr, opc, "\t$dst, $a, $b",
415 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
416 let Inst{11-4} = 0b00000000;
418 let isCommutable = Commutable;
420 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
421 IIC_iALUsr, opc, "\t$dst, $a, $b",
422 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
427 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
428 /// instruction modifies the CPSR register.
429 let Defs = [CPSR] in {
430 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
431 bit Commutable = 0> {
432 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
433 IIC_iALUi, opc, "\t$dst, $a, $b",
434 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
438 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
439 IIC_iALUr, opc, "\t$dst, $a, $b",
440 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
441 let isCommutable = Commutable;
442 let Inst{11-4} = 0b00000000;
446 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
447 IIC_iALUsr, opc, "\t$dst, $a, $b",
448 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
455 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
456 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
457 /// a explicit result, only implicitly set CPSR.
458 let Defs = [CPSR] in {
459 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
460 bit Commutable = 0> {
461 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
463 [(opnode GPR:$a, so_imm:$b)]> {
467 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
469 [(opnode GPR:$a, GPR:$b)]> {
470 let Inst{11-4} = 0b00000000;
473 let isCommutable = Commutable;
475 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
477 [(opnode GPR:$a, so_reg:$b)]> {
484 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
485 /// register and one whose operand is a register rotated by 8/16/24.
486 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
487 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
488 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
489 IIC_iUNAr, opc, "\t$dst, $src",
490 [(set GPR:$dst, (opnode GPR:$src))]>,
491 Requires<[IsARM, HasV6]> {
492 let Inst{11-10} = 0b00;
493 let Inst{19-16} = 0b1111;
495 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
496 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
497 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
498 Requires<[IsARM, HasV6]> {
499 let Inst{19-16} = 0b1111;
503 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
504 /// register and one whose operand is a register rotated by 8/16/24.
505 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
506 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
507 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
508 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
509 Requires<[IsARM, HasV6]> {
510 let Inst{11-10} = 0b00;
512 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
513 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
514 [(set GPR:$dst, (opnode GPR:$LHS,
515 (rotr GPR:$RHS, rot_imm:$rot)))]>,
516 Requires<[IsARM, HasV6]>;
519 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
520 let Uses = [CPSR] in {
521 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
522 bit Commutable = 0> {
523 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
524 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
525 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
526 Requires<[IsARM, CarryDefIsUnused]> {
529 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
530 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
531 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
532 Requires<[IsARM, CarryDefIsUnused]> {
533 let isCommutable = Commutable;
534 let Inst{11-4} = 0b00000000;
537 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
538 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
539 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
540 Requires<[IsARM, CarryDefIsUnused]> {
544 // Carry setting variants
545 let Defs = [CPSR] in {
546 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
547 bit Commutable = 0> {
548 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
549 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
550 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
551 Requires<[IsARM, CarryDefIsUsed]> {
556 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
557 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
558 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
559 Requires<[IsARM, CarryDefIsUsed]> {
561 let Inst{11-4} = 0b00000000;
565 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
566 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
567 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
568 Requires<[IsARM, CarryDefIsUsed]> {
577 //===----------------------------------------------------------------------===//
579 //===----------------------------------------------------------------------===//
581 //===----------------------------------------------------------------------===//
582 // Miscellaneous Instructions.
585 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
586 /// the function. The first operand is the ID# for this instruction, the second
587 /// is the index into the MachineConstantPool that this is, the third is the
588 /// size in bytes of this constant pool entry.
589 let neverHasSideEffects = 1, isNotDuplicable = 1 in
590 def CONSTPOOL_ENTRY :
591 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
592 i32imm:$size), NoItinerary,
593 "${instid:label} ${cpidx:cpentry}", []>;
595 let Defs = [SP], Uses = [SP] in {
597 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
598 "@ ADJCALLSTACKUP $amt1",
599 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
601 def ADJCALLSTACKDOWN :
602 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
603 "@ ADJCALLSTACKDOWN $amt",
604 [(ARMcallseq_start timm:$amt)]>;
607 // Address computation and loads and stores in PIC mode.
608 let isNotDuplicable = 1 in {
609 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
610 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
611 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
613 let AddedComplexity = 10 in {
614 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
615 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
616 [(set GPR:$dst, (load addrmodepc:$addr))]>;
618 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
619 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
620 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
622 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
623 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
624 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
626 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
627 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
628 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
630 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
631 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
632 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
634 let AddedComplexity = 10 in {
635 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
636 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
637 [(store GPR:$src, addrmodepc:$addr)]>;
639 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
640 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
641 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
643 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
644 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
645 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
647 } // isNotDuplicable = 1
650 // LEApcrel - Load a pc-relative address into a register without offending the
652 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
654 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
655 "${:private}PCRELL${:uid}+8))\n"),
656 !strconcat("${:private}PCRELL${:uid}:\n\t",
657 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
660 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
661 (ins i32imm:$label, nohash_imm:$id, pred:$p),
663 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
665 "${:private}PCRELL${:uid}+8))\n"),
666 !strconcat("${:private}PCRELL${:uid}:\n\t",
667 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
672 //===----------------------------------------------------------------------===//
673 // Control Flow Instructions.
676 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
677 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
678 "bx", "\tlr", [(ARMretflag)]> {
679 let Inst{3-0} = 0b1110;
680 let Inst{7-4} = 0b0001;
681 let Inst{19-8} = 0b111111111111;
682 let Inst{27-20} = 0b00010010;
686 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
687 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
688 [(brind GPR:$dst)]> {
689 let Inst{7-4} = 0b0001;
690 let Inst{19-8} = 0b111111111111;
691 let Inst{27-20} = 0b00010010;
692 let Inst{31-28} = 0b1110;
696 // FIXME: remove when we have a way to marking a MI with these properties.
697 // FIXME: Should pc be an implicit operand like PICADD, etc?
698 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
699 hasExtraDefRegAllocReq = 1 in
700 def LDM_RET : AXI4ld<(outs),
701 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
702 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
705 // On non-Darwin platforms R9 is callee-saved.
707 Defs = [R0, R1, R2, R3, R12, LR,
708 D0, D1, D2, D3, D4, D5, D6, D7,
709 D16, D17, D18, D19, D20, D21, D22, D23,
710 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
711 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
712 IIC_Br, "bl\t${func:call}",
713 [(ARMcall tglobaladdr:$func)]>,
714 Requires<[IsARM, IsNotDarwin]> {
715 let Inst{31-28} = 0b1110;
718 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
719 IIC_Br, "bl", "\t${func:call}",
720 [(ARMcall_pred tglobaladdr:$func)]>,
721 Requires<[IsARM, IsNotDarwin]>;
724 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
725 IIC_Br, "blx\t$func",
726 [(ARMcall GPR:$func)]>,
727 Requires<[IsARM, HasV5T, IsNotDarwin]> {
728 let Inst{7-4} = 0b0011;
729 let Inst{19-8} = 0b111111111111;
730 let Inst{27-20} = 0b00010010;
734 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
735 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
736 [(ARMcall_nolink GPR:$func)]>,
737 Requires<[IsARM, IsNotDarwin]> {
738 let Inst{7-4} = 0b0001;
739 let Inst{19-8} = 0b111111111111;
740 let Inst{27-20} = 0b00010010;
744 // On Darwin R9 is call-clobbered.
746 Defs = [R0, R1, R2, R3, R9, R12, LR,
747 D0, D1, D2, D3, D4, D5, D6, D7,
748 D16, D17, D18, D19, D20, D21, D22, D23,
749 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
750 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
751 IIC_Br, "bl\t${func:call}",
752 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
753 let Inst{31-28} = 0b1110;
756 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
757 IIC_Br, "bl", "\t${func:call}",
758 [(ARMcall_pred tglobaladdr:$func)]>,
759 Requires<[IsARM, IsDarwin]>;
762 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
763 IIC_Br, "blx\t$func",
764 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
765 let Inst{7-4} = 0b0011;
766 let Inst{19-8} = 0b111111111111;
767 let Inst{27-20} = 0b00010010;
771 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
772 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
773 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
774 let Inst{7-4} = 0b0001;
775 let Inst{19-8} = 0b111111111111;
776 let Inst{27-20} = 0b00010010;
780 let isBranch = 1, isTerminator = 1 in {
781 // B is "predicable" since it can be xformed into a Bcc.
782 let isBarrier = 1 in {
783 let isPredicable = 1 in
784 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
785 "b\t$target", [(br bb:$target)]>;
787 let isNotDuplicable = 1, isIndirectBranch = 1 in {
788 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
789 IIC_Br, "mov\tpc, $target \n$jt",
790 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
791 let Inst{11-4} = 0b00000000;
792 let Inst{15-12} = 0b1111;
793 let Inst{20} = 0; // S Bit
794 let Inst{24-21} = 0b1101;
795 let Inst{27-25} = 0b000;
797 def BR_JTm : JTI<(outs),
798 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
799 IIC_Br, "ldr\tpc, $target \n$jt",
800 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
802 let Inst{15-12} = 0b1111;
803 let Inst{20} = 1; // L bit
804 let Inst{21} = 0; // W bit
805 let Inst{22} = 0; // B bit
806 let Inst{24} = 1; // P bit
807 let Inst{27-25} = 0b011;
809 def BR_JTadd : JTI<(outs),
810 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
811 IIC_Br, "add\tpc, $target, $idx \n$jt",
812 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
814 let Inst{15-12} = 0b1111;
815 let Inst{20} = 0; // S bit
816 let Inst{24-21} = 0b0100;
817 let Inst{27-25} = 0b000;
819 } // isNotDuplicable = 1, isIndirectBranch = 1
822 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
823 // a two-value operand where a dag node expects two operands. :(
824 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
825 IIC_Br, "b", "\t$target",
826 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
829 //===----------------------------------------------------------------------===//
830 // Load / store Instructions.
834 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
835 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
836 "ldr", "\t$dst, $addr",
837 [(set GPR:$dst, (load addrmode2:$addr))]>;
839 // Special LDR for loads from non-pc-relative constpools.
840 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
841 mayHaveSideEffects = 1 in
842 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
843 "ldr", "\t$dst, $addr", []>;
845 // Loads with zero extension
846 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
847 IIC_iLoadr, "ldrh", "\t$dst, $addr",
848 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
850 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
851 IIC_iLoadr, "ldrb", "\t$dst, $addr",
852 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
854 // Loads with sign extension
855 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
856 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
857 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
859 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
860 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
861 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
863 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
865 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
866 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
867 []>, Requires<[IsARM, HasV5TE]>;
870 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
871 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
872 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
874 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
875 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
876 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
878 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
879 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
880 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
882 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
883 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
884 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
886 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
887 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
888 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
890 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
891 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
892 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
894 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
895 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
896 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
898 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
899 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
900 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
902 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
903 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
904 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
906 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
907 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
908 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
912 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
913 "str", "\t$src, $addr",
914 [(store GPR:$src, addrmode2:$addr)]>;
916 // Stores with truncate
917 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
918 "strh", "\t$src, $addr",
919 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
921 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
922 "strb", "\t$src, $addr",
923 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
926 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
927 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
928 StMiscFrm, IIC_iStorer,
929 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
932 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
933 (ins GPR:$src, GPR:$base, am2offset:$offset),
935 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
937 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
939 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
940 (ins GPR:$src, GPR:$base,am2offset:$offset),
942 "str", "\t$src, [$base], $offset", "$base = $base_wb",
944 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
946 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
947 (ins GPR:$src, GPR:$base,am3offset:$offset),
948 StMiscFrm, IIC_iStoreru,
949 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
951 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
953 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
954 (ins GPR:$src, GPR:$base,am3offset:$offset),
955 StMiscFrm, IIC_iStoreru,
956 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
957 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
958 GPR:$base, am3offset:$offset))]>;
960 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
961 (ins GPR:$src, GPR:$base,am2offset:$offset),
963 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
964 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
965 GPR:$base, am2offset:$offset))]>;
967 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
968 (ins GPR:$src, GPR:$base,am2offset:$offset),
970 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
971 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
972 GPR:$base, am2offset:$offset))]>;
974 //===----------------------------------------------------------------------===//
975 // Load / store multiple Instructions.
978 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
979 def LDM : AXI4ld<(outs),
980 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
981 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
984 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
985 def STM : AXI4st<(outs),
986 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
987 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
990 //===----------------------------------------------------------------------===//
991 // Move Instructions.
994 let neverHasSideEffects = 1 in
995 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
996 "mov", "\t$dst, $src", []>, UnaryDP {
997 let Inst{11-4} = 0b00000000;
1001 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1002 DPSoRegFrm, IIC_iMOVsr,
1003 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1007 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1008 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1009 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1013 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1014 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1016 "movw", "\t$dst, $src",
1017 [(set GPR:$dst, imm0_65535:$src)]>,
1018 Requires<[IsARM, HasV6T2]> {
1023 let Constraints = "$src = $dst" in
1024 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1026 "movt", "\t$dst, $imm",
1028 (or (and GPR:$src, 0xffff),
1029 lo16AllZero:$imm))]>, UnaryDP,
1030 Requires<[IsARM, HasV6T2]> {
1035 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1036 Requires<[IsARM, HasV6T2]>;
1038 let Uses = [CPSR] in
1039 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1040 "mov", "\t$dst, $src, rrx",
1041 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1043 // These aren't really mov instructions, but we have to define them this way
1044 // due to flag operands.
1046 let Defs = [CPSR] in {
1047 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1048 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1049 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1050 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1051 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1052 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1055 //===----------------------------------------------------------------------===//
1056 // Extend Instructions.
1061 defm SXTB : AI_unary_rrot<0b01101010,
1062 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1063 defm SXTH : AI_unary_rrot<0b01101011,
1064 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1066 defm SXTAB : AI_bin_rrot<0b01101010,
1067 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1068 defm SXTAH : AI_bin_rrot<0b01101011,
1069 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1071 // TODO: SXT(A){B|H}16
1075 let AddedComplexity = 16 in {
1076 defm UXTB : AI_unary_rrot<0b01101110,
1077 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1078 defm UXTH : AI_unary_rrot<0b01101111,
1079 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1080 defm UXTB16 : AI_unary_rrot<0b01101100,
1081 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1083 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1084 (UXTB16r_rot GPR:$Src, 24)>;
1085 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1086 (UXTB16r_rot GPR:$Src, 8)>;
1088 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1089 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1090 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1091 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1094 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1095 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1097 // TODO: UXT(A){B|H}16
1099 def SBFX : I<(outs GPR:$dst),
1100 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1101 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1102 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1103 Requires<[IsARM, HasV6T2]> {
1104 let Inst{27-21} = 0b0111101;
1105 let Inst{6-4} = 0b101;
1108 def UBFX : I<(outs GPR:$dst),
1109 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1110 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1111 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1112 Requires<[IsARM, HasV6T2]> {
1113 let Inst{27-21} = 0b0111111;
1114 let Inst{6-4} = 0b101;
1117 //===----------------------------------------------------------------------===//
1118 // Arithmetic Instructions.
1121 defm ADD : AsI1_bin_irs<0b0100, "add",
1122 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1123 defm SUB : AsI1_bin_irs<0b0010, "sub",
1124 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1126 // ADD and SUB with 's' bit set.
1127 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1128 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1129 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1130 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1132 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1133 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1134 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1135 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1136 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1137 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1138 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1139 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1141 // These don't define reg/reg forms, because they are handled above.
1142 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1143 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1144 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1148 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1149 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1150 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1154 // RSB with 's' bit set.
1155 let Defs = [CPSR] in {
1156 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1157 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1158 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1162 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1163 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1164 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1170 let Uses = [CPSR] in {
1171 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1172 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1173 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1174 Requires<[IsARM, CarryDefIsUnused]> {
1177 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1178 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1179 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1180 Requires<[IsARM, CarryDefIsUnused]> {
1185 // FIXME: Allow these to be predicated.
1186 let Defs = [CPSR], Uses = [CPSR] in {
1187 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1188 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1189 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1190 Requires<[IsARM, CarryDefIsUnused]> {
1194 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1195 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1196 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1197 Requires<[IsARM, CarryDefIsUnused]> {
1203 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1204 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1205 (SUBri GPR:$src, so_imm_neg:$imm)>;
1207 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1208 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1209 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1210 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1212 // Note: These are implemented in C++ code, because they have to generate
1213 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1215 // (mul X, 2^n+1) -> (add (X << n), X)
1216 // (mul X, 2^n-1) -> (rsb X, (X << n))
1219 //===----------------------------------------------------------------------===//
1220 // Bitwise Instructions.
1223 defm AND : AsI1_bin_irs<0b0000, "and",
1224 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1225 defm ORR : AsI1_bin_irs<0b1100, "orr",
1226 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1227 defm EOR : AsI1_bin_irs<0b0001, "eor",
1228 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1229 defm BIC : AsI1_bin_irs<0b1110, "bic",
1230 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1232 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1233 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1234 "bfc", "\t$dst, $imm", "$src = $dst",
1235 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1236 Requires<[IsARM, HasV6T2]> {
1237 let Inst{27-21} = 0b0111110;
1238 let Inst{6-0} = 0b0011111;
1241 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1242 "mvn", "\t$dst, $src",
1243 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1244 let Inst{11-4} = 0b00000000;
1246 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1247 IIC_iMOVsr, "mvn", "\t$dst, $src",
1248 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
1249 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1250 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1251 IIC_iMOVi, "mvn", "\t$dst, $imm",
1252 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1256 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1257 (BICri GPR:$src, so_imm_not:$imm)>;
1259 //===----------------------------------------------------------------------===//
1260 // Multiply Instructions.
1263 let isCommutable = 1 in
1264 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1265 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1266 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1268 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1269 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1270 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1272 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1273 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1274 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1275 Requires<[IsARM, HasV6T2]>;
1277 // Extra precision multiplies with low / high results
1278 let neverHasSideEffects = 1 in {
1279 let isCommutable = 1 in {
1280 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1281 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1282 "smull", "\t$ldst, $hdst, $a, $b", []>;
1284 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1285 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1286 "umull", "\t$ldst, $hdst, $a, $b", []>;
1289 // Multiply + accumulate
1290 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1291 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1292 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1294 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1295 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1296 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1298 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1299 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1300 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1301 Requires<[IsARM, HasV6]>;
1302 } // neverHasSideEffects
1304 // Most significant word multiply
1305 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1306 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1307 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1308 Requires<[IsARM, HasV6]> {
1309 let Inst{7-4} = 0b0001;
1310 let Inst{15-12} = 0b1111;
1313 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1314 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1315 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1316 Requires<[IsARM, HasV6]> {
1317 let Inst{7-4} = 0b0001;
1321 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1322 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1323 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1324 Requires<[IsARM, HasV6]> {
1325 let Inst{7-4} = 0b1101;
1328 multiclass AI_smul<string opc, PatFrag opnode> {
1329 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1330 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1331 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1332 (sext_inreg GPR:$b, i16)))]>,
1333 Requires<[IsARM, HasV5TE]> {
1338 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1339 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1340 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1341 (sra GPR:$b, (i32 16))))]>,
1342 Requires<[IsARM, HasV5TE]> {
1347 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1348 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1349 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1350 (sext_inreg GPR:$b, i16)))]>,
1351 Requires<[IsARM, HasV5TE]> {
1356 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1357 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1358 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1359 (sra GPR:$b, (i32 16))))]>,
1360 Requires<[IsARM, HasV5TE]> {
1365 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1366 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1367 [(set GPR:$dst, (sra (opnode GPR:$a,
1368 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1369 Requires<[IsARM, HasV5TE]> {
1374 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1375 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1376 [(set GPR:$dst, (sra (opnode GPR:$a,
1377 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1378 Requires<[IsARM, HasV5TE]> {
1385 multiclass AI_smla<string opc, PatFrag opnode> {
1386 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1387 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1388 [(set GPR:$dst, (add GPR:$acc,
1389 (opnode (sext_inreg GPR:$a, i16),
1390 (sext_inreg GPR:$b, i16))))]>,
1391 Requires<[IsARM, HasV5TE]> {
1396 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1397 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1398 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1399 (sra GPR:$b, (i32 16)))))]>,
1400 Requires<[IsARM, HasV5TE]> {
1405 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1406 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1407 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1408 (sext_inreg GPR:$b, i16))))]>,
1409 Requires<[IsARM, HasV5TE]> {
1414 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1415 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1416 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1417 (sra GPR:$b, (i32 16)))))]>,
1418 Requires<[IsARM, HasV5TE]> {
1423 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1424 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1425 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1426 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1427 Requires<[IsARM, HasV5TE]> {
1432 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1433 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1434 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1435 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1436 Requires<[IsARM, HasV5TE]> {
1442 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1443 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1445 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1446 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1448 //===----------------------------------------------------------------------===//
1449 // Misc. Arithmetic Instructions.
1452 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1453 "clz", "\t$dst, $src",
1454 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1455 let Inst{7-4} = 0b0001;
1456 let Inst{11-8} = 0b1111;
1457 let Inst{19-16} = 0b1111;
1460 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1461 "rbit", "\t$dst, $src",
1462 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1463 Requires<[IsARM, HasV6T2]> {
1464 let Inst{7-4} = 0b0011;
1465 let Inst{11-8} = 0b1111;
1466 let Inst{19-16} = 0b1111;
1469 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1470 "rev", "\t$dst, $src",
1471 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1472 let Inst{7-4} = 0b0011;
1473 let Inst{11-8} = 0b1111;
1474 let Inst{19-16} = 0b1111;
1477 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1478 "rev16", "\t$dst, $src",
1480 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1481 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1482 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1483 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1484 Requires<[IsARM, HasV6]> {
1485 let Inst{7-4} = 0b1011;
1486 let Inst{11-8} = 0b1111;
1487 let Inst{19-16} = 0b1111;
1490 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1491 "revsh", "\t$dst, $src",
1494 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1495 (shl GPR:$src, (i32 8))), i16))]>,
1496 Requires<[IsARM, HasV6]> {
1497 let Inst{7-4} = 0b1011;
1498 let Inst{11-8} = 0b1111;
1499 let Inst{19-16} = 0b1111;
1502 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1503 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1504 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1505 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1506 (and (shl GPR:$src2, (i32 imm:$shamt)),
1508 Requires<[IsARM, HasV6]> {
1509 let Inst{6-4} = 0b001;
1512 // Alternate cases for PKHBT where identities eliminate some nodes.
1513 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1514 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1515 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1516 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1519 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1520 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1521 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1522 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1523 (and (sra GPR:$src2, imm16_31:$shamt),
1524 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1525 let Inst{6-4} = 0b101;
1528 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
1529 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1530 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1531 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1532 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1533 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1534 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1536 //===----------------------------------------------------------------------===//
1537 // Comparison Instructions...
1540 defm CMP : AI1_cmp_irs<0b1010, "cmp",
1541 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1542 defm CMN : AI1_cmp_irs<0b1011, "cmn",
1543 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1545 // Note that TST/TEQ don't set all the same flags that CMP does!
1546 defm TST : AI1_cmp_irs<0b1000, "tst",
1547 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1548 defm TEQ : AI1_cmp_irs<0b1001, "teq",
1549 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1551 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1552 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1553 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1554 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1556 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1557 (CMNri GPR:$src, so_imm_neg:$imm)>;
1559 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1560 (CMNri GPR:$src, so_imm_neg:$imm)>;
1563 // Conditional moves
1564 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1565 // a two-value operand where a dag node expects two operands. :(
1566 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1567 IIC_iCMOVr, "mov", "\t$dst, $true",
1568 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1569 RegConstraint<"$false = $dst">, UnaryDP {
1570 let Inst{11-4} = 0b00000000;
1574 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1575 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1576 "mov", "\t$dst, $true",
1577 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1578 RegConstraint<"$false = $dst">, UnaryDP {
1582 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1583 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1584 "mov", "\t$dst, $true",
1585 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1586 RegConstraint<"$false = $dst">, UnaryDP {
1590 //===----------------------------------------------------------------------===//
1591 // Atomic operations intrinsics
1594 // memory barriers protect the atomic sequences
1595 let hasSideEffects = 1 in {
1596 def Int_MemBarrierV7 : AInoP<(outs), (ins),
1597 Pseudo, NoItinerary,
1599 [(ARMMemBarrierV7)]>,
1600 Requires<[IsARM, HasV7]> {
1601 let Inst{31-4} = 0xf57ff05;
1602 // FIXME: add support for options other than a full system DMB
1603 let Inst{3-0} = 0b1111;
1606 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1607 Pseudo, NoItinerary,
1609 [(ARMSyncBarrierV7)]>,
1610 Requires<[IsARM, HasV7]> {
1611 let Inst{31-4} = 0xf57ff04;
1612 // FIXME: add support for options other than a full system DSB
1613 let Inst{3-0} = 0b1111;
1616 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1617 Pseudo, NoItinerary,
1618 "mcr", "\tp15, 0, $zero, c7, c10, 5",
1619 [(ARMMemBarrierV6 GPR:$zero)]>,
1620 Requires<[IsARM, HasV6]> {
1621 // FIXME: add support for options other than a full system DMB
1622 // FIXME: add encoding
1625 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1626 Pseudo, NoItinerary,
1627 "mcr", "\tp15, 0, $zero, c7, c10, 4",
1628 [(ARMSyncBarrierV6 GPR:$zero)]>,
1629 Requires<[IsARM, HasV6]> {
1630 // FIXME: add support for options other than a full system DSB
1631 // FIXME: add encoding
1635 let usesCustomInserter = 1 in {
1636 let Uses = [CPSR] in {
1637 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1638 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1639 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1640 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1641 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1642 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1643 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1644 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1645 def ATOMIC_LOAD_AND_I8 : PseudoInst<
1646 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1647 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1648 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1649 def ATOMIC_LOAD_OR_I8 : PseudoInst<
1650 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1651 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1652 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1653 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1654 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1655 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1656 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1657 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1658 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1659 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1660 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1661 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1662 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1663 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1664 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1665 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1666 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1667 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1668 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1669 def ATOMIC_LOAD_AND_I16 : PseudoInst<
1670 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1671 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1672 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1673 def ATOMIC_LOAD_OR_I16 : PseudoInst<
1674 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1675 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1676 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1677 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1678 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1679 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1680 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1681 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1682 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1683 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1684 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1685 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1686 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1687 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1688 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1689 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1690 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1691 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1692 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1693 def ATOMIC_LOAD_AND_I32 : PseudoInst<
1694 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1695 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1696 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1697 def ATOMIC_LOAD_OR_I32 : PseudoInst<
1698 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1699 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1700 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1701 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1702 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1703 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1704 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1705 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1706 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1707 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1708 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1710 def ATOMIC_SWAP_I8 : PseudoInst<
1711 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1712 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1713 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1714 def ATOMIC_SWAP_I16 : PseudoInst<
1715 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1716 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1717 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1718 def ATOMIC_SWAP_I32 : PseudoInst<
1719 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1720 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1721 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1723 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1724 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1725 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1726 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1727 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1728 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1729 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1730 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1731 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1732 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1733 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1734 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1738 let mayLoad = 1 in {
1739 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1740 "ldrexb", "\t$dest, [$ptr]",
1742 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1743 "ldrexh", "\t$dest, [$ptr]",
1745 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1746 "ldrex", "\t$dest, [$ptr]",
1748 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1750 "ldrexd", "\t$dest, $dest2, [$ptr]",
1754 let mayStore = 1, Constraints = "@earlyclobber $success" in {
1755 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1757 "strexb", "\t$success, $src, [$ptr]",
1759 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1761 "strexh", "\t$success, $src, [$ptr]",
1763 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1765 "strex", "\t$success, $src, [$ptr]",
1767 def STREXD : AIstrex<0b01, (outs GPR:$success),
1768 (ins GPR:$src, GPR:$src2, GPR:$ptr),
1770 "strexd", "\t$success, $src, $src2, [$ptr]",
1774 //===----------------------------------------------------------------------===//
1778 // __aeabi_read_tp preserves the registers r1-r3.
1780 Defs = [R0, R12, LR, CPSR] in {
1781 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1782 "bl\t__aeabi_read_tp",
1783 [(set R0, ARMthread_pointer)]>;
1786 //===----------------------------------------------------------------------===//
1787 // SJLJ Exception handling intrinsics
1788 // eh_sjlj_setjmp() is an instruction sequence to store the return
1789 // address and save #0 in R0 for the non-longjmp case.
1790 // Since by its nature we may be coming from some other function to get
1791 // here, and we're using the stack frame for the containing function to
1792 // save/restore registers, we can't keep anything live in regs across
1793 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1794 // when we get here from a longjmp(). We force everthing out of registers
1795 // except for our own input by listing the relevant registers in Defs. By
1796 // doing so, we also cause the prologue/epilogue code to actively preserve
1797 // all of the callee-saved resgisters, which is exactly what we want.
1799 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
1800 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1801 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1803 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
1804 AddrModeNone, SizeSpecial, IndexModeNone,
1805 Pseudo, NoItinerary,
1806 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1807 "add\tr12, pc, #8\n\t"
1808 "str\tr12, [$src, #+4]\n\t"
1810 "add\tpc, pc, #0\n\t"
1811 "mov\tr0, #1 @ eh_setjmp end", "",
1812 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1815 //===----------------------------------------------------------------------===//
1816 // Non-Instruction Patterns
1819 // Large immediate handling.
1821 // Two piece so_imms.
1822 let isReMaterializable = 1 in
1823 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
1825 "mov", "\t$dst, $src",
1826 [(set GPR:$dst, so_imm2part:$src)]>,
1827 Requires<[IsARM, NoV6T2]>;
1829 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1830 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1831 (so_imm2part_2 imm:$RHS))>;
1832 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1833 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1834 (so_imm2part_2 imm:$RHS))>;
1835 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1836 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1837 (so_imm2part_2 imm:$RHS))>;
1838 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1839 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1840 (so_neg_imm2part_2 imm:$RHS))>;
1842 // 32-bit immediate using movw + movt.
1843 // This is a single pseudo instruction, the benefit is that it can be remat'd
1844 // as a single unit instead of having to handle reg inputs.
1845 // FIXME: Remove this when we can do generalized remat.
1846 let isReMaterializable = 1 in
1847 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1848 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1849 [(set GPR:$dst, (i32 imm:$src))]>,
1850 Requires<[IsARM, HasV6T2]>;
1852 // ConstantPool, GlobalAddress, and JumpTable
1853 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1854 Requires<[IsARM, DontUseMovt]>;
1855 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1856 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1857 Requires<[IsARM, UseMovt]>;
1858 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1859 (LEApcrelJT tjumptable:$dst, imm:$id)>;
1861 // TODO: add,sub,and, 3-instr forms?
1865 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1866 Requires<[IsARM, IsNotDarwin]>;
1867 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1868 Requires<[IsARM, IsDarwin]>;
1870 // zextload i1 -> zextload i8
1871 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1873 // extload -> zextload
1874 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1875 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1876 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
1878 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1879 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1882 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1883 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1884 (SMULBB GPR:$a, GPR:$b)>;
1885 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1886 (SMULBB GPR:$a, GPR:$b)>;
1887 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1888 (sra GPR:$b, (i32 16))),
1889 (SMULBT GPR:$a, GPR:$b)>;
1890 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
1891 (SMULBT GPR:$a, GPR:$b)>;
1892 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1893 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1894 (SMULTB GPR:$a, GPR:$b)>;
1895 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
1896 (SMULTB GPR:$a, GPR:$b)>;
1897 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1899 (SMULWB GPR:$a, GPR:$b)>;
1900 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
1901 (SMULWB GPR:$a, GPR:$b)>;
1903 def : ARMV5TEPat<(add GPR:$acc,
1904 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1905 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1906 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1907 def : ARMV5TEPat<(add GPR:$acc,
1908 (mul sext_16_node:$a, sext_16_node:$b)),
1909 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1910 def : ARMV5TEPat<(add GPR:$acc,
1911 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1912 (sra GPR:$b, (i32 16)))),
1913 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1914 def : ARMV5TEPat<(add GPR:$acc,
1915 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
1916 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1917 def : ARMV5TEPat<(add GPR:$acc,
1918 (mul (sra GPR:$a, (i32 16)),
1919 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1920 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1921 def : ARMV5TEPat<(add GPR:$acc,
1922 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
1923 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1924 def : ARMV5TEPat<(add GPR:$acc,
1925 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1927 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1928 def : ARMV5TEPat<(add GPR:$acc,
1929 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
1930 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1932 //===----------------------------------------------------------------------===//
1936 include "ARMInstrThumb.td"
1938 //===----------------------------------------------------------------------===//
1942 include "ARMInstrThumb2.td"
1944 //===----------------------------------------------------------------------===//
1945 // Floating Point Support
1948 include "ARMInstrVFP.td"
1950 //===----------------------------------------------------------------------===//
1951 // Advanced SIMD (NEON) Support
1954 include "ARMInstrNEON.td"