blob: b4fb8a77d8644f0b2fa229c66247caa5c018d4bb [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
Dan Gohmanf17a25c2007-07-18 16:29:46 +00006// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the ARM instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// ARM specific DAG Nodes.
16//
17
18// Type profiles.
Bill Wendling7173da52007-11-13 09:19:02 +000019def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000021
22def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
23
24def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
25
26def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
28 SDTCisVT<3, i32>]>;
29
30def 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 Cheng6e2ebc92009-07-25 00:33:29 +000036def SDT_ARMBr2JT : SDTypeProfile<0, 4,
37 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
38 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +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
45def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
Jim Grosbach4a9025e2009-05-14 00:46:35 +000046def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000047
48// Node definitions.
49def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
50def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
51
Bill Wendling7173da52007-11-13 09:19:02 +000052def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
Bill Wendling6c02cd22008-02-27 06:33:05 +000053 [SDNPHasChain, SDNPOutFlag]>;
Bill Wendling7173da52007-11-13 09:19:02 +000054def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
Bill Wendling6c02cd22008-02-27 06:33:05 +000055 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000056
57def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
58 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
59def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
60 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
61def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
62 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
63
Chris Lattner3d254552008-01-15 22:02:54 +000064def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Cheng6e2ebc92009-07-25 00:33:29 +000078def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
79 [SDNPHasChain]>;
80
Dan Gohmanf17a25c2007-07-18 16:29:46 +000081def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
82 [SDNPOutFlag]>;
83
David Goodwin8bdcbb32009-06-29 15:33:01 +000084def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
85 [SDNPOutFlag,SDNPCommutative]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000086
87def 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 ]>;
92
93def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
Jim Grosbach4a9025e2009-05-14 00:46:35 +000094def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000095
96//===----------------------------------------------------------------------===//
97// ARM Instruction Predicate Definitions.
98//
Anton Korobeynikovcba02692009-06-15 21:46:20 +000099def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
100def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
101def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
Evan Chengc8147e12009-07-06 22:05:45 +0000102def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
Bob Wilsone60fee02009-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 Korobeynikovcba02692009-06-15 21:46:20 +0000107def IsThumb : Predicate<"Subtarget->isThumb()">;
Evan Cheng36173712009-06-23 17:48:47 +0000108def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
Evan Chengb1b2abc2009-07-02 06:38:40 +0000109def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
Anton Korobeynikovcba02692009-06-15 21:46:20 +0000110def IsARM : Predicate<"!Subtarget->isThumb()">;
Bob Wilson243b37c2009-06-22 21:01:46 +0000111def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
112def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
Evan Cheng3e9a99e2009-06-26 06:10:18 +0000113def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000114def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000115
116//===----------------------------------------------------------------------===//
117// 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
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Cheng8be2a5b2009-07-08 21:03:57 +0000130 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Cheng8be2a5b2009-07-08 21:03:57 +0000136 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Gohmanfaeb4a32008-09-12 16:56:44 +0000141 int32_t v = (int32_t)N->getZExtValue();
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Gohmanfaeb4a32008-09-12 16:56:44 +0000147 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Gohmanfaeb4a32008-09-12 16:56:44 +0000152 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000153}]>;
154
155def so_imm_neg :
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000156 PatLeaf<(imm), [{
157 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
158 }], so_imm_neg_XFORM>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000159
160def so_imm_not :
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000161 PatLeaf<(imm), [{
162 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
163 }], so_imm_not_XFORM>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Gohman8181bd12008-07-27 21:46:04 +0000167 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000168}]>;
169
Evan Cheng299ee652009-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 Goodwinf354d362009-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 Cheng299ee652009-07-06 22:23:46 +0000187}] > {
188 let PrintMethod = "printBitfieldInvMaskImmOperand";
189}
190
Evan Cheng7b0249b2008-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>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000193
194//===----------------------------------------------------------------------===//
195// Operand Definitions.
196//
197
198// Branch target.
199def brtarget : Operand<OtherVT>;
200
201// 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 Cheng6e2ebc92009-07-25 00:33:29 +0000214def jt2block_operand : Operand<i32> {
215 let PrintMethod = "printJT2BlockOperand";
216}
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Cheng8be2a5b2009-07-08 21:03:57 +0000237 PatLeaf<(imm), [{
238 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
239 }]> {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000240 let PrintMethod = "printSOImmOperand";
241}
242
243// 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 Gohmanfaeb4a32008-09-12 16:56:44 +0000247 PatLeaf<(imm), [{
248 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
249 }]> {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000250 let PrintMethod = "printSOImm2PartOperand";
251}
252
253def so_imm2part_1 : SDNodeXForm<imm, [{
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000254 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
Evan Cheng8be2a5b2009-07-08 21:03:57 +0000255 return CurDAG->getTargetConstant(V, MVT::i32);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000256}]>;
257
258def so_imm2part_2 : SDNodeXForm<imm, [{
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000259 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
Evan Cheng8be2a5b2009-07-08 21:03:57 +0000260 return CurDAG->getTargetConstant(V, MVT::i32);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000261}]>;
262
263
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 Wilson970a10d2009-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
Dan Gohmanf17a25c2007-07-18 16:29:46 +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
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000328//===----------------------------------------------------------------------===//
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000329
Evan Cheng7b0249b2008-08-28 23:39:26 +0000330include "ARMInstrFormats.td"
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000331
332//===----------------------------------------------------------------------===//
Evan Cheng7b0249b2008-08-28 23:39:26 +0000333// Multiclass helpers...
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000334//
335
Evan Cheng40d64532008-08-29 07:36:24 +0000336/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000337/// binop that produces a value.
Evan Chengbdd679a2009-06-26 00:19:44 +0000338multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
339 bit Commutable = 0> {
Evan Cheng86a926a2008-11-05 18:35:52 +0000340 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000341 opc, " $dst, $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000342 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
343 let Inst{25} = 1;
344 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000345 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000346 opc, " $dst, $a, $b",
Evan Chengbdd679a2009-06-26 00:19:44 +0000347 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
Evan Cheng83a32b42009-07-07 23:40:25 +0000348 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000349 let isCommutable = Commutable;
350 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000351 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000352 opc, " $dst, $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000353 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
354 let Inst{25} = 0;
355 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000356}
357
Evan Chengd4e2f052009-06-25 20:59:23 +0000358/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000359/// instruction modifies the CSPR register.
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000360let Defs = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000361multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
362 bit Commutable = 0> {
Evan Cheng86a926a2008-11-05 18:35:52 +0000363 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000364 opc, "s $dst, $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000365 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
366 let Inst{25} = 1;
367 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000368 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000369 opc, "s $dst, $a, $b",
Evan Chengbdd679a2009-06-26 00:19:44 +0000370 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
371 let isCommutable = Commutable;
Evan Cheng83a32b42009-07-07 23:40:25 +0000372 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000373 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000374 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000375 opc, "s $dst, $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000376 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
377 let Inst{25} = 0;
378 }
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000379}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000380}
381
382/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
383/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
384/// a explicit result, only implicitly set CPSR.
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000385let Defs = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000386multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
387 bit Commutable = 0> {
Evan Cheng86a926a2008-11-05 18:35:52 +0000388 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000389 opc, " $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000390 [(opnode GPR:$a, so_imm:$b)]> {
391 let Inst{25} = 1;
392 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000393 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000394 opc, " $a, $b",
Evan Chengbdd679a2009-06-26 00:19:44 +0000395 [(opnode GPR:$a, GPR:$b)]> {
Evan Cheng83a32b42009-07-07 23:40:25 +0000396 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000397 let isCommutable = Commutable;
398 }
Evan Cheng86a926a2008-11-05 18:35:52 +0000399 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000400 opc, " $a, $b",
Evan Cheng83a32b42009-07-07 23:40:25 +0000401 [(opnode GPR:$a, so_reg:$b)]> {
402 let Inst{25} = 0;
403 }
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000404}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000405}
406
407/// 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 Cheng37afa432008-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),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000412 opc, " $dst, $Src",
Evan Cheng37afa432008-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),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000418 opc, " $dst, $Src, ror $rot",
419 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
Evan Cheng37afa432008-11-06 22:15:19 +0000420 Requires<[IsARM, HasV6]> {
421 let Inst{19-16} = 0b1111;
422 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Cheng37afa432008-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",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000430 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
431 Requires<[IsARM, HasV6]>;
Evan Cheng37afa432008-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",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000434 [(set GPR:$dst, (opnode GPR:$LHS,
435 (rotr GPR:$RHS, rot_imm:$rot)))]>,
436 Requires<[IsARM, HasV6]>;
437}
438
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000439/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
440let Uses = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000441multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
442 bit Commutable = 0> {
Evan Cheng9b4d26f2009-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 Cheng83a32b42009-07-07 23:40:25 +0000446 Requires<[IsARM, CarryDefIsUnused]> {
447 let Inst{25} = 1;
448 }
Evan Cheng9b4d26f2009-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 Chengbdd679a2009-06-26 00:19:44 +0000452 Requires<[IsARM, CarryDefIsUnused]> {
453 let isCommutable = Commutable;
Evan Cheng83a32b42009-07-07 23:40:25 +0000454 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000455 }
Evan Cheng9b4d26f2009-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 Cheng83a32b42009-07-07 23:40:25 +0000459 Requires<[IsARM, CarryDefIsUnused]> {
460 let Inst{25} = 0;
461 }
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000462 // Carry setting variants
463 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Chengd4e2f052009-06-25 20:59:23 +0000464 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000465 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
466 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng83a32b42009-07-07 23:40:25 +0000467 let Defs = [CPSR];
468 let Inst{25} = 1;
Evan Chengbdd679a2009-06-26 00:19:44 +0000469 }
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000470 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengd4e2f052009-06-25 20:59:23 +0000471 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000472 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
473 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng83a32b42009-07-07 23:40:25 +0000474 let Defs = [CPSR];
475 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000476 }
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000477 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Chengd4e2f052009-06-25 20:59:23 +0000478 DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000479 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
480 Requires<[IsARM, CarryDefIsUsed]> {
Evan Cheng83a32b42009-07-07 23:40:25 +0000481 let Defs = [CPSR];
482 let Inst{25} = 0;
Evan Chengbdd679a2009-06-26 00:19:44 +0000483 }
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000484}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000485}
486
487//===----------------------------------------------------------------------===//
488// Instructions
489//===----------------------------------------------------------------------===//
490
491//===----------------------------------------------------------------------===//
492// Miscellaneous Instructions.
493//
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000494
495/// 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 Chengd97d7142009-06-12 20:46:18 +0000499let neverHasSideEffects = 1, isNotDuplicable = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000500def CONSTPOOL_ENTRY :
Evan Chengb783fa32007-07-19 01:14:50 +0000501PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
Evan Chengf8e8b622008-11-06 17:48:05 +0000502 i32imm:$size),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000503 "${instid:label} ${cpidx:cpentry}", []>;
504
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000505let Defs = [SP], Uses = [SP] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000506def ADJCALLSTACKUP :
Bill Wendling22f8deb2007-11-13 00:44:25 +0000507PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
508 "@ ADJCALLSTACKUP $amt1",
Chris Lattnerfe5d4022008-10-11 22:08:30 +0000509 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000510
511def ADJCALLSTACKDOWN :
Evan Chengb783fa32007-07-19 01:14:50 +0000512PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000513 "@ ADJCALLSTACKDOWN $amt",
Chris Lattnerfe5d4022008-10-11 22:08:30 +0000514 [(ARMcallseq_start timm:$amt)]>;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000515}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000516
517def DWARF_LOC :
Evan Chengb783fa32007-07-19 01:14:50 +0000518PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000519 ".loc $file, $line, $col",
520 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
521
Evan Chengf8e8b622008-11-06 17:48:05 +0000522
523// Address computation and loads and stores in PIC mode.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000524let isNotDuplicable = 1 in {
Evan Cheng0d28b382008-10-31 19:11:09 +0000525def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000526 Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000527 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
528
Evan Cheng8610a3b2008-01-07 23:56:57 +0000529let AddedComplexity = 10 in {
Dan Gohman5574cc72008-12-03 18:15:48 +0000530let canFoldAsLoad = 1 in
Evan Chengbe998242008-11-06 08:47:38 +0000531def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000532 Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000533 [(set GPR:$dst, (load addrmodepc:$addr))]>;
534
Evan Chengbe998242008-11-06 08:47:38 +0000535def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000536 Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000537 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
538
Evan Chengbe998242008-11-06 08:47:38 +0000539def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000540 Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000541 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
542
Evan Chengbe998242008-11-06 08:47:38 +0000543def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000544 Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000545 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
546
Evan Chengbe998242008-11-06 08:47:38 +0000547def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000548 Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000549 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
550}
Chris Lattnerf823faf2008-01-06 05:55:01 +0000551let AddedComplexity = 10 in {
Evan Chengbe998242008-11-06 08:47:38 +0000552def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000553 Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000554 [(store GPR:$src, addrmodepc:$addr)]>;
555
Evan Chengbe998242008-11-06 08:47:38 +0000556def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000557 Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000558 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
559
Evan Chengbe998242008-11-06 08:47:38 +0000560def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000561 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000562 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
563}
Evan Chengf8e8b622008-11-06 17:48:05 +0000564} // isNotDuplicable = 1
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000565
Evan Chenga1366cd2009-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 Cheng9cf1e3e2009-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 Chenga1366cd2009-06-23 05:25:29 +0000574 []>;
575
Evan Chengba83d7c2009-06-24 23:14:45 +0000576def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
577 (ins i32imm:$label, i32imm:$id, pred:$p),
Evan Chenga1366cd2009-06-23 05:25:29 +0000578 Pseudo,
Evan Cheng9cf1e3e2009-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 Cheng83a32b42009-07-07 23:40:25 +0000584 []> {
585 let Inst{25} = 1;
586}
Evan Chenga1366cd2009-06-23 05:25:29 +0000587
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000588//===----------------------------------------------------------------------===//
589// Control Flow Instructions.
590//
591
592let isReturn = 1, isTerminator = 1 in
Evan Chengf8e8b622008-11-06 17:48:05 +0000593 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
Jim Grosbach88c246f2008-10-14 20:36:24 +0000594 let Inst{7-4} = 0b0001;
595 let Inst{19-8} = 0b111111111111;
596 let Inst{27-20} = 0b00010010;
Evan Cheng469bc762008-09-17 07:53:38 +0000597}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000598
599// FIXME: remove when we have a way to marking a MI with these properties.
Evan Chengb783fa32007-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 Chengf8e8b622008-11-06 17:48:05 +0000602// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Cheng7bd57f82009-07-09 22:57:41 +0000603let isReturn = 1, isTerminator = 1, mayLoad = 1 in
Evan Chengf8e8b622008-11-06 17:48:05 +0000604 def LDM_RET : AXI4ld<(outs),
Evan Chengb783fa32007-07-19 01:14:50 +0000605 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng11838a82008-11-12 07:18:38 +0000606 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000607 []>;
608
Bob Wilson243b37c2009-06-22 21:01:46 +0000609// On non-Darwin platforms R9 is callee-saved.
Evan Cheng88e78d22009-06-19 01:51:50 +0000610let isCall = 1, Itinerary = IIC_Br,
Evan Cheng27396a62009-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 Chengf8e8b622008-11-06 17:48:05 +0000615 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000616 "bl ${func:call}",
Bob Wilson243b37c2009-06-22 21:01:46 +0000617 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000618
Evan Chengf8e8b622008-11-06 17:48:05 +0000619 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
Evan Cheng10a9eb82008-09-01 08:25:56 +0000620 "bl", " ${func:call}",
Bob Wilson243b37c2009-06-22 21:01:46 +0000621 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000622
623 // ARMv5T and above
Evan Chengf8e8b622008-11-06 17:48:05 +0000624 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
Evan Chengb783fa32007-07-19 01:14:50 +0000625 "blx $func",
Bob Wilson243b37c2009-06-22 21:01:46 +0000626 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
Jim Grosbach88c246f2008-10-14 20:36:24 +0000627 let Inst{7-4} = 0b0011;
628 let Inst{19-8} = 0b111111111111;
629 let Inst{27-20} = 0b00010010;
Evan Cheng469bc762008-09-17 07:53:38 +0000630 }
631
Evan Chengfb1d1472009-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 Wilson243b37c2009-06-22 21:01:46 +0000639 }
640}
641
642// On Darwin R9 is call-clobbered.
643let isCall = 1, Itinerary = IIC_Br,
Evan Cheng27396a62009-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 Wilson243b37c2009-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 Chengfb1d1472009-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;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000672 }
673}
674
Evan Cheng88e78d22009-06-19 01:51:50 +0000675let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000676 // B is "predicable" since it can be xformed into a Bcc.
677 let isBarrier = 1 in {
678 let isPredicable = 1 in
Evan Chengf8e8b622008-11-06 17:48:05 +0000679 def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
Evan Chengb783fa32007-07-19 01:14:50 +0000680 [(br bb:$target)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000681
Owen Andersonf8053082007-11-12 07:39:39 +0000682 let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng0f63ae12008-11-07 09:06:08 +0000683 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
Evan Chengb783fa32007-07-19 01:14:50 +0000684 "mov pc, $target \n$jt",
Evan Cheng0f63ae12008-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 Chenge5f32ae2009-07-07 23:45:10 +0000688 let Inst{27-25} = 0b000;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000689 }
Evan Cheng0f63ae12008-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 Chenge5f32ae2009-07-07 23:45:10 +0000699 let Inst{27-25} = 0b011;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000700 }
Evan Cheng0f63ae12008-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 Chenge5f32ae2009-07-07 23:45:10 +0000708 let Inst{27-25} = 0b000;
Evan Cheng0f63ae12008-11-07 09:06:08 +0000709 }
710 } // isNotDuplicable = 1, isIndirectBranch = 1
711 } // isBarrier = 1
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000712
713 // 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 Chengf8e8b622008-11-06 17:48:05 +0000715 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000716 "b", " $target",
717 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000718}
719
720//===----------------------------------------------------------------------===//
721// Load / store Instructions.
722//
723
724// Load
Dan Gohman5574cc72008-12-03 18:15:48 +0000725let canFoldAsLoad = 1 in
Evan Cheng81794bb2008-11-13 07:34:59 +0000726def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000727 "ldr", " $dst, $addr",
728 [(set GPR:$dst, (load addrmode2:$addr))]>;
729
730// Special LDR for loads from non-pc-relative constpools.
Dan Gohman5574cc72008-12-03 18:15:48 +0000731let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
Evan Cheng81794bb2008-11-13 07:34:59 +0000732def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000733 "ldr", " $dst, $addr", []>;
734
735// Loads with zero extension
Evan Cheng81794bb2008-11-13 07:34:59 +0000736def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000737 "ldr", "h $dst, $addr",
738 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
739
Evan Cheng81794bb2008-11-13 07:34:59 +0000740def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000741 "ldr", "b $dst, $addr",
742 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
743
744// Loads with sign extension
Evan Cheng81794bb2008-11-13 07:34:59 +0000745def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000746 "ldr", "sh $dst, $addr",
747 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
748
Evan Cheng81794bb2008-11-13 07:34:59 +0000749def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000750 "ldr", "sb $dst, $addr",
751 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
752
Chris Lattnerca4e0fe2008-01-10 05:12:37 +0000753let mayLoad = 1 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000754// Load doubleword
Evan Cheng41169552009-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]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000757
758// Indexed loads
Evan Chengbe998242008-11-06 08:47:38 +0000759def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000760 (ins addrmode2:$addr), LdFrm,
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000761 "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000762
Evan Chengbe998242008-11-06 08:47:38 +0000763def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000764 (ins GPR:$base, am2offset:$offset), LdFrm,
Evan Chenga7b3e7c2007-08-07 01:37:15 +0000765 "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000766
Evan Chengbe998242008-11-06 08:47:38 +0000767def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000768 (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000769 "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
770
Evan Chengbe998242008-11-06 08:47:38 +0000771def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000772 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000773 "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
774
Evan Chengbe998242008-11-06 08:47:38 +0000775def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000776 (ins addrmode2:$addr), LdFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000777 "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
778
Evan Chengbe998242008-11-06 08:47:38 +0000779def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000780 (ins GPR:$base,am2offset:$offset), LdFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000781 "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
782
Evan Chengbe998242008-11-06 08:47:38 +0000783def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000784 (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000785 "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
786
Evan Chengbe998242008-11-06 08:47:38 +0000787def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000788 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
789 "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000790
Evan Chengbe998242008-11-06 08:47:38 +0000791def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000792 (ins addrmode3:$addr), LdMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000793 "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
794
Evan Chengbe998242008-11-06 08:47:38 +0000795def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000796 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
Evan Chengb04191f2009-07-02 01:30:04 +0000797 "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
Chris Lattnerca4e0fe2008-01-10 05:12:37 +0000798}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000799
800// Store
Evan Cheng81794bb2008-11-13 07:34:59 +0000801def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000802 "str", " $src, $addr",
803 [(store GPR:$src, addrmode2:$addr)]>;
804
805// Stores with truncate
Evan Cheng81794bb2008-11-13 07:34:59 +0000806def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000807 "str", "h $src, $addr",
808 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
809
Evan Cheng81794bb2008-11-13 07:34:59 +0000810def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000811 "str", "b $src, $addr",
812 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
813
814// Store doubleword
Chris Lattner6887b142008-01-06 08:36:04 +0000815let mayStore = 1 in
Evan Cheng41169552009-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]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000818
819// Indexed stores
Evan Chengbe998242008-11-06 08:47:38 +0000820def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000821 (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000822 "str", " $src, [$base, $offset]!", "$base = $base_wb",
823 [(set GPR:$base_wb,
824 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
825
Evan Chengbe998242008-11-06 08:47:38 +0000826def STR_POST : AI2stwpo<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000827 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000828 "str", " $src, [$base], $offset", "$base = $base_wb",
829 [(set GPR:$base_wb,
830 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
831
Evan Chengbe998242008-11-06 08:47:38 +0000832def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000833 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000834 "str", "h $src, [$base, $offset]!", "$base = $base_wb",
835 [(set GPR:$base_wb,
836 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
837
Evan Chengbe998242008-11-06 08:47:38 +0000838def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000839 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000840 "str", "h $src, [$base], $offset", "$base = $base_wb",
841 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
842 GPR:$base, am3offset:$offset))]>;
843
Evan Chengbe998242008-11-06 08:47:38 +0000844def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000845 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000846 "str", "b $src, [$base, $offset]!", "$base = $base_wb",
847 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
848 GPR:$base, am2offset:$offset))]>;
849
Evan Chengbe998242008-11-06 08:47:38 +0000850def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
Evan Cheng81794bb2008-11-13 07:34:59 +0000851 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000852 "str", "b $src, [$base], $offset", "$base = $base_wb",
853 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
854 GPR:$base, am2offset:$offset))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000855
856//===----------------------------------------------------------------------===//
857// Load / store multiple Instructions.
858//
859
Evan Chengb783fa32007-07-19 01:14:50 +0000860// FIXME: $dst1 should be a def.
Chris Lattnerca4e0fe2008-01-10 05:12:37 +0000861let mayLoad = 1 in
Evan Chengbe998242008-11-06 08:47:38 +0000862def LDM : AXI4ld<(outs),
Evan Chengb783fa32007-07-19 01:14:50 +0000863 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng11838a82008-11-12 07:18:38 +0000864 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000865 []>;
866
Chris Lattner6887b142008-01-06 08:36:04 +0000867let mayStore = 1 in
Evan Chengbe998242008-11-06 08:47:38 +0000868def STM : AXI4st<(outs),
Evan Chengb783fa32007-07-19 01:14:50 +0000869 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
Evan Cheng11838a82008-11-12 07:18:38 +0000870 LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000871 []>;
872
873//===----------------------------------------------------------------------===//
874// Move Instructions.
875//
876
Evan Chengd97d7142009-06-12 20:46:18 +0000877let neverHasSideEffects = 1 in
Evan Cheng86a926a2008-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;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000882
Evan Chengbd0ca9c2009-02-05 08:42:55 +0000883let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng86a926a2008-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;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000886
Evan Cheng7f240d22008-11-14 20:09:11 +0000887def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Evan Chengb783fa32007-07-19 01:14:50 +0000888 "mov", " $dst, $src, rrx",
Evan Cheng86a926a2008-11-05 18:35:52 +0000889 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000890
891// These aren't really mov instructions, but we have to define them this way
892// due to flag operands.
893
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000894let Defs = [CPSR] in {
Evan Cheng7f240d22008-11-14 20:09:11 +0000895def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000896 "mov", "s $dst, $src, lsr #1",
Evan Cheng86a926a2008-11-05 18:35:52 +0000897 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
Evan Cheng7f240d22008-11-14 20:09:11 +0000898def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000899 "mov", "s $dst, $src, asr #1",
Evan Cheng86a926a2008-11-05 18:35:52 +0000900 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000901}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000902
903//===----------------------------------------------------------------------===//
904// Extend Instructions.
905//
906
907// Sign extenders
908
Evan Cheng37afa432008-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)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000913
Evan Cheng37afa432008-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))>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000918
919// TODO: SXT(A){B|H}16
920
921// Zero extenders
922
923let AddedComplexity = 16 in {
Evan Cheng37afa432008-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)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000930
Bob Wilson74590a02009-06-22 22:08:29 +0000931def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000932 (UXTB16r_rot GPR:$Src, 24)>;
Bob Wilson74590a02009-06-22 22:08:29 +0000933def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000934 (UXTB16r_rot GPR:$Src, 8)>;
935
Evan Cheng37afa432008-11-06 22:15:19 +0000936defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000937 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
Evan Cheng37afa432008-11-06 22:15:19 +0000938defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000939 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
940}
941
942// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
943//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
944
945// TODO: UXT(A){B|H}16
946
947//===----------------------------------------------------------------------===//
948// Arithmetic Instructions.
949//
950
Jim Grosbach88c246f2008-10-14 20:36:24 +0000951defm ADD : AsI1_bin_irs<0b0100, "add",
Evan Chengbdd679a2009-06-26 00:19:44 +0000952 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Jim Grosbach88c246f2008-10-14 20:36:24 +0000953defm SUB : AsI1_bin_irs<0b0010, "sub",
Evan Cheng469bc762008-09-17 07:53:38 +0000954 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000955
956// ADD and SUB with 's' bit set.
Evan Chengd4e2f052009-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)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000961
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000962defm ADC : AI1_adde_sube_irs<0b0101, "adc",
Evan Chengbdd679a2009-06-26 00:19:44 +0000963 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000964defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
965 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000966
967// These don't define reg/reg forms, because they are handled above.
Evan Cheng86a926a2008-11-05 18:35:52 +0000968def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000969 "rsb", " $dst, $a, $b",
970 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
971
Evan Cheng86a926a2008-11-05 18:35:52 +0000972def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000973 "rsb", " $dst, $a, $b",
974 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
975
976// RSB with 's' bit set.
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000977let Defs = [CPSR] in {
Evan Cheng86a926a2008-11-05 18:35:52 +0000978def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000979 "rsb", "s $dst, $a, $b",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000980 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
Evan Cheng86a926a2008-11-05 18:35:52 +0000981def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000982 "rsb", "s $dst, $a, $b",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000983 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
984}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000985
Evan Cheng9b4d26f2009-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 Chengd4e2f052009-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 Cheng9b4d26f2009-06-25 23:34:10 +00001001 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1002 Requires<[IsARM, CarryDefIsUnused]>;
Evan Chengd4e2f052009-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 Cheng9b4d26f2009-06-25 23:34:10 +00001005 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1006 Requires<[IsARM, CarryDefIsUnused]>;
Evan Cheng6e4d1d92007-09-11 19:55:27 +00001007}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001008
1009// (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 Grosbach88c246f2008-10-14 20:36:24 +00001029defm AND : AsI1_bin_irs<0b0000, "and",
Evan Chengbdd679a2009-06-26 00:19:44 +00001030 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
Jim Grosbach88c246f2008-10-14 20:36:24 +00001031defm ORR : AsI1_bin_irs<0b1100, "orr",
Evan Chengbdd679a2009-06-26 00:19:44 +00001032 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
Jim Grosbach88c246f2008-10-14 20:36:24 +00001033defm EOR : AsI1_bin_irs<0b0001, "eor",
Evan Chengbdd679a2009-06-26 00:19:44 +00001034 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Jim Grosbach88c246f2008-10-14 20:36:24 +00001035defm BIC : AsI1_bin_irs<0b1110, "bic",
Evan Cheng469bc762008-09-17 07:53:38 +00001036 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001037
Evan Cheng299ee652009-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 Cheng86a926a2008-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 Chengbd0ca9c2009-02-05 08:42:55 +00001053let isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng86a926a2008-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;
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Chengbdd679a2009-06-26 00:19:44 +00001065let isCommutable = 1 in
Evan Chengee80fb72008-11-06 01:21:28 +00001066def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Chengf8e8b622008-11-06 17:48:05 +00001067 "mul", " $dst, $a, $b",
1068 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001069
Evan Chengee80fb72008-11-06 01:21:28 +00001070def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Chengf8e8b622008-11-06 17:48:05 +00001071 "mla", " $dst, $a, $b, $c",
1072 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001073
Evan Chengc8147e12009-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
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001079// Extra precision multiplies with low / high results
Evan Chengd97d7142009-06-12 20:46:18 +00001080let neverHasSideEffects = 1 in {
Evan Chengbdd679a2009-06-26 00:19:44 +00001081let isCommutable = 1 in {
Evan Chengee80fb72008-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", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001085
Evan Chengee80fb72008-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 Chengbdd679a2009-06-26 00:19:44 +00001089}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001090
1091// Multiply + accumulate
Evan Chengee80fb72008-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", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001095
Evan Chengee80fb72008-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", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001099
Evan Chengee80fb72008-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 Chengd97d7142009-06-12 20:46:18 +00001104} // neverHasSideEffects
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001105
1106// Most significant word multiply
Evan Chengee80fb72008-11-06 01:21:28 +00001107def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001108 "smmul", " $dst, $a, $b",
1109 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
Evan Chengee80fb72008-11-06 01:21:28 +00001110 Requires<[IsARM, HasV6]> {
1111 let Inst{7-4} = 0b0001;
1112 let Inst{15-12} = 0b1111;
1113}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001114
Evan Chengee80fb72008-11-06 01:21:28 +00001115def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001116 "smmla", " $dst, $a, $b, $c",
1117 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
Evan Chengee80fb72008-11-06 01:21:28 +00001118 Requires<[IsARM, HasV6]> {
1119 let Inst{7-4} = 0b0001;
1120}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001121
1122
Evan Chengee80fb72008-11-06 01:21:28 +00001123def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001124 "smmls", " $dst, $a, $b, $c",
1125 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
Evan Chengee80fb72008-11-06 01:21:28 +00001126 Requires<[IsARM, HasV6]> {
1127 let Inst{7-4} = 0b1101;
1128}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001129
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001130multiclass AI_smul<string opc, PatFrag opnode> {
Evan Cheng38396be2008-11-06 03:35:07 +00001131 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001132 !strconcat(opc, "bb"), " $dst, $a, $b",
1133 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1134 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001135 Requires<[IsARM, HasV5TE]> {
1136 let Inst{5} = 0;
1137 let Inst{6} = 0;
1138 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001139
Evan Cheng38396be2008-11-06 03:35:07 +00001140 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001141 !strconcat(opc, "bt"), " $dst, $a, $b",
1142 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
Bob Wilson74590a02009-06-22 22:08:29 +00001143 (sra GPR:$b, (i32 16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001144 Requires<[IsARM, HasV5TE]> {
1145 let Inst{5} = 0;
1146 let Inst{6} = 1;
1147 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001148
Evan Cheng38396be2008-11-06 03:35:07 +00001149 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001150 !strconcat(opc, "tb"), " $dst, $a, $b",
Bob Wilson74590a02009-06-22 22:08:29 +00001151 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001152 (sext_inreg GPR:$b, i16)))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001153 Requires<[IsARM, HasV5TE]> {
1154 let Inst{5} = 1;
1155 let Inst{6} = 0;
1156 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001157
Evan Cheng38396be2008-11-06 03:35:07 +00001158 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001159 !strconcat(opc, "tt"), " $dst, $a, $b",
Bob Wilson74590a02009-06-22 22:08:29 +00001160 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1161 (sra GPR:$b, (i32 16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001162 Requires<[IsARM, HasV5TE]> {
1163 let Inst{5} = 1;
1164 let Inst{6} = 1;
1165 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001166
Evan Cheng38396be2008-11-06 03:35:07 +00001167 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001168 !strconcat(opc, "wb"), " $dst, $a, $b",
1169 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilson74590a02009-06-22 22:08:29 +00001170 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001171 Requires<[IsARM, HasV5TE]> {
1172 let Inst{5} = 1;
1173 let Inst{6} = 0;
1174 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001175
Evan Cheng38396be2008-11-06 03:35:07 +00001176 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001177 !strconcat(opc, "wt"), " $dst, $a, $b",
1178 [(set GPR:$dst, (sra (opnode GPR:$a,
Bob Wilson74590a02009-06-22 22:08:29 +00001179 (sra GPR:$b, (i32 16))), (i32 16)))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001180 Requires<[IsARM, HasV5TE]> {
1181 let Inst{5} = 1;
1182 let Inst{6} = 1;
1183 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001184}
1185
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001186
1187multiclass AI_smla<string opc, PatFrag opnode> {
Evan Cheng38396be2008-11-06 03:35:07 +00001188 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001189 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
1190 [(set GPR:$dst, (add GPR:$acc,
1191 (opnode (sext_inreg GPR:$a, i16),
1192 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001193 Requires<[IsARM, HasV5TE]> {
1194 let Inst{5} = 0;
1195 let Inst{6} = 0;
1196 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001197
Evan Cheng38396be2008-11-06 03:35:07 +00001198 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001199 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
1200 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Bob Wilson74590a02009-06-22 22:08:29 +00001201 (sra GPR:$b, (i32 16)))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001202 Requires<[IsARM, HasV5TE]> {
1203 let Inst{5} = 0;
1204 let Inst{6} = 1;
1205 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001206
Evan Cheng38396be2008-11-06 03:35:07 +00001207 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001208 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
Bob Wilson74590a02009-06-22 22:08:29 +00001209 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001210 (sext_inreg GPR:$b, i16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001211 Requires<[IsARM, HasV5TE]> {
1212 let Inst{5} = 1;
1213 let Inst{6} = 0;
1214 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001215
Evan Cheng38396be2008-11-06 03:35:07 +00001216 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001217 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
Bob Wilson74590a02009-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 Cheng38396be2008-11-06 03:35:07 +00001220 Requires<[IsARM, HasV5TE]> {
1221 let Inst{5} = 1;
1222 let Inst{6} = 1;
1223 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001224
Evan Cheng38396be2008-11-06 03:35:07 +00001225 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001226 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
1227 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilson74590a02009-06-22 22:08:29 +00001228 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001229 Requires<[IsARM, HasV5TE]> {
1230 let Inst{5} = 0;
1231 let Inst{6} = 0;
1232 }
Raul Herbster2e07e8d2007-08-30 23:25:47 +00001233
Evan Cheng38396be2008-11-06 03:35:07 +00001234 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001235 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
1236 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
Bob Wilson74590a02009-06-22 22:08:29 +00001237 (sra GPR:$b, (i32 16))), (i32 16))))]>,
Evan Cheng38396be2008-11-06 03:35:07 +00001238 Requires<[IsARM, HasV5TE]> {
1239 let Inst{5} = 0;
1240 let Inst{6} = 1;
1241 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001242}
1243
Raul Herbster2e07e8d2007-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)>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001246
1247// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1248// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1249
1250//===----------------------------------------------------------------------===//
1251// Misc. Arithmetic Instructions.
1252//
1253
Evan Chengc2121a22008-11-07 01:41:35 +00001254def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001255 "clz", " $dst, $src",
Evan Chengc2121a22008-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}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001261
Evan Chengc2121a22008-11-07 01:41:35 +00001262def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001263 "rev", " $dst, $src",
Evan Chengc2121a22008-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}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001269
Evan Chengc2121a22008-11-07 01:41:35 +00001270def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001271 "rev16", " $dst, $src",
1272 [(set GPR:$dst,
Bob Wilson74590a02009-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 Chengc2121a22008-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}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001282
Evan Chengc2121a22008-11-07 01:41:35 +00001283def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001284 "revsh", " $dst, $src",
1285 [(set GPR:$dst,
1286 (sext_inreg
Bob Wilson74590a02009-06-22 22:08:29 +00001287 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1288 (shl GPR:$src, (i32 8))), i16))]>,
Evan Chengc2121a22008-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}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001294
Evan Chengc2121a22008-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",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001298 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1299 (and (shl GPR:$src2, (i32 imm:$shamt)),
1300 0xFFFF0000)))]>,
Evan Chengc2121a22008-11-07 01:41:35 +00001301 Requires<[IsARM, HasV6]> {
1302 let Inst{6-4} = 0b001;
1303}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001304
1305// 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)>;
1310
1311
Evan Chengc2121a22008-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",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001315 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1316 (and (sra GPR:$src2, imm16_31:$shamt),
Evan Chengc2121a22008-11-07 01:41:35 +00001317 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1318 let Inst{6-4} = 0b101;
1319}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001320
1321// 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 Wilson74590a02009-06-22 22:08:29 +00001323def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +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)>;
1328
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001329//===----------------------------------------------------------------------===//
1330// Comparison Instructions...
1331//
1332
Jim Grosbach88c246f2008-10-14 20:36:24 +00001333defm CMP : AI1_cmp_irs<0b1010, "cmp",
Evan Chenga7b3e7c2007-08-07 01:37:15 +00001334 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
Jim Grosbach88c246f2008-10-14 20:36:24 +00001335defm CMN : AI1_cmp_irs<0b1011, "cmn",
Evan Chenga7b3e7c2007-08-07 01:37:15 +00001336 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001337
1338// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Chengbe998242008-11-06 08:47:38 +00001339defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwin8bdcbb32009-06-29 15:33:01 +00001340 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Chengbe998242008-11-06 08:47:38 +00001341defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwin8bdcbb32009-06-29 15:33:01 +00001342 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001343
David Goodwin8bdcbb32009-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))>>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001348
1349def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1350 (CMNri GPR:$src, so_imm_neg:$imm)>;
1351
David Goodwin8bdcbb32009-06-29 15:33:01 +00001352def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001353 (CMNri GPR:$src, so_imm_neg:$imm)>;
1354
1355
1356// Conditional moves
1357// 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 Chengbe998242008-11-06 08:47:38 +00001359def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Cheng86a926a2008-11-05 18:35:52 +00001360 "mov", " $dst, $true",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001361 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Chengbe998242008-11-06 08:47:38 +00001362 RegConstraint<"$false = $dst">, UnaryDP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001363
Evan Chengbe998242008-11-06 08:47:38 +00001364def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1365 (ins GPR:$false, so_reg:$true), DPSoRegFrm,
Evan Cheng86a926a2008-11-05 18:35:52 +00001366 "mov", " $dst, $true",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001367 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng86a926a2008-11-05 18:35:52 +00001368 RegConstraint<"$false = $dst">, UnaryDP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001369
Evan Chengbe998242008-11-06 08:47:38 +00001370def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1371 (ins GPR:$false, so_imm:$true), DPFrm,
Evan Cheng86a926a2008-11-05 18:35:52 +00001372 "mov", " $dst, $true",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001373 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng86a926a2008-11-05 18:35:52 +00001374 RegConstraint<"$false = $dst">, UnaryDP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001375
1376
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001377//===----------------------------------------------------------------------===//
1378// TLS Instructions
1379//
1380
1381// __aeabi_read_tp preserves the registers r1-r3.
1382let isCall = 1,
1383 Defs = [R0, R12, LR, CPSR] in {
Evan Chengf8e8b622008-11-06 17:48:05 +00001384 def TPsoft : ABXI<0b1011, (outs), (ins),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001385 "bl __aeabi_read_tp",
1386 [(set R0, ARMthread_pointer)]>;
1387}
1388
1389//===----------------------------------------------------------------------===//
Jim Grosbachc10915b2009-05-12 23:59:14 +00001390// SJLJ Exception handling intrinsics
Jim Grosbach4a9025e2009-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 Grosbachc10915b2009-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 Grosbach4a9025e2009-05-14 00:46:35 +00001396// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
Jim Grosbachc10915b2009-05-12 23:59:14 +00001397// when we get here from a longjmp(). We force everthing out of registers
Jim Grosbach4a9025e2009-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 Grosbachc10915b2009-05-12 23:59:14 +00001401let Defs =
Evan Cheng27396a62009-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 Grosbach4a9025e2009-05-14 00:46:35 +00001406 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
Jim Grosbachc10915b2009-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 Grosbach4a9025e2009-05-14 00:46:35 +00001410 "mov r0, #0 @ eh_setjmp", "",
1411 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
Jim Grosbachc10915b2009-05-12 23:59:14 +00001412}
1413
1414//===----------------------------------------------------------------------===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001415// Non-Instruction Patterns
1416//
1417
1418// 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),
1422 (LEApcrelJT tjumptable:$dst, imm:$id)>;
1423
1424// Large immediate handling.
1425
1426// Two piece so_imms.
1427let isReMaterializable = 1 in
Evan Chengbe998242008-11-06 08:47:38 +00001428def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001429 "mov", " $dst, $src",
Evan Cheng7cd4acb2008-11-06 02:25:39 +00001430 [(set GPR:$dst, so_imm2part:$src)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001431
1432def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
Evan Cheng8be2a5b2009-07-08 21:03:57 +00001433 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1434 (so_imm2part_2 imm:$RHS))>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001435def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
Evan Cheng8be2a5b2009-07-08 21:03:57 +00001436 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1437 (so_imm2part_2 imm:$RHS))>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001438
1439// TODO: add,sub,and, 3-instr forms?
1440
1441
1442// Direct calls
Bob Wilson243b37c2009-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]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001447
1448// zextload i1 -> zextload i8
1449def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1450
1451// 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)>;
1455
Evan Chengc41fb3152008-11-05 23:22:34 +00001456def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1457def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1458
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001459// smul* and smla*
Bob Wilson74590a02009-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))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001462 (SMULBB GPR:$a, GPR:$b)>;
1463def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1464 (SMULBB GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001465def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1466 (sra GPR:$b, (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001467 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001468def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001469 (SMULBT GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001470def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1471 (sra (shl GPR:$b, (i32 16)), (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001472 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001473def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001474 (SMULTB GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001475def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1476 (i32 16)),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001477 (SMULWB GPR:$a, GPR:$b)>;
Bob Wilson74590a02009-06-22 22:08:29 +00001478def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001479 (SMULWB GPR:$a, GPR:$b)>;
1480
1481def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001482 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1483 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Wilson74590a02009-06-22 22:08:29 +00001489 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1490 (sra GPR:$b, (i32 16)))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001491 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1492def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001493 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001494 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1495def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001496 (mul (sra GPR:$a, (i32 16)),
1497 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001498 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1499def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001500 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001501 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1502def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001503 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1504 (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001505 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1506def : ARMV5TEPat<(add GPR:$acc,
Bob Wilson74590a02009-06-22 22:08:29 +00001507 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001508 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1509
1510//===----------------------------------------------------------------------===//
1511// Thumb Support
1512//
1513
1514include "ARMInstrThumb.td"
1515
1516//===----------------------------------------------------------------------===//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +00001517// Thumb2 Support
1518//
1519
1520include "ARMInstrThumb2.td"
1521
1522//===----------------------------------------------------------------------===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001523// Floating Point Support
1524//
1525
1526include "ARMInstrVFP.td"
Bob Wilsone60fee02009-06-22 23:27:02 +00001527
1528//===----------------------------------------------------------------------===//
1529// Advanced SIMD (NEON) Support
1530//
1531
1532include "ARMInstrNEON.td"