blob: b4fb8a77d8644f0b2fa229c66247caa5c018d4bb [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>]>;
Evan Chengf3a1fce2009-07-25 00:33:29 +000036def SDT_ARMBr2JT : SDTypeProfile<0, 4,
37 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
38 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
Evan Cheng10043e22007-01-19 07:51:42 +000039
40def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
41
42def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
43 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
44
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000045def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
Jim Grosbach06928192009-05-14 00:46:35 +000046def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000047
Evan Cheng10043e22007-01-19 07:51:42 +000048// Node definitions.
49def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
Evan Cheng10043e22007-01-19 07:51:42 +000050def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
51
Bill Wendling77b13af2007-11-13 09:19:02 +000052def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
Bill Wendling97925ec2008-02-27 06:33:05 +000053 [SDNPHasChain, SDNPOutFlag]>;
Bill Wendling77b13af2007-11-13 09:19:02 +000054def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
Bill Wendling97925ec2008-02-27 06:33:05 +000055 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Cheng10043e22007-01-19 07:51:42 +000056
57def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
58 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Chengc3c949b42007-06-19 21:05:09 +000059def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
60 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Evan Cheng10043e22007-01-19 07:51:42 +000061def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
62 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
63
Chris Lattner9a249b02008-01-15 22:02:54 +000064def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
Evan Cheng10043e22007-01-19 07:51:42 +000065 [SDNPHasChain, SDNPOptInFlag]>;
66
67def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
68 [SDNPInFlag]>;
69def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
70 [SDNPInFlag]>;
71
72def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
73 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
74
75def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
76 [SDNPHasChain]>;
77
Evan Chengf3a1fce2009-07-25 00:33:29 +000078def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
79 [SDNPHasChain]>;
80
Evan Cheng10043e22007-01-19 07:51:42 +000081def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
82 [SDNPOutFlag]>;
83
David Goodwindbf11ba2009-06-29 15:33:01 +000084def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
85 [SDNPOutFlag,SDNPCommutative]>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +000086
Evan Cheng10043e22007-01-19 07:51:42 +000087def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
88
89def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
90def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
91def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
Rafael Espindola19398ec2006-10-17 18:04:53 +000092
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000093def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
Jim Grosbach06928192009-05-14 00:46:35 +000094def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000095
Rafael Espindolaffdc24b2006-05-14 22:18:28 +000096//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +000097// ARM Instruction Predicate Definitions.
98//
Anton Korobeynikov409105f2009-06-15 21:46:20 +000099def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
100def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
101def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
Evan Chenge63b0e62009-07-06 22:05:45 +0000102def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
Bob Wilson2e076c42009-06-22 23:27:02 +0000103def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
104def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
105def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
106def HasNEON : Predicate<"Subtarget->hasNEON()">;
Anton Korobeynikov409105f2009-06-15 21:46:20 +0000107def IsThumb : Predicate<"Subtarget->isThumb()">;
Evan Cheng431cf562009-06-23 17:48:47 +0000108def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
Evan Cheng2c450d32009-07-02 06:38:40 +0000109def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
Anton Korobeynikov409105f2009-06-15 21:46:20 +0000110def IsARM : Predicate<"!Subtarget->isThumb()">;
Bob Wilson45825302009-06-22 21:01:46 +0000111def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
112def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
Evan Cheng1eda6372009-06-26 06:10:18 +0000113def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng97727a62009-06-25 23:34:10 +0000114def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng10043e22007-01-19 07:51:42 +0000115
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000116//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +0000117// ARM Flag Definitions.
118
119class RegConstraint<string C> {
120 string Constraints = C;
121}
122
123//===----------------------------------------------------------------------===//
124// ARM specific transformation functions and pattern fragments.
125//
126
Evan Cheng10043e22007-01-19 07:51:42 +0000127// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
128// so_imm_neg def below.
129def so_imm_neg_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// so_imm_not_XFORM - Return a so_imm value packed into the format described for
134// so_imm_not def below.
135def so_imm_not_XFORM : SDNodeXForm<imm, [{
Evan Chenge3a53c42009-07-08 21:03:57 +0000136 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
Evan Cheng10043e22007-01-19 07:51:42 +0000137}]>;
138
139// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
140def rot_imm : PatLeaf<(i32 imm), [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000141 int32_t v = (int32_t)N->getZExtValue();
Evan Cheng10043e22007-01-19 07:51:42 +0000142 return v == 8 || v == 16 || v == 24;
143}]>;
144
145/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
146def imm1_15 : PatLeaf<(i32 imm), [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000147 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
Evan Cheng10043e22007-01-19 07:51:42 +0000148}]>;
149
150/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
151def imm16_31 : PatLeaf<(i32 imm), [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000152 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
Evan Cheng10043e22007-01-19 07:51:42 +0000153}]>;
154
155def so_imm_neg :
Dan Gohmaneffb8942008-09-12 16:56:44 +0000156 PatLeaf<(imm), [{
157 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
158 }], so_imm_neg_XFORM>;
Evan Cheng10043e22007-01-19 07:51:42 +0000159
Evan Cheng5be3e092007-03-19 07:09:02 +0000160def so_imm_not :
Dan Gohmaneffb8942008-09-12 16:56:44 +0000161 PatLeaf<(imm), [{
162 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
163 }], so_imm_not_XFORM>;
Evan Cheng10043e22007-01-19 07:51:42 +0000164
165// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
166def sext_16_node : PatLeaf<(i32 GPR:$a), [{
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000167 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
Evan Cheng10043e22007-01-19 07:51:42 +0000168}]>;
169
Evan Cheng40398232009-07-06 22:23:46 +0000170/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
171/// e.g., 0xf000ffff
172def bf_inv_mask_imm : Operand<i32>,
173 PatLeaf<(imm), [{
174 uint32_t v = (uint32_t)N->getZExtValue();
175 if (v == 0xffffffff)
176 return 0;
David Goodwin72b80ac2009-07-14 00:57:56 +0000177 // there can be 1's on either or both "outsides", all the "inside"
178 // bits must be 0's
179 unsigned int lsb = 0, msb = 31;
180 while (v & (1 << msb)) --msb;
181 while (v & (1 << lsb)) ++lsb;
182 for (unsigned int i = lsb; i <= msb; ++i) {
183 if (v & (1 << i))
184 return 0;
185 }
186 return 1;
Evan Cheng40398232009-07-06 22:23:46 +0000187}] > {
188 let PrintMethod = "printBitfieldInvMaskImmOperand";
189}
190
Evan Cheng2d37f192008-08-28 23:39:26 +0000191class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
192class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
Evan Cheng10043e22007-01-19 07:51:42 +0000193
194//===----------------------------------------------------------------------===//
195// Operand Definitions.
196//
197
198// Branch target.
199def brtarget : Operand<OtherVT>;
200
Evan Cheng10043e22007-01-19 07:51:42 +0000201// A list of registers separated by comma. Used by load/store multiple.
202def reglist : Operand<i32> {
203 let PrintMethod = "printRegisterList";
204}
205
206// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
207def cpinst_operand : Operand<i32> {
208 let PrintMethod = "printCPInstOperand";
209}
210
211def jtblock_operand : Operand<i32> {
212 let PrintMethod = "printJTBlockOperand";
213}
Evan Chengf3a1fce2009-07-25 00:33:29 +0000214def jt2block_operand : Operand<i32> {
215 let PrintMethod = "printJT2BlockOperand";
216}
Evan Cheng10043e22007-01-19 07:51:42 +0000217
218// Local PC labels.
219def pclabel : Operand<i32> {
220 let PrintMethod = "printPCLabel";
221}
222
223// shifter_operand operands: so_reg and so_imm.
224def so_reg : Operand<i32>, // reg reg imm
225 ComplexPattern<i32, 3, "SelectShifterOperandReg",
226 [shl,srl,sra,rotr]> {
227 let PrintMethod = "printSORegOperand";
228 let MIOperandInfo = (ops GPR, GPR, i32imm);
229}
230
231// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
232// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
233// represented in the imm field in the same 12-bit form that they are encoded
234// into so_imm instructions: the 8-bit immediate is the least significant bits
235// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
236def so_imm : Operand<i32>,
Evan Chenge3a53c42009-07-08 21:03:57 +0000237 PatLeaf<(imm), [{
238 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
239 }]> {
Evan Cheng10043e22007-01-19 07:51:42 +0000240 let PrintMethod = "printSOImmOperand";
241}
242
Evan Cheng9e7b8382007-03-20 08:11:30 +0000243// Break so_imm's up into two pieces. This handles immediates with up to 16
244// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
245// get the first/second pieces.
246def so_imm2part : Operand<i32>,
Dan Gohmaneffb8942008-09-12 16:56:44 +0000247 PatLeaf<(imm), [{
248 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
249 }]> {
Evan Cheng9e7b8382007-03-20 08:11:30 +0000250 let PrintMethod = "printSOImm2PartOperand";
251}
252
253def so_imm2part_1 : SDNodeXForm<imm, [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000254 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
Evan Chenge3a53c42009-07-08 21:03:57 +0000255 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Cheng9e7b8382007-03-20 08:11:30 +0000256}]>;
257
258def so_imm2part_2 : SDNodeXForm<imm, [{
Dan Gohmaneffb8942008-09-12 16:56:44 +0000259 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
Evan Chenge3a53c42009-07-08 21:03:57 +0000260 return CurDAG->getTargetConstant(V, MVT::i32);
Evan Cheng9e7b8382007-03-20 08:11:30 +0000261}]>;
262
Evan Cheng10043e22007-01-19 07:51:42 +0000263
264// Define ARM specific addressing modes.
265
266// addrmode2 := reg +/- reg shop imm
267// addrmode2 := reg +/- imm12
268//
269def addrmode2 : Operand<i32>,
270 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
271 let PrintMethod = "printAddrMode2Operand";
272 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
273}
274
275def am2offset : Operand<i32>,
276 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
277 let PrintMethod = "printAddrMode2OffsetOperand";
278 let MIOperandInfo = (ops GPR, i32imm);
279}
280
281// addrmode3 := reg +/- reg
282// addrmode3 := reg +/- imm8
283//
284def addrmode3 : Operand<i32>,
285 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
286 let PrintMethod = "printAddrMode3Operand";
287 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
288}
289
290def am3offset : Operand<i32>,
291 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
292 let PrintMethod = "printAddrMode3OffsetOperand";
293 let MIOperandInfo = (ops GPR, i32imm);
294}
295
296// addrmode4 := reg, <mode|W>
297//
298def addrmode4 : Operand<i32>,
299 ComplexPattern<i32, 2, "", []> {
300 let PrintMethod = "printAddrMode4Operand";
301 let MIOperandInfo = (ops GPR, i32imm);
302}
303
304// addrmode5 := reg +/- imm8*4
305//
306def addrmode5 : Operand<i32>,
307 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
308 let PrintMethod = "printAddrMode5Operand";
309 let MIOperandInfo = (ops GPR, i32imm);
310}
311
Bob Wilsondeb35af2009-07-01 23:16:05 +0000312// addrmode6 := reg with optional writeback
313//
314def addrmode6 : Operand<i32>,
315 ComplexPattern<i32, 3, "SelectAddrMode6", []> {
316 let PrintMethod = "printAddrMode6Operand";
317 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm);
318}
319
Evan Cheng10043e22007-01-19 07:51:42 +0000320// addrmodepc := pc + reg
321//
322def addrmodepc : Operand<i32>,
323 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
324 let PrintMethod = "printAddrModePCOperand";
325 let MIOperandInfo = (ops GPR, i32imm);
326}
327
328//===----------------------------------------------------------------------===//
Evan Chengf7c6eff2007-08-07 01:37:15 +0000329
Evan Cheng2d37f192008-08-28 23:39:26 +0000330include "ARMInstrFormats.td"
Evan Chengf7c6eff2007-08-07 01:37:15 +0000331
332//===----------------------------------------------------------------------===//
Evan Cheng2d37f192008-08-28 23:39:26 +0000333// Multiclass helpers...
Evan Cheng10043e22007-01-19 07:51:42 +0000334//
335
Evan Cheng9f717af2008-08-29 07:36:24 +0000336/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
Evan Cheng10043e22007-01-19 07:51:42 +0000337/// binop that produces a value.
Evan Cheng5bf90112009-06-26 00:19:44 +0000338multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
339 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000340 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000341 opc, " $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000342 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
343 let Inst{25} = 1;
344 }
Evan Cheng81889d012008-11-05 18:35:52 +0000345 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000346 opc, " $dst, $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000347 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000348 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000349 let isCommutable = Commutable;
350 }
Evan Cheng81889d012008-11-05 18:35:52 +0000351 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000352 opc, " $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000353 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
354 let Inst{25} = 0;
355 }
Evan Cheng10043e22007-01-19 07:51:42 +0000356}
357
Evan Chengc7ea8df2009-06-25 20:59:23 +0000358/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
Evan Chengaa3b8012007-07-05 07:13:32 +0000359/// instruction modifies the CSPR register.
Evan Cheng3e18e502007-09-11 19:55:27 +0000360let Defs = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000361multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
362 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000363 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000364 opc, "s $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000365 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
366 let Inst{25} = 1;
367 }
Evan Cheng81889d012008-11-05 18:35:52 +0000368 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000369 opc, "s $dst, $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000370 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
371 let isCommutable = Commutable;
Evan Cheng2cff0762009-07-07 23:40:25 +0000372 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000373 }
Evan Cheng81889d012008-11-05 18:35:52 +0000374 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000375 opc, "s $dst, $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000376 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
377 let Inst{25} = 0;
378 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000379}
Evan Chengaa3b8012007-07-05 07:13:32 +0000380}
381
382/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
Evan Cheng9d41b312007-07-10 18:08:01 +0000383/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
Evan Chengaa3b8012007-07-05 07:13:32 +0000384/// a explicit result, only implicitly set CPSR.
Evan Cheng3e18e502007-09-11 19:55:27 +0000385let Defs = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000386multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
387 bit Commutable = 0> {
Evan Cheng81889d012008-11-05 18:35:52 +0000388 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000389 opc, " $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000390 [(opnode GPR:$a, so_imm:$b)]> {
391 let Inst{25} = 1;
392 }
Evan Cheng81889d012008-11-05 18:35:52 +0000393 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000394 opc, " $a, $b",
Evan Cheng5bf90112009-06-26 00:19:44 +0000395 [(opnode GPR:$a, GPR:$b)]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000396 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000397 let isCommutable = Commutable;
398 }
Evan Cheng81889d012008-11-05 18:35:52 +0000399 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000400 opc, " $a, $b",
Evan Cheng2cff0762009-07-07 23:40:25 +0000401 [(opnode GPR:$a, so_reg:$b)]> {
402 let Inst{25} = 0;
403 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000404}
Evan Cheng10043e22007-01-19 07:51:42 +0000405}
406
Evan Cheng10043e22007-01-19 07:51:42 +0000407/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
408/// register and one whose operand is a register rotated by 8/16/24.
Evan Cheng49d66522008-11-06 22:15:19 +0000409/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
410multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
411 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000412 opc, " $dst, $Src",
Evan Cheng49d66522008-11-06 22:15:19 +0000413 [(set GPR:$dst, (opnode GPR:$Src))]>,
414 Requires<[IsARM, HasV6]> {
415 let Inst{19-16} = 0b1111;
416 }
417 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000418 opc, " $dst, $Src, ror $rot",
Evan Cheng10043e22007-01-19 07:51:42 +0000419 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
Evan Cheng49d66522008-11-06 22:15:19 +0000420 Requires<[IsARM, HasV6]> {
421 let Inst{19-16} = 0b1111;
422 }
Evan Cheng10043e22007-01-19 07:51:42 +0000423}
424
425/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
426/// register and one whose operand is a register rotated by 8/16/24.
Evan Cheng49d66522008-11-06 22:15:19 +0000427multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
428 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
429 opc, " $dst, $LHS, $RHS",
Evan Cheng10043e22007-01-19 07:51:42 +0000430 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
431 Requires<[IsARM, HasV6]>;
Evan Cheng49d66522008-11-06 22:15:19 +0000432 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
433 opc, " $dst, $LHS, $RHS, ror $rot",
Evan Cheng10043e22007-01-19 07:51:42 +0000434 [(set GPR:$dst, (opnode GPR:$LHS,
435 (rotr GPR:$RHS, rot_imm:$rot)))]>,
436 Requires<[IsARM, HasV6]>;
437}
438
Evan Cheng97727a62009-06-25 23:34:10 +0000439/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
440let Uses = [CPSR] in {
Evan Cheng5bf90112009-06-26 00:19:44 +0000441multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
442 bit Commutable = 0> {
Evan Cheng97727a62009-06-25 23:34:10 +0000443 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
444 DPFrm, opc, " $dst, $a, $b",
445 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
Evan Cheng2cff0762009-07-07 23:40:25 +0000446 Requires<[IsARM, CarryDefIsUnused]> {
447 let Inst{25} = 1;
448 }
Evan Cheng97727a62009-06-25 23:34:10 +0000449 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
450 DPFrm, opc, " $dst, $a, $b",
451 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
Evan Cheng5bf90112009-06-26 00:19:44 +0000452 Requires<[IsARM, CarryDefIsUnused]> {
453 let isCommutable = Commutable;
Evan Cheng2cff0762009-07-07 23:40:25 +0000454 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000455 }
Evan Cheng97727a62009-06-25 23:34:10 +0000456 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
457 DPSoRegFrm, opc, " $dst, $a, $b",
458 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
Evan Cheng2cff0762009-07-07 23:40:25 +0000459 Requires<[IsARM, CarryDefIsUnused]> {
460 let Inst{25} = 0;
461 }
Evan Cheng97727a62009-06-25 23:34:10 +0000462 // Carry setting variants
463 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000464 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000465 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
466 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000467 let Defs = [CPSR];
468 let Inst{25} = 1;
Evan Cheng5bf90112009-06-26 00:19:44 +0000469 }
Evan Cheng97727a62009-06-25 23:34:10 +0000470 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000471 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000472 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
473 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000474 let Defs = [CPSR];
475 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000476 }
Evan Cheng97727a62009-06-25 23:34:10 +0000477 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Chengc7ea8df2009-06-25 20:59:23 +0000478 DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng97727a62009-06-25 23:34:10 +0000479 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
480 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng2cff0762009-07-07 23:40:25 +0000481 let Defs = [CPSR];
482 let Inst{25} = 0;
Evan Cheng5bf90112009-06-26 00:19:44 +0000483 }
Evan Cheng3e18e502007-09-11 19:55:27 +0000484}
Evan Chengaa3b8012007-07-05 07:13:32 +0000485}
486
Rafael Espindola203922d2006-10-16 17:57:20 +0000487//===----------------------------------------------------------------------===//
488// Instructions
489//===----------------------------------------------------------------------===//
490
Evan Cheng10043e22007-01-19 07:51:42 +0000491//===----------------------------------------------------------------------===//
492// Miscellaneous Instructions.
493//
Rafael Espindolafe03fe92006-08-24 16:13:15 +0000494
Evan Cheng10043e22007-01-19 07:51:42 +0000495/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
496/// the function. The first operand is the ID# for this instruction, the second
497/// is the index into the MachineConstantPool that this is, the third is the
498/// size in bytes of this constant pool entry.
Evan Chengd93b5b62009-06-12 20:46:18 +0000499let neverHasSideEffects = 1, isNotDuplicable = 1 in
Evan Cheng10043e22007-01-19 07:51:42 +0000500def CONSTPOOL_ENTRY :
Evan Cheng94b5a802007-07-19 01:14:50 +0000501PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
Evan Chengaa03cd32008-11-06 17:48:05 +0000502 i32imm:$size),
Evan Cheng10043e22007-01-19 07:51:42 +0000503 "${instid:label} ${cpidx:cpentry}", []>;
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000504
Evan Cheng3e18e502007-09-11 19:55:27 +0000505let Defs = [SP], Uses = [SP] in {
Evan Cheng10043e22007-01-19 07:51:42 +0000506def ADJCALLSTACKUP :
Bill Wendlingf359fed2007-11-13 00:44:25 +0000507PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
508 "@ ADJCALLSTACKUP $amt1",
Chris Lattner27539552008-10-11 22:08:30 +0000509 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
Rafael Espindola29e48752006-08-24 17:19:08 +0000510
Evan Cheng10043e22007-01-19 07:51:42 +0000511def ADJCALLSTACKDOWN :
Evan Cheng94b5a802007-07-19 01:14:50 +0000512PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
Evan Cheng10043e22007-01-19 07:51:42 +0000513 "@ ADJCALLSTACKDOWN $amt",
Chris Lattner27539552008-10-11 22:08:30 +0000514 [(ARMcallseq_start timm:$amt)]>;
Evan Cheng3e18e502007-09-11 19:55:27 +0000515}
Rafael Espindolad0dee772006-08-21 22:00:32 +0000516
Evan Cheng10043e22007-01-19 07:51:42 +0000517def DWARF_LOC :
Evan Cheng94b5a802007-07-19 01:14:50 +0000518PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
Evan Cheng10043e22007-01-19 07:51:42 +0000519 ".loc $file, $line, $col",
520 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
Rafael Espindolad15c8922006-10-10 12:56:00 +0000521
Evan Chengaa03cd32008-11-06 17:48:05 +0000522
523// Address computation and loads and stores in PIC mode.
Evan Chenga7ca6242007-06-19 01:26:51 +0000524let isNotDuplicable = 1 in {
Evan Cheng8fce66a2008-10-31 19:11:09 +0000525def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000526 Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000527 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
Dale Johannesen7d55f372007-05-21 22:14:33 +0000528
Evan Cheng72501202008-01-07 23:56:57 +0000529let AddedComplexity = 10 in {
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000530let canFoldAsLoad = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000531def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000532 Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000533 [(set GPR:$dst, (load addrmodepc:$addr))]>;
Rafael Espindola75269be2006-07-16 01:02:57 +0000534
Evan Cheng47b546d2008-11-06 08:47:38 +0000535def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000536 Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000537 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
538
Evan Cheng47b546d2008-11-06 08:47:38 +0000539def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000540 Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000541 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
542
Evan Cheng47b546d2008-11-06 08:47:38 +0000543def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000544 Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000545 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
546
Evan Cheng47b546d2008-11-06 08:47:38 +0000547def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000548 Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000549 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
550}
Chris Lattnerf4d55ec2008-01-06 05:55:01 +0000551let AddedComplexity = 10 in {
Evan Cheng47b546d2008-11-06 08:47:38 +0000552def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000553 Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000554 [(store GPR:$src, addrmodepc:$addr)]>;
555
Evan Cheng47b546d2008-11-06 08:47:38 +0000556def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000557 Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000558 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
559
Evan Cheng47b546d2008-11-06 08:47:38 +0000560def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000561 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
Dale Johannesen7d55f372007-05-21 22:14:33 +0000562 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
563}
Evan Chengaa03cd32008-11-06 17:48:05 +0000564} // isNotDuplicable = 1
Dale Johannesen7d55f372007-05-21 22:14:33 +0000565
Evan Cheng6a42ec32009-06-23 05:25:29 +0000566
567// LEApcrel - Load a pc-relative address into a register without offending the
568// assembler.
569def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo,
Evan Chenge270d4a2009-07-22 22:03:29 +0000570 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
571 "${:private}PCRELL${:uid}+8))\n"),
572 !strconcat("${:private}PCRELL${:uid}:\n\t",
573 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
Evan Cheng6a42ec32009-06-23 05:25:29 +0000574 []>;
575
Evan Cheng4c048fe2009-06-24 23:14:45 +0000576def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
577 (ins i32imm:$label, i32imm:$id, pred:$p),
Evan Cheng6a42ec32009-06-23 05:25:29 +0000578 Pseudo,
Evan Chenge270d4a2009-07-22 22:03:29 +0000579 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
580 "(${label}_${id:no_hash}-(",
581 "${:private}PCRELL${:uid}+8))\n"),
582 !strconcat("${:private}PCRELL${:uid}:\n\t",
583 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
Evan Cheng2cff0762009-07-07 23:40:25 +0000584 []> {
585 let Inst{25} = 1;
586}
Evan Cheng6a42ec32009-06-23 05:25:29 +0000587
Evan Cheng10043e22007-01-19 07:51:42 +0000588//===----------------------------------------------------------------------===//
589// Control Flow Instructions.
590//
Rafael Espindolad55c0a42006-10-02 19:30:56 +0000591
Evan Cheng10043e22007-01-19 07:51:42 +0000592let isReturn = 1, isTerminator = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000593 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000594 let Inst{7-4} = 0b0001;
595 let Inst{19-8} = 0b111111111111;
596 let Inst{27-20} = 0b00010010;
Evan Cheng7848cfc2008-09-17 07:53:38 +0000597}
Rafael Espindola53f78be2006-09-29 21:20:16 +0000598
Evan Cheng10043e22007-01-19 07:51:42 +0000599// FIXME: remove when we have a way to marking a MI with these properties.
Evan Cheng94b5a802007-07-19 01:14:50 +0000600// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
601// operand list.
Evan Chengaa03cd32008-11-06 17:48:05 +0000602// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Chenga02fc2d2009-07-09 22:57:41 +0000603let isReturn = 1, isTerminator = 1, mayLoad = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000604 def LDM_RET : AXI4ld<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000605 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000606 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Cheng10043e22007-01-19 07:51:42 +0000607 []>;
Rafael Espindolae04df412006-10-05 16:48:49 +0000608
Bob Wilson45825302009-06-22 21:01:46 +0000609// On non-Darwin platforms R9 is callee-saved.
Evan Cheng4e712de2009-06-19 01:51:50 +0000610let isCall = 1, Itinerary = IIC_Br,
Evan Cheng4b02b2f2009-07-22 06:46:53 +0000611 Defs = [R0, R1, R2, R3, R12, LR,
612 D0, D1, D2, D3, D4, D5, D6, D7,
613 D16, D17, D18, D19, D20, D21, D22, D23,
614 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Evan Chengaa03cd32008-11-06 17:48:05 +0000615 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Cheng4ae18402007-05-18 01:53:54 +0000616 "bl ${func:call}",
Bob Wilson45825302009-06-22 21:01:46 +0000617 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Chengc3c949b42007-06-19 21:05:09 +0000618
Evan Chengaa03cd32008-11-06 17:48:05 +0000619 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Chengfa558782008-09-01 08:25:56 +0000620 "bl", " ${func:call}",
Bob Wilson45825302009-06-22 21:01:46 +0000621 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Evan Chengc3c949b42007-06-19 21:05:09 +0000622
Evan Cheng10043e22007-01-19 07:51:42 +0000623 // ARMv5T and above
Evan Chengaa03cd32008-11-06 17:48:05 +0000624 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
Evan Cheng94b5a802007-07-19 01:14:50 +0000625 "blx $func",
Bob Wilson45825302009-06-22 21:01:46 +0000626 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000627 let Inst{7-4} = 0b0011;
628 let Inst{19-8} = 0b111111111111;
629 let Inst{27-20} = 0b00010010;
Evan Cheng7848cfc2008-09-17 07:53:38 +0000630 }
631
Evan Chengbd9ba422009-07-14 01:49:27 +0000632 // ARMv4T
633 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
634 "mov lr, pc\n\tbx $func",
635 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]> {
636 let Inst{7-4} = 0b0001;
637 let Inst{19-8} = 0b111111111111;
638 let Inst{27-20} = 0b00010010;
Bob Wilson45825302009-06-22 21:01:46 +0000639 }
640}
641
642// On Darwin R9 is call-clobbered.
643let isCall = 1, Itinerary = IIC_Br,
Evan Cheng4b02b2f2009-07-22 06:46:53 +0000644 Defs = [R0, R1, R2, R3, R9, R12, LR,
645 D0, D1, D2, D3, D4, D5, D6, D7,
646 D16, D17, D18, D19, D20, D21, D22, D23,
647 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
Bob Wilson45825302009-06-22 21:01:46 +0000648 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
649 "bl ${func:call}",
650 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
651
652 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
653 "bl", " ${func:call}",
654 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>;
655
656 // ARMv5T and above
657 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
658 "blx $func",
659 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
660 let Inst{7-4} = 0b0011;
661 let Inst{19-8} = 0b111111111111;
662 let Inst{27-20} = 0b00010010;
663 }
664
Evan Chengbd9ba422009-07-14 01:49:27 +0000665 // ARMv4T
666 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
667 "mov lr, pc\n\tbx $func",
668 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
669 let Inst{7-4} = 0b0001;
670 let Inst{19-8} = 0b111111111111;
671 let Inst{27-20} = 0b00010010;
Lauro Ramos Venancioa88c4a72007-03-20 17:57:23 +0000672 }
Rafael Espindolabf3a17c2006-07-18 17:00:30 +0000673}
Rafael Espindolab15597b2006-05-18 21:45:49 +0000674
Evan Cheng4e712de2009-06-19 01:51:50 +0000675let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
Evan Chengdcd6cdf2007-05-16 20:50:01 +0000676 // B is "predicable" since it can be xformed into a Bcc.
Evan Cheng01a42272007-05-16 07:45:54 +0000677 let isBarrier = 1 in {
Evan Chengdcd6cdf2007-05-16 20:50:01 +0000678 let isPredicable = 1 in
Evan Chengaa03cd32008-11-06 17:48:05 +0000679 def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
Evan Cheng94b5a802007-07-19 01:14:50 +0000680 [(br bb:$target)]>;
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000681
Owen Anderson933b5b72007-11-12 07:39:39 +0000682 let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng7095cd22008-11-07 09:06:08 +0000683 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
Evan Cheng94b5a802007-07-19 01:14:50 +0000684 "mov pc, $target \n$jt",
Evan Cheng7095cd22008-11-07 09:06:08 +0000685 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
686 let Inst{20} = 0; // S Bit
687 let Inst{24-21} = 0b1101;
Evan Chengf0080b72009-07-07 23:45:10 +0000688 let Inst{27-25} = 0b000;
Evan Cheng01a42272007-05-16 07:45:54 +0000689 }
Evan Cheng7095cd22008-11-07 09:06:08 +0000690 def BR_JTm : JTI<(outs),
691 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
692 "ldr pc, $target \n$jt",
693 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
694 imm:$id)]> {
695 let Inst{20} = 1; // L bit
696 let Inst{21} = 0; // W bit
697 let Inst{22} = 0; // B bit
698 let Inst{24} = 1; // P bit
Evan Chengf0080b72009-07-07 23:45:10 +0000699 let Inst{27-25} = 0b011;
Evan Chenga7ca6242007-06-19 01:26:51 +0000700 }
Evan Cheng7095cd22008-11-07 09:06:08 +0000701 def BR_JTadd : JTI<(outs),
702 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
703 "add pc, $target, $idx \n$jt",
704 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
705 imm:$id)]> {
706 let Inst{20} = 0; // S bit
707 let Inst{24-21} = 0b0100;
Evan Chengf0080b72009-07-07 23:45:10 +0000708 let Inst{27-25} = 0b000;
Evan Cheng7095cd22008-11-07 09:06:08 +0000709 }
710 } // isNotDuplicable = 1, isIndirectBranch = 1
711 } // isBarrier = 1
Evan Cheng01a42272007-05-16 07:45:54 +0000712
Evan Chengaa3b8012007-07-05 07:13:32 +0000713 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
714 // a two-value operand where a dag node expects two operands. :(
Evan Chengaa03cd32008-11-06 17:48:05 +0000715 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
Evan Chengf7c6eff2007-08-07 01:37:15 +0000716 "b", " $target",
717 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
Rafael Espindola8b7bd822006-08-01 18:53:10 +0000718}
Rafael Espindola75269be2006-07-16 01:02:57 +0000719
Evan Cheng10043e22007-01-19 07:51:42 +0000720//===----------------------------------------------------------------------===//
721// Load / store Instructions.
722//
Rafael Espindola677ee832006-10-16 17:17:22 +0000723
Evan Cheng10043e22007-01-19 07:51:42 +0000724// Load
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000725let canFoldAsLoad = 1 in
Evan Cheng2666f592008-11-13 07:34:59 +0000726def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000727 "ldr", " $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000728 [(set GPR:$dst, (load addrmode2:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000729
Evan Chengee2763f2007-03-19 07:20:03 +0000730// Special LDR for loads from non-pc-relative constpools.
Dan Gohman69cc2cb2008-12-03 18:15:48 +0000731let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
Evan Cheng2666f592008-11-13 07:34:59 +0000732def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000733 "ldr", " $dst, $addr", []>;
Evan Chengee2763f2007-03-19 07:20:03 +0000734
Evan Cheng10043e22007-01-19 07:51:42 +0000735// Loads with zero extension
Evan Cheng2666f592008-11-13 07:34:59 +0000736def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000737 "ldr", "h $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000738 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000739
Evan Cheng2666f592008-11-13 07:34:59 +0000740def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000741 "ldr", "b $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000742 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
Rafael Espindola677ee832006-10-16 17:17:22 +0000743
Evan Cheng10043e22007-01-19 07:51:42 +0000744// Loads with sign extension
Evan Cheng2666f592008-11-13 07:34:59 +0000745def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000746 "ldr", "sh $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000747 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
Rafael Espindolaffdc24b2006-05-14 22:18:28 +0000748
Evan Cheng2666f592008-11-13 07:34:59 +0000749def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000750 "ldr", "sb $dst, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000751 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
Rafael Espindolab43efe82006-10-23 20:34:27 +0000752
Chris Lattner94de7bc2008-01-10 05:12:37 +0000753let mayLoad = 1 in {
Evan Cheng10043e22007-01-19 07:51:42 +0000754// Load doubleword
Evan Cheng1283c6a2009-06-15 08:28:29 +0000755def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
756 "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
Rafael Espindolab43efe82006-10-23 20:34:27 +0000757
Evan Cheng10043e22007-01-19 07:51:42 +0000758// Indexed loads
Evan Cheng47b546d2008-11-06 08:47:38 +0000759def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000760 (ins addrmode2:$addr), LdFrm,
Evan Chengf7c6eff2007-08-07 01:37:15 +0000761 "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindolab15597b2006-05-18 21:45:49 +0000762
Evan Cheng47b546d2008-11-06 08:47:38 +0000763def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000764 (ins GPR:$base, am2offset:$offset), LdFrm,
Evan Chengf7c6eff2007-08-07 01:37:15 +0000765 "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
Rafael Espindola1bbe5812006-12-12 00:37:38 +0000766
Evan Cheng47b546d2008-11-06 08:47:38 +0000767def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000768 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000769 "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
Rafael Espindola4443c7d2006-09-08 16:59:47 +0000770
Evan Cheng47b546d2008-11-06 08:47:38 +0000771def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000772 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000773 "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
Lauro Ramos Venancio7251e572006-12-28 13:11:14 +0000774
Evan Cheng47b546d2008-11-06 08:47:38 +0000775def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000776 (ins addrmode2:$addr), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000777 "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
Lauro Ramos Venancio7251e572006-12-28 13:11:14 +0000778
Evan Cheng47b546d2008-11-06 08:47:38 +0000779def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000780 (ins GPR:$base,am2offset:$offset), LdFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000781 "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000782
Evan Cheng47b546d2008-11-06 08:47:38 +0000783def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000784 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000785 "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000786
Evan Cheng47b546d2008-11-06 08:47:38 +0000787def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000788 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
789 "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000790
Evan Cheng47b546d2008-11-06 08:47:38 +0000791def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000792 (ins addrmode3:$addr), LdMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000793 "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000794
Evan Cheng47b546d2008-11-06 08:47:38 +0000795def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000796 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Cheng979da0e2009-07-02 01:30:04 +0000797 "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
Chris Lattner94de7bc2008-01-10 05:12:37 +0000798}
Evan Cheng10043e22007-01-19 07:51:42 +0000799
800// Store
Evan Cheng2666f592008-11-13 07:34:59 +0000801def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000802 "str", " $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000803 [(store GPR:$src, addrmode2:$addr)]>;
804
805// Stores with truncate
Evan Cheng2666f592008-11-13 07:34:59 +0000806def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000807 "str", "h $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000808 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
809
Evan Cheng2666f592008-11-13 07:34:59 +0000810def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000811 "str", "b $src, $addr",
Evan Cheng10043e22007-01-19 07:51:42 +0000812 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
813
814// Store doubleword
Chris Lattner10324d02008-01-06 08:36:04 +0000815let mayStore = 1 in
Evan Cheng1283c6a2009-06-15 08:28:29 +0000816def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),StMiscFrm,
817 "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5T]>;
Evan Cheng10043e22007-01-19 07:51:42 +0000818
819// Indexed stores
Evan Cheng47b546d2008-11-06 08:47:38 +0000820def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000821 (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000822 "str", " $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000823 [(set GPR:$base_wb,
824 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
825
Evan Cheng47b546d2008-11-06 08:47:38 +0000826def STR_POST : AI2stwpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000827 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000828 "str", " $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000829 [(set GPR:$base_wb,
830 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
831
Evan Cheng47b546d2008-11-06 08:47:38 +0000832def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000833 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000834 "str", "h $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000835 [(set GPR:$base_wb,
836 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
837
Evan Cheng47b546d2008-11-06 08:47:38 +0000838def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000839 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000840 "str", "h $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000841 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
842 GPR:$base, am3offset:$offset))]>;
843
Evan Cheng47b546d2008-11-06 08:47:38 +0000844def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000845 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000846 "str", "b $src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000847 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
848 GPR:$base, am2offset:$offset))]>;
849
Evan Cheng47b546d2008-11-06 08:47:38 +0000850def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
Evan Cheng2666f592008-11-13 07:34:59 +0000851 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000852 "str", "b $src, [$base], $offset", "$base = $base_wb",
Evan Cheng10043e22007-01-19 07:51:42 +0000853 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
854 GPR:$base, am2offset:$offset))]>;
Evan Cheng10043e22007-01-19 07:51:42 +0000855
856//===----------------------------------------------------------------------===//
857// Load / store multiple Instructions.
858//
859
Evan Cheng94b5a802007-07-19 01:14:50 +0000860// FIXME: $dst1 should be a def.
Chris Lattner94de7bc2008-01-10 05:12:37 +0000861let mayLoad = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000862def LDM : AXI4ld<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000863 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000864 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000865 []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000866
Chris Lattner10324d02008-01-06 08:36:04 +0000867let mayStore = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +0000868def STM : AXI4st<(outs),
Evan Cheng94b5a802007-07-19 01:14:50 +0000869 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
Evan Chengaf644b52008-11-12 07:18:38 +0000870 LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
Evan Cheng0f7cbe82007-05-15 01:29:07 +0000871 []>;
Evan Cheng10043e22007-01-19 07:51:42 +0000872
873//===----------------------------------------------------------------------===//
874// Move Instructions.
875//
876
Evan Chengd93b5b62009-06-12 20:46:18 +0000877let neverHasSideEffects = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +0000878def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
879 "mov", " $dst, $src", []>, UnaryDP;
880def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
881 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
Evan Cheng5be3e092007-03-19 07:09:02 +0000882
Evan Cheng64fdacc2009-02-05 08:42:55 +0000883let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +0000884def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm,
885 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP;
Evan Cheng9d41b312007-07-10 18:08:01 +0000886
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000887def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Cheng94b5a802007-07-19 01:14:50 +0000888 "mov", " $dst, $src, rrx",
Evan Cheng81889d012008-11-05 18:35:52 +0000889 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
Evan Cheng10043e22007-01-19 07:51:42 +0000890
891// These aren't really mov instructions, but we have to define them this way
892// due to flag operands.
893
Evan Cheng3e18e502007-09-11 19:55:27 +0000894let Defs = [CPSR] in {
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000895def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000896 "mov", "s $dst, $src, lsr #1",
Evan Cheng81889d012008-11-05 18:35:52 +0000897 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
Evan Cheng30f6f8f2008-11-14 20:09:11 +0000898def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chenga6e9a4c2007-05-29 23:32:06 +0000899 "mov", "s $dst, $src, asr #1",
Evan Cheng81889d012008-11-05 18:35:52 +0000900 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
Evan Cheng3e18e502007-09-11 19:55:27 +0000901}
Evan Cheng10043e22007-01-19 07:51:42 +0000902
Evan Cheng10043e22007-01-19 07:51:42 +0000903//===----------------------------------------------------------------------===//
904// Extend Instructions.
905//
906
907// Sign extenders
908
Evan Cheng49d66522008-11-06 22:15:19 +0000909defm SXTB : AI_unary_rrot<0b01101010,
910 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
911defm SXTH : AI_unary_rrot<0b01101011,
912 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000913
Evan Cheng49d66522008-11-06 22:15:19 +0000914defm SXTAB : AI_bin_rrot<0b01101010,
915 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
916defm SXTAH : AI_bin_rrot<0b01101011,
917 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000918
919// TODO: SXT(A){B|H}16
920
921// Zero extenders
922
923let AddedComplexity = 16 in {
Evan Cheng49d66522008-11-06 22:15:19 +0000924defm UXTB : AI_unary_rrot<0b01101110,
925 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
926defm UXTH : AI_unary_rrot<0b01101111,
927 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
928defm UXTB16 : AI_unary_rrot<0b01101100,
929 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000930
Bob Wilsone67b7702009-06-22 22:08:29 +0000931def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Cheng10043e22007-01-19 07:51:42 +0000932 (UXTB16r_rot GPR:$Src, 24)>;
Bob Wilsone67b7702009-06-22 22:08:29 +0000933def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
Evan Cheng10043e22007-01-19 07:51:42 +0000934 (UXTB16r_rot GPR:$Src, 8)>;
935
Evan Cheng49d66522008-11-06 22:15:19 +0000936defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
Evan Cheng10043e22007-01-19 07:51:42 +0000937 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
Evan Cheng49d66522008-11-06 22:15:19 +0000938defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
Evan Cheng10043e22007-01-19 07:51:42 +0000939 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
Rafael Espindolad0dee772006-08-21 22:00:32 +0000940}
941
Evan Cheng10043e22007-01-19 07:51:42 +0000942// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
943//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
Rafael Espindolac7829d62006-09-11 19:24:19 +0000944
Evan Cheng10043e22007-01-19 07:51:42 +0000945// TODO: UXT(A){B|H}16
946
947//===----------------------------------------------------------------------===//
948// Arithmetic Instructions.
949//
950
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000951defm ADD : AsI1_bin_irs<0b0100, "add",
Evan Cheng5bf90112009-06-26 00:19:44 +0000952 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +0000953defm SUB : AsI1_bin_irs<0b0010, "sub",
Evan Cheng7848cfc2008-09-17 07:53:38 +0000954 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000955
Evan Chengaa3b8012007-07-05 07:13:32 +0000956// ADD and SUB with 's' bit set.
Evan Chengc7ea8df2009-06-25 20:59:23 +0000957defm ADDS : AI1_bin_s_irs<0b0100, "add",
958 BinOpFrag<(addc node:$LHS, node:$RHS)>>;
959defm SUBS : AI1_bin_s_irs<0b0010, "sub",
960 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Chenge8c3cbf2007-06-06 10:17:05 +0000961
Evan Cheng97727a62009-06-25 23:34:10 +0000962defm ADC : AI1_adde_sube_irs<0b0101, "adc",
Evan Cheng5bf90112009-06-26 00:19:44 +0000963 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
Evan Cheng97727a62009-06-25 23:34:10 +0000964defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
965 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Cheng10043e22007-01-19 07:51:42 +0000966
Evan Chengaa3b8012007-07-05 07:13:32 +0000967// These don't define reg/reg forms, because they are handled above.
Evan Cheng81889d012008-11-05 18:35:52 +0000968def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng9d41b312007-07-10 18:08:01 +0000969 "rsb", " $dst, $a, $b",
970 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
971
Evan Cheng81889d012008-11-05 18:35:52 +0000972def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng9d41b312007-07-10 18:08:01 +0000973 "rsb", " $dst, $a, $b",
974 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
Evan Chengaa3b8012007-07-05 07:13:32 +0000975
976// RSB with 's' bit set.
Evan Cheng3e18e502007-09-11 19:55:27 +0000977let Defs = [CPSR] in {
Evan Cheng81889d012008-11-05 18:35:52 +0000978def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000979 "rsb", "s $dst, $a, $b",
Evan Cheng3e18e502007-09-11 19:55:27 +0000980 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
Evan Cheng81889d012008-11-05 18:35:52 +0000981def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Chengaa3b8012007-07-05 07:13:32 +0000982 "rsb", "s $dst, $a, $b",
Evan Cheng3e18e502007-09-11 19:55:27 +0000983 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
984}
Evan Chengaa3b8012007-07-05 07:13:32 +0000985
Evan Cheng97727a62009-06-25 23:34:10 +0000986let Uses = [CPSR] in {
987def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
988 DPFrm, "rsc", " $dst, $a, $b",
989 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
990 Requires<[IsARM, CarryDefIsUnused]>;
991def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
992 DPSoRegFrm, "rsc", " $dst, $a, $b",
993 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
994 Requires<[IsARM, CarryDefIsUnused]>;
995}
996
997// FIXME: Allow these to be predicated.
Evan Chengc7ea8df2009-06-25 20:59:23 +0000998let Defs = [CPSR], Uses = [CPSR] in {
999def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1000 DPFrm, "rscs $dst, $a, $b",
Evan Cheng97727a62009-06-25 23:34:10 +00001001 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1002 Requires<[IsARM, CarryDefIsUnused]>;
Evan Chengc7ea8df2009-06-25 20:59:23 +00001003def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1004 DPSoRegFrm, "rscs $dst, $a, $b",
Evan Cheng97727a62009-06-25 23:34:10 +00001005 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1006 Requires<[IsARM, CarryDefIsUnused]>;
Evan Cheng3e18e502007-09-11 19:55:27 +00001007}
Evan Chenge8c3cbf2007-06-06 10:17:05 +00001008
Evan Cheng10043e22007-01-19 07:51:42 +00001009// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1010def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1011 (SUBri GPR:$src, so_imm_neg:$imm)>;
1012
1013//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1014// (SUBSri GPR:$src, so_imm_neg:$imm)>;
1015//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1016// (SBCri GPR:$src, so_imm_neg:$imm)>;
1017
1018// Note: These are implemented in C++ code, because they have to generate
1019// ADD/SUBrs instructions, which use a complex pattern that a xform function
1020// cannot produce.
1021// (mul X, 2^n+1) -> (add (X << n), X)
1022// (mul X, 2^n-1) -> (rsb X, (X << n))
1023
1024
1025//===----------------------------------------------------------------------===//
1026// Bitwise Instructions.
1027//
1028
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001029defm AND : AsI1_bin_irs<0b0000, "and",
Evan Cheng5bf90112009-06-26 00:19:44 +00001030 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001031defm ORR : AsI1_bin_irs<0b1100, "orr",
Evan Cheng5bf90112009-06-26 00:19:44 +00001032 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001033defm EOR : AsI1_bin_irs<0b0001, "eor",
Evan Cheng5bf90112009-06-26 00:19:44 +00001034 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001035defm BIC : AsI1_bin_irs<0b1110, "bic",
Evan Cheng7848cfc2008-09-17 07:53:38 +00001036 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Cheng10043e22007-01-19 07:51:42 +00001037
Evan Cheng40398232009-07-06 22:23:46 +00001038def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1039 AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
1040 "bfc", " $dst, $imm", "$src = $dst",
1041 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1042 Requires<[IsARM, HasV6T2]> {
1043 let Inst{27-21} = 0b0111110;
1044 let Inst{6-0} = 0b0011111;
1045}
1046
Evan Cheng81889d012008-11-05 18:35:52 +00001047def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
1048 "mvn", " $dst, $src",
1049 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
1050def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1051 "mvn", " $dst, $src",
1052 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
Evan Cheng64fdacc2009-02-05 08:42:55 +00001053let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng81889d012008-11-05 18:35:52 +00001054def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1055 "mvn", " $dst, $imm",
1056 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP;
Evan Cheng10043e22007-01-19 07:51:42 +00001057
1058def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1059 (BICri GPR:$src, so_imm_not:$imm)>;
1060
1061//===----------------------------------------------------------------------===//
1062// Multiply Instructions.
1063//
1064
Evan Cheng5bf90112009-06-26 00:19:44 +00001065let isCommutable = 1 in
Evan Cheng2686c8f2008-11-06 01:21:28 +00001066def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengaa03cd32008-11-06 17:48:05 +00001067 "mul", " $dst, $a, $b",
1068 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
Evan Cheng10043e22007-01-19 07:51:42 +00001069
Evan Cheng2686c8f2008-11-06 01:21:28 +00001070def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Chengaa03cd32008-11-06 17:48:05 +00001071 "mla", " $dst, $a, $b, $c",
1072 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
Evan Cheng10043e22007-01-19 07:51:42 +00001073
Evan Chenge63b0e62009-07-06 22:05:45 +00001074def MLS : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1075 "mls", " $dst, $a, $b, $c",
1076 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1077 Requires<[IsARM, HasV6T2]>;
1078
Evan Cheng10043e22007-01-19 07:51:42 +00001079// Extra precision multiplies with low / high results
Evan Chengd93b5b62009-06-12 20:46:18 +00001080let neverHasSideEffects = 1 in {
Evan Cheng5bf90112009-06-26 00:19:44 +00001081let isCommutable = 1 in {
Evan Cheng2686c8f2008-11-06 01:21:28 +00001082def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1083 (ins GPR:$a, GPR:$b),
1084 "smull", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001085
Evan Cheng2686c8f2008-11-06 01:21:28 +00001086def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1087 (ins GPR:$a, GPR:$b),
1088 "umull", " $ldst, $hdst, $a, $b", []>;
Evan Cheng5bf90112009-06-26 00:19:44 +00001089}
Evan Cheng10043e22007-01-19 07:51:42 +00001090
1091// Multiply + accumulate
Evan Cheng2686c8f2008-11-06 01:21:28 +00001092def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1093 (ins GPR:$a, GPR:$b),
1094 "smlal", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001095
Evan Cheng2686c8f2008-11-06 01:21:28 +00001096def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1097 (ins GPR:$a, GPR:$b),
1098 "umlal", " $ldst, $hdst, $a, $b", []>;
Evan Cheng10043e22007-01-19 07:51:42 +00001099
Evan Cheng2686c8f2008-11-06 01:21:28 +00001100def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1101 (ins GPR:$a, GPR:$b),
1102 "umaal", " $ldst, $hdst, $a, $b", []>,
1103 Requires<[IsARM, HasV6]>;
Evan Chengd93b5b62009-06-12 20:46:18 +00001104} // neverHasSideEffects
Evan Cheng10043e22007-01-19 07:51:42 +00001105
1106// Most significant word multiply
Evan Cheng2686c8f2008-11-06 01:21:28 +00001107def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng9d41b312007-07-10 18:08:01 +00001108 "smmul", " $dst, $a, $b",
1109 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001110 Requires<[IsARM, HasV6]> {
1111 let Inst{7-4} = 0b0001;
1112 let Inst{15-12} = 0b1111;
1113}
Evan Cheng9d41b312007-07-10 18:08:01 +00001114
Evan Cheng2686c8f2008-11-06 01:21:28 +00001115def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng9d41b312007-07-10 18:08:01 +00001116 "smmla", " $dst, $a, $b, $c",
1117 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001118 Requires<[IsARM, HasV6]> {
1119 let Inst{7-4} = 0b0001;
1120}
Evan Cheng10043e22007-01-19 07:51:42 +00001121
1122
Evan Cheng2686c8f2008-11-06 01:21:28 +00001123def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001124 "smmls", " $dst, $a, $b, $c",
Evan Cheng10043e22007-01-19 07:51:42 +00001125 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
Evan Cheng2686c8f2008-11-06 01:21:28 +00001126 Requires<[IsARM, HasV6]> {
1127 let Inst{7-4} = 0b1101;
1128}
Evan Cheng10043e22007-01-19 07:51:42 +00001129
Raul Herbster73489272007-08-30 23:25:47 +00001130multiclass AI_smul<string opc, PatFrag opnode> {
Evan Cheng36ae4032008-11-06 03:35:07 +00001131 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001132 !strconcat(opc, "bb"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001133 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1134 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001135 Requires<[IsARM, HasV5TE]> {
1136 let Inst{5} = 0;
1137 let Inst{6} = 0;
1138 }
Raul Herbster73489272007-08-30 23:25:47 +00001139
Evan Cheng36ae4032008-11-06 03:35:07 +00001140 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001141 !strconcat(opc, "bt"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001142 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
Bob Wilsone67b7702009-06-22 22:08:29 +00001143 (sra GPR:$b, (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001144 Requires<[IsARM, HasV5TE]> {
1145 let Inst{5} = 0;
1146 let Inst{6} = 1;
1147 }
Raul Herbster73489272007-08-30 23:25:47 +00001148
Evan Cheng36ae4032008-11-06 03:35:07 +00001149 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001150 !strconcat(opc, "tb"), " $dst, $a, $b",
Bob Wilsone67b7702009-06-22 22:08:29 +00001151 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001152 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001153 Requires<[IsARM, HasV5TE]> {
1154 let Inst{5} = 1;
1155 let Inst{6} = 0;
1156 }
Raul Herbster73489272007-08-30 23:25:47 +00001157
Evan Cheng36ae4032008-11-06 03:35:07 +00001158 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001159 !strconcat(opc, "tt"), " $dst, $a, $b",
Bob Wilsone67b7702009-06-22 22:08:29 +00001160 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1161 (sra GPR:$b, (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001162 Requires<[IsARM, HasV5TE]> {
1163 let Inst{5} = 1;
1164 let Inst{6} = 1;
1165 }
Raul Herbster73489272007-08-30 23:25:47 +00001166
Evan Cheng36ae4032008-11-06 03:35:07 +00001167 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001168 !strconcat(opc, "wb"), " $dst, $a, $b",
Evan Cheng77c15de2007-01-19 20:27:35 +00001169 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001170 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001171 Requires<[IsARM, HasV5TE]> {
1172 let Inst{5} = 1;
1173 let Inst{6} = 0;
1174 }
Raul Herbster73489272007-08-30 23:25:47 +00001175
Evan Cheng36ae4032008-11-06 03:35:07 +00001176 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001177 !strconcat(opc, "wt"), " $dst, $a, $b",
Evan Cheng10043e22007-01-19 07:51:42 +00001178 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001179 (sra GPR:$b, (i32 16))), (i32 16)))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001180 Requires<[IsARM, HasV5TE]> {
1181 let Inst{5} = 1;
1182 let Inst{6} = 1;
1183 }
Rafael Espindola595dc4c2006-10-16 16:33:29 +00001184}
1185
Raul Herbster73489272007-08-30 23:25:47 +00001186
1187multiclass AI_smla<string opc, PatFrag opnode> {
Evan Cheng36ae4032008-11-06 03:35:07 +00001188 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001189 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001190 [(set GPR:$dst, (add GPR:$acc,
1191 (opnode (sext_inreg GPR:$a, i16),
1192 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001193 Requires<[IsARM, HasV5TE]> {
1194 let Inst{5} = 0;
1195 let Inst{6} = 0;
1196 }
Raul Herbster73489272007-08-30 23:25:47 +00001197
Evan Cheng36ae4032008-11-06 03:35:07 +00001198 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001199 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001200 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Bob Wilsone67b7702009-06-22 22:08:29 +00001201 (sra GPR:$b, (i32 16)))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001202 Requires<[IsARM, HasV5TE]> {
1203 let Inst{5} = 0;
1204 let Inst{6} = 1;
1205 }
Raul Herbster73489272007-08-30 23:25:47 +00001206
Evan Cheng36ae4032008-11-06 03:35:07 +00001207 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001208 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
Bob Wilsone67b7702009-06-22 22:08:29 +00001209 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001210 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001211 Requires<[IsARM, HasV5TE]> {
1212 let Inst{5} = 1;
1213 let Inst{6} = 0;
1214 }
Raul Herbster73489272007-08-30 23:25:47 +00001215
Evan Cheng36ae4032008-11-06 03:35:07 +00001216 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001217 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
Bob Wilsone67b7702009-06-22 22:08:29 +00001218 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1219 (sra GPR:$b, (i32 16)))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001220 Requires<[IsARM, HasV5TE]> {
1221 let Inst{5} = 1;
1222 let Inst{6} = 1;
1223 }
Evan Cheng10043e22007-01-19 07:51:42 +00001224
Evan Cheng36ae4032008-11-06 03:35:07 +00001225 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001226 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
Evan Cheng77c15de2007-01-19 20:27:35 +00001227 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001228 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001229 Requires<[IsARM, HasV5TE]> {
1230 let Inst{5} = 0;
1231 let Inst{6} = 0;
1232 }
Raul Herbster73489272007-08-30 23:25:47 +00001233
Evan Cheng36ae4032008-11-06 03:35:07 +00001234 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001235 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
Evan Cheng10043e22007-01-19 07:51:42 +00001236 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilsone67b7702009-06-22 22:08:29 +00001237 (sra GPR:$b, (i32 16))), (i32 16))))]>,
Evan Cheng36ae4032008-11-06 03:35:07 +00001238 Requires<[IsARM, HasV5TE]> {
1239 let Inst{5} = 0;
1240 let Inst{6} = 1;
1241 }
Rafael Espindola01dd97a2006-10-18 16:20:57 +00001242}
Rafael Espindola778769a2006-09-08 12:47:03 +00001243
Raul Herbster73489272007-08-30 23:25:47 +00001244defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1245defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
Rafael Espindola53f78be2006-09-29 21:20:16 +00001246
Evan Cheng10043e22007-01-19 07:51:42 +00001247// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1248// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
Rafael Espindola3874a162006-10-13 13:14:59 +00001249
Evan Cheng10043e22007-01-19 07:51:42 +00001250//===----------------------------------------------------------------------===//
1251// Misc. Arithmetic Instructions.
1252//
Rafael Espindolad1a4ea42006-10-10 16:33:47 +00001253
Evan Cheng98dc53e2008-11-07 01:41:35 +00001254def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001255 "clz", " $dst, $src",
Evan Cheng98dc53e2008-11-07 01:41:35 +00001256 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1257 let Inst{7-4} = 0b0001;
1258 let Inst{11-8} = 0b1111;
1259 let Inst{19-16} = 0b1111;
1260}
Rafael Espindolac31ee942006-10-17 13:13:23 +00001261
Evan Cheng98dc53e2008-11-07 01:41:35 +00001262def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001263 "rev", " $dst, $src",
Evan Cheng98dc53e2008-11-07 01:41:35 +00001264 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1265 let Inst{7-4} = 0b0011;
1266 let Inst{11-8} = 0b1111;
1267 let Inst{19-16} = 0b1111;
1268}
Rafael Espindolac31ee942006-10-17 13:13:23 +00001269
Evan Cheng98dc53e2008-11-07 01:41:35 +00001270def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001271 "rev16", " $dst, $src",
Evan Cheng10043e22007-01-19 07:51:42 +00001272 [(set GPR:$dst,
Bob Wilsone67b7702009-06-22 22:08:29 +00001273 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1274 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1275 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1276 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001277 Requires<[IsARM, HasV6]> {
1278 let Inst{7-4} = 0b1011;
1279 let Inst{11-8} = 0b1111;
1280 let Inst{19-16} = 0b1111;
1281}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001282
Evan Cheng98dc53e2008-11-07 01:41:35 +00001283def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001284 "revsh", " $dst, $src",
Evan Cheng10043e22007-01-19 07:51:42 +00001285 [(set GPR:$dst,
1286 (sext_inreg
Bob Wilsone67b7702009-06-22 22:08:29 +00001287 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1288 (shl GPR:$src, (i32 8))), i16))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001289 Requires<[IsARM, HasV6]> {
1290 let Inst{7-4} = 0b1011;
1291 let Inst{11-8} = 0b1111;
1292 let Inst{19-16} = 0b1111;
1293}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001294
Evan Cheng98dc53e2008-11-07 01:41:35 +00001295def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1296 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1297 "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Cheng10043e22007-01-19 07:51:42 +00001298 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1299 (and (shl GPR:$src2, (i32 imm:$shamt)),
1300 0xFFFF0000)))]>,
Evan Cheng98dc53e2008-11-07 01:41:35 +00001301 Requires<[IsARM, HasV6]> {
1302 let Inst{6-4} = 0b001;
1303}
Rafael Espindola53f78be2006-09-29 21:20:16 +00001304
Evan Cheng10043e22007-01-19 07:51:42 +00001305// Alternate cases for PKHBT where identities eliminate some nodes.
1306def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1307 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1308def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1309 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
Rafael Espindolad55c0a42006-10-02 19:30:56 +00001310
Rafael Espindolae04df412006-10-05 16:48:49 +00001311
Evan Cheng98dc53e2008-11-07 01:41:35 +00001312def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1313 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1314 "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Cheng10043e22007-01-19 07:51:42 +00001315 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1316 (and (sra GPR:$src2, imm16_31:$shamt),
Evan Cheng98dc53e2008-11-07 01:41:35 +00001317 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1318 let Inst{6-4} = 0b101;
1319}
Rafael Espindolad55c0a42006-10-02 19:30:56 +00001320
Evan Cheng10043e22007-01-19 07:51:42 +00001321// Alternate cases for PKHTB where identities eliminate some nodes. Note that
1322// a shift amount of 0 is *not legal* here, it is PKHBT instead.
Bob Wilsone67b7702009-06-22 22:08:29 +00001323def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
Evan Cheng10043e22007-01-19 07:51:42 +00001324 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1325def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1326 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1327 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Rafael Espindola57d109f2006-10-10 18:55:14 +00001328
Evan Cheng10043e22007-01-19 07:51:42 +00001329//===----------------------------------------------------------------------===//
1330// Comparison Instructions...
1331//
Rafael Espindola57d109f2006-10-10 18:55:14 +00001332
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001333defm CMP : AI1_cmp_irs<0b1010, "cmp",
Evan Chengf7c6eff2007-08-07 01:37:15 +00001334 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
Jim Grosbachb7c01f52008-10-14 20:36:24 +00001335defm CMN : AI1_cmp_irs<0b1011, "cmn",
Evan Chengf7c6eff2007-08-07 01:37:15 +00001336 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
Rafael Espindolab5093882006-10-07 14:24:52 +00001337
Evan Cheng10043e22007-01-19 07:51:42 +00001338// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Cheng47b546d2008-11-06 08:47:38 +00001339defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwindbf11ba2009-06-29 15:33:01 +00001340 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Cheng47b546d2008-11-06 08:47:38 +00001341defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwindbf11ba2009-06-29 15:33:01 +00001342 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001343
David Goodwindbf11ba2009-06-29 15:33:01 +00001344defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1345 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1346defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1347 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chenge8c3cbf2007-06-06 10:17:05 +00001348
1349def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1350 (CMNri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001351
David Goodwindbf11ba2009-06-29 15:33:01 +00001352def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
Lauro Ramos Venancio6be85332007-04-02 01:30:03 +00001353 (CMNri GPR:$src, so_imm_neg:$imm)>;
1354
Rafael Espindolab5093882006-10-07 14:24:52 +00001355
Evan Cheng10043e22007-01-19 07:51:42 +00001356// Conditional moves
Evan Chengaa3b8012007-07-05 07:13:32 +00001357// FIXME: should be able to write a pattern for ARMcmov, but can't use
1358// a two-value operand where a dag node expects two operands. :(
Evan Cheng47b546d2008-11-06 08:47:38 +00001359def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001360 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001361 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng47b546d2008-11-06 08:47:38 +00001362 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola8429e1f2006-10-10 20:38:57 +00001363
Evan Cheng47b546d2008-11-06 08:47:38 +00001364def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1365 (ins GPR:$false, so_reg:$true), DPSoRegFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001366 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001367 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng81889d012008-11-05 18:35:52 +00001368 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola9e29ec32006-10-09 17:50:29 +00001369
Evan Cheng47b546d2008-11-06 08:47:38 +00001370def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1371 (ins GPR:$false, so_imm:$true), DPFrm,
Evan Cheng81889d012008-11-05 18:35:52 +00001372 "mov", " $dst, $true",
Evan Chengaa3b8012007-07-05 07:13:32 +00001373 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng81889d012008-11-05 18:35:52 +00001374 RegConstraint<"$false = $dst">, UnaryDP;
Rafael Espindola40f5dd22006-10-07 13:46:42 +00001375
Rafael Espindolad15c8922006-10-10 12:56:00 +00001376
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +00001377//===----------------------------------------------------------------------===//
1378// TLS Instructions
1379//
1380
1381// __aeabi_read_tp preserves the registers r1-r3.
Evan Cheng9d41b312007-07-10 18:08:01 +00001382let isCall = 1,
1383 Defs = [R0, R12, LR, CPSR] in {
Evan Chengaa03cd32008-11-06 17:48:05 +00001384 def TPsoft : ABXI<0b1011, (outs), (ins),
Evan Cheng4ae18402007-05-18 01:53:54 +00001385 "bl __aeabi_read_tp",
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +00001386 [(set R0, ARMthread_pointer)]>;
1387}
Rafael Espindola99bf1332006-10-17 20:33:13 +00001388
Evan Cheng10043e22007-01-19 07:51:42 +00001389//===----------------------------------------------------------------------===//
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001390// SJLJ Exception handling intrinsics
Jim Grosbach06928192009-05-14 00:46:35 +00001391// eh_sjlj_setjmp() is a three instruction sequence to store the return
1392// address and save #0 in R0 for the non-longjmp case.
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001393// Since by its nature we may be coming from some other function to get
1394// here, and we're using the stack frame for the containing function to
1395// save/restore registers, we can't keep anything live in regs across
Jim Grosbach06928192009-05-14 00:46:35 +00001396// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001397// when we get here from a longjmp(). We force everthing out of registers
Jim Grosbach06928192009-05-14 00:46:35 +00001398// except for our own input by listing the relevant registers in Defs. By
1399// doing so, we also cause the prologue/epilogue code to actively preserve
1400// all of the callee-saved resgisters, which is exactly what we want.
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001401let Defs =
Evan Cheng4b02b2f2009-07-22 06:46:53 +00001402 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1403 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1404 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D31,
1405 D31 ] in {
Jim Grosbach06928192009-05-14 00:46:35 +00001406 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001407 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
1408 "add r0, pc, #4\n\t"
1409 "str r0, [$src, #+4]\n\t"
Jim Grosbach06928192009-05-14 00:46:35 +00001410 "mov r0, #0 @ eh_setjmp", "",
1411 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
Jim Grosbachaeca45d2009-05-12 23:59:14 +00001412}
1413
1414//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +00001415// Non-Instruction Patterns
1416//
Rafael Espindola58c368b2006-10-07 14:03:39 +00001417
Evan Cheng10043e22007-01-19 07:51:42 +00001418// ConstantPool, GlobalAddress, and JumpTable
1419def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
1420def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1421def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
Evan Cheng9e7b8382007-03-20 08:11:30 +00001422 (LEApcrelJT tjumptable:$dst, imm:$id)>;
Rafael Espindola58c368b2006-10-07 14:03:39 +00001423
Evan Cheng10043e22007-01-19 07:51:42 +00001424// Large immediate handling.
Rafael Espindolaf719c5f2006-10-16 21:10:32 +00001425
Evan Cheng10043e22007-01-19 07:51:42 +00001426// Two piece so_imms.
Dan Gohmane8c1e422007-06-26 00:48:07 +00001427let isReMaterializable = 1 in
Evan Cheng47b546d2008-11-06 08:47:38 +00001428def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
Evan Cheng0f7cbe82007-05-15 01:29:07 +00001429 "mov", " $dst, $src",
Evan Chengb870fd82008-11-06 02:25:39 +00001430 [(set GPR:$dst, so_imm2part:$src)]>;
Rafael Espindola418c8e62006-10-17 13:36:07 +00001431
Evan Cheng10043e22007-01-19 07:51:42 +00001432def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
Evan Chenge3a53c42009-07-08 21:03:57 +00001433 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1434 (so_imm2part_2 imm:$RHS))>;
Evan Cheng10043e22007-01-19 07:51:42 +00001435def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
Evan Chenge3a53c42009-07-08 21:03:57 +00001436 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1437 (so_imm2part_2 imm:$RHS))>;
Rafael Espindola418c8e62006-10-17 13:36:07 +00001438
Evan Cheng10043e22007-01-19 07:51:42 +00001439// TODO: add,sub,and, 3-instr forms?
Rafael Espindolaf719c5f2006-10-16 21:10:32 +00001440
Rafael Espindola336d62e2006-10-19 17:05:03 +00001441
Evan Cheng10043e22007-01-19 07:51:42 +00001442// Direct calls
Bob Wilson45825302009-06-22 21:01:46 +00001443def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1444 Requires<[IsNotDarwin]>;
1445def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1446 Requires<[IsDarwin]>;
Rafael Espindola0cd8d142006-11-01 14:13:27 +00001447
Evan Cheng10043e22007-01-19 07:51:42 +00001448// zextload i1 -> zextload i8
1449def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
Lauro Ramos Venanciod0ced3f2006-12-26 19:30:42 +00001450
Evan Cheng10043e22007-01-19 07:51:42 +00001451// extload -> zextload
1452def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1453def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1454def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
Rafael Espindola0cd8d142006-11-01 14:13:27 +00001455
Evan Chengfd2adbf2008-11-05 23:22:34 +00001456def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1457def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1458
Evan Cheng77c15de2007-01-19 20:27:35 +00001459// smul* and smla*
Bob Wilsone67b7702009-06-22 22:08:29 +00001460def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1461 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001462 (SMULBB GPR:$a, GPR:$b)>;
1463def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1464 (SMULBB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001465def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1466 (sra GPR:$b, (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001467 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001468def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001469 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001470def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1471 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001472 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001473def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
Evan Cheng77c15de2007-01-19 20:27:35 +00001474 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001475def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1476 (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001477 (SMULWB GPR:$a, GPR:$b)>;
Bob Wilsone67b7702009-06-22 22:08:29 +00001478def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001479 (SMULWB GPR:$a, GPR:$b)>;
1480
1481def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001482 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1483 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001484 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1485def : ARMV5TEPat<(add GPR:$acc,
1486 (mul sext_16_node:$a, sext_16_node:$b)),
1487 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1488def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001489 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1490 (sra GPR:$b, (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001491 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1492def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001493 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001494 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1495def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001496 (mul (sra GPR:$a, (i32 16)),
1497 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001498 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1499def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001500 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
Evan Cheng77c15de2007-01-19 20:27:35 +00001501 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1502def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001503 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1504 (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001505 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1506def : ARMV5TEPat<(add GPR:$acc,
Bob Wilsone67b7702009-06-22 22:08:29 +00001507 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
Evan Cheng77c15de2007-01-19 20:27:35 +00001508 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1509
Evan Cheng10043e22007-01-19 07:51:42 +00001510//===----------------------------------------------------------------------===//
1511// Thumb Support
1512//
1513
1514include "ARMInstrThumb.td"
1515
1516//===----------------------------------------------------------------------===//
Anton Korobeynikov02bb33c2009-06-17 18:13:58 +00001517// Thumb2 Support
1518//
1519
1520include "ARMInstrThumb2.td"
1521
1522//===----------------------------------------------------------------------===//
Evan Cheng10043e22007-01-19 07:51:42 +00001523// Floating Point Support
1524//
1525
1526include "ARMInstrVFP.td"
Bob Wilson2e076c42009-06-22 23:27:02 +00001527
1528//===----------------------------------------------------------------------===//
1529// Advanced SIMD (NEON) Support
1530//
1531
1532include "ARMInstrNEON.td"