blob: 74291edfda44d1d0e723473664a551188dd7482c [file] [log] [blame]
Evan Chenga8e29892007-01-19 07:51:42 +00001//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
Rafael Espindola7bc59bc2006-05-14 22:18:28 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
Rafael Espindola7bc59bc2006-05-14 22:18:28 +00006// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the ARM instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
Evan Chenga8e29892007-01-19 07:51:42 +000014//===----------------------------------------------------------------------===//
15// ARM specific DAG Nodes.
16//
Rafael Espindola7cca7c52006-09-11 17:25:40 +000017
Evan Chenga8e29892007-01-19 07:51:42 +000018// Type profiles.
Bill Wendlingc69107c2007-11-13 09:19:02 +000019def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
Rafael Espindola6e8c6492006-11-08 17:07:32 +000021
Evan Chenga8e29892007-01-19 07:51:42 +000022def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
Rafael Espindola32bd5f42006-10-17 18:04:53 +000023
Evan Chenga8e29892007-01-19 07:51:42 +000024def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
Rafael Espindola7cca7c52006-09-11 17:25:40 +000025
Evan Chenga8e29892007-01-19 07:51:42 +000026def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
28 SDTCisVT<3, i32>]>;
Rafael Espindola6e8c6492006-11-08 17:07:32 +000029
Evan Chenga8e29892007-01-19 07:51:42 +000030def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
32
33def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
35 SDTCisVT<2, i32>]>;
36
37def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
38
39def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
40 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
41
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +000042def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
Jim Grosbachf9570122009-05-14 00:46:35 +000043def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +000044
Evan Chenga8e29892007-01-19 07:51:42 +000045// Node definitions.
46def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
Evan Chenga8e29892007-01-19 07:51:42 +000047def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
48
Bill Wendlingc69107c2007-11-13 09:19:02 +000049def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
Bill Wendling6ef781f2008-02-27 06:33:05 +000050 [SDNPHasChain, SDNPOutFlag]>;
Bill Wendlingc69107c2007-11-13 09:19:02 +000051def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
Bill Wendling6ef781f2008-02-27 06:33:05 +000052 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Chenga8e29892007-01-19 07:51:42 +000053
54def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
55 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Cheng277f0742007-06-19 21:05:09 +000056def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
57 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Chenga8e29892007-01-19 07:51:42 +000058def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
59 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
60
Chris Lattner48be23c2008-01-15 22:02:54 +000061def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
Evan Chenga8e29892007-01-19 07:51:42 +000062 [SDNPHasChain, SDNPOptInFlag]>;
63
64def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
65 [SDNPInFlag]>;
66def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
67 [SDNPInFlag]>;
68
69def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
70 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
71
72def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
73 [SDNPHasChain]>;
74
75def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
76 [SDNPOutFlag]>;
77
David Goodwinc0309b42009-06-29 15:33:01 +000078def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
79 [SDNPOutFlag,SDNPCommutative]>;
Lauro Ramos Venancio99966632007-04-02 01:30:03 +000080
Evan Chenga8e29892007-01-19 07:51:42 +000081def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
82
83def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
84def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
85def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
Rafael Espindola32bd5f42006-10-17 18:04:53 +000086
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +000087def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
Jim Grosbachf9570122009-05-14 00:46:35 +000088def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +000089
Rafael Espindola7bc59bc2006-05-14 22:18:28 +000090//===----------------------------------------------------------------------===//
Evan Chenga8e29892007-01-19 07:51:42 +000091// ARM Instruction Predicate Definitions.
92//
Anton Korobeynikovbb629622009-06-15 21:46:20 +000093def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
94def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
95def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
Evan Chengedcbada2009-07-06 22:05:45 +000096def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
Bob Wilson5bafff32009-06-22 23:27:02 +000097def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
98def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
99def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
100def HasNEON : Predicate<"Subtarget->hasNEON()">;
Anton Korobeynikovbb629622009-06-15 21:46:20 +0000101def IsThumb : Predicate<"Subtarget->isThumb()">;
Evan Chengf49810c2009-06-23 17:48:47 +0000102def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
Evan Chengd770d9e2009-07-02 06:38:40 +0000103def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
Anton Korobeynikovbb629622009-06-15 21:46:20 +0000104def IsARM : Predicate<"!Subtarget->isThumb()">;
Bob Wilson54fc1242009-06-22 21:01:46 +0000105def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
106def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
Evan Cheng2b51d512009-06-26 06:10:18 +0000107def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng62674222009-06-25 23:34:10 +0000108def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
Evan Chenga8e29892007-01-19 07:51:42 +0000109
Rafael Espindola7bc59bc2006-05-14 22:18:28 +0000110//===----------------------------------------------------------------------===//
Evan Chenga8e29892007-01-19 07:51:42 +0000111// ARM Flag Definitions.
112
113class RegConstraint<string C> {
114 string Constraints = C;
115}
116
117//===----------------------------------------------------------------------===//
118// ARM specific transformation functions and pattern fragments.
119//
120
Evan Chenga8e29892007-01-19 07:51:42 +0000121// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
122// so_imm_neg def below.
123def so_imm_neg_XFORM : SDNodeXForm<imm, [{
Evan Chenge7cbe412009-07-08 21:03:57 +0000124 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
Evan Chenga8e29892007-01-19 07:51:42 +0000125}]>;
126
127// so_imm_not_XFORM - Return a so_imm value packed into the format described for
128// so_imm_not def below.
129def so_imm_not_XFORM : SDNodeXForm<imm, [{
Evan Chenge7cbe412009-07-08 21:03:57 +0000130 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
Evan Chenga8e29892007-01-19 07:51:42 +0000131}]>;
132
133// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
134def rot_imm : PatLeaf<(i32 imm), [{
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000135 int32_t v = (int32_t)N->getZExtValue();
Evan Chenga8e29892007-01-19 07:51:42 +0000136 return v == 8 || v == 16 || v == 24;
137}]>;
138
139/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
140def imm1_15 : PatLeaf<(i32 imm), [{
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000141 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
Evan Chenga8e29892007-01-19 07:51:42 +0000142}]>;
143
144/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
145def imm16_31 : PatLeaf<(i32 imm), [{
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000146 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
Evan Chenga8e29892007-01-19 07:51:42 +0000147}]>;
148
149def so_imm_neg :
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000150 PatLeaf<(imm), [{
151 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
152 }], so_imm_neg_XFORM>;
Evan Chenga8e29892007-01-19 07:51:42 +0000153
Evan Chenga2515702007-03-19 07:09:02 +0000154def so_imm_not :
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000155 PatLeaf<(imm), [{
156 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
157 }], so_imm_not_XFORM>;
Evan Chenga8e29892007-01-19 07:51:42 +0000158
159// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
160def sext_16_node : PatLeaf<(i32 GPR:$a), [{
Dan Gohman475871a2008-07-27 21:46:04 +0000161 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
Evan Chenga8e29892007-01-19 07:51:42 +0000162}]>;
163
Evan Cheng36a0aeb2009-07-06 22:23:46 +0000164/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
165/// e.g., 0xf000ffff
166def bf_inv_mask_imm : Operand<i32>,
167 PatLeaf<(imm), [{
168 uint32_t v = (uint32_t)N->getZExtValue();
169 if (v == 0xffffffff)
170 return 0;
David Goodwinc2ffd282009-07-14 00:57:56 +0000171 // there can be 1's on either or both "outsides", all the "inside"
172 // bits must be 0's
173 unsigned int lsb = 0, msb = 31;
174 while (v & (1 << msb)) --msb;
175 while (v & (1 << lsb)) ++lsb;
176 for (unsigned int i = lsb; i <= msb; ++i) {
177 if (v & (1 << i))
178 return 0;
179 }
180 return 1;
Evan Cheng36a0aeb2009-07-06 22:23:46 +0000181}] > {
182 let PrintMethod = "printBitfieldInvMaskImmOperand";
183}
184
Evan Cheng37f25d92008-08-28 23:39:26 +0000185class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
186class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
Evan Chenga8e29892007-01-19 07:51:42 +0000187
188//===----------------------------------------------------------------------===//
189// Operand Definitions.
190//
191
192// Branch target.
193def brtarget : Operand<OtherVT>;
194
Evan Chenga8e29892007-01-19 07:51:42 +0000195// A list of registers separated by comma. Used by load/store multiple.
196def reglist : Operand<i32> {
197 let PrintMethod = "printRegisterList";
198}
199
200// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
201def cpinst_operand : Operand<i32> {
202 let PrintMethod = "printCPInstOperand";
203}
204
205def jtblock_operand : Operand<i32> {
206 let PrintMethod = "printJTBlockOperand";
207}
208
209// Local PC labels.
210def pclabel : Operand<i32> {
211 let PrintMethod = "printPCLabel";
212}
213
214// shifter_operand operands: so_reg and so_imm.
215def so_reg : Operand<i32>, // reg reg imm
216 ComplexPattern<i32, 3, "SelectShifterOperandReg",
217 [shl,srl,sra,rotr]> {
218 let PrintMethod = "printSORegOperand";
219 let MIOperandInfo = (ops GPR, GPR, i32imm);
220}
221
222// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
223// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
224// represented in the imm field in the same 12-bit form that they are encoded
225// into so_imm instructions: the 8-bit immediate is the least significant bits
226// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
227def so_imm : Operand<i32>,
Evan Chenge7cbe412009-07-08 21:03:57 +0000228 PatLeaf<(imm), [{
229 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
230 }]> {
Evan Chenga8e29892007-01-19 07:51:42 +0000231 let PrintMethod = "printSOImmOperand";
232}
233
Evan Chengc70d1842007-03-20 08:11:30 +0000234// Break so_imm's up into two pieces. This handles immediates with up to 16
235// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
236// get the first/second pieces.
237def so_imm2part : Operand<i32>,
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000238 PatLeaf<(imm), [{
239 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
240 }]> {
Evan Chengc70d1842007-03-20 08:11:30 +0000241 let PrintMethod = "printSOImm2PartOperand";
242}
243
244def so_imm2part_1 : SDNodeXForm<imm, [{
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000245 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
Evan Chenge7cbe412009-07-08 21:03:57 +0000246 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Chengc70d1842007-03-20 08:11:30 +0000247}]>;
248
249def so_imm2part_2 : SDNodeXForm<imm, [{
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000250 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
Evan Chenge7cbe412009-07-08 21:03:57 +0000251 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Chengc70d1842007-03-20 08:11:30 +0000252}]>;
253
Evan Chenga8e29892007-01-19 07:51:42 +0000254
255// Define ARM specific addressing modes.
256
257// addrmode2 := reg +/- reg shop imm
258// addrmode2 := reg +/- imm12
259//
260def addrmode2 : Operand<i32>,
261 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
262 let PrintMethod = "printAddrMode2Operand";
263 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
264}
265
266def am2offset : Operand<i32>,
267 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
268 let PrintMethod = "printAddrMode2OffsetOperand";
269 let MIOperandInfo = (ops GPR, i32imm);
270}
271
272// addrmode3 := reg +/- reg
273// addrmode3 := reg +/- imm8
274//
275def addrmode3 : Operand<i32>,
276 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
277 let PrintMethod = "printAddrMode3Operand";
278 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
279}
280
281def am3offset : Operand<i32>,
282 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
283 let PrintMethod = "printAddrMode3OffsetOperand";
284 let MIOperandInfo = (ops GPR, i32imm);
285}
286
287// addrmode4 := reg, <mode|W>
288//
289def addrmode4 : Operand<i32>,
290 ComplexPattern<i32, 2, "", []> {
291 let PrintMethod = "printAddrMode4Operand";
292 let MIOperandInfo = (ops GPR, i32imm);
293}
294
295// addrmode5 := reg +/- imm8*4
296//
297def addrmode5 : Operand<i32>,
298 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
299 let PrintMethod = "printAddrMode5Operand";
300 let MIOperandInfo = (ops GPR, i32imm);
301}
302
Bob Wilson8b024a52009-07-01 23:16:05 +0000303// addrmode6 := reg with optional writeback
304//
305def addrmode6 : Operand<i32>,
306 ComplexPattern<i32, 3, "SelectAddrMode6", []> {
307 let PrintMethod = "printAddrMode6Operand";
308 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm);
309}
310
Evan Chenga8e29892007-01-19 07:51:42 +0000311// addrmodepc := pc + reg
312//
313def addrmodepc : Operand<i32>,
314 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
315 let PrintMethod = "printAddrModePCOperand";
316 let MIOperandInfo = (ops GPR, i32imm);
317}
318
319//===----------------------------------------------------------------------===//
Evan Cheng0ff94f72007-08-07 01:37:15 +0000320
Evan Cheng37f25d92008-08-28 23:39:26 +0000321include "ARMInstrFormats.td"
Evan Cheng0ff94f72007-08-07 01:37:15 +0000322
323//===----------------------------------------------------------------------===//
Evan Cheng37f25d92008-08-28 23:39:26 +0000324// Multiclass helpers...
Evan Chenga8e29892007-01-19 07:51:42 +0000325//
326
Evan Cheng3924f782008-08-29 07:36:24 +0000327/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
Evan Chenga8e29892007-01-19 07:51:42 +0000328/// binop that produces a value.
Evan Cheng8de898a2009-06-26 00:19:44 +0000329multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
330 bit Commutable = 0> {
Evan Chengedda31c2008-11-05 18:35:52 +0000331 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000332 opc, " $dst, $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000333 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
334 let Inst{25} = 1;
335 }
Evan Chengedda31c2008-11-05 18:35:52 +0000336 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000337 opc, " $dst, $a, $b",
Evan Cheng8de898a2009-06-26 00:19:44 +0000338 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
Evan Chengbc8a9452009-07-07 23:40:25 +0000339 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000340 let isCommutable = Commutable;
341 }
Evan Chengedda31c2008-11-05 18:35:52 +0000342 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000343 opc, " $dst, $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000344 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
345 let Inst{25} = 0;
346 }
Evan Chenga8e29892007-01-19 07:51:42 +0000347}
348
Evan Cheng1e249e32009-06-25 20:59:23 +0000349/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
Evan Chengc85e8322007-07-05 07:13:32 +0000350/// instruction modifies the CSPR register.
Evan Cheng071a2792007-09-11 19:55:27 +0000351let Defs = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000352multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
353 bit Commutable = 0> {
Evan Chengedda31c2008-11-05 18:35:52 +0000354 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000355 opc, "s $dst, $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000356 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
357 let Inst{25} = 1;
358 }
Evan Chengedda31c2008-11-05 18:35:52 +0000359 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000360 opc, "s $dst, $a, $b",
Evan Cheng8de898a2009-06-26 00:19:44 +0000361 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
362 let isCommutable = Commutable;
Evan Chengbc8a9452009-07-07 23:40:25 +0000363 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000364 }
Evan Chengedda31c2008-11-05 18:35:52 +0000365 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000366 opc, "s $dst, $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000367 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
368 let Inst{25} = 0;
369 }
Evan Cheng071a2792007-09-11 19:55:27 +0000370}
Evan Chengc85e8322007-07-05 07:13:32 +0000371}
372
373/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
Evan Cheng13ab0202007-07-10 18:08:01 +0000374/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
Evan Chengc85e8322007-07-05 07:13:32 +0000375/// a explicit result, only implicitly set CPSR.
Evan Cheng071a2792007-09-11 19:55:27 +0000376let Defs = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000377multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
378 bit Commutable = 0> {
Evan Chengedda31c2008-11-05 18:35:52 +0000379 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000380 opc, " $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000381 [(opnode GPR:$a, so_imm:$b)]> {
382 let Inst{25} = 1;
383 }
Evan Chengedda31c2008-11-05 18:35:52 +0000384 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000385 opc, " $a, $b",
Evan Cheng8de898a2009-06-26 00:19:44 +0000386 [(opnode GPR:$a, GPR:$b)]> {
Evan Chengbc8a9452009-07-07 23:40:25 +0000387 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000388 let isCommutable = Commutable;
389 }
Evan Chengedda31c2008-11-05 18:35:52 +0000390 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000391 opc, " $a, $b",
Evan Chengbc8a9452009-07-07 23:40:25 +0000392 [(opnode GPR:$a, so_reg:$b)]> {
393 let Inst{25} = 0;
394 }
Evan Cheng071a2792007-09-11 19:55:27 +0000395}
Evan Chenga8e29892007-01-19 07:51:42 +0000396}
397
Evan Chenga8e29892007-01-19 07:51:42 +0000398/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
399/// register and one whose operand is a register rotated by 8/16/24.
Evan Cheng97f48c32008-11-06 22:15:19 +0000400/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
401multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
402 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src),
Evan Cheng44bec522007-05-15 01:29:07 +0000403 opc, " $dst, $Src",
Evan Cheng97f48c32008-11-06 22:15:19 +0000404 [(set GPR:$dst, (opnode GPR:$Src))]>,
405 Requires<[IsARM, HasV6]> {
406 let Inst{19-16} = 0b1111;
407 }
408 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
Evan Cheng44bec522007-05-15 01:29:07 +0000409 opc, " $dst, $Src, ror $rot",
Evan Chenga8e29892007-01-19 07:51:42 +0000410 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
Evan Cheng97f48c32008-11-06 22:15:19 +0000411 Requires<[IsARM, HasV6]> {
412 let Inst{19-16} = 0b1111;
413 }
Evan Chenga8e29892007-01-19 07:51:42 +0000414}
415
416/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
417/// register and one whose operand is a register rotated by 8/16/24.
Evan Cheng97f48c32008-11-06 22:15:19 +0000418multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
419 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
420 opc, " $dst, $LHS, $RHS",
Evan Chenga8e29892007-01-19 07:51:42 +0000421 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
422 Requires<[IsARM, HasV6]>;
Evan Cheng97f48c32008-11-06 22:15:19 +0000423 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
424 opc, " $dst, $LHS, $RHS, ror $rot",
Evan Chenga8e29892007-01-19 07:51:42 +0000425 [(set GPR:$dst, (opnode GPR:$LHS,
426 (rotr GPR:$RHS, rot_imm:$rot)))]>,
427 Requires<[IsARM, HasV6]>;
428}
429
Evan Cheng62674222009-06-25 23:34:10 +0000430/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
431let Uses = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000432multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
433 bit Commutable = 0> {
Evan Cheng62674222009-06-25 23:34:10 +0000434 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
435 DPFrm, opc, " $dst, $a, $b",
436 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
Evan Chengbc8a9452009-07-07 23:40:25 +0000437 Requires<[IsARM, CarryDefIsUnused]> {
438 let Inst{25} = 1;
439 }
Evan Cheng62674222009-06-25 23:34:10 +0000440 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
441 DPFrm, opc, " $dst, $a, $b",
442 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
Evan Cheng8de898a2009-06-26 00:19:44 +0000443 Requires<[IsARM, CarryDefIsUnused]> {
444 let isCommutable = Commutable;
Evan Chengbc8a9452009-07-07 23:40:25 +0000445 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000446 }
Evan Cheng62674222009-06-25 23:34:10 +0000447 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
448 DPSoRegFrm, opc, " $dst, $a, $b",
449 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
Evan Chengbc8a9452009-07-07 23:40:25 +0000450 Requires<[IsARM, CarryDefIsUnused]> {
451 let Inst{25} = 0;
452 }
Evan Cheng62674222009-06-25 23:34:10 +0000453 // Carry setting variants
454 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Cheng1e249e32009-06-25 20:59:23 +0000455 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng62674222009-06-25 23:34:10 +0000456 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
457 Requires<[IsARM, CarryDefIsUsed]> {
Evan Chengbc8a9452009-07-07 23:40:25 +0000458 let Defs = [CPSR];
459 let Inst{25} = 1;
Evan Cheng8de898a2009-06-26 00:19:44 +0000460 }
Evan Cheng62674222009-06-25 23:34:10 +0000461 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng1e249e32009-06-25 20:59:23 +0000462 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng62674222009-06-25 23:34:10 +0000463 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
464 Requires<[IsARM, CarryDefIsUsed]> {
Evan Chengbc8a9452009-07-07 23:40:25 +0000465 let Defs = [CPSR];
466 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000467 }
Evan Cheng62674222009-06-25 23:34:10 +0000468 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Cheng1e249e32009-06-25 20:59:23 +0000469 DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng62674222009-06-25 23:34:10 +0000470 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
471 Requires<[IsARM, CarryDefIsUsed]> {
Evan Chengbc8a9452009-07-07 23:40:25 +0000472 let Defs = [CPSR];
473 let Inst{25} = 0;
Evan Cheng8de898a2009-06-26 00:19:44 +0000474 }
Evan Cheng071a2792007-09-11 19:55:27 +0000475}
Evan Chengc85e8322007-07-05 07:13:32 +0000476}
477
Rafael Espindola15a6c3e2006-10-16 17:57:20 +0000478//===----------------------------------------------------------------------===//
479// Instructions
480//===----------------------------------------------------------------------===//
481
Evan Chenga8e29892007-01-19 07:51:42 +0000482//===----------------------------------------------------------------------===//
483// Miscellaneous Instructions.
484//
Rafael Espindola6f602de2006-08-24 16:13:15 +0000485
Evan Chenga8e29892007-01-19 07:51:42 +0000486/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
487/// the function. The first operand is the ID# for this instruction, the second
488/// is the index into the MachineConstantPool that this is, the third is the
489/// size in bytes of this constant pool entry.
Evan Chengcd799b92009-06-12 20:46:18 +0000490let neverHasSideEffects = 1, isNotDuplicable = 1 in
Evan Chenga8e29892007-01-19 07:51:42 +0000491def CONSTPOOL_ENTRY :
Evan Cheng64d80e32007-07-19 01:14:50 +0000492PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
Evan Cheng12c3a532008-11-06 17:48:05 +0000493 i32imm:$size),
Evan Chenga8e29892007-01-19 07:51:42 +0000494 "${instid:label} ${cpidx:cpentry}", []>;
Rafael Espindola7bc59bc2006-05-14 22:18:28 +0000495
Evan Cheng071a2792007-09-11 19:55:27 +0000496let Defs = [SP], Uses = [SP] in {
Evan Chenga8e29892007-01-19 07:51:42 +0000497def ADJCALLSTACKUP :
Bill Wendling0f8d9c02007-11-13 00:44:25 +0000498PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
499 "@ ADJCALLSTACKUP $amt1",
Chris Lattnere563bbc2008-10-11 22:08:30 +0000500 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
Rafael Espindolacdda88c2006-08-24 17:19:08 +0000501
Evan Chenga8e29892007-01-19 07:51:42 +0000502def ADJCALLSTACKDOWN :
Evan Cheng64d80e32007-07-19 01:14:50 +0000503PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
Evan Chenga8e29892007-01-19 07:51:42 +0000504 "@ ADJCALLSTACKDOWN $amt",
Chris Lattnere563bbc2008-10-11 22:08:30 +0000505 [(ARMcallseq_start timm:$amt)]>;
Evan Cheng071a2792007-09-11 19:55:27 +0000506}
Rafael Espindola3c000bf2006-08-21 22:00:32 +0000507
Evan Chenga8e29892007-01-19 07:51:42 +0000508def DWARF_LOC :
Evan Cheng64d80e32007-07-19 01:14:50 +0000509PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
Evan Chenga8e29892007-01-19 07:51:42 +0000510 ".loc $file, $line, $col",
511 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
Rafael Espindola4b20fbc2006-10-10 12:56:00 +0000512
Evan Cheng12c3a532008-11-06 17:48:05 +0000513
514// Address computation and loads and stores in PIC mode.
Evan Chengeaa91b02007-06-19 01:26:51 +0000515let isNotDuplicable = 1 in {
Evan Chengc0729662008-10-31 19:11:09 +0000516def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000517 Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
Evan Cheng44bec522007-05-15 01:29:07 +0000518 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
Dale Johannesen86d40692007-05-21 22:14:33 +0000519
Evan Cheng325474e2008-01-07 23:56:57 +0000520let AddedComplexity = 10 in {
Dan Gohman15511cf2008-12-03 18:15:48 +0000521let canFoldAsLoad = 1 in
Evan Chengd87293c2008-11-06 08:47:38 +0000522def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000523 Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000524 [(set GPR:$dst, (load addrmodepc:$addr))]>;
Rafael Espindola84b19be2006-07-16 01:02:57 +0000525
Evan Chengd87293c2008-11-06 08:47:38 +0000526def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000527 Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000528 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
529
Evan Chengd87293c2008-11-06 08:47:38 +0000530def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000531 Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000532 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
533
Evan Chengd87293c2008-11-06 08:47:38 +0000534def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000535 Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000536 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
537
Evan Chengd87293c2008-11-06 08:47:38 +0000538def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000539 Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000540 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
541}
Chris Lattner13c63102008-01-06 05:55:01 +0000542let AddedComplexity = 10 in {
Evan Chengd87293c2008-11-06 08:47:38 +0000543def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000544 Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000545 [(store GPR:$src, addrmodepc:$addr)]>;
546
Evan Chengd87293c2008-11-06 08:47:38 +0000547def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000548 Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000549 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
550
Evan Chengd87293c2008-11-06 08:47:38 +0000551def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000552 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
Dale Johannesen86d40692007-05-21 22:14:33 +0000553 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
554}
Evan Cheng12c3a532008-11-06 17:48:05 +0000555} // isNotDuplicable = 1
Dale Johannesen86d40692007-05-21 22:14:33 +0000556
Evan Chenge07715c2009-06-23 05:25:29 +0000557
558// LEApcrel - Load a pc-relative address into a register without offending the
559// assembler.
560def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo,
561 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
562 "${:private}PCRELL${:uid}+8))\n"),
563 !strconcat("${:private}PCRELL${:uid}:\n\t",
564 "add$p $dst, pc, #PCRELV${:uid}")),
565 []>;
566
Evan Cheng023dd3f2009-06-24 23:14:45 +0000567def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
568 (ins i32imm:$label, i32imm:$id, pred:$p),
Evan Chenge07715c2009-06-23 05:25:29 +0000569 Pseudo,
570 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
571 "${:private}PCRELL${:uid}+8))\n"),
572 !strconcat("${:private}PCRELL${:uid}:\n\t",
573 "add$p $dst, pc, #PCRELV${:uid}")),
Evan Chengbc8a9452009-07-07 23:40:25 +0000574 []> {
575 let Inst{25} = 1;
576}
Evan Chenge07715c2009-06-23 05:25:29 +0000577
Evan Chenga8e29892007-01-19 07:51:42 +0000578//===----------------------------------------------------------------------===//
579// Control Flow Instructions.
580//
Rafael Espindola9e071f02006-10-02 19:30:56 +0000581
Evan Chenga8e29892007-01-19 07:51:42 +0000582let isReturn = 1, isTerminator = 1 in
Evan Cheng12c3a532008-11-06 17:48:05 +0000583 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
Jim Grosbach26421962008-10-14 20:36:24 +0000584 let Inst{7-4} = 0b0001;
585 let Inst{19-8} = 0b111111111111;
586 let Inst{27-20} = 0b00010010;
Evan Cheng7fd7ca42008-09-17 07:53:38 +0000587}
Rafael Espindola27185192006-09-29 21:20:16 +0000588
Evan Chenga8e29892007-01-19 07:51:42 +0000589// FIXME: remove when we have a way to marking a MI with these properties.
Evan Cheng64d80e32007-07-19 01:14:50 +0000590// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
591// operand list.
Evan Cheng12c3a532008-11-06 17:48:05 +0000592// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Chengd75223d2009-07-09 22:57:41 +0000593let isReturn = 1, isTerminator = 1, mayLoad = 1 in
Evan Cheng12c3a532008-11-06 17:48:05 +0000594 def LDM_RET : AXI4ld<(outs),
Evan Cheng64d80e32007-07-19 01:14:50 +0000595 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng3c4a4ff2008-11-12 07:18:38 +0000596 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Chenga8e29892007-01-19 07:51:42 +0000597 []>;
Rafael Espindolaa2845842006-10-05 16:48:49 +0000598
Bob Wilson54fc1242009-06-22 21:01:46 +0000599// On non-Darwin platforms R9 is callee-saved.
Evan Cheng8557c2b2009-06-19 01:51:50 +0000600let isCall = 1, Itinerary = IIC_Br,
Evan Cheng756da122009-07-22 06:46:53 +0000601 Defs = [R0, R1, R2, R3, R12, LR,
602 D0, D1, D2, D3, D4, D5, D6, D7,
603 D16, D17, D18, D19, D20, D21, D22, D23,
604 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Evan Cheng12c3a532008-11-06 17:48:05 +0000605 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Chengdcc50a42007-05-18 01:53:54 +0000606 "bl ${func:call}",
Bob Wilson54fc1242009-06-22 21:01:46 +0000607 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Cheng277f0742007-06-19 21:05:09 +0000608
Evan Cheng12c3a532008-11-06 17:48:05 +0000609 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Cheng3aac7882008-09-01 08:25:56 +0000610 "bl", " ${func:call}",
Bob Wilson54fc1242009-06-22 21:01:46 +0000611 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Cheng277f0742007-06-19 21:05:09 +0000612
Evan Chenga8e29892007-01-19 07:51:42 +0000613 // ARMv5T and above
Evan Cheng12c3a532008-11-06 17:48:05 +0000614 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
Evan Cheng64d80e32007-07-19 01:14:50 +0000615 "blx $func",
Bob Wilson54fc1242009-06-22 21:01:46 +0000616 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
Jim Grosbach26421962008-10-14 20:36:24 +0000617 let Inst{7-4} = 0b0011;
618 let Inst{19-8} = 0b111111111111;
619 let Inst{27-20} = 0b00010010;
Evan Cheng7fd7ca42008-09-17 07:53:38 +0000620 }
621
Evan Chengf6bc4ae2009-07-14 01:49:27 +0000622 // ARMv4T
623 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
624 "mov lr, pc\n\tbx $func",
625 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]> {
626 let Inst{7-4} = 0b0001;
627 let Inst{19-8} = 0b111111111111;
628 let Inst{27-20} = 0b00010010;
Bob Wilson54fc1242009-06-22 21:01:46 +0000629 }
630}
631
632// On Darwin R9 is call-clobbered.
633let isCall = 1, Itinerary = IIC_Br,
Evan Cheng756da122009-07-22 06:46:53 +0000634 Defs = [R0, R1, R2, R3, R9, R12, LR,
635 D0, D1, D2, D3, D4, D5, D6, D7,
636 D16, D17, D18, D19, D20, D21, D22, D23,
637 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Bob Wilson54fc1242009-06-22 21:01:46 +0000638 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
639 "bl ${func:call}",
640 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
641
642 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
643 "bl", " ${func:call}",
644 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>;
645
646 // ARMv5T and above
647 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
648 "blx $func",
649 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
650 let Inst{7-4} = 0b0011;
651 let Inst{19-8} = 0b111111111111;
652 let Inst{27-20} = 0b00010010;
653 }
654
Evan Chengf6bc4ae2009-07-14 01:49:27 +0000655 // ARMv4T
656 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
657 "mov lr, pc\n\tbx $func",
658 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
659 let Inst{7-4} = 0b0001;
660 let Inst{19-8} = 0b111111111111;
661 let Inst{27-20} = 0b00010010;
Lauro Ramos Venancio64c88d72007-03-20 17:57:23 +0000662 }
Rafael Espindola35574632006-07-18 17:00:30 +0000663}
Rafael Espindoladc124a22006-05-18 21:45:49 +0000664
Evan Cheng8557c2b2009-06-19 01:51:50 +0000665let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
Evan Cheng5ada1992007-05-16 20:50:01 +0000666 // B is "predicable" since it can be xformed into a Bcc.
Evan Chengaeafca02007-05-16 07:45:54 +0000667 let isBarrier = 1 in {
Evan Cheng5ada1992007-05-16 20:50:01 +0000668 let isPredicable = 1 in
Evan Cheng12c3a532008-11-06 17:48:05 +0000669 def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
Evan Cheng64d80e32007-07-19 01:14:50 +0000670 [(br bb:$target)]>;
Evan Cheng44bec522007-05-15 01:29:07 +0000671
Owen Anderson20ab2902007-11-12 07:39:39 +0000672 let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng4df60f52008-11-07 09:06:08 +0000673 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
Evan Cheng64d80e32007-07-19 01:14:50 +0000674 "mov pc, $target \n$jt",
Evan Cheng4df60f52008-11-07 09:06:08 +0000675 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
676 let Inst{20} = 0; // S Bit
677 let Inst{24-21} = 0b1101;
Evan Cheng0fc0ade2009-07-07 23:45:10 +0000678 let Inst{27-25} = 0b000;
Evan Chengaeafca02007-05-16 07:45:54 +0000679 }
Evan Cheng4df60f52008-11-07 09:06:08 +0000680 def BR_JTm : JTI<(outs),
681 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
682 "ldr pc, $target \n$jt",
683 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
684 imm:$id)]> {
685 let Inst{20} = 1; // L bit
686 let Inst{21} = 0; // W bit
687 let Inst{22} = 0; // B bit
688 let Inst{24} = 1; // P bit
Evan Cheng0fc0ade2009-07-07 23:45:10 +0000689 let Inst{27-25} = 0b011;
Evan Chengeaa91b02007-06-19 01:26:51 +0000690 }
Evan Cheng4df60f52008-11-07 09:06:08 +0000691 def BR_JTadd : JTI<(outs),
692 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
693 "add pc, $target, $idx \n$jt",
694 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
695 imm:$id)]> {
696 let Inst{20} = 0; // S bit
697 let Inst{24-21} = 0b0100;
Evan Cheng0fc0ade2009-07-07 23:45:10 +0000698 let Inst{27-25} = 0b000;
Evan Cheng4df60f52008-11-07 09:06:08 +0000699 }
700 } // isNotDuplicable = 1, isIndirectBranch = 1
701 } // isBarrier = 1
Evan Chengaeafca02007-05-16 07:45:54 +0000702
Evan Chengc85e8322007-07-05 07:13:32 +0000703 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
704 // a two-value operand where a dag node expects two operands. :(
Evan Cheng12c3a532008-11-06 17:48:05 +0000705 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
Evan Cheng0ff94f72007-08-07 01:37:15 +0000706 "b", " $target",
707 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
Rafael Espindola1ed3af12006-08-01 18:53:10 +0000708}
Rafael Espindola84b19be2006-07-16 01:02:57 +0000709
Evan Chenga8e29892007-01-19 07:51:42 +0000710//===----------------------------------------------------------------------===//
711// Load / store Instructions.
712//
Rafael Espindola82c678b2006-10-16 17:17:22 +0000713
Evan Chenga8e29892007-01-19 07:51:42 +0000714// Load
Dan Gohman15511cf2008-12-03 18:15:48 +0000715let canFoldAsLoad = 1 in
Evan Cheng148cad82008-11-13 07:34:59 +0000716def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000717 "ldr", " $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000718 [(set GPR:$dst, (load addrmode2:$addr))]>;
Rafael Espindola82c678b2006-10-16 17:17:22 +0000719
Evan Chengfa775d02007-03-19 07:20:03 +0000720// Special LDR for loads from non-pc-relative constpools.
Dan Gohman15511cf2008-12-03 18:15:48 +0000721let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
Evan Cheng148cad82008-11-13 07:34:59 +0000722def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000723 "ldr", " $dst, $addr", []>;
Evan Chengfa775d02007-03-19 07:20:03 +0000724
Evan Chenga8e29892007-01-19 07:51:42 +0000725// Loads with zero extension
Evan Cheng148cad82008-11-13 07:34:59 +0000726def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000727 "ldr", "h $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000728 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
Rafael Espindola82c678b2006-10-16 17:17:22 +0000729
Evan Cheng148cad82008-11-13 07:34:59 +0000730def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000731 "ldr", "b $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000732 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
Rafael Espindola82c678b2006-10-16 17:17:22 +0000733
Evan Chenga8e29892007-01-19 07:51:42 +0000734// Loads with sign extension
Evan Cheng148cad82008-11-13 07:34:59 +0000735def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000736 "ldr", "sh $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000737 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
Rafael Espindola7bc59bc2006-05-14 22:18:28 +0000738
Evan Cheng148cad82008-11-13 07:34:59 +0000739def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000740 "ldr", "sb $dst, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000741 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
Rafael Espindolac391d162006-10-23 20:34:27 +0000742
Chris Lattner9b37aaf2008-01-10 05:12:37 +0000743let mayLoad = 1 in {
Evan Chenga8e29892007-01-19 07:51:42 +0000744// Load doubleword
Evan Cheng358dec52009-06-15 08:28:29 +0000745def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
746 "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
Rafael Espindolac391d162006-10-23 20:34:27 +0000747
Evan Chenga8e29892007-01-19 07:51:42 +0000748// Indexed loads
Evan Chengd87293c2008-11-06 08:47:38 +0000749def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000750 (ins addrmode2:$addr), LdFrm,
Evan Cheng0ff94f72007-08-07 01:37:15 +0000751 "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindoladc124a22006-05-18 21:45:49 +0000752
Evan Chengd87293c2008-11-06 08:47:38 +0000753def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000754 (ins GPR:$base, am2offset:$offset), LdFrm,
Evan Cheng0ff94f72007-08-07 01:37:15 +0000755 "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
Rafael Espindola450856d2006-12-12 00:37:38 +0000756
Evan Chengd87293c2008-11-06 08:47:38 +0000757def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000758 (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000759 "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindola4e307642006-09-08 16:59:47 +0000760
Evan Chengd87293c2008-11-06 08:47:38 +0000761def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000762 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000763 "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
Lauro Ramos Venancio301009a2006-12-28 13:11:14 +0000764
Evan Chengd87293c2008-11-06 08:47:38 +0000765def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000766 (ins addrmode2:$addr), LdFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000767 "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
Lauro Ramos Venancio301009a2006-12-28 13:11:14 +0000768
Evan Chengd87293c2008-11-06 08:47:38 +0000769def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000770 (ins GPR:$base,am2offset:$offset), LdFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000771 "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000772
Evan Chengd87293c2008-11-06 08:47:38 +0000773def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000774 (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000775 "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000776
Evan Chengd87293c2008-11-06 08:47:38 +0000777def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000778 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
779 "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000780
Evan Chengd87293c2008-11-06 08:47:38 +0000781def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000782 (ins addrmode3:$addr), LdMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000783 "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000784
Evan Chengd87293c2008-11-06 08:47:38 +0000785def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000786 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Cheng31926a72009-07-02 01:30:04 +0000787 "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
Chris Lattner9b37aaf2008-01-10 05:12:37 +0000788}
Evan Chenga8e29892007-01-19 07:51:42 +0000789
790// Store
Evan Cheng148cad82008-11-13 07:34:59 +0000791def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000792 "str", " $src, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000793 [(store GPR:$src, addrmode2:$addr)]>;
794
795// Stores with truncate
Evan Cheng148cad82008-11-13 07:34:59 +0000796def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000797 "str", "h $src, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000798 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
799
Evan Cheng148cad82008-11-13 07:34:59 +0000800def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000801 "str", "b $src, $addr",
Evan Chenga8e29892007-01-19 07:51:42 +0000802 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
803
804// Store doubleword
Chris Lattner2e48a702008-01-06 08:36:04 +0000805let mayStore = 1 in
Evan Cheng358dec52009-06-15 08:28:29 +0000806def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),StMiscFrm,
807 "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5T]>;
Evan Chenga8e29892007-01-19 07:51:42 +0000808
809// Indexed stores
Evan Chengd87293c2008-11-06 08:47:38 +0000810def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000811 (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000812 "str", " $src, [$base, $offset]!", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000813 [(set GPR:$base_wb,
814 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
815
Evan Chengd87293c2008-11-06 08:47:38 +0000816def STR_POST : AI2stwpo<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000817 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Cheng44bec522007-05-15 01:29:07 +0000818 "str", " $src, [$base], $offset", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000819 [(set GPR:$base_wb,
820 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
821
Evan Chengd87293c2008-11-06 08:47:38 +0000822def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000823 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000824 "str", "h $src, [$base, $offset]!", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000825 [(set GPR:$base_wb,
826 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
827
Evan Chengd87293c2008-11-06 08:47:38 +0000828def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000829 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000830 "str", "h $src, [$base], $offset", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000831 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
832 GPR:$base, am3offset:$offset))]>;
833
Evan Chengd87293c2008-11-06 08:47:38 +0000834def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000835 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000836 "str", "b $src, [$base, $offset]!", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000837 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
838 GPR:$base, am2offset:$offset))]>;
839
Evan Chengd87293c2008-11-06 08:47:38 +0000840def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
Evan Cheng148cad82008-11-13 07:34:59 +0000841 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chengfd488ed2007-05-29 23:32:06 +0000842 "str", "b $src, [$base], $offset", "$base = $base_wb",
Evan Chenga8e29892007-01-19 07:51:42 +0000843 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
844 GPR:$base, am2offset:$offset))]>;
Evan Chenga8e29892007-01-19 07:51:42 +0000845
846//===----------------------------------------------------------------------===//
847// Load / store multiple Instructions.
848//
849
Evan Cheng64d80e32007-07-19 01:14:50 +0000850// FIXME: $dst1 should be a def.
Chris Lattner9b37aaf2008-01-10 05:12:37 +0000851let mayLoad = 1 in
Evan Chengd87293c2008-11-06 08:47:38 +0000852def LDM : AXI4ld<(outs),
Evan Cheng64d80e32007-07-19 01:14:50 +0000853 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng3c4a4ff2008-11-12 07:18:38 +0000854 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Cheng44bec522007-05-15 01:29:07 +0000855 []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000856
Chris Lattner2e48a702008-01-06 08:36:04 +0000857let mayStore = 1 in
Evan Chengd87293c2008-11-06 08:47:38 +0000858def STM : AXI4st<(outs),
Evan Cheng64d80e32007-07-19 01:14:50 +0000859 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
Evan Cheng3c4a4ff2008-11-12 07:18:38 +0000860 LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
Evan Cheng44bec522007-05-15 01:29:07 +0000861 []>;
Evan Chenga8e29892007-01-19 07:51:42 +0000862
863//===----------------------------------------------------------------------===//
864// Move Instructions.
865//
866
Evan Chengcd799b92009-06-12 20:46:18 +0000867let neverHasSideEffects = 1 in
Evan Chengedda31c2008-11-05 18:35:52 +0000868def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
869 "mov", " $dst, $src", []>, UnaryDP;
870def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
871 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
Evan Chenga2515702007-03-19 07:09:02 +0000872
Evan Chengb3379fb2009-02-05 08:42:55 +0000873let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Chengedda31c2008-11-05 18:35:52 +0000874def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm,
875 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP;
Evan Cheng13ab0202007-07-10 18:08:01 +0000876
Evan Chenga9562552008-11-14 20:09:11 +0000877def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Cheng64d80e32007-07-19 01:14:50 +0000878 "mov", " $dst, $src, rrx",
Evan Chengedda31c2008-11-05 18:35:52 +0000879 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
Evan Chenga8e29892007-01-19 07:51:42 +0000880
881// These aren't really mov instructions, but we have to define them this way
882// due to flag operands.
883
Evan Cheng071a2792007-09-11 19:55:27 +0000884let Defs = [CPSR] in {
Evan Chenga9562552008-11-14 20:09:11 +0000885def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chengfd488ed2007-05-29 23:32:06 +0000886 "mov", "s $dst, $src, lsr #1",
Evan Chengedda31c2008-11-05 18:35:52 +0000887 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
Evan Chenga9562552008-11-14 20:09:11 +0000888def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chengfd488ed2007-05-29 23:32:06 +0000889 "mov", "s $dst, $src, asr #1",
Evan Chengedda31c2008-11-05 18:35:52 +0000890 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
Evan Cheng071a2792007-09-11 19:55:27 +0000891}
Evan Chenga8e29892007-01-19 07:51:42 +0000892
Evan Chenga8e29892007-01-19 07:51:42 +0000893//===----------------------------------------------------------------------===//
894// Extend Instructions.
895//
896
897// Sign extenders
898
Evan Cheng97f48c32008-11-06 22:15:19 +0000899defm SXTB : AI_unary_rrot<0b01101010,
900 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
901defm SXTH : AI_unary_rrot<0b01101011,
902 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
Evan Chenga8e29892007-01-19 07:51:42 +0000903
Evan Cheng97f48c32008-11-06 22:15:19 +0000904defm SXTAB : AI_bin_rrot<0b01101010,
905 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
906defm SXTAH : AI_bin_rrot<0b01101011,
907 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
Evan Chenga8e29892007-01-19 07:51:42 +0000908
909// TODO: SXT(A){B|H}16
910
911// Zero extenders
912
913let AddedComplexity = 16 in {
Evan Cheng97f48c32008-11-06 22:15:19 +0000914defm UXTB : AI_unary_rrot<0b01101110,
915 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
916defm UXTH : AI_unary_rrot<0b01101111,
917 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
918defm UXTB16 : AI_unary_rrot<0b01101100,
919 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
Evan Chenga8e29892007-01-19 07:51:42 +0000920
Bob Wilson1c76d0e2009-06-22 22:08:29 +0000921def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Chenga8e29892007-01-19 07:51:42 +0000922 (UXTB16r_rot GPR:$Src, 24)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +0000923def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Chenga8e29892007-01-19 07:51:42 +0000924 (UXTB16r_rot GPR:$Src, 8)>;
925
Evan Cheng97f48c32008-11-06 22:15:19 +0000926defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
Evan Chenga8e29892007-01-19 07:51:42 +0000927 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
Evan Cheng97f48c32008-11-06 22:15:19 +0000928defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
Evan Chenga8e29892007-01-19 07:51:42 +0000929 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
Rafael Espindola3c000bf2006-08-21 22:00:32 +0000930}
931
Evan Chenga8e29892007-01-19 07:51:42 +0000932// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
933//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
Rafael Espindola817e7fd2006-09-11 19:24:19 +0000934
Evan Chenga8e29892007-01-19 07:51:42 +0000935// TODO: UXT(A){B|H}16
936
937//===----------------------------------------------------------------------===//
938// Arithmetic Instructions.
939//
940
Jim Grosbach26421962008-10-14 20:36:24 +0000941defm ADD : AsI1_bin_irs<0b0100, "add",
Evan Cheng8de898a2009-06-26 00:19:44 +0000942 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Jim Grosbach26421962008-10-14 20:36:24 +0000943defm SUB : AsI1_bin_irs<0b0010, "sub",
Evan Cheng7fd7ca42008-09-17 07:53:38 +0000944 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Evan Chenga8e29892007-01-19 07:51:42 +0000945
Evan Chengc85e8322007-07-05 07:13:32 +0000946// ADD and SUB with 's' bit set.
Evan Cheng1e249e32009-06-25 20:59:23 +0000947defm ADDS : AI1_bin_s_irs<0b0100, "add",
948 BinOpFrag<(addc node:$LHS, node:$RHS)>>;
949defm SUBS : AI1_bin_s_irs<0b0010, "sub",
950 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng2c614c52007-06-06 10:17:05 +0000951
Evan Cheng62674222009-06-25 23:34:10 +0000952defm ADC : AI1_adde_sube_irs<0b0101, "adc",
Evan Cheng8de898a2009-06-26 00:19:44 +0000953 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
Evan Cheng62674222009-06-25 23:34:10 +0000954defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
955 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chenga8e29892007-01-19 07:51:42 +0000956
Evan Chengc85e8322007-07-05 07:13:32 +0000957// These don't define reg/reg forms, because they are handled above.
Evan Chengedda31c2008-11-05 18:35:52 +0000958def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng13ab0202007-07-10 18:08:01 +0000959 "rsb", " $dst, $a, $b",
960 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
961
Evan Chengedda31c2008-11-05 18:35:52 +0000962def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng13ab0202007-07-10 18:08:01 +0000963 "rsb", " $dst, $a, $b",
964 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
Evan Chengc85e8322007-07-05 07:13:32 +0000965
966// RSB with 's' bit set.
Evan Cheng071a2792007-09-11 19:55:27 +0000967let Defs = [CPSR] in {
Evan Chengedda31c2008-11-05 18:35:52 +0000968def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000969 "rsb", "s $dst, $a, $b",
Evan Cheng071a2792007-09-11 19:55:27 +0000970 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
Evan Chengedda31c2008-11-05 18:35:52 +0000971def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengc85e8322007-07-05 07:13:32 +0000972 "rsb", "s $dst, $a, $b",
Evan Cheng071a2792007-09-11 19:55:27 +0000973 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
974}
Evan Chengc85e8322007-07-05 07:13:32 +0000975
Evan Cheng62674222009-06-25 23:34:10 +0000976let Uses = [CPSR] in {
977def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
978 DPFrm, "rsc", " $dst, $a, $b",
979 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
980 Requires<[IsARM, CarryDefIsUnused]>;
981def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
982 DPSoRegFrm, "rsc", " $dst, $a, $b",
983 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
984 Requires<[IsARM, CarryDefIsUnused]>;
985}
986
987// FIXME: Allow these to be predicated.
Evan Cheng1e249e32009-06-25 20:59:23 +0000988let Defs = [CPSR], Uses = [CPSR] in {
989def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
990 DPFrm, "rscs $dst, $a, $b",
Evan Cheng62674222009-06-25 23:34:10 +0000991 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
992 Requires<[IsARM, CarryDefIsUnused]>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000993def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
994 DPSoRegFrm, "rscs $dst, $a, $b",
Evan Cheng62674222009-06-25 23:34:10 +0000995 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
996 Requires<[IsARM, CarryDefIsUnused]>;
Evan Cheng071a2792007-09-11 19:55:27 +0000997}
Evan Cheng2c614c52007-06-06 10:17:05 +0000998
Evan Chenga8e29892007-01-19 07:51:42 +0000999// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1000def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1001 (SUBri GPR:$src, so_imm_neg:$imm)>;
1002
1003//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1004// (SUBSri GPR:$src, so_imm_neg:$imm)>;
1005//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1006// (SBCri GPR:$src, so_imm_neg:$imm)>;
1007
1008// Note: These are implemented in C++ code, because they have to generate
1009// ADD/SUBrs instructions, which use a complex pattern that a xform function
1010// cannot produce.
1011// (mul X, 2^n+1) -> (add (X << n), X)
1012// (mul X, 2^n-1) -> (rsb X, (X << n))
1013
1014
1015//===----------------------------------------------------------------------===//
1016// Bitwise Instructions.
1017//
1018
Jim Grosbach26421962008-10-14 20:36:24 +00001019defm AND : AsI1_bin_irs<0b0000, "and",
Evan Cheng8de898a2009-06-26 00:19:44 +00001020 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
Jim Grosbach26421962008-10-14 20:36:24 +00001021defm ORR : AsI1_bin_irs<0b1100, "orr",
Evan Cheng8de898a2009-06-26 00:19:44 +00001022 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
Jim Grosbach26421962008-10-14 20:36:24 +00001023defm EOR : AsI1_bin_irs<0b0001, "eor",
Evan Cheng8de898a2009-06-26 00:19:44 +00001024 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Jim Grosbach26421962008-10-14 20:36:24 +00001025defm BIC : AsI1_bin_irs<0b1110, "bic",
Evan Cheng7fd7ca42008-09-17 07:53:38 +00001026 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Chenga8e29892007-01-19 07:51:42 +00001027
Evan Cheng36a0aeb2009-07-06 22:23:46 +00001028def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1029 AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
1030 "bfc", " $dst, $imm", "$src = $dst",
1031 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1032 Requires<[IsARM, HasV6T2]> {
1033 let Inst{27-21} = 0b0111110;
1034 let Inst{6-0} = 0b0011111;
1035}
1036
Evan Chengedda31c2008-11-05 18:35:52 +00001037def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
1038 "mvn", " $dst, $src",
1039 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
1040def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1041 "mvn", " $dst, $src",
1042 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
Evan Chengb3379fb2009-02-05 08:42:55 +00001043let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Chengedda31c2008-11-05 18:35:52 +00001044def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1045 "mvn", " $dst, $imm",
1046 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP;
Evan Chenga8e29892007-01-19 07:51:42 +00001047
1048def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1049 (BICri GPR:$src, so_imm_not:$imm)>;
1050
1051//===----------------------------------------------------------------------===//
1052// Multiply Instructions.
1053//
1054
Evan Cheng8de898a2009-06-26 00:19:44 +00001055let isCommutable = 1 in
Evan Chengfbc9d412008-11-06 01:21:28 +00001056def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng12c3a532008-11-06 17:48:05 +00001057 "mul", " $dst, $a, $b",
1058 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
Evan Chenga8e29892007-01-19 07:51:42 +00001059
Evan Chengfbc9d412008-11-06 01:21:28 +00001060def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng12c3a532008-11-06 17:48:05 +00001061 "mla", " $dst, $a, $b, $c",
1062 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
Evan Chenga8e29892007-01-19 07:51:42 +00001063
Evan Chengedcbada2009-07-06 22:05:45 +00001064def MLS : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1065 "mls", " $dst, $a, $b, $c",
1066 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1067 Requires<[IsARM, HasV6T2]>;
1068
Evan Chenga8e29892007-01-19 07:51:42 +00001069// Extra precision multiplies with low / high results
Evan Chengcd799b92009-06-12 20:46:18 +00001070let neverHasSideEffects = 1 in {
Evan Cheng8de898a2009-06-26 00:19:44 +00001071let isCommutable = 1 in {
Evan Chengfbc9d412008-11-06 01:21:28 +00001072def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1073 (ins GPR:$a, GPR:$b),
1074 "smull", " $ldst, $hdst, $a, $b", []>;
Evan Chenga8e29892007-01-19 07:51:42 +00001075
Evan Chengfbc9d412008-11-06 01:21:28 +00001076def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1077 (ins GPR:$a, GPR:$b),
1078 "umull", " $ldst, $hdst, $a, $b", []>;
Evan Cheng8de898a2009-06-26 00:19:44 +00001079}
Evan Chenga8e29892007-01-19 07:51:42 +00001080
1081// Multiply + accumulate
Evan Chengfbc9d412008-11-06 01:21:28 +00001082def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1083 (ins GPR:$a, GPR:$b),
1084 "smlal", " $ldst, $hdst, $a, $b", []>;
Evan Chenga8e29892007-01-19 07:51:42 +00001085
Evan Chengfbc9d412008-11-06 01:21:28 +00001086def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1087 (ins GPR:$a, GPR:$b),
1088 "umlal", " $ldst, $hdst, $a, $b", []>;
Evan Chenga8e29892007-01-19 07:51:42 +00001089
Evan Chengfbc9d412008-11-06 01:21:28 +00001090def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1091 (ins GPR:$a, GPR:$b),
1092 "umaal", " $ldst, $hdst, $a, $b", []>,
1093 Requires<[IsARM, HasV6]>;
Evan Chengcd799b92009-06-12 20:46:18 +00001094} // neverHasSideEffects
Evan Chenga8e29892007-01-19 07:51:42 +00001095
1096// Most significant word multiply
Evan Chengfbc9d412008-11-06 01:21:28 +00001097def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng13ab0202007-07-10 18:08:01 +00001098 "smmul", " $dst, $a, $b",
1099 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
Evan Chengfbc9d412008-11-06 01:21:28 +00001100 Requires<[IsARM, HasV6]> {
1101 let Inst{7-4} = 0b0001;
1102 let Inst{15-12} = 0b1111;
1103}
Evan Cheng13ab0202007-07-10 18:08:01 +00001104
Evan Chengfbc9d412008-11-06 01:21:28 +00001105def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng13ab0202007-07-10 18:08:01 +00001106 "smmla", " $dst, $a, $b, $c",
1107 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
Evan Chengfbc9d412008-11-06 01:21:28 +00001108 Requires<[IsARM, HasV6]> {
1109 let Inst{7-4} = 0b0001;
1110}
Evan Chenga8e29892007-01-19 07:51:42 +00001111
1112
Evan Chengfbc9d412008-11-06 01:21:28 +00001113def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng44bec522007-05-15 01:29:07 +00001114 "smmls", " $dst, $a, $b, $c",
Evan Chenga8e29892007-01-19 07:51:42 +00001115 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
Evan Chengfbc9d412008-11-06 01:21:28 +00001116 Requires<[IsARM, HasV6]> {
1117 let Inst{7-4} = 0b1101;
1118}
Evan Chenga8e29892007-01-19 07:51:42 +00001119
Raul Herbster37fb5b12007-08-30 23:25:47 +00001120multiclass AI_smul<string opc, PatFrag opnode> {
Evan Chengeb4f52e2008-11-06 03:35:07 +00001121 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001122 !strconcat(opc, "bb"), " $dst, $a, $b",
Evan Cheng34b12d22007-01-19 20:27:35 +00001123 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1124 (sext_inreg GPR:$b, i16)))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001125 Requires<[IsARM, HasV5TE]> {
1126 let Inst{5} = 0;
1127 let Inst{6} = 0;
1128 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001129
Evan Chengeb4f52e2008-11-06 03:35:07 +00001130 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001131 !strconcat(opc, "bt"), " $dst, $a, $b",
Evan Cheng34b12d22007-01-19 20:27:35 +00001132 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001133 (sra GPR:$b, (i32 16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001134 Requires<[IsARM, HasV5TE]> {
1135 let Inst{5} = 0;
1136 let Inst{6} = 1;
1137 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001138
Evan Chengeb4f52e2008-11-06 03:35:07 +00001139 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001140 !strconcat(opc, "tb"), " $dst, $a, $b",
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001141 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng34b12d22007-01-19 20:27:35 +00001142 (sext_inreg GPR:$b, i16)))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001143 Requires<[IsARM, HasV5TE]> {
1144 let Inst{5} = 1;
1145 let Inst{6} = 0;
1146 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001147
Evan Chengeb4f52e2008-11-06 03:35:07 +00001148 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001149 !strconcat(opc, "tt"), " $dst, $a, $b",
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001150 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1151 (sra GPR:$b, (i32 16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001152 Requires<[IsARM, HasV5TE]> {
1153 let Inst{5} = 1;
1154 let Inst{6} = 1;
1155 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001156
Evan Chengeb4f52e2008-11-06 03:35:07 +00001157 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001158 !strconcat(opc, "wb"), " $dst, $a, $b",
Evan Cheng34b12d22007-01-19 20:27:35 +00001159 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001160 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001161 Requires<[IsARM, HasV5TE]> {
1162 let Inst{5} = 1;
1163 let Inst{6} = 0;
1164 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001165
Evan Chengeb4f52e2008-11-06 03:35:07 +00001166 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng44bec522007-05-15 01:29:07 +00001167 !strconcat(opc, "wt"), " $dst, $a, $b",
Evan Chenga8e29892007-01-19 07:51:42 +00001168 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001169 (sra GPR:$b, (i32 16))), (i32 16)))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001170 Requires<[IsARM, HasV5TE]> {
1171 let Inst{5} = 1;
1172 let Inst{6} = 1;
1173 }
Rafael Espindolabec2e382006-10-16 16:33:29 +00001174}
1175
Raul Herbster37fb5b12007-08-30 23:25:47 +00001176
1177multiclass AI_smla<string opc, PatFrag opnode> {
Evan Chengeb4f52e2008-11-06 03:35:07 +00001178 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001179 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
Evan Cheng34b12d22007-01-19 20:27:35 +00001180 [(set GPR:$dst, (add GPR:$acc,
1181 (opnode (sext_inreg GPR:$a, i16),
1182 (sext_inreg GPR:$b, i16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001183 Requires<[IsARM, HasV5TE]> {
1184 let Inst{5} = 0;
1185 let Inst{6} = 0;
1186 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001187
Evan Chengeb4f52e2008-11-06 03:35:07 +00001188 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001189 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
Evan Cheng34b12d22007-01-19 20:27:35 +00001190 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001191 (sra GPR:$b, (i32 16)))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001192 Requires<[IsARM, HasV5TE]> {
1193 let Inst{5} = 0;
1194 let Inst{6} = 1;
1195 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001196
Evan Chengeb4f52e2008-11-06 03:35:07 +00001197 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001198 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001199 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng34b12d22007-01-19 20:27:35 +00001200 (sext_inreg GPR:$b, i16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001201 Requires<[IsARM, HasV5TE]> {
1202 let Inst{5} = 1;
1203 let Inst{6} = 0;
1204 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001205
Evan Chengeb4f52e2008-11-06 03:35:07 +00001206 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001207 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001208 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1209 (sra GPR:$b, (i32 16)))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001210 Requires<[IsARM, HasV5TE]> {
1211 let Inst{5} = 1;
1212 let Inst{6} = 1;
1213 }
Evan Chenga8e29892007-01-19 07:51:42 +00001214
Evan Chengeb4f52e2008-11-06 03:35:07 +00001215 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001216 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
Evan Cheng34b12d22007-01-19 20:27:35 +00001217 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001218 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001219 Requires<[IsARM, HasV5TE]> {
1220 let Inst{5} = 0;
1221 let Inst{6} = 0;
1222 }
Raul Herbster37fb5b12007-08-30 23:25:47 +00001223
Evan Chengeb4f52e2008-11-06 03:35:07 +00001224 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng44bec522007-05-15 01:29:07 +00001225 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
Evan Chenga8e29892007-01-19 07:51:42 +00001226 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001227 (sra GPR:$b, (i32 16))), (i32 16))))]>,
Evan Chengeb4f52e2008-11-06 03:35:07 +00001228 Requires<[IsARM, HasV5TE]> {
1229 let Inst{5} = 0;
1230 let Inst{6} = 1;
1231 }
Rafael Espindola70673a12006-10-18 16:20:57 +00001232}
Rafael Espindola5c2aa0a2006-09-08 12:47:03 +00001233
Raul Herbster37fb5b12007-08-30 23:25:47 +00001234defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1235defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
Rafael Espindola27185192006-09-29 21:20:16 +00001236
Evan Chenga8e29892007-01-19 07:51:42 +00001237// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1238// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
Rafael Espindola42b62f32006-10-13 13:14:59 +00001239
Evan Chenga8e29892007-01-19 07:51:42 +00001240//===----------------------------------------------------------------------===//
1241// Misc. Arithmetic Instructions.
1242//
Rafael Espindola0d9fe762006-10-10 16:33:47 +00001243
Evan Cheng8b59db32008-11-07 01:41:35 +00001244def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng44bec522007-05-15 01:29:07 +00001245 "clz", " $dst, $src",
Evan Cheng8b59db32008-11-07 01:41:35 +00001246 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1247 let Inst{7-4} = 0b0001;
1248 let Inst{11-8} = 0b1111;
1249 let Inst{19-16} = 0b1111;
1250}
Rafael Espindola199dd672006-10-17 13:13:23 +00001251
Evan Cheng8b59db32008-11-07 01:41:35 +00001252def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng44bec522007-05-15 01:29:07 +00001253 "rev", " $dst, $src",
Evan Cheng8b59db32008-11-07 01:41:35 +00001254 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1255 let Inst{7-4} = 0b0011;
1256 let Inst{11-8} = 0b1111;
1257 let Inst{19-16} = 0b1111;
1258}
Rafael Espindola199dd672006-10-17 13:13:23 +00001259
Evan Cheng8b59db32008-11-07 01:41:35 +00001260def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng44bec522007-05-15 01:29:07 +00001261 "rev16", " $dst, $src",
Evan Chenga8e29892007-01-19 07:51:42 +00001262 [(set GPR:$dst,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001263 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1264 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1265 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1266 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
Evan Cheng8b59db32008-11-07 01:41:35 +00001267 Requires<[IsARM, HasV6]> {
1268 let Inst{7-4} = 0b1011;
1269 let Inst{11-8} = 0b1111;
1270 let Inst{19-16} = 0b1111;
1271}
Rafael Espindola27185192006-09-29 21:20:16 +00001272
Evan Cheng8b59db32008-11-07 01:41:35 +00001273def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng44bec522007-05-15 01:29:07 +00001274 "revsh", " $dst, $src",
Evan Chenga8e29892007-01-19 07:51:42 +00001275 [(set GPR:$dst,
1276 (sext_inreg
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001277 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1278 (shl GPR:$src, (i32 8))), i16))]>,
Evan Cheng8b59db32008-11-07 01:41:35 +00001279 Requires<[IsARM, HasV6]> {
1280 let Inst{7-4} = 0b1011;
1281 let Inst{11-8} = 0b1111;
1282 let Inst{19-16} = 0b1111;
1283}
Rafael Espindola27185192006-09-29 21:20:16 +00001284
Evan Cheng8b59db32008-11-07 01:41:35 +00001285def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1286 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1287 "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Chenga8e29892007-01-19 07:51:42 +00001288 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1289 (and (shl GPR:$src2, (i32 imm:$shamt)),
1290 0xFFFF0000)))]>,
Evan Cheng8b59db32008-11-07 01:41:35 +00001291 Requires<[IsARM, HasV6]> {
1292 let Inst{6-4} = 0b001;
1293}
Rafael Espindola27185192006-09-29 21:20:16 +00001294
Evan Chenga8e29892007-01-19 07:51:42 +00001295// Alternate cases for PKHBT where identities eliminate some nodes.
1296def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1297 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1298def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1299 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
Rafael Espindola9e071f02006-10-02 19:30:56 +00001300
Rafael Espindolaa2845842006-10-05 16:48:49 +00001301
Evan Cheng8b59db32008-11-07 01:41:35 +00001302def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1303 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1304 "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Chenga8e29892007-01-19 07:51:42 +00001305 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1306 (and (sra GPR:$src2, imm16_31:$shamt),
Evan Cheng8b59db32008-11-07 01:41:35 +00001307 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1308 let Inst{6-4} = 0b101;
1309}
Rafael Espindola9e071f02006-10-02 19:30:56 +00001310
Evan Chenga8e29892007-01-19 07:51:42 +00001311// Alternate cases for PKHTB where identities eliminate some nodes. Note that
1312// a shift amount of 0 is *not legal* here, it is PKHBT instead.
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001313def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
Evan Chenga8e29892007-01-19 07:51:42 +00001314 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1315def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1316 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1317 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Rafael Espindolab47e1d02006-10-10 18:55:14 +00001318
Evan Chenga8e29892007-01-19 07:51:42 +00001319//===----------------------------------------------------------------------===//
1320// Comparison Instructions...
1321//
Rafael Espindolab47e1d02006-10-10 18:55:14 +00001322
Jim Grosbach26421962008-10-14 20:36:24 +00001323defm CMP : AI1_cmp_irs<0b1010, "cmp",
Evan Cheng0ff94f72007-08-07 01:37:15 +00001324 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
Jim Grosbach26421962008-10-14 20:36:24 +00001325defm CMN : AI1_cmp_irs<0b1011, "cmn",
Evan Cheng0ff94f72007-08-07 01:37:15 +00001326 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
Rafael Espindolae5bbd6d2006-10-07 14:24:52 +00001327
Evan Chenga8e29892007-01-19 07:51:42 +00001328// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Chengd87293c2008-11-06 08:47:38 +00001329defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwinc0309b42009-06-29 15:33:01 +00001330 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Chengd87293c2008-11-06 08:47:38 +00001331defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwinc0309b42009-06-29 15:33:01 +00001332 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Lauro Ramos Venancio99966632007-04-02 01:30:03 +00001333
David Goodwinc0309b42009-06-29 15:33:01 +00001334defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1335 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1336defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1337 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Cheng2c614c52007-06-06 10:17:05 +00001338
1339def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1340 (CMNri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio99966632007-04-02 01:30:03 +00001341
David Goodwinc0309b42009-06-29 15:33:01 +00001342def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
Lauro Ramos Venancio99966632007-04-02 01:30:03 +00001343 (CMNri GPR:$src, so_imm_neg:$imm)>;
1344
Rafael Espindolae5bbd6d2006-10-07 14:24:52 +00001345
Evan Chenga8e29892007-01-19 07:51:42 +00001346// Conditional moves
Evan Chengc85e8322007-07-05 07:13:32 +00001347// FIXME: should be able to write a pattern for ARMcmov, but can't use
1348// a two-value operand where a dag node expects two operands. :(
Evan Chengd87293c2008-11-06 08:47:38 +00001349def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Chengedda31c2008-11-05 18:35:52 +00001350 "mov", " $dst, $true",
Evan Chengc85e8322007-07-05 07:13:32 +00001351 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Chengd87293c2008-11-06 08:47:38 +00001352 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola493a7fc2006-10-10 20:38:57 +00001353
Evan Chengd87293c2008-11-06 08:47:38 +00001354def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1355 (ins GPR:$false, so_reg:$true), DPSoRegFrm,
Evan Chengedda31c2008-11-05 18:35:52 +00001356 "mov", " $dst, $true",
Evan Chengc85e8322007-07-05 07:13:32 +00001357 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Chengedda31c2008-11-05 18:35:52 +00001358 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola2dc0f2b2006-10-09 17:50:29 +00001359
Evan Chengd87293c2008-11-06 08:47:38 +00001360def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1361 (ins GPR:$false, so_imm:$true), DPFrm,
Evan Chengedda31c2008-11-05 18:35:52 +00001362 "mov", " $dst, $true",
Evan Chengc85e8322007-07-05 07:13:32 +00001363 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Chengedda31c2008-11-05 18:35:52 +00001364 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindolad9ae7782006-10-07 13:46:42 +00001365
Rafael Espindola4b20fbc2006-10-10 12:56:00 +00001366
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +00001367//===----------------------------------------------------------------------===//
1368// TLS Instructions
1369//
1370
1371// __aeabi_read_tp preserves the registers r1-r3.
Evan Cheng13ab0202007-07-10 18:08:01 +00001372let isCall = 1,
1373 Defs = [R0, R12, LR, CPSR] in {
Evan Cheng12c3a532008-11-06 17:48:05 +00001374 def TPsoft : ABXI<0b1011, (outs), (ins),
Evan Chengdcc50a42007-05-18 01:53:54 +00001375 "bl __aeabi_read_tp",
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +00001376 [(set R0, ARMthread_pointer)]>;
1377}
Rafael Espindolac01c87c2006-10-17 20:33:13 +00001378
Evan Chenga8e29892007-01-19 07:51:42 +00001379//===----------------------------------------------------------------------===//
Jim Grosbach0e0da732009-05-12 23:59:14 +00001380// SJLJ Exception handling intrinsics
Jim Grosbachf9570122009-05-14 00:46:35 +00001381// eh_sjlj_setjmp() is a three instruction sequence to store the return
1382// address and save #0 in R0 for the non-longjmp case.
Jim Grosbach0e0da732009-05-12 23:59:14 +00001383// Since by its nature we may be coming from some other function to get
1384// here, and we're using the stack frame for the containing function to
1385// save/restore registers, we can't keep anything live in regs across
Jim Grosbachf9570122009-05-14 00:46:35 +00001386// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
Jim Grosbach0e0da732009-05-12 23:59:14 +00001387// when we get here from a longjmp(). We force everthing out of registers
Jim Grosbachf9570122009-05-14 00:46:35 +00001388// except for our own input by listing the relevant registers in Defs. By
1389// doing so, we also cause the prologue/epilogue code to actively preserve
1390// all of the callee-saved resgisters, which is exactly what we want.
Jim Grosbach0e0da732009-05-12 23:59:14 +00001391let Defs =
Evan Cheng756da122009-07-22 06:46:53 +00001392 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1393 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1394 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D31,
1395 D31 ] in {
Jim Grosbachf9570122009-05-14 00:46:35 +00001396 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
Jim Grosbach0e0da732009-05-12 23:59:14 +00001397 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
1398 "add r0, pc, #4\n\t"
1399 "str r0, [$src, #+4]\n\t"
Jim Grosbachf9570122009-05-14 00:46:35 +00001400 "mov r0, #0 @ eh_setjmp", "",
1401 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
Jim Grosbach0e0da732009-05-12 23:59:14 +00001402}
1403
1404//===----------------------------------------------------------------------===//
Evan Chenga8e29892007-01-19 07:51:42 +00001405// Non-Instruction Patterns
1406//
Rafael Espindola5aca9272006-10-07 14:03:39 +00001407
Evan Chenga8e29892007-01-19 07:51:42 +00001408// ConstantPool, GlobalAddress, and JumpTable
1409def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
1410def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1411def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
Evan Chengc70d1842007-03-20 08:11:30 +00001412 (LEApcrelJT tjumptable:$dst, imm:$id)>;
Rafael Espindola5aca9272006-10-07 14:03:39 +00001413
Evan Chenga8e29892007-01-19 07:51:42 +00001414// Large immediate handling.
Rafael Espindola0505be02006-10-16 21:10:32 +00001415
Evan Chenga8e29892007-01-19 07:51:42 +00001416// Two piece so_imms.
Dan Gohmand45eddd2007-06-26 00:48:07 +00001417let isReMaterializable = 1 in
Evan Chengd87293c2008-11-06 08:47:38 +00001418def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
Evan Cheng44bec522007-05-15 01:29:07 +00001419 "mov", " $dst, $src",
Evan Cheng90922132008-11-06 02:25:39 +00001420 [(set GPR:$dst, so_imm2part:$src)]>;
Rafael Espindolaf621abc2006-10-17 13:36:07 +00001421
Evan Chenga8e29892007-01-19 07:51:42 +00001422def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
Evan Chenge7cbe412009-07-08 21:03:57 +00001423 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1424 (so_imm2part_2 imm:$RHS))>;
Evan Chenga8e29892007-01-19 07:51:42 +00001425def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
Evan Chenge7cbe412009-07-08 21:03:57 +00001426 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1427 (so_imm2part_2 imm:$RHS))>;
Rafael Espindolaf621abc2006-10-17 13:36:07 +00001428
Evan Chenga8e29892007-01-19 07:51:42 +00001429// TODO: add,sub,and, 3-instr forms?
Rafael Espindola0505be02006-10-16 21:10:32 +00001430
Rafael Espindola24357862006-10-19 17:05:03 +00001431
Evan Chenga8e29892007-01-19 07:51:42 +00001432// Direct calls
Bob Wilson54fc1242009-06-22 21:01:46 +00001433def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1434 Requires<[IsNotDarwin]>;
1435def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1436 Requires<[IsDarwin]>;
Rafael Espindola9dca7ad2006-11-01 14:13:27 +00001437
Evan Chenga8e29892007-01-19 07:51:42 +00001438// zextload i1 -> zextload i8
1439def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
Lauro Ramos Venancioa8f9f4a2006-12-26 19:30:42 +00001440
Evan Chenga8e29892007-01-19 07:51:42 +00001441// extload -> zextload
1442def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1443def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1444def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
Rafael Espindola9dca7ad2006-11-01 14:13:27 +00001445
Evan Cheng83b5cf02008-11-05 23:22:34 +00001446def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1447def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1448
Evan Cheng34b12d22007-01-19 20:27:35 +00001449// smul* and smla*
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001450def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1451 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001452 (SMULBB GPR:$a, GPR:$b)>;
1453def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1454 (SMULBB GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001455def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1456 (sra GPR:$b, (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001457 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001458def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001459 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001460def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1461 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001462 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001463def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
Evan Cheng34b12d22007-01-19 20:27:35 +00001464 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001465def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1466 (i32 16)),
Evan Cheng34b12d22007-01-19 20:27:35 +00001467 (SMULWB GPR:$a, GPR:$b)>;
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001468def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
Evan Cheng34b12d22007-01-19 20:27:35 +00001469 (SMULWB GPR:$a, GPR:$b)>;
1470
1471def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001472 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1473 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001474 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1475def : ARMV5TEPat<(add GPR:$acc,
1476 (mul sext_16_node:$a, sext_16_node:$b)),
1477 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1478def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001479 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1480 (sra GPR:$b, (i32 16)))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001481 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1482def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001483 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001484 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1485def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001486 (mul (sra GPR:$a, (i32 16)),
1487 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001488 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1489def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001490 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
Evan Cheng34b12d22007-01-19 20:27:35 +00001491 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1492def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001493 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1494 (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001495 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1496def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson1c76d0e2009-06-22 22:08:29 +00001497 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
Evan Cheng34b12d22007-01-19 20:27:35 +00001498 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1499
Evan Chenga8e29892007-01-19 07:51:42 +00001500//===----------------------------------------------------------------------===//
1501// Thumb Support
1502//
1503
1504include "ARMInstrThumb.td"
1505
1506//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +00001507// Thumb2 Support
1508//
1509
1510include "ARMInstrThumb2.td"
1511
1512//===----------------------------------------------------------------------===//
Evan Chenga8e29892007-01-19 07:51:42 +00001513// Floating Point Support
1514//
1515
1516include "ARMInstrVFP.td"
Bob Wilson5bafff32009-06-22 23:27:02 +00001517
1518//===----------------------------------------------------------------------===//
1519// Advanced SIMD (NEON) Support
1520//
1521
1522include "ARMInstrNEON.td"