blob: 611c42fd0e4b627f86c1b56c4ea382bb429902b6 [file] [log] [blame]
Evan Cheng10043e22007-01-19 07:51:42 +00001//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
Rafael Espindolaffdc24b2006-05-14 22:18:28 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
Rafael Espindolaffdc24b2006-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 Cheng10043e22007-01-19 07:51:42 +000014//===----------------------------------------------------------------------===//
15// ARM specific DAG Nodes.
16//
Rafael Espindolae45a79a2006-09-11 17:25:40 +000017
Evan Cheng10043e22007-01-19 07:51:42 +000018// Type profiles.
Bill Wendling77b13af2007-11-13 09:19:02 +000019def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
Rafael Espindola708cb602006-11-08 17:07:32 +000021
Evan Cheng10043e22007-01-19 07:51:42 +000022def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
Rafael Espindola19398ec2006-10-17 18:04:53 +000023
Evan Cheng10043e22007-01-19 07:51:42 +000024def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
Rafael Espindolae45a79a2006-09-11 17:25:40 +000025
Evan Cheng10043e22007-01-19 07:51:42 +000026def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
28 SDTCisVT<3, i32>]>;
Rafael Espindola708cb602006-11-08 17:07:32 +000029
Evan Cheng10043e22007-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 Venancioc39c12a2007-04-27 13:54:47 +000042def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
Jim Grosbach06928192009-05-14 00:46:35 +000043def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000044
Evan Cheng10043e22007-01-19 07:51:42 +000045// Node definitions.
46def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
Evan Cheng10043e22007-01-19 07:51:42 +000047def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
48
Bill Wendling77b13af2007-11-13 09:19:02 +000049def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
Bill Wendling97925ec2008-02-27 06:33:05 +000050 [SDNPHasChain, SDNPOutFlag]>;
Bill Wendling77b13af2007-11-13 09:19:02 +000051def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
Bill Wendling97925ec2008-02-27 06:33:05 +000052 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Cheng10043e22007-01-19 07:51:42 +000053
54def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
55 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Chengc3c949b42007-06-19 21:05:09 +000056def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
57 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Cheng10043e22007-01-19 07:51:42 +000058def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
59 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
60
Chris Lattner9a249b02008-01-15 22:02:54 +000061def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
Evan Cheng10043e22007-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 Goodwindbf11ba2009-06-29 15:33:01 +000078def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
79 [SDNPOutFlag,SDNPCommutative]>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +000080
Evan Cheng10043e22007-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 Espindola19398ec2006-10-17 18:04:53 +000086
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000087def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
Jim Grosbach06928192009-05-14 00:46:35 +000088def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000089
Rafael Espindolaffdc24b2006-05-14 22:18:28 +000090//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +000091// ARM Instruction Predicate Definitions.
92//
Anton Korobeynikov409105f2009-06-15 21:46:20 +000093def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
94def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
95def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
Evan Chenge63b0e62009-07-06 22:05:45 +000096def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
Bob Wilson2e076c42009-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 Korobeynikov409105f2009-06-15 21:46:20 +0000101def IsThumb : Predicate<"Subtarget->isThumb()">;
Evan Cheng431cf562009-06-23 17:48:47 +0000102def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
Evan Cheng2c450d32009-07-02 06:38:40 +0000103def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
Anton Korobeynikov409105f2009-06-15 21:46:20 +0000104def IsARM : Predicate<"!Subtarget->isThumb()">;
Bob Wilson45825302009-06-22 21:01:46 +0000105def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
106def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
Evan Cheng1eda6372009-06-26 06:10:18 +0000107def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng97727a62009-06-25 23:34:10 +0000108def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng10043e22007-01-19 07:51:42 +0000109
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000110//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-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 Cheng10043e22007-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 Chenge3a53c42009-07-08 21:03:57 +0000124 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
Evan Cheng10043e22007-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 Chenge3a53c42009-07-08 21:03:57 +0000130 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
Evan Cheng10043e22007-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 Gohmaneffb8942008-09-12 16:56:44 +0000135 int32_t v = (int32_t)N->getZExtValue();
Evan Cheng10043e22007-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 Gohmaneffb8942008-09-12 16:56:44 +0000141 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
Evan Cheng10043e22007-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 Gohmaneffb8942008-09-12 16:56:44 +0000146 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
Evan Cheng10043e22007-01-19 07:51:42 +0000147}]>;
148
149def so_imm_neg :
Dan Gohmaneffb8942008-09-12 16:56:44 +0000150 PatLeaf<(imm), [{
151 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
152 }], so_imm_neg_XFORM>;
Evan Cheng10043e22007-01-19 07:51:42 +0000153
Evan Cheng5be3e092007-03-19 07:09:02 +0000154def so_imm_not :
Dan Gohmaneffb8942008-09-12 16:56:44 +0000155 PatLeaf<(imm), [{
156 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
157 }], so_imm_not_XFORM>;
Evan Cheng10043e22007-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 Gohman2ce6f2a2008-07-27 21:46:04 +0000161 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
Evan Cheng10043e22007-01-19 07:51:42 +0000162}]>;
163
Evan Cheng40398232009-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 Goodwin72b80ac2009-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 Cheng40398232009-07-06 22:23:46 +0000181}] > {
182 let PrintMethod = "printBitfieldInvMaskImmOperand";
183}
184
Evan Cheng2d37f192008-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 Cheng10043e22007-01-19 07:51:42 +0000187
188//===----------------------------------------------------------------------===//
189// Operand Definitions.
190//
191
192// Branch target.
193def brtarget : Operand<OtherVT>;
194
Evan Cheng10043e22007-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 Chenge3a53c42009-07-08 21:03:57 +0000228 PatLeaf<(imm), [{
229 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
230 }]> {
Evan Cheng10043e22007-01-19 07:51:42 +0000231 let PrintMethod = "printSOImmOperand";
232}
233
Evan Cheng9e7b8382007-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 Gohmaneffb8942008-09-12 16:56:44 +0000238 PatLeaf<(imm), [{
239 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
240 }]> {
Evan Cheng9e7b8382007-03-20 08:11:30 +0000241 let PrintMethod = "printSOImm2PartOperand";
242}
243
244def so_imm2part_1 : SDNodeXForm<imm, [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000245 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
Evan Chenge3a53c42009-07-08 21:03:57 +0000246 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Cheng9e7b8382007-03-20 08:11:30 +0000247}]>;
248
249def so_imm2part_2 : SDNodeXForm<imm, [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000250 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
Evan Chenge3a53c42009-07-08 21:03:57 +0000251 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Cheng9e7b8382007-03-20 08:11:30 +0000252}]>;
253
Evan Cheng10043e22007-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 Wilsondeb35af2009-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 Cheng10043e22007-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 Chengf7c6eff2007-08-07 01:37:15 +0000320
Evan Cheng2d37f192008-08-28 23:39:26 +0000321include "ARMInstrFormats.td"
Evan Chengf7c6eff2007-08-07 01:37:15 +0000322
323//===----------------------------------------------------------------------===//
Evan Cheng2d37f192008-08-28 23:39:26 +0000324// Multiclass helpers...
Evan Cheng10043e22007-01-19 07:51:42 +0000325//
326
Evan Cheng9f717af2008-08-29 07:36:24 +0000327/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
Evan Cheng10043e22007-01-19 07:51:42 +0000328/// binop that produces a value.
Evan Cheng5bf90112009-06-26 00:19:44 +0000329multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
330 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000331 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000332 opc, " $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000333 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
334 let Inst{25} = 1;
335 }
Evan Cheng81889d012008-11-05 18:35:52 +0000336 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000337 opc, " $dst, $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000338 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000339 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000340 let isCommutable = Commutable;
341 }
Evan Cheng81889d012008-11-05 18:35:52 +0000342 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000343 opc, " $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000344 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
345 let Inst{25} = 0;
346 }
Evan Cheng10043e22007-01-19 07:51:42 +0000347}
348
Evan Chengc7ea8df2009-06-25 20:59:23 +0000349/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
Evan Chengaa3b8012007-07-05 07:13:32 +0000350/// instruction modifies the CSPR register.
Evan Cheng3e18e502007-09-11 19:55:27 +0000351let Defs = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000352multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
353 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000354 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000355 opc, "s $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000356 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
357 let Inst{25} = 1;
358 }
Evan Cheng81889d012008-11-05 18:35:52 +0000359 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000360 opc, "s $dst, $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000361 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
362 let isCommutable = Commutable;
Evan Cheng2cff0762009-07-07 23:40:25 +0000363 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000364 }
Evan Cheng81889d012008-11-05 18:35:52 +0000365 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000366 opc, "s $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000367 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
368 let Inst{25} = 0;
369 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000370}
Evan Chengaa3b8012007-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 Cheng9d41b312007-07-10 18:08:01 +0000374/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
Evan Chengaa3b8012007-07-05 07:13:32 +0000375/// a explicit result, only implicitly set CPSR.
Evan Cheng3e18e502007-09-11 19:55:27 +0000376let Defs = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000377multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
378 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000379 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000380 opc, " $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000381 [(opnode GPR:$a, so_imm:$b)]> {
382 let Inst{25} = 1;
383 }
Evan Cheng81889d012008-11-05 18:35:52 +0000384 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000385 opc, " $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000386 [(opnode GPR:$a, GPR:$b)]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000387 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000388 let isCommutable = Commutable;
389 }
Evan Cheng81889d012008-11-05 18:35:52 +0000390 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000391 opc, " $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000392 [(opnode GPR:$a, so_reg:$b)]> {
393 let Inst{25} = 0;
394 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000395}
Evan Cheng10043e22007-01-19 07:51:42 +0000396}
397
Evan Cheng10043e22007-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 Cheng49d66522008-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 Cheng0f7cbe82007-05-15 01:29:07 +0000403 opc, " $dst, $Src",
Evan Cheng49d66522008-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 Cheng0f7cbe82007-05-15 01:29:07 +0000409 opc, " $dst, $Src, ror $rot",
Evan Cheng10043e22007-01-19 07:51:42 +0000410 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
Evan Cheng49d66522008-11-06 22:15:19 +0000411 Requires<[IsARM, HasV6]> {
412 let Inst{19-16} = 0b1111;
413 }
Evan Cheng10043e22007-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 Cheng49d66522008-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 Cheng10043e22007-01-19 07:51:42 +0000421 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
422 Requires<[IsARM, HasV6]>;
Evan Cheng49d66522008-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 Cheng10043e22007-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 Cheng97727a62009-06-25 23:34:10 +0000430/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
431let Uses = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000432multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
433 bit Commutable = 0> {
Evan Cheng97727a62009-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 Cheng2cff0762009-07-07 23:40:25 +0000437 Requires<[IsARM, CarryDefIsUnused]> {
438 let Inst{25} = 1;
439 }
Evan Cheng97727a62009-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 Cheng5bf90112009-06-26 00:19:44 +0000443 Requires<[IsARM, CarryDefIsUnused]> {
444 let isCommutable = Commutable;
Evan Cheng2cff0762009-07-07 23:40:25 +0000445 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000446 }
Evan Cheng97727a62009-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 Cheng2cff0762009-07-07 23:40:25 +0000450 Requires<[IsARM, CarryDefIsUnused]> {
451 let Inst{25} = 0;
452 }
Evan Cheng97727a62009-06-25 23:34:10 +0000453 // Carry setting variants
454 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000455 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000456 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
457 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000458 let Defs = [CPSR];
459 let Inst{25} = 1;
Evan Cheng5bf90112009-06-26 00:19:44 +0000460 }
Evan Cheng97727a62009-06-25 23:34:10 +0000461 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000462 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000463 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
464 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000465 let Defs = [CPSR];
466 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000467 }
Evan Cheng97727a62009-06-25 23:34:10 +0000468 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000469 DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000470 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
471 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000472 let Defs = [CPSR];
473 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000474 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000475}
Evan Chengaa3b8012007-07-05 07:13:32 +0000476}
477
Rafael Espindola203922d2006-10-16 17:57:20 +0000478//===----------------------------------------------------------------------===//
479// Instructions
480//===----------------------------------------------------------------------===//
481
Evan Cheng10043e22007-01-19 07:51:42 +0000482//===----------------------------------------------------------------------===//
483// Miscellaneous Instructions.
484//
Rafael Espindolafe03fe92006-08-24 16:13:15 +0000485
Evan Cheng10043e22007-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 Chengd93b5b62009-06-12 20:46:18 +0000490let neverHasSideEffects = 1, isNotDuplicable = 1 in
Evan Cheng10043e22007-01-19 07:51:42 +0000491def CONSTPOOL_ENTRY :
Evan Cheng94b5a802007-07-19 01:14:50 +0000492PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
Evan Chengaa03cd32008-11-06 17:48:05 +0000493 i32imm:$size),
Evan Cheng10043e22007-01-19 07:51:42 +0000494 "${instid:label} ${cpidx:cpentry}", []>;
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000495
Evan Cheng3e18e502007-09-11 19:55:27 +0000496let Defs = [SP], Uses = [SP] in {
Evan Cheng10043e22007-01-19 07:51:42 +0000497def ADJCALLSTACKUP :
Bill Wendlingf359fed2007-11-13 00:44:25 +0000498PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
499 "@ ADJCALLSTACKUP $amt1",
Chris Lattner27539552008-10-11 22:08:30 +0000500 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
Rafael Espindola29e48752006-08-24 17:19:08 +0000501
Evan Cheng10043e22007-01-19 07:51:42 +0000502def ADJCALLSTACKDOWN :
Evan Cheng94b5a802007-07-19 01:14:50 +0000503PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
Evan Cheng10043e22007-01-19 07:51:42 +0000504 "@ ADJCALLSTACKDOWN $amt",
Chris Lattner27539552008-10-11 22:08:30 +0000505 [(ARMcallseq_start timm:$amt)]>;
Evan Cheng3e18e502007-09-11 19:55:27 +0000506}
Rafael Espindolad0dee772006-08-21 22:00:32 +0000507
Evan Cheng10043e22007-01-19 07:51:42 +0000508def DWARF_LOC :
Evan Cheng94b5a802007-07-19 01:14:50 +0000509PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
Evan Cheng10043e22007-01-19 07:51:42 +0000510 ".loc $file, $line, $col",
511 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
Rafael Espindolad15c8922006-10-10 12:56:00 +0000512
Evan Chengaa03cd32008-11-06 17:48:05 +0000513
514// Address computation and loads and stores in PIC mode.
Evan Chenga7ca6242007-06-19 01:26:51 +0000515let isNotDuplicable = 1 in {
Evan Cheng8fce66a2008-10-31 19:11:09 +0000516def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000517 Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000518 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
Dale Johannesen7d55f372007-05-21 22:14:33 +0000519
Evan Cheng72501202008-01-07 23:56:57 +0000520let AddedComplexity = 10 in {
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000521let canFoldAsLoad = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000522def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000523 Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000524 [(set GPR:$dst, (load addrmodepc:$addr))]>;
Rafael Espindola75269be2006-07-16 01:02:57 +0000525
Evan Cheng47b546d2008-11-06 08:47:38 +0000526def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000527 Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000528 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
529
Evan Cheng47b546d2008-11-06 08:47:38 +0000530def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000531 Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000532 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
533
Evan Cheng47b546d2008-11-06 08:47:38 +0000534def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000535 Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000536 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
537
Evan Cheng47b546d2008-11-06 08:47:38 +0000538def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000539 Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000540 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
541}
Chris Lattnerf4d55ec2008-01-06 05:55:01 +0000542let AddedComplexity = 10 in {
Evan Cheng47b546d2008-11-06 08:47:38 +0000543def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000544 Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000545 [(store GPR:$src, addrmodepc:$addr)]>;
546
Evan Cheng47b546d2008-11-06 08:47:38 +0000547def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000548 Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000549 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
550
Evan Cheng47b546d2008-11-06 08:47:38 +0000551def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000552 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000553 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
554}
Evan Chengaa03cd32008-11-06 17:48:05 +0000555} // isNotDuplicable = 1
Dale Johannesen7d55f372007-05-21 22:14:33 +0000556
Evan Cheng6a42ec32009-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,
Evan Chenge270d4a2009-07-22 22:03:29 +0000561 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
562 "${:private}PCRELL${:uid}+8))\n"),
563 !strconcat("${:private}PCRELL${:uid}:\n\t",
564 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
Evan Cheng6a42ec32009-06-23 05:25:29 +0000565 []>;
566
Evan Cheng4c048fe2009-06-24 23:14:45 +0000567def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
568 (ins i32imm:$label, i32imm:$id, pred:$p),
Evan Cheng6a42ec32009-06-23 05:25:29 +0000569 Pseudo,
Evan Chenge270d4a2009-07-22 22:03:29 +0000570 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
571 "(${label}_${id:no_hash}-(",
572 "${:private}PCRELL${:uid}+8))\n"),
573 !strconcat("${:private}PCRELL${:uid}:\n\t",
574 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
Evan Cheng2cff0762009-07-07 23:40:25 +0000575 []> {
576 let Inst{25} = 1;
577}
Evan Cheng6a42ec32009-06-23 05:25:29 +0000578
Evan Cheng10043e22007-01-19 07:51:42 +0000579//===----------------------------------------------------------------------===//
580// Control Flow Instructions.
581//
Rafael Espindolad55c0a42006-10-02 19:30:56 +0000582
Evan Cheng10043e22007-01-19 07:51:42 +0000583let isReturn = 1, isTerminator = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000584 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000585 let Inst{7-4} = 0b0001;
586 let Inst{19-8} = 0b111111111111;
587 let Inst{27-20} = 0b00010010;
Evan Cheng7848cfc2008-09-17 07:53:38 +0000588}
Rafael Espindola53f78be2006-09-29 21:20:16 +0000589
Evan Cheng10043e22007-01-19 07:51:42 +0000590// FIXME: remove when we have a way to marking a MI with these properties.
Evan Cheng94b5a802007-07-19 01:14:50 +0000591// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
592// operand list.
Evan Chengaa03cd32008-11-06 17:48:05 +0000593// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Chenga02fc2d2009-07-09 22:57:41 +0000594let isReturn = 1, isTerminator = 1, mayLoad = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000595 def LDM_RET : AXI4ld<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000596 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000597 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Cheng10043e22007-01-19 07:51:42 +0000598 []>;
Rafael Espindolae04df412006-10-05 16:48:49 +0000599
Bob Wilson45825302009-06-22 21:01:46 +0000600// On non-Darwin platforms R9 is callee-saved.
Evan Cheng4e712de2009-06-19 01:51:50 +0000601let isCall = 1, Itinerary = IIC_Br,
Evan Cheng4b02b2f2009-07-22 06:46:53 +0000602 Defs = [R0, R1, R2, R3, R12, LR,
603 D0, D1, D2, D3, D4, D5, D6, D7,
604 D16, D17, D18, D19, D20, D21, D22, D23,
605 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Evan Chengaa03cd32008-11-06 17:48:05 +0000606 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Cheng4ae18402007-05-18 01:53:54 +0000607 "bl ${func:call}",
Bob Wilson45825302009-06-22 21:01:46 +0000608 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Chengc3c949b42007-06-19 21:05:09 +0000609
Evan Chengaa03cd32008-11-06 17:48:05 +0000610 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Chengfa558782008-09-01 08:25:56 +0000611 "bl", " ${func:call}",
Bob Wilson45825302009-06-22 21:01:46 +0000612 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Chengc3c949b42007-06-19 21:05:09 +0000613
Evan Cheng10043e22007-01-19 07:51:42 +0000614 // ARMv5T and above
Evan Chengaa03cd32008-11-06 17:48:05 +0000615 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
Evan Cheng94b5a802007-07-19 01:14:50 +0000616 "blx $func",
Bob Wilson45825302009-06-22 21:01:46 +0000617 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000618 let Inst{7-4} = 0b0011;
619 let Inst{19-8} = 0b111111111111;
620 let Inst{27-20} = 0b00010010;
Evan Cheng7848cfc2008-09-17 07:53:38 +0000621 }
622
Evan Chengbd9ba422009-07-14 01:49:27 +0000623 // ARMv4T
624 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
625 "mov lr, pc\n\tbx $func",
626 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]> {
627 let Inst{7-4} = 0b0001;
628 let Inst{19-8} = 0b111111111111;
629 let Inst{27-20} = 0b00010010;
Bob Wilson45825302009-06-22 21:01:46 +0000630 }
631}
632
633// On Darwin R9 is call-clobbered.
634let isCall = 1, Itinerary = IIC_Br,
Evan Cheng4b02b2f2009-07-22 06:46:53 +0000635 Defs = [R0, R1, R2, R3, R9, R12, LR,
636 D0, D1, D2, D3, D4, D5, D6, D7,
637 D16, D17, D18, D19, D20, D21, D22, D23,
638 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Bob Wilson45825302009-06-22 21:01:46 +0000639 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
640 "bl ${func:call}",
641 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
642
643 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
644 "bl", " ${func:call}",
645 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>;
646
647 // ARMv5T and above
648 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
649 "blx $func",
650 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
651 let Inst{7-4} = 0b0011;
652 let Inst{19-8} = 0b111111111111;
653 let Inst{27-20} = 0b00010010;
654 }
655
Evan Chengbd9ba422009-07-14 01:49:27 +0000656 // ARMv4T
657 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
658 "mov lr, pc\n\tbx $func",
659 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
660 let Inst{7-4} = 0b0001;
661 let Inst{19-8} = 0b111111111111;
662 let Inst{27-20} = 0b00010010;
Lauro Ramos Venancioa88c4a72007-03-20 17:57:23 +0000663 }
Rafael Espindolabf3a17c2006-07-18 17:00:30 +0000664}
Rafael Espindolab15597b2006-05-18 21:45:49 +0000665
Evan Cheng4e712de2009-06-19 01:51:50 +0000666let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
Evan Chengdcd6cdf2007-05-16 20:50:01 +0000667 // B is "predicable" since it can be xformed into a Bcc.
Evan Cheng01a42272007-05-16 07:45:54 +0000668 let isBarrier = 1 in {
Evan Chengdcd6cdf2007-05-16 20:50:01 +0000669 let isPredicable = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000670 def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
Evan Cheng94b5a802007-07-19 01:14:50 +0000671 [(br bb:$target)]>;
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000672
Owen Anderson933b5b72007-11-12 07:39:39 +0000673 let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng7095cd22008-11-07 09:06:08 +0000674 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
Evan Cheng94b5a802007-07-19 01:14:50 +0000675 "mov pc, $target \n$jt",
Evan Cheng7095cd22008-11-07 09:06:08 +0000676 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
677 let Inst{20} = 0; // S Bit
678 let Inst{24-21} = 0b1101;
Evan Chengf0080b72009-07-07 23:45:10 +0000679 let Inst{27-25} = 0b000;
Evan Cheng01a42272007-05-16 07:45:54 +0000680 }
Evan Cheng7095cd22008-11-07 09:06:08 +0000681 def BR_JTm : JTI<(outs),
682 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
683 "ldr pc, $target \n$jt",
684 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
685 imm:$id)]> {
686 let Inst{20} = 1; // L bit
687 let Inst{21} = 0; // W bit
688 let Inst{22} = 0; // B bit
689 let Inst{24} = 1; // P bit
Evan Chengf0080b72009-07-07 23:45:10 +0000690 let Inst{27-25} = 0b011;
Evan Chenga7ca6242007-06-19 01:26:51 +0000691 }
Evan Cheng7095cd22008-11-07 09:06:08 +0000692 def BR_JTadd : JTI<(outs),
693 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
694 "add pc, $target, $idx \n$jt",
695 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
696 imm:$id)]> {
697 let Inst{20} = 0; // S bit
698 let Inst{24-21} = 0b0100;
Evan Chengf0080b72009-07-07 23:45:10 +0000699 let Inst{27-25} = 0b000;
Evan Cheng7095cd22008-11-07 09:06:08 +0000700 }
701 } // isNotDuplicable = 1, isIndirectBranch = 1
702 } // isBarrier = 1
Evan Cheng01a42272007-05-16 07:45:54 +0000703
Evan Chengaa3b8012007-07-05 07:13:32 +0000704 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
705 // a two-value operand where a dag node expects two operands. :(
Evan Chengaa03cd32008-11-06 17:48:05 +0000706 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000707 "b", " $target",
708 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
Rafael Espindola8b7bd822006-08-01 18:53:10 +0000709}
Rafael Espindola75269be2006-07-16 01:02:57 +0000710
Evan Cheng10043e22007-01-19 07:51:42 +0000711//===----------------------------------------------------------------------===//
712// Load / store Instructions.
713//
Rafael Espindola677ee832006-10-16 17:17:22 +0000714
Evan Cheng10043e22007-01-19 07:51:42 +0000715// Load
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000716let canFoldAsLoad = 1 in
Evan Cheng2666f592008-11-13 07:34:59 +0000717def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000718 "ldr", " $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000719 [(set GPR:$dst, (load addrmode2:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000720
Evan Chengee2763f2007-03-19 07:20:03 +0000721// Special LDR for loads from non-pc-relative constpools.
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000722let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
Evan Cheng2666f592008-11-13 07:34:59 +0000723def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000724 "ldr", " $dst, $addr", []>;
Evan Chengee2763f2007-03-19 07:20:03 +0000725
Evan Cheng10043e22007-01-19 07:51:42 +0000726// Loads with zero extension
Evan Cheng2666f592008-11-13 07:34:59 +0000727def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000728 "ldr", "h $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000729 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000730
Evan Cheng2666f592008-11-13 07:34:59 +0000731def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000732 "ldr", "b $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000733 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000734
Evan Cheng10043e22007-01-19 07:51:42 +0000735// Loads with sign extension
Evan Cheng2666f592008-11-13 07:34:59 +0000736def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000737 "ldr", "sh $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000738 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000739
Evan Cheng2666f592008-11-13 07:34:59 +0000740def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000741 "ldr", "sb $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000742 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
Rafael Espindolab43efe82006-10-23 20:34:27 +0000743
Chris Lattner94de7bc2008-01-10 05:12:37 +0000744let mayLoad = 1 in {
Evan Cheng10043e22007-01-19 07:51:42 +0000745// Load doubleword
Evan Cheng1283c6a2009-06-15 08:28:29 +0000746def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
747 "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
Rafael Espindolab43efe82006-10-23 20:34:27 +0000748
Evan Cheng10043e22007-01-19 07:51:42 +0000749// Indexed loads
Evan Cheng47b546d2008-11-06 08:47:38 +0000750def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000751 (ins addrmode2:$addr), LdFrm,
Evan Chengf7c6eff2007-08-07 01:37:15 +0000752 "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindolab15597b2006-05-18 21:45:49 +0000753
Evan Cheng47b546d2008-11-06 08:47:38 +0000754def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000755 (ins GPR:$base, am2offset:$offset), LdFrm,
Evan Chengf7c6eff2007-08-07 01:37:15 +0000756 "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
Rafael Espindola1bbe5812006-12-12 00:37:38 +0000757
Evan Cheng47b546d2008-11-06 08:47:38 +0000758def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000759 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000760 "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindola4443c7d2006-09-08 16:59:47 +0000761
Evan Cheng47b546d2008-11-06 08:47:38 +0000762def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000763 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000764 "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
Lauro Ramos Venancio7251e572006-12-28 13:11:14 +0000765
Evan Cheng47b546d2008-11-06 08:47:38 +0000766def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000767 (ins addrmode2:$addr), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000768 "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
Lauro Ramos Venancio7251e572006-12-28 13:11:14 +0000769
Evan Cheng47b546d2008-11-06 08:47:38 +0000770def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000771 (ins GPR:$base,am2offset:$offset), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000772 "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000773
Evan Cheng47b546d2008-11-06 08:47:38 +0000774def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000775 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000776 "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000777
Evan Cheng47b546d2008-11-06 08:47:38 +0000778def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000779 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
780 "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000781
Evan Cheng47b546d2008-11-06 08:47:38 +0000782def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000783 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000784 "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000785
Evan Cheng47b546d2008-11-06 08:47:38 +0000786def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000787 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Cheng979da0e2009-07-02 01:30:04 +0000788 "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
Chris Lattner94de7bc2008-01-10 05:12:37 +0000789}
Evan Cheng10043e22007-01-19 07:51:42 +0000790
791// Store
Evan Cheng2666f592008-11-13 07:34:59 +0000792def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000793 "str", " $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000794 [(store GPR:$src, addrmode2:$addr)]>;
795
796// Stores with truncate
Evan Cheng2666f592008-11-13 07:34:59 +0000797def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000798 "str", "h $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000799 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
800
Evan Cheng2666f592008-11-13 07:34:59 +0000801def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000802 "str", "b $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000803 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
804
805// Store doubleword
Chris Lattner10324d02008-01-06 08:36:04 +0000806let mayStore = 1 in
Evan Cheng1283c6a2009-06-15 08:28:29 +0000807def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),StMiscFrm,
808 "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5T]>;
Evan Cheng10043e22007-01-19 07:51:42 +0000809
810// Indexed stores
Evan Cheng47b546d2008-11-06 08:47:38 +0000811def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000812 (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000813 "str", " $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000814 [(set GPR:$base_wb,
815 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
816
Evan Cheng47b546d2008-11-06 08:47:38 +0000817def STR_POST : AI2stwpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000818 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000819 "str", " $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000820 [(set GPR:$base_wb,
821 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
822
Evan Cheng47b546d2008-11-06 08:47:38 +0000823def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000824 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000825 "str", "h $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000826 [(set GPR:$base_wb,
827 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
828
Evan Cheng47b546d2008-11-06 08:47:38 +0000829def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000830 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000831 "str", "h $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000832 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
833 GPR:$base, am3offset:$offset))]>;
834
Evan Cheng47b546d2008-11-06 08:47:38 +0000835def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000836 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000837 "str", "b $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000838 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
839 GPR:$base, am2offset:$offset))]>;
840
Evan Cheng47b546d2008-11-06 08:47:38 +0000841def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000842 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000843 "str", "b $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000844 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
845 GPR:$base, am2offset:$offset))]>;
Evan Cheng10043e22007-01-19 07:51:42 +0000846
847//===----------------------------------------------------------------------===//
848// Load / store multiple Instructions.
849//
850
Evan Cheng94b5a802007-07-19 01:14:50 +0000851// FIXME: $dst1 should be a def.
Chris Lattner94de7bc2008-01-10 05:12:37 +0000852let mayLoad = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000853def LDM : AXI4ld<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000854 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000855 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000856 []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000857
Chris Lattner10324d02008-01-06 08:36:04 +0000858let mayStore = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000859def STM : AXI4st<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000860 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000861 LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000862 []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000863
864//===----------------------------------------------------------------------===//
865// Move Instructions.
866//
867
Evan Chengd93b5b62009-06-12 20:46:18 +0000868let neverHasSideEffects = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +0000869def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
870 "mov", " $dst, $src", []>, UnaryDP;
871def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
872 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
Evan Cheng5be3e092007-03-19 07:09:02 +0000873
Evan Cheng64fdacc2009-02-05 08:42:55 +0000874let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +0000875def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm,
876 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP;
Evan Cheng9d41b312007-07-10 18:08:01 +0000877
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000878def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Cheng94b5a802007-07-19 01:14:50 +0000879 "mov", " $dst, $src, rrx",
Evan Cheng81889d012008-11-05 18:35:52 +0000880 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
Evan Cheng10043e22007-01-19 07:51:42 +0000881
882// These aren't really mov instructions, but we have to define them this way
883// due to flag operands.
884
Evan Cheng3e18e502007-09-11 19:55:27 +0000885let Defs = [CPSR] in {
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000886def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000887 "mov", "s $dst, $src, lsr #1",
Evan Cheng81889d012008-11-05 18:35:52 +0000888 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000889def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000890 "mov", "s $dst, $src, asr #1",
Evan Cheng81889d012008-11-05 18:35:52 +0000891 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
Evan Cheng3e18e502007-09-11 19:55:27 +0000892}
Evan Cheng10043e22007-01-19 07:51:42 +0000893
Evan Cheng10043e22007-01-19 07:51:42 +0000894//===----------------------------------------------------------------------===//
895// Extend Instructions.
896//
897
898// Sign extenders
899
Evan Cheng49d66522008-11-06 22:15:19 +0000900defm SXTB : AI_unary_rrot<0b01101010,
901 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
902defm SXTH : AI_unary_rrot<0b01101011,
903 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000904
Evan Cheng49d66522008-11-06 22:15:19 +0000905defm SXTAB : AI_bin_rrot<0b01101010,
906 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
907defm SXTAH : AI_bin_rrot<0b01101011,
908 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000909
910// TODO: SXT(A){B|H}16
911
912// Zero extenders
913
914let AddedComplexity = 16 in {
Evan Cheng49d66522008-11-06 22:15:19 +0000915defm UXTB : AI_unary_rrot<0b01101110,
916 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
917defm UXTH : AI_unary_rrot<0b01101111,
918 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
919defm UXTB16 : AI_unary_rrot<0b01101100,
920 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000921
Bob Wilsone67b7702009-06-22 22:08:29 +0000922def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Cheng10043e22007-01-19 07:51:42 +0000923 (UXTB16r_rot GPR:$Src, 24)>;
Bob Wilsone67b7702009-06-22 22:08:29 +0000924def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Cheng10043e22007-01-19 07:51:42 +0000925 (UXTB16r_rot GPR:$Src, 8)>;
926
Evan Cheng49d66522008-11-06 22:15:19 +0000927defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
Evan Cheng10043e22007-01-19 07:51:42 +0000928 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
Evan Cheng49d66522008-11-06 22:15:19 +0000929defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
Evan Cheng10043e22007-01-19 07:51:42 +0000930 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
Rafael Espindolad0dee772006-08-21 22:00:32 +0000931}
932
Evan Cheng10043e22007-01-19 07:51:42 +0000933// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
934//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
Rafael Espindolac7829d62006-09-11 19:24:19 +0000935
Evan Cheng10043e22007-01-19 07:51:42 +0000936// TODO: UXT(A){B|H}16
937
938//===----------------------------------------------------------------------===//
939// Arithmetic Instructions.
940//
941
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000942defm ADD : AsI1_bin_irs<0b0100, "add",
Evan Cheng5bf90112009-06-26 00:19:44 +0000943 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000944defm SUB : AsI1_bin_irs<0b0010, "sub",
Evan Cheng7848cfc2008-09-17 07:53:38 +0000945 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000946
Evan Chengaa3b8012007-07-05 07:13:32 +0000947// ADD and SUB with 's' bit set.
Evan Chengc7ea8df2009-06-25 20:59:23 +0000948defm ADDS : AI1_bin_s_irs<0b0100, "add",
949 BinOpFrag<(addc node:$LHS, node:$RHS)>>;
950defm SUBS : AI1_bin_s_irs<0b0010, "sub",
951 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Chenge8c3cbf2007-06-06 10:17:05 +0000952
Evan Cheng97727a62009-06-25 23:34:10 +0000953defm ADC : AI1_adde_sube_irs<0b0101, "adc",
Evan Cheng5bf90112009-06-26 00:19:44 +0000954 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
Evan Cheng97727a62009-06-25 23:34:10 +0000955defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
956 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000957
Evan Chengaa3b8012007-07-05 07:13:32 +0000958// These don't define reg/reg forms, because they are handled above.
Evan Cheng81889d012008-11-05 18:35:52 +0000959def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng9d41b312007-07-10 18:08:01 +0000960 "rsb", " $dst, $a, $b",
961 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
962
Evan Cheng81889d012008-11-05 18:35:52 +0000963def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng9d41b312007-07-10 18:08:01 +0000964 "rsb", " $dst, $a, $b",
965 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
Evan Chengaa3b8012007-07-05 07:13:32 +0000966
967// RSB with 's' bit set.
Evan Cheng3e18e502007-09-11 19:55:27 +0000968let Defs = [CPSR] in {
Evan Cheng81889d012008-11-05 18:35:52 +0000969def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000970 "rsb", "s $dst, $a, $b",
Evan Cheng3e18e502007-09-11 19:55:27 +0000971 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
Evan Cheng81889d012008-11-05 18:35:52 +0000972def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000973 "rsb", "s $dst, $a, $b",
Evan Cheng3e18e502007-09-11 19:55:27 +0000974 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
975}
Evan Chengaa3b8012007-07-05 07:13:32 +0000976
Evan Cheng97727a62009-06-25 23:34:10 +0000977let Uses = [CPSR] in {
978def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
979 DPFrm, "rsc", " $dst, $a, $b",
980 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
981 Requires<[IsARM, CarryDefIsUnused]>;
982def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
983 DPSoRegFrm, "rsc", " $dst, $a, $b",
984 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
985 Requires<[IsARM, CarryDefIsUnused]>;
986}
987
988// FIXME: Allow these to be predicated.
Evan Chengc7ea8df2009-06-25 20:59:23 +0000989let Defs = [CPSR], Uses = [CPSR] in {
990def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
991 DPFrm, "rscs $dst, $a, $b",
Evan Cheng97727a62009-06-25 23:34:10 +0000992 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
993 Requires<[IsARM, CarryDefIsUnused]>;
Evan Chengc7ea8df2009-06-25 20:59:23 +0000994def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
995 DPSoRegFrm, "rscs $dst, $a, $b",
Evan Cheng97727a62009-06-25 23:34:10 +0000996 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
997 Requires<[IsARM, CarryDefIsUnused]>;
Evan Cheng3e18e502007-09-11 19:55:27 +0000998}
Evan Chenge8c3cbf2007-06-06 10:17:05 +0000999
Evan Cheng10043e22007-01-19 07:51:42 +00001000// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1001def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1002 (SUBri GPR:$src, so_imm_neg:$imm)>;
1003
1004//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1005// (SUBSri GPR:$src, so_imm_neg:$imm)>;
1006//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1007// (SBCri GPR:$src, so_imm_neg:$imm)>;
1008
1009// Note: These are implemented in C++ code, because they have to generate
1010// ADD/SUBrs instructions, which use a complex pattern that a xform function
1011// cannot produce.
1012// (mul X, 2^n+1) -> (add (X << n), X)
1013// (mul X, 2^n-1) -> (rsb X, (X << n))
1014
1015
1016//===----------------------------------------------------------------------===//
1017// Bitwise Instructions.
1018//
1019
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001020defm AND : AsI1_bin_irs<0b0000, "and",
Evan Cheng5bf90112009-06-26 00:19:44 +00001021 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001022defm ORR : AsI1_bin_irs<0b1100, "orr",
Evan Cheng5bf90112009-06-26 00:19:44 +00001023 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001024defm EOR : AsI1_bin_irs<0b0001, "eor",
Evan Cheng5bf90112009-06-26 00:19:44 +00001025 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001026defm BIC : AsI1_bin_irs<0b1110, "bic",
Evan Cheng7848cfc2008-09-17 07:53:38 +00001027 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Cheng10043e22007-01-19 07:51:42 +00001028
Evan Cheng40398232009-07-06 22:23:46 +00001029def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1030 AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
1031 "bfc", " $dst, $imm", "$src = $dst",
1032 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1033 Requires<[IsARM, HasV6T2]> {
1034 let Inst{27-21} = 0b0111110;
1035 let Inst{6-0} = 0b0011111;
1036}
1037
Evan Cheng81889d012008-11-05 18:35:52 +00001038def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
1039 "mvn", " $dst, $src",
1040 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
1041def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1042 "mvn", " $dst, $src",
1043 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
Evan Cheng64fdacc2009-02-05 08:42:55 +00001044let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +00001045def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1046 "mvn", " $dst, $imm",
1047 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP;
Evan Cheng10043e22007-01-19 07:51:42 +00001048
1049def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1050 (BICri GPR:$src, so_imm_not:$imm)>;
1051
1052//===----------------------------------------------------------------------===//
1053// Multiply Instructions.
1054//
1055
Evan Cheng5bf90112009-06-26 00:19:44 +00001056let isCommutable = 1 in
Evan Cheng2686c8f2008-11-06 01:21:28 +00001057def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengaa03cd32008-11-06 17:48:05 +00001058 "mul", " $dst, $a, $b",
1059 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
Evan Cheng10043e22007-01-19 07:51:42 +00001060
Evan Cheng2686c8f2008-11-06 01:21:28 +00001061def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Chengaa03cd32008-11-06 17:48:05 +00001062 "mla", " $dst, $a, $b, $c",
1063 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
Evan Cheng10043e22007-01-19 07:51:42 +00001064
Evan Chenge63b0e62009-07-06 22:05:45 +00001065def MLS : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1066 "mls", " $dst, $a, $b, $c",
1067 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1068 Requires<[IsARM, HasV6T2]>;
1069
Evan Cheng10043e22007-01-19 07:51:42 +00001070// Extra precision multiplies with low / high results
Evan Chengd93b5b62009-06-12 20:46:18 +00001071let neverHasSideEffects = 1 in {
Evan Cheng5bf90112009-06-26 00:19:44 +00001072let isCommutable = 1 in {
Evan Cheng2686c8f2008-11-06 01:21:28 +00001073def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1074 (ins GPR:$a, GPR:$b),
1075 "smull", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001076
Evan Cheng2686c8f2008-11-06 01:21:28 +00001077def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1078 (ins GPR:$a, GPR:$b),
1079 "umull", " $ldst, $hdst, $a, $b", []>;
Evan Cheng5bf90112009-06-26 00:19:44 +00001080}
Evan Cheng10043e22007-01-19 07:51:42 +00001081
1082// Multiply + accumulate
Evan Cheng2686c8f2008-11-06 01:21:28 +00001083def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1084 (ins GPR:$a, GPR:$b),
1085 "smlal", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001086
Evan Cheng2686c8f2008-11-06 01:21:28 +00001087def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1088 (ins GPR:$a, GPR:$b),
1089 "umlal", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001090
Evan Cheng2686c8f2008-11-06 01:21:28 +00001091def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1092 (ins GPR:$a, GPR:$b),
1093 "umaal", " $ldst, $hdst, $a, $b", []>,
1094 Requires<[IsARM, HasV6]>;
Evan Chengd93b5b62009-06-12 20:46:18 +00001095} // neverHasSideEffects
Evan Cheng10043e22007-01-19 07:51:42 +00001096
1097// Most significant word multiply
Evan Cheng2686c8f2008-11-06 01:21:28 +00001098def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng9d41b312007-07-10 18:08:01 +00001099 "smmul", " $dst, $a, $b",
1100 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001101 Requires<[IsARM, HasV6]> {
1102 let Inst{7-4} = 0b0001;
1103 let Inst{15-12} = 0b1111;
1104}
Evan Cheng9d41b312007-07-10 18:08:01 +00001105
Evan Cheng2686c8f2008-11-06 01:21:28 +00001106def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng9d41b312007-07-10 18:08:01 +00001107 "smmla", " $dst, $a, $b, $c",
1108 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001109 Requires<[IsARM, HasV6]> {
1110 let Inst{7-4} = 0b0001;
1111}
Evan Cheng10043e22007-01-19 07:51:42 +00001112
1113
Evan Cheng2686c8f2008-11-06 01:21:28 +00001114def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001115 "smmls", " $dst, $a, $b, $c",
Evan Cheng10043e22007-01-19 07:51:42 +00001116 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001117 Requires<[IsARM, HasV6]> {
1118 let Inst{7-4} = 0b1101;
1119}
Evan Cheng10043e22007-01-19 07:51:42 +00001120
Raul Herbster73489272007-08-30 23:25:47 +00001121multiclass AI_smul<string opc, PatFrag opnode> {
Evan Cheng36ae4032008-11-06 03:35:07 +00001122 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001123 !strconcat(opc, "bb"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001124 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1125 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001126 Requires<[IsARM, HasV5TE]> {
1127 let Inst{5} = 0;
1128 let Inst{6} = 0;
1129 }
Raul Herbster73489272007-08-30 23:25:47 +00001130
Evan Cheng36ae4032008-11-06 03:35:07 +00001131 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001132 !strconcat(opc, "bt"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001133 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
Bob Wilsone67b7702009-06-22 22:08:29 +00001134 (sra GPR:$b, (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001135 Requires<[IsARM, HasV5TE]> {
1136 let Inst{5} = 0;
1137 let Inst{6} = 1;
1138 }
Raul Herbster73489272007-08-30 23:25:47 +00001139
Evan Cheng36ae4032008-11-06 03:35:07 +00001140 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001141 !strconcat(opc, "tb"), " $dst, $a, $b",
Bob Wilsone67b7702009-06-22 22:08:29 +00001142 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001143 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001144 Requires<[IsARM, HasV5TE]> {
1145 let Inst{5} = 1;
1146 let Inst{6} = 0;
1147 }
Raul Herbster73489272007-08-30 23:25:47 +00001148
Evan Cheng36ae4032008-11-06 03:35:07 +00001149 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001150 !strconcat(opc, "tt"), " $dst, $a, $b",
Bob Wilsone67b7702009-06-22 22:08:29 +00001151 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1152 (sra GPR:$b, (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001153 Requires<[IsARM, HasV5TE]> {
1154 let Inst{5} = 1;
1155 let Inst{6} = 1;
1156 }
Raul Herbster73489272007-08-30 23:25:47 +00001157
Evan Cheng36ae4032008-11-06 03:35:07 +00001158 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001159 !strconcat(opc, "wb"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001160 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001161 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001162 Requires<[IsARM, HasV5TE]> {
1163 let Inst{5} = 1;
1164 let Inst{6} = 0;
1165 }
Raul Herbster73489272007-08-30 23:25:47 +00001166
Evan Cheng36ae4032008-11-06 03:35:07 +00001167 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001168 !strconcat(opc, "wt"), " $dst, $a, $b",
Evan Cheng10043e22007-01-19 07:51:42 +00001169 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001170 (sra GPR:$b, (i32 16))), (i32 16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001171 Requires<[IsARM, HasV5TE]> {
1172 let Inst{5} = 1;
1173 let Inst{6} = 1;
1174 }
Rafael Espindola595dc4c2006-10-16 16:33:29 +00001175}
1176
Raul Herbster73489272007-08-30 23:25:47 +00001177
1178multiclass AI_smla<string opc, PatFrag opnode> {
Evan Cheng36ae4032008-11-06 03:35:07 +00001179 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001180 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001181 [(set GPR:$dst, (add GPR:$acc,
1182 (opnode (sext_inreg GPR:$a, i16),
1183 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001184 Requires<[IsARM, HasV5TE]> {
1185 let Inst{5} = 0;
1186 let Inst{6} = 0;
1187 }
Raul Herbster73489272007-08-30 23:25:47 +00001188
Evan Cheng36ae4032008-11-06 03:35:07 +00001189 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001190 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001191 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Bob Wilsone67b7702009-06-22 22:08:29 +00001192 (sra GPR:$b, (i32 16)))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001193 Requires<[IsARM, HasV5TE]> {
1194 let Inst{5} = 0;
1195 let Inst{6} = 1;
1196 }
Raul Herbster73489272007-08-30 23:25:47 +00001197
Evan Cheng36ae4032008-11-06 03:35:07 +00001198 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001199 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
Bob Wilsone67b7702009-06-22 22:08:29 +00001200 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001201 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001202 Requires<[IsARM, HasV5TE]> {
1203 let Inst{5} = 1;
1204 let Inst{6} = 0;
1205 }
Raul Herbster73489272007-08-30 23:25:47 +00001206
Evan Cheng36ae4032008-11-06 03:35:07 +00001207 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001208 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
Bob Wilsone67b7702009-06-22 22:08:29 +00001209 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1210 (sra GPR:$b, (i32 16)))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001211 Requires<[IsARM, HasV5TE]> {
1212 let Inst{5} = 1;
1213 let Inst{6} = 1;
1214 }
Evan Cheng10043e22007-01-19 07:51:42 +00001215
Evan Cheng36ae4032008-11-06 03:35:07 +00001216 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001217 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001218 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001219 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001220 Requires<[IsARM, HasV5TE]> {
1221 let Inst{5} = 0;
1222 let Inst{6} = 0;
1223 }
Raul Herbster73489272007-08-30 23:25:47 +00001224
Evan Cheng36ae4032008-11-06 03:35:07 +00001225 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001226 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
Evan Cheng10043e22007-01-19 07:51:42 +00001227 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001228 (sra GPR:$b, (i32 16))), (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001229 Requires<[IsARM, HasV5TE]> {
1230 let Inst{5} = 0;
1231 let Inst{6} = 1;
1232 }
Rafael Espindola01dd97a2006-10-18 16:20:57 +00001233}
Rafael Espindola778769a2006-09-08 12:47:03 +00001234
Raul Herbster73489272007-08-30 23:25:47 +00001235defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1236defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
Rafael Espindola53f78be2006-09-29 21:20:16 +00001237
Evan Cheng10043e22007-01-19 07:51:42 +00001238// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1239// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
Rafael Espindola3874a162006-10-13 13:14:59 +00001240
Evan Cheng10043e22007-01-19 07:51:42 +00001241//===----------------------------------------------------------------------===//
1242// Misc. Arithmetic Instructions.
1243//
Rafael Espindolad1a4ea42006-10-10 16:33:47 +00001244
Evan Cheng98dc53e2008-11-07 01:41:35 +00001245def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001246 "clz", " $dst, $src",
Evan Cheng98dc53e2008-11-07 01:41:35 +00001247 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1248 let Inst{7-4} = 0b0001;
1249 let Inst{11-8} = 0b1111;
1250 let Inst{19-16} = 0b1111;
1251}
Rafael Espindolac31ee942006-10-17 13:13:23 +00001252
Evan Cheng98dc53e2008-11-07 01:41:35 +00001253def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001254 "rev", " $dst, $src",
Evan Cheng98dc53e2008-11-07 01:41:35 +00001255 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1256 let Inst{7-4} = 0b0011;
1257 let Inst{11-8} = 0b1111;
1258 let Inst{19-16} = 0b1111;
1259}
Rafael Espindolac31ee942006-10-17 13:13:23 +00001260
Evan Cheng98dc53e2008-11-07 01:41:35 +00001261def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001262 "rev16", " $dst, $src",
Evan Cheng10043e22007-01-19 07:51:42 +00001263 [(set GPR:$dst,
Bob Wilsone67b7702009-06-22 22:08:29 +00001264 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1265 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1266 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1267 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001268 Requires<[IsARM, HasV6]> {
1269 let Inst{7-4} = 0b1011;
1270 let Inst{11-8} = 0b1111;
1271 let Inst{19-16} = 0b1111;
1272}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001273
Evan Cheng98dc53e2008-11-07 01:41:35 +00001274def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001275 "revsh", " $dst, $src",
Evan Cheng10043e22007-01-19 07:51:42 +00001276 [(set GPR:$dst,
1277 (sext_inreg
Bob Wilsone67b7702009-06-22 22:08:29 +00001278 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1279 (shl GPR:$src, (i32 8))), i16))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001280 Requires<[IsARM, HasV6]> {
1281 let Inst{7-4} = 0b1011;
1282 let Inst{11-8} = 0b1111;
1283 let Inst{19-16} = 0b1111;
1284}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001285
Evan Cheng98dc53e2008-11-07 01:41:35 +00001286def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1287 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1288 "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Cheng10043e22007-01-19 07:51:42 +00001289 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1290 (and (shl GPR:$src2, (i32 imm:$shamt)),
1291 0xFFFF0000)))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001292 Requires<[IsARM, HasV6]> {
1293 let Inst{6-4} = 0b001;
1294}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001295
Evan Cheng10043e22007-01-19 07:51:42 +00001296// Alternate cases for PKHBT where identities eliminate some nodes.
1297def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1298 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1299def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1300 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
Rafael Espindolad55c0a42006-10-02 19:30:56 +00001301
Rafael Espindolae04df412006-10-05 16:48:49 +00001302
Evan Cheng98dc53e2008-11-07 01:41:35 +00001303def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1304 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1305 "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Cheng10043e22007-01-19 07:51:42 +00001306 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1307 (and (sra GPR:$src2, imm16_31:$shamt),
Evan Cheng98dc53e2008-11-07 01:41:35 +00001308 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1309 let Inst{6-4} = 0b101;
1310}
Rafael Espindolad55c0a42006-10-02 19:30:56 +00001311
Evan Cheng10043e22007-01-19 07:51:42 +00001312// Alternate cases for PKHTB where identities eliminate some nodes. Note that
1313// a shift amount of 0 is *not legal* here, it is PKHBT instead.
Bob Wilsone67b7702009-06-22 22:08:29 +00001314def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
Evan Cheng10043e22007-01-19 07:51:42 +00001315 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1316def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1317 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1318 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Rafael Espindola57d109f2006-10-10 18:55:14 +00001319
Evan Cheng10043e22007-01-19 07:51:42 +00001320//===----------------------------------------------------------------------===//
1321// Comparison Instructions...
1322//
Rafael Espindola57d109f2006-10-10 18:55:14 +00001323
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001324defm CMP : AI1_cmp_irs<0b1010, "cmp",
Evan Chengf7c6eff2007-08-07 01:37:15 +00001325 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001326defm CMN : AI1_cmp_irs<0b1011, "cmn",
Evan Chengf7c6eff2007-08-07 01:37:15 +00001327 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
Rafael Espindolab5093882006-10-07 14:24:52 +00001328
Evan Cheng10043e22007-01-19 07:51:42 +00001329// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Cheng47b546d2008-11-06 08:47:38 +00001330defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwindbf11ba2009-06-29 15:33:01 +00001331 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Cheng47b546d2008-11-06 08:47:38 +00001332defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwindbf11ba2009-06-29 15:33:01 +00001333 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001334
David Goodwindbf11ba2009-06-29 15:33:01 +00001335defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1336 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1337defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1338 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chenge8c3cbf2007-06-06 10:17:05 +00001339
1340def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1341 (CMNri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001342
David Goodwindbf11ba2009-06-29 15:33:01 +00001343def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001344 (CMNri GPR:$src, so_imm_neg:$imm)>;
1345
Rafael Espindolab5093882006-10-07 14:24:52 +00001346
Evan Cheng10043e22007-01-19 07:51:42 +00001347// Conditional moves
Evan Chengaa3b8012007-07-05 07:13:32 +00001348// FIXME: should be able to write a pattern for ARMcmov, but can't use
1349// a two-value operand where a dag node expects two operands. :(
Evan Cheng47b546d2008-11-06 08:47:38 +00001350def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001351 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001352 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng47b546d2008-11-06 08:47:38 +00001353 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola8429e1f2006-10-10 20:38:57 +00001354
Evan Cheng47b546d2008-11-06 08:47:38 +00001355def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1356 (ins GPR:$false, so_reg:$true), DPSoRegFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001357 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001358 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng81889d012008-11-05 18:35:52 +00001359 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola9e29ec32006-10-09 17:50:29 +00001360
Evan Cheng47b546d2008-11-06 08:47:38 +00001361def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1362 (ins GPR:$false, so_imm:$true), DPFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001363 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001364 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng81889d012008-11-05 18:35:52 +00001365 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola40f5dd22006-10-07 13:46:42 +00001366
Rafael Espindolad15c8922006-10-10 12:56:00 +00001367
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +00001368//===----------------------------------------------------------------------===//
1369// TLS Instructions
1370//
1371
1372// __aeabi_read_tp preserves the registers r1-r3.
Evan Cheng9d41b312007-07-10 18:08:01 +00001373let isCall = 1,
1374 Defs = [R0, R12, LR, CPSR] in {
Evan Chengaa03cd32008-11-06 17:48:05 +00001375 def TPsoft : ABXI<0b1011, (outs), (ins),
Evan Cheng4ae18402007-05-18 01:53:54 +00001376 "bl __aeabi_read_tp",
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +00001377 [(set R0, ARMthread_pointer)]>;
1378}
Rafael Espindola99bf1332006-10-17 20:33:13 +00001379
Evan Cheng10043e22007-01-19 07:51:42 +00001380//===----------------------------------------------------------------------===//
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001381// SJLJ Exception handling intrinsics
Jim Grosbach06928192009-05-14 00:46:35 +00001382// eh_sjlj_setjmp() is a three instruction sequence to store the return
1383// address and save #0 in R0 for the non-longjmp case.
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001384// Since by its nature we may be coming from some other function to get
1385// here, and we're using the stack frame for the containing function to
1386// save/restore registers, we can't keep anything live in regs across
Jim Grosbach06928192009-05-14 00:46:35 +00001387// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001388// when we get here from a longjmp(). We force everthing out of registers
Jim Grosbach06928192009-05-14 00:46:35 +00001389// except for our own input by listing the relevant registers in Defs. By
1390// doing so, we also cause the prologue/epilogue code to actively preserve
1391// all of the callee-saved resgisters, which is exactly what we want.
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001392let Defs =
Evan Cheng4b02b2f2009-07-22 06:46:53 +00001393 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1394 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1395 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D31,
1396 D31 ] in {
Jim Grosbach06928192009-05-14 00:46:35 +00001397 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001398 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
1399 "add r0, pc, #4\n\t"
1400 "str r0, [$src, #+4]\n\t"
Jim Grosbach06928192009-05-14 00:46:35 +00001401 "mov r0, #0 @ eh_setjmp", "",
1402 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001403}
1404
1405//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +00001406// Non-Instruction Patterns
1407//
Rafael Espindola58c368b2006-10-07 14:03:39 +00001408
Evan Cheng10043e22007-01-19 07:51:42 +00001409// ConstantPool, GlobalAddress, and JumpTable
1410def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
1411def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1412def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
Evan Cheng9e7b8382007-03-20 08:11:30 +00001413 (LEApcrelJT tjumptable:$dst, imm:$id)>;
Rafael Espindola58c368b2006-10-07 14:03:39 +00001414
Evan Cheng10043e22007-01-19 07:51:42 +00001415// Large immediate handling.
Rafael Espindolaf719c5f2006-10-16 21:10:32 +00001416
Evan Cheng10043e22007-01-19 07:51:42 +00001417// Two piece so_imms.
Dan Gohmane8c1e422007-06-26 00:48:07 +00001418let isReMaterializable = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +00001419def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001420 "mov", " $dst, $src",
Evan Chengb870fd82008-11-06 02:25:39 +00001421 [(set GPR:$dst, so_imm2part:$src)]>;
Rafael Espindola418c8e62006-10-17 13:36:07 +00001422
Evan Cheng10043e22007-01-19 07:51:42 +00001423def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
Evan Chenge3a53c42009-07-08 21:03:57 +00001424 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1425 (so_imm2part_2 imm:$RHS))>;
Evan Cheng10043e22007-01-19 07:51:42 +00001426def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
Evan Chenge3a53c42009-07-08 21:03:57 +00001427 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1428 (so_imm2part_2 imm:$RHS))>;
Rafael Espindola418c8e62006-10-17 13:36:07 +00001429
Evan Cheng10043e22007-01-19 07:51:42 +00001430// TODO: add,sub,and, 3-instr forms?
Rafael Espindolaf719c5f2006-10-16 21:10:32 +00001431
Rafael Espindola336d62e2006-10-19 17:05:03 +00001432
Evan Cheng10043e22007-01-19 07:51:42 +00001433// Direct calls
Bob Wilson45825302009-06-22 21:01:46 +00001434def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1435 Requires<[IsNotDarwin]>;
1436def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1437 Requires<[IsDarwin]>;
Rafael Espindola0cd8d142006-11-01 14:13:27 +00001438
Evan Cheng10043e22007-01-19 07:51:42 +00001439// zextload i1 -> zextload i8
1440def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
Lauro Ramos Venanciod0ced3f2006-12-26 19:30:42 +00001441
Evan Cheng10043e22007-01-19 07:51:42 +00001442// extload -> zextload
1443def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1444def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1445def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
Rafael Espindola0cd8d142006-11-01 14:13:27 +00001446
Evan Chengfd2adbf2008-11-05 23:22:34 +00001447def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1448def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1449
Evan Cheng77c15de2007-01-19 20:27:35 +00001450// smul* and smla*
Bob Wilsone67b7702009-06-22 22:08:29 +00001451def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1452 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001453 (SMULBB GPR:$a, GPR:$b)>;
1454def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1455 (SMULBB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001456def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1457 (sra GPR:$b, (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001458 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001459def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001460 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001461def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1462 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001463 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001464def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
Evan Cheng77c15de2007-01-19 20:27:35 +00001465 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001466def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1467 (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001468 (SMULWB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001469def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001470 (SMULWB GPR:$a, GPR:$b)>;
1471
1472def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001473 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1474 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001475 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1476def : ARMV5TEPat<(add GPR:$acc,
1477 (mul sext_16_node:$a, sext_16_node:$b)),
1478 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1479def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001480 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1481 (sra GPR:$b, (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001482 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1483def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001484 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001485 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1486def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001487 (mul (sra GPR:$a, (i32 16)),
1488 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001489 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1490def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001491 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001492 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1493def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001494 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1495 (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001496 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1497def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001498 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001499 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1500
Evan Cheng10043e22007-01-19 07:51:42 +00001501//===----------------------------------------------------------------------===//
1502// Thumb Support
1503//
1504
1505include "ARMInstrThumb.td"
1506
1507//===----------------------------------------------------------------------===//
Anton Korobeynikov02bb33c2009-06-17 18:13:58 +00001508// Thumb2 Support
1509//
1510
1511include "ARMInstrThumb2.td"
1512
1513//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +00001514// Floating Point Support
1515//
1516
1517include "ARMInstrVFP.td"
Bob Wilson2e076c42009-06-22 23:27:02 +00001518
1519//===----------------------------------------------------------------------===//
1520// Advanced SIMD (NEON) Support
1521//
1522
1523include "ARMInstrNEON.td"