ARMInstrInfo.td revision 202878
1//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// 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.
19def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20def SDT_ARMCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
21
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>]>;
36
37def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
38                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39                                   SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
40
41def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
42
43def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
45
46def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
48
49def SDT_ARMMEMBARRIERV7  : SDTypeProfile<0, 0, []>;
50def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
51def SDT_ARMMEMBARRIERV6  : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
52def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
53
54// Node definitions.
55def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
56def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
57
58def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
59                              [SDNPHasChain, SDNPOutFlag]>;
60def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
61                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
62
63def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
64                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
65def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
66                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
67def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
68                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
69
70def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
71                              [SDNPHasChain, SDNPOptInFlag]>;
72
73def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
74                              [SDNPInFlag]>;
75def ARMcneg          : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
76                              [SDNPInFlag]>;
77
78def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
79                              [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
80
81def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
82                              [SDNPHasChain]>;
83def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
84                              [SDNPHasChain]>;
85
86def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
87                              [SDNPOutFlag]>;
88
89def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
90                              [SDNPOutFlag,SDNPCommutative]>;
91
92def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
93
94def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
95def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInFlag ]>;
97
98def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
99def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
100
101def ARMMemBarrierV7  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
102                              [SDNPHasChain]>;
103def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
104                              [SDNPHasChain]>;
105def ARMMemBarrierV6  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
106                              [SDNPHasChain]>;
107def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
108                              [SDNPHasChain]>;
109
110def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
111
112//===----------------------------------------------------------------------===//
113// ARM Instruction Predicate Definitions.
114//
115def HasV5T    : Predicate<"Subtarget->hasV5TOps()">;
116def HasV5TE   : Predicate<"Subtarget->hasV5TEOps()">;
117def HasV6     : Predicate<"Subtarget->hasV6Ops()">;
118def HasV6T2   : Predicate<"Subtarget->hasV6T2Ops()">;
119def NoV6T2    : Predicate<"!Subtarget->hasV6T2Ops()">;
120def HasV7     : Predicate<"Subtarget->hasV7Ops()">;
121def HasVFP2   : Predicate<"Subtarget->hasVFP2()">;
122def HasVFP3   : Predicate<"Subtarget->hasVFP3()">;
123def HasNEON   : Predicate<"Subtarget->hasNEON()">;
124def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
125def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
126def IsThumb   : Predicate<"Subtarget->isThumb()">;
127def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
128def IsThumb2  : Predicate<"Subtarget->isThumb2()">;
129def IsARM     : Predicate<"!Subtarget->isThumb()">;
130def IsDarwin    : Predicate<"Subtarget->isTargetDarwin()">;
131def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
132def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
133def CarryDefIsUsed   : Predicate<"N->hasAnyUseOfValue(1)">;
134
135// FIXME: Eventually this will be just "hasV6T2Ops".
136def UseMovt   : Predicate<"Subtarget->useMovt()">;
137def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
138
139//===----------------------------------------------------------------------===//
140// ARM Flag Definitions.
141
142class RegConstraint<string C> {
143  string Constraints = C;
144}
145
146//===----------------------------------------------------------------------===//
147//  ARM specific transformation functions and pattern fragments.
148//
149
150// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
151// so_imm_neg def below.
152def so_imm_neg_XFORM : SDNodeXForm<imm, [{
153  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
154}]>;
155
156// so_imm_not_XFORM - Return a so_imm value packed into the format described for
157// so_imm_not def below.
158def so_imm_not_XFORM : SDNodeXForm<imm, [{
159  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
160}]>;
161
162// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
163def rot_imm : PatLeaf<(i32 imm), [{
164  int32_t v = (int32_t)N->getZExtValue();
165  return v == 8 || v == 16 || v == 24;
166}]>;
167
168/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
169def imm1_15 : PatLeaf<(i32 imm), [{
170  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
171}]>;
172
173/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
174def imm16_31 : PatLeaf<(i32 imm), [{
175  return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
176}]>;
177
178def so_imm_neg : 
179  PatLeaf<(imm), [{
180    return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
181  }], so_imm_neg_XFORM>;
182
183def so_imm_not :
184  PatLeaf<(imm), [{
185    return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
186  }], so_imm_not_XFORM>;
187
188// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
189def sext_16_node : PatLeaf<(i32 GPR:$a), [{
190  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
191}]>;
192
193/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
194/// e.g., 0xf000ffff
195def bf_inv_mask_imm : Operand<i32>,
196                      PatLeaf<(imm), [{ 
197  uint32_t v = (uint32_t)N->getZExtValue();
198  if (v == 0xffffffff)
199    return 0;
200  // there can be 1's on either or both "outsides", all the "inside"
201  // bits must be 0's
202  unsigned int lsb = 0, msb = 31;
203  while (v & (1 << msb)) --msb;
204  while (v & (1 << lsb)) ++lsb;
205  for (unsigned int i = lsb; i <= msb; ++i) {
206    if (v & (1 << i))
207      return 0;
208  }
209  return 1;
210}] > {
211  let PrintMethod = "printBitfieldInvMaskImmOperand";
212}
213
214/// Split a 32-bit immediate into two 16 bit parts.
215def lo16 : SDNodeXForm<imm, [{
216  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
217                                   MVT::i32);
218}]>;
219
220def hi16 : SDNodeXForm<imm, [{
221  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
222}]>;
223
224def lo16AllZero : PatLeaf<(i32 imm), [{
225  // Returns true if all low 16-bits are 0.
226  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
227}], hi16>;
228
229/// imm0_65535 predicate - True if the 32-bit immediate is in the range 
230/// [0.65535].
231def imm0_65535 : PatLeaf<(i32 imm), [{
232  return (uint32_t)N->getZExtValue() < 65536;
233}]>;
234
235class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
236class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
237
238//===----------------------------------------------------------------------===//
239// Operand Definitions.
240//
241
242// Branch target.
243def brtarget : Operand<OtherVT>;
244
245// A list of registers separated by comma. Used by load/store multiple.
246def reglist : Operand<i32> {
247  let PrintMethod = "printRegisterList";
248}
249
250// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
251def cpinst_operand : Operand<i32> {
252  let PrintMethod = "printCPInstOperand";
253}
254
255def jtblock_operand : Operand<i32> {
256  let PrintMethod = "printJTBlockOperand";
257}
258def jt2block_operand : Operand<i32> {
259  let PrintMethod = "printJT2BlockOperand";
260}
261
262// Local PC labels.
263def pclabel : Operand<i32> {
264  let PrintMethod = "printPCLabel";
265}
266
267// shifter_operand operands: so_reg and so_imm.
268def so_reg : Operand<i32>,    // reg reg imm
269            ComplexPattern<i32, 3, "SelectShifterOperandReg",
270                            [shl,srl,sra,rotr]> {
271  let PrintMethod = "printSORegOperand";
272  let MIOperandInfo = (ops GPR, GPR, i32imm);
273}
274
275// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
276// 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
277// represented in the imm field in the same 12-bit form that they are encoded
278// into so_imm instructions: the 8-bit immediate is the least significant bits
279// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
280def so_imm : Operand<i32>,
281             PatLeaf<(imm), [{
282      return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
283    }]> {
284  let PrintMethod = "printSOImmOperand";
285}
286
287// Break so_imm's up into two pieces.  This handles immediates with up to 16
288// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
289// get the first/second pieces.
290def so_imm2part : Operand<i32>,
291                  PatLeaf<(imm), [{
292      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
293    }]> {
294  let PrintMethod = "printSOImm2PartOperand";
295}
296
297def so_imm2part_1 : SDNodeXForm<imm, [{
298  unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
299  return CurDAG->getTargetConstant(V, MVT::i32);
300}]>;
301
302def so_imm2part_2 : SDNodeXForm<imm, [{
303  unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
304  return CurDAG->getTargetConstant(V, MVT::i32);
305}]>;
306
307def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
308      return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
309    }]> {
310  let PrintMethod = "printSOImm2PartOperand";
311}
312
313def so_neg_imm2part_1 : SDNodeXForm<imm, [{
314  unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
315  return CurDAG->getTargetConstant(V, MVT::i32);
316}]>;
317
318def so_neg_imm2part_2 : SDNodeXForm<imm, [{
319  unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
320  return CurDAG->getTargetConstant(V, MVT::i32);
321}]>;
322
323/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
324def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
325  return (int32_t)N->getZExtValue() < 32;
326}]>;
327
328// Define ARM specific addressing modes.
329
330// addrmode2 := reg +/- reg shop imm
331// addrmode2 := reg +/- imm12
332//
333def addrmode2 : Operand<i32>,
334                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
335  let PrintMethod = "printAddrMode2Operand";
336  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
337}
338
339def am2offset : Operand<i32>,
340                ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
341  let PrintMethod = "printAddrMode2OffsetOperand";
342  let MIOperandInfo = (ops GPR, i32imm);
343}
344
345// addrmode3 := reg +/- reg
346// addrmode3 := reg +/- imm8
347//
348def addrmode3 : Operand<i32>,
349                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
350  let PrintMethod = "printAddrMode3Operand";
351  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
352}
353
354def am3offset : Operand<i32>,
355                ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
356  let PrintMethod = "printAddrMode3OffsetOperand";
357  let MIOperandInfo = (ops GPR, i32imm);
358}
359
360// addrmode4 := reg, <mode|W>
361//
362def addrmode4 : Operand<i32>,
363                ComplexPattern<i32, 2, "SelectAddrMode4", []> {
364  let PrintMethod = "printAddrMode4Operand";
365  let MIOperandInfo = (ops GPR, i32imm);
366}
367
368// addrmode5 := reg +/- imm8*4
369//
370def addrmode5 : Operand<i32>,
371                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
372  let PrintMethod = "printAddrMode5Operand";
373  let MIOperandInfo = (ops GPR, i32imm);
374}
375
376// addrmode6 := reg with optional writeback
377//
378def addrmode6 : Operand<i32>,
379                ComplexPattern<i32, 4, "SelectAddrMode6", []> {
380  let PrintMethod = "printAddrMode6Operand";
381  let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
382}
383
384// addrmodepc := pc + reg
385//
386def addrmodepc : Operand<i32>,
387                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
388  let PrintMethod = "printAddrModePCOperand";
389  let MIOperandInfo = (ops GPR, i32imm);
390}
391
392def nohash_imm : Operand<i32> {
393  let PrintMethod = "printNoHashImmediate";
394}
395
396//===----------------------------------------------------------------------===//
397
398include "ARMInstrFormats.td"
399
400//===----------------------------------------------------------------------===//
401// Multiclass helpers...
402//
403
404/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
405/// binop that produces a value.
406multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
407                        bit Commutable = 0> {
408  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
409               IIC_iALUi, opc, "\t$dst, $a, $b",
410               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
411    let Inst{25} = 1;
412  }
413  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
414               IIC_iALUr, opc, "\t$dst, $a, $b",
415               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
416    let Inst{11-4} = 0b00000000;
417    let Inst{25} = 0;
418    let isCommutable = Commutable;
419  }
420  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
421               IIC_iALUsr, opc, "\t$dst, $a, $b",
422               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
423    let Inst{25} = 0;
424  }
425}
426
427/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
428/// instruction modifies the CPSR register.
429let Defs = [CPSR] in {
430multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
431                         bit Commutable = 0> {
432  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
433               IIC_iALUi, opc, "\t$dst, $a, $b",
434               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
435    let Inst{20} = 1;
436    let Inst{25} = 1;
437  }
438  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
439               IIC_iALUr, opc, "\t$dst, $a, $b",
440               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
441    let isCommutable = Commutable;
442    let Inst{11-4} = 0b00000000;
443    let Inst{20} = 1;
444    let Inst{25} = 0;
445  }
446  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
447               IIC_iALUsr, opc, "\t$dst, $a, $b",
448               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
449    let Inst{20} = 1;
450    let Inst{25} = 0;
451  }
452}
453}
454
455/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
456/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
457/// a explicit result, only implicitly set CPSR.
458let Defs = [CPSR] in {
459multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
460                       bit Commutable = 0> {
461  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
462               opc, "\t$a, $b",
463               [(opnode GPR:$a, so_imm:$b)]> {
464    let Inst{20} = 1;
465    let Inst{25} = 1;
466  }
467  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
468               opc, "\t$a, $b",
469               [(opnode GPR:$a, GPR:$b)]> {
470    let Inst{11-4} = 0b00000000;
471    let Inst{20} = 1;
472    let Inst{25} = 0;
473    let isCommutable = Commutable;
474  }
475  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
476               opc, "\t$a, $b",
477               [(opnode GPR:$a, so_reg:$b)]> {
478    let Inst{20} = 1;
479    let Inst{25} = 0;
480  }
481}
482}
483
484/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
485/// register and one whose operand is a register rotated by 8/16/24.
486/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
487multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
488  def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
489                 IIC_iUNAr, opc, "\t$dst, $src",
490                 [(set GPR:$dst, (opnode GPR:$src))]>,
491              Requires<[IsARM, HasV6]> {
492    let Inst{11-10} = 0b00;
493    let Inst{19-16} = 0b1111;
494  }
495  def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
496                 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
497                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
498              Requires<[IsARM, HasV6]> {
499    let Inst{19-16} = 0b1111;
500  }
501}
502
503/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
504/// register and one whose operand is a register rotated by 8/16/24.
505multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
506  def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
507                  IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
508                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
509               Requires<[IsARM, HasV6]> {
510    let Inst{11-10} = 0b00;
511  }
512  def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
513                  IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
514                  [(set GPR:$dst, (opnode GPR:$LHS,
515                                          (rotr GPR:$RHS, rot_imm:$rot)))]>,
516                  Requires<[IsARM, HasV6]>;
517}
518
519/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
520let Uses = [CPSR] in {
521multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
522                             bit Commutable = 0> {
523  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
524                DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
525               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
526               Requires<[IsARM, CarryDefIsUnused]> {
527    let Inst{25} = 1;
528  }
529  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
530                DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
531               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
532               Requires<[IsARM, CarryDefIsUnused]> {
533    let isCommutable = Commutable;
534    let Inst{11-4} = 0b00000000;
535    let Inst{25} = 0;
536  }
537  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
538                DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
539               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
540               Requires<[IsARM, CarryDefIsUnused]> {
541    let Inst{25} = 0;
542  }
543}
544// Carry setting variants
545let Defs = [CPSR] in {
546multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
547                             bit Commutable = 0> {
548  def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
549                DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
550               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
551               Requires<[IsARM, CarryDefIsUsed]> {
552    let Defs = [CPSR];
553    let Inst{20} = 1;
554    let Inst{25} = 1;
555  }
556  def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
557                DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
558               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
559               Requires<[IsARM, CarryDefIsUsed]> {
560    let Defs = [CPSR];
561    let Inst{11-4} = 0b00000000;
562    let Inst{20} = 1;
563    let Inst{25} = 0;
564  }
565  def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
566                DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
567               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
568               Requires<[IsARM, CarryDefIsUsed]> {
569    let Defs = [CPSR];
570    let Inst{20} = 1;
571    let Inst{25} = 0;
572  }
573}
574}
575}
576
577//===----------------------------------------------------------------------===//
578// Instructions
579//===----------------------------------------------------------------------===//
580
581//===----------------------------------------------------------------------===//
582//  Miscellaneous Instructions.
583//
584
585/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
586/// the function.  The first operand is the ID# for this instruction, the second
587/// is the index into the MachineConstantPool that this is, the third is the
588/// size in bytes of this constant pool entry.
589let neverHasSideEffects = 1, isNotDuplicable = 1 in
590def CONSTPOOL_ENTRY :
591PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
592                    i32imm:$size), NoItinerary,
593           "${instid:label} ${cpidx:cpentry}", []>;
594
595let Defs = [SP], Uses = [SP] in {
596def ADJCALLSTACKUP :
597PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
598           "@ ADJCALLSTACKUP $amt1",
599           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
600
601def ADJCALLSTACKDOWN : 
602PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
603           "@ ADJCALLSTACKDOWN $amt",
604           [(ARMcallseq_start timm:$amt)]>;
605}
606
607// Address computation and loads and stores in PIC mode.
608let isNotDuplicable = 1 in {
609def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
610                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
611                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
612
613let AddedComplexity = 10 in {
614def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
615                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
616                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
617
618def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
619                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
620                  [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
621
622def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
623                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
624                  [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
625
626def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
627               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
628                  [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
629
630def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
631               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
632                  [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
633}
634let AddedComplexity = 10 in {
635def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
636               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
637               [(store GPR:$src, addrmodepc:$addr)]>;
638
639def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
640               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
641               [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
642
643def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
644               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
645               [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
646}
647} // isNotDuplicable = 1
648
649
650// LEApcrel - Load a pc-relative address into a register without offending the
651// assembler.
652def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
653                    Pseudo, IIC_iALUi,
654           !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
655                                 "${:private}PCRELL${:uid}+8))\n"),
656                      !strconcat("${:private}PCRELL${:uid}:\n\t",
657                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
658                   []>;
659
660def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
661                           (ins i32imm:$label, nohash_imm:$id, pred:$p),
662          Pseudo, IIC_iALUi,
663   !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
664                         "(${label}_${id}-(",
665                                  "${:private}PCRELL${:uid}+8))\n"),
666                       !strconcat("${:private}PCRELL${:uid}:\n\t",
667                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
668                   []> {
669    let Inst{25} = 1;
670}
671
672//===----------------------------------------------------------------------===//
673//  Control Flow Instructions.
674//
675
676let isReturn = 1, isTerminator = 1, isBarrier = 1 in
677  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
678                  "bx", "\tlr", [(ARMretflag)]> {
679  let Inst{3-0}   = 0b1110;
680  let Inst{7-4}   = 0b0001;
681  let Inst{19-8}  = 0b111111111111;
682  let Inst{27-20} = 0b00010010;
683}
684
685// Indirect branches
686let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
687  def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
688                  [(brind GPR:$dst)]> {
689    let Inst{7-4}   = 0b0001;
690    let Inst{19-8}  = 0b111111111111;
691    let Inst{27-20} = 0b00010010;
692    let Inst{31-28} = 0b1110;
693  }
694}
695
696// FIXME: remove when we have a way to marking a MI with these properties.
697// FIXME: Should pc be an implicit operand like PICADD, etc?
698let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
699    hasExtraDefRegAllocReq = 1 in
700  def LDM_RET : AXI4ld<(outs),
701                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
702                    LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
703                    []>;
704
705// On non-Darwin platforms R9 is callee-saved.
706let isCall = 1,
707  Defs = [R0,  R1,  R2,  R3,  R12, LR,
708          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
709          D16, D17, D18, D19, D20, D21, D22, D23,
710          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
711  def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
712                IIC_Br, "bl\t${func:call}",
713                [(ARMcall tglobaladdr:$func)]>,
714            Requires<[IsARM, IsNotDarwin]> {
715    let Inst{31-28} = 0b1110;
716  }
717
718  def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
719                   IIC_Br, "bl", "\t${func:call}",
720                   [(ARMcall_pred tglobaladdr:$func)]>,
721                Requires<[IsARM, IsNotDarwin]>;
722
723  // ARMv5T and above
724  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
725                IIC_Br, "blx\t$func",
726                [(ARMcall GPR:$func)]>,
727            Requires<[IsARM, HasV5T, IsNotDarwin]> {
728    let Inst{7-4}   = 0b0011;
729    let Inst{19-8}  = 0b111111111111;
730    let Inst{27-20} = 0b00010010;
731  }
732
733  // ARMv4T
734  def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
735                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
736                  [(ARMcall_nolink GPR:$func)]>,
737           Requires<[IsARM, IsNotDarwin]> {
738    let Inst{7-4}   = 0b0001;
739    let Inst{19-8}  = 0b111111111111;
740    let Inst{27-20} = 0b00010010;
741  }
742}
743
744// On Darwin R9 is call-clobbered.
745let isCall = 1,
746  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
747          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
748          D16, D17, D18, D19, D20, D21, D22, D23,
749          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
750  def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
751                IIC_Br, "bl\t${func:call}",
752                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
753    let Inst{31-28} = 0b1110;
754  }
755
756  def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
757                   IIC_Br, "bl", "\t${func:call}",
758                   [(ARMcall_pred tglobaladdr:$func)]>,
759                  Requires<[IsARM, IsDarwin]>;
760
761  // ARMv5T and above
762  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
763                IIC_Br, "blx\t$func",
764                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
765    let Inst{7-4}   = 0b0011;
766    let Inst{19-8}  = 0b111111111111;
767    let Inst{27-20} = 0b00010010;
768  }
769
770  // ARMv4T
771  def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
772                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
773                  [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
774    let Inst{7-4}   = 0b0001;
775    let Inst{19-8}  = 0b111111111111;
776    let Inst{27-20} = 0b00010010;
777  }
778}
779
780let isBranch = 1, isTerminator = 1 in {
781  // B is "predicable" since it can be xformed into a Bcc.
782  let isBarrier = 1 in {
783    let isPredicable = 1 in
784    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
785                "b\t$target", [(br bb:$target)]>;
786
787  let isNotDuplicable = 1, isIndirectBranch = 1 in {
788  def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
789                    IIC_Br, "mov\tpc, $target \n$jt",
790                    [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
791    let Inst{11-4}  = 0b00000000;
792    let Inst{15-12} = 0b1111;
793    let Inst{20}    = 0; // S Bit
794    let Inst{24-21} = 0b1101;
795    let Inst{27-25} = 0b000;
796  }
797  def BR_JTm : JTI<(outs),
798                   (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
799                   IIC_Br, "ldr\tpc, $target \n$jt",
800                   [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
801                     imm:$id)]> {
802    let Inst{15-12} = 0b1111;
803    let Inst{20}    = 1; // L bit
804    let Inst{21}    = 0; // W bit
805    let Inst{22}    = 0; // B bit
806    let Inst{24}    = 1; // P bit
807    let Inst{27-25} = 0b011;
808  }
809  def BR_JTadd : JTI<(outs),
810                   (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
811                    IIC_Br, "add\tpc, $target, $idx \n$jt",
812                    [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
813                      imm:$id)]> {
814    let Inst{15-12} = 0b1111;
815    let Inst{20}    = 0; // S bit
816    let Inst{24-21} = 0b0100;
817    let Inst{27-25} = 0b000;
818  }
819  } // isNotDuplicable = 1, isIndirectBranch = 1
820  } // isBarrier = 1
821
822  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
823  // a two-value operand where a dag node expects two operands. :( 
824  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
825               IIC_Br, "b", "\t$target",
826               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
827}
828
829//===----------------------------------------------------------------------===//
830//  Load / store Instructions.
831//
832
833// Load
834let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 
835def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
836               "ldr", "\t$dst, $addr",
837               [(set GPR:$dst, (load addrmode2:$addr))]>;
838
839// Special LDR for loads from non-pc-relative constpools.
840let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
841    mayHaveSideEffects = 1  in
842def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
843                 "ldr", "\t$dst, $addr", []>;
844
845// Loads with zero extension
846def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
847                  IIC_iLoadr, "ldrh", "\t$dst, $addr",
848                  [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
849
850def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
851                  IIC_iLoadr, "ldrb", "\t$dst, $addr",
852                  [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
853
854// Loads with sign extension
855def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
856                   IIC_iLoadr, "ldrsh", "\t$dst, $addr",
857                   [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
858
859def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
860                   IIC_iLoadr, "ldrsb", "\t$dst, $addr",
861                   [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
862
863let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
864// Load doubleword
865def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
866                 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
867                 []>, Requires<[IsARM, HasV5TE]>;
868
869// Indexed loads
870def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
871                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
872                     "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
873
874def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
875                     (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
876                     "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
877
878def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
879                     (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
880                     "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
881
882def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
883                     (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
884                    "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
885
886def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
887                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
888                     "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
889
890def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
891                     (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
892                    "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
893
894def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
895                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
896                      "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
897
898def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
899                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
900                   "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
901
902def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
903                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
904                      "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
905
906def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
907                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
908                   "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
909}
910
911// Store
912def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
913               "str", "\t$src, $addr",
914               [(store GPR:$src, addrmode2:$addr)]>;
915
916// Stores with truncate
917def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
918               "strh", "\t$src, $addr",
919               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
920
921def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
922               "strb", "\t$src, $addr",
923               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
924
925// Store doubleword
926let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
927def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
928               StMiscFrm, IIC_iStorer,
929               "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
930
931// Indexed stores
932def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
933                     (ins GPR:$src, GPR:$base, am2offset:$offset), 
934                     StFrm, IIC_iStoreru,
935                    "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
936                    [(set GPR:$base_wb,
937                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
938
939def STR_POST : AI2stwpo<(outs GPR:$base_wb),
940                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
941                     StFrm, IIC_iStoreru,
942                    "str", "\t$src, [$base], $offset", "$base = $base_wb",
943                    [(set GPR:$base_wb,
944                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
945
946def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
947                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
948                     StMiscFrm, IIC_iStoreru,
949                     "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
950                    [(set GPR:$base_wb,
951                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
952
953def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
954                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
955                     StMiscFrm, IIC_iStoreru,
956                     "strh", "\t$src, [$base], $offset", "$base = $base_wb",
957                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
958                                         GPR:$base, am3offset:$offset))]>;
959
960def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
961                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
962                     StFrm, IIC_iStoreru,
963                     "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
964                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
965                                         GPR:$base, am2offset:$offset))]>;
966
967def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
968                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
969                     StFrm, IIC_iStoreru,
970                     "strb", "\t$src, [$base], $offset", "$base = $base_wb",
971                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
972                                         GPR:$base, am2offset:$offset))]>;
973
974//===----------------------------------------------------------------------===//
975//  Load / store multiple Instructions.
976//
977
978let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
979def LDM : AXI4ld<(outs),
980               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
981               LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
982               []>;
983
984let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
985def STM : AXI4st<(outs),
986               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
987               LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
988               []>;
989
990//===----------------------------------------------------------------------===//
991//  Move Instructions.
992//
993
994let neverHasSideEffects = 1 in
995def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
996                "mov", "\t$dst, $src", []>, UnaryDP {
997  let Inst{11-4} = 0b00000000;
998  let Inst{25} = 0;
999}
1000
1001def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
1002                DPSoRegFrm, IIC_iMOVsr,
1003                "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1004  let Inst{25} = 0;
1005}
1006
1007let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1008def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1009                "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1010  let Inst{25} = 1;
1011}
1012
1013let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1014def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
1015                 DPFrm, IIC_iMOVi,
1016                 "movw", "\t$dst, $src",
1017                 [(set GPR:$dst, imm0_65535:$src)]>,
1018                 Requires<[IsARM, HasV6T2]> {
1019  let Inst{20} = 0;
1020  let Inst{25} = 1;
1021}
1022
1023let Constraints = "$src = $dst" in
1024def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1025                  DPFrm, IIC_iMOVi,
1026                  "movt", "\t$dst, $imm",
1027                  [(set GPR:$dst,
1028                        (or (and GPR:$src, 0xffff), 
1029                            lo16AllZero:$imm))]>, UnaryDP,
1030                  Requires<[IsARM, HasV6T2]> {
1031  let Inst{20} = 0;
1032  let Inst{25} = 1;
1033}
1034
1035def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1036      Requires<[IsARM, HasV6T2]>;
1037
1038let Uses = [CPSR] in
1039def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1040                 "mov", "\t$dst, $src, rrx",
1041                 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1042
1043// These aren't really mov instructions, but we have to define them this way
1044// due to flag operands.
1045
1046let Defs = [CPSR] in {
1047def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
1048                      IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1049                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1050def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1051                      IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1052                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1053}
1054
1055//===----------------------------------------------------------------------===//
1056//  Extend Instructions.
1057//
1058
1059// Sign extenders
1060
1061defm SXTB  : AI_unary_rrot<0b01101010,
1062                           "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1063defm SXTH  : AI_unary_rrot<0b01101011,
1064                           "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1065
1066defm SXTAB : AI_bin_rrot<0b01101010,
1067               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1068defm SXTAH : AI_bin_rrot<0b01101011,
1069               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1070
1071// TODO: SXT(A){B|H}16
1072
1073// Zero extenders
1074
1075let AddedComplexity = 16 in {
1076defm UXTB   : AI_unary_rrot<0b01101110,
1077                            "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1078defm UXTH   : AI_unary_rrot<0b01101111,
1079                            "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1080defm UXTB16 : AI_unary_rrot<0b01101100,
1081                            "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1082
1083def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1084               (UXTB16r_rot GPR:$Src, 24)>;
1085def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1086               (UXTB16r_rot GPR:$Src, 8)>;
1087
1088defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1089                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1090defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1091                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1092}
1093
1094// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1095//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1096
1097// TODO: UXT(A){B|H}16
1098
1099def SBFX  : I<(outs GPR:$dst),
1100              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1101               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1102               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1103               Requires<[IsARM, HasV6T2]> {
1104  let Inst{27-21} = 0b0111101;
1105  let Inst{6-4}   = 0b101;
1106}
1107
1108def UBFX  : I<(outs GPR:$dst),
1109              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1110               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1111               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1112               Requires<[IsARM, HasV6T2]> {
1113  let Inst{27-21} = 0b0111111;
1114  let Inst{6-4}   = 0b101;
1115}
1116
1117//===----------------------------------------------------------------------===//
1118//  Arithmetic Instructions.
1119//
1120
1121defm ADD  : AsI1_bin_irs<0b0100, "add",
1122                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1123defm SUB  : AsI1_bin_irs<0b0010, "sub",
1124                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1125
1126// ADD and SUB with 's' bit set.
1127defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1128                          BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1129defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1130                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1131
1132defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1133                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1134defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1135                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1136defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1137                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1138defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1139                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1140
1141// These don't define reg/reg forms, because they are handled above.
1142def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1143                  IIC_iALUi, "rsb", "\t$dst, $a, $b",
1144                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1145    let Inst{25} = 1;
1146}
1147
1148def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1149                  IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1150                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1151    let Inst{25} = 0;
1152}
1153
1154// RSB with 's' bit set.
1155let Defs = [CPSR] in {
1156def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1157                 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1158                 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1159    let Inst{20} = 1;
1160    let Inst{25} = 1;
1161}
1162def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1163                 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1164                 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1165    let Inst{20} = 1;
1166    let Inst{25} = 0;
1167}
1168}
1169
1170let Uses = [CPSR] in {
1171def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1172                 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1173                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1174                 Requires<[IsARM, CarryDefIsUnused]> {
1175    let Inst{25} = 1;
1176}
1177def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1178                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1179                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1180                 Requires<[IsARM, CarryDefIsUnused]> {
1181    let Inst{25} = 0;
1182}
1183}
1184
1185// FIXME: Allow these to be predicated.
1186let Defs = [CPSR], Uses = [CPSR] in {
1187def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1188                  DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1189                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1190                  Requires<[IsARM, CarryDefIsUnused]> {
1191    let Inst{20} = 1;
1192    let Inst{25} = 1;
1193}
1194def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1195                  DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1196                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1197                  Requires<[IsARM, CarryDefIsUnused]> {
1198    let Inst{20} = 1;
1199    let Inst{25} = 0;
1200}
1201}
1202
1203// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1204def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1205             (SUBri  GPR:$src, so_imm_neg:$imm)>;
1206
1207//def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1208//             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1209//def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1210//             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1211
1212// Note: These are implemented in C++ code, because they have to generate
1213// ADD/SUBrs instructions, which use a complex pattern that a xform function
1214// cannot produce.
1215// (mul X, 2^n+1) -> (add (X << n), X)
1216// (mul X, 2^n-1) -> (rsb X, (X << n))
1217
1218
1219//===----------------------------------------------------------------------===//
1220//  Bitwise Instructions.
1221//
1222
1223defm AND   : AsI1_bin_irs<0b0000, "and",
1224                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1225defm ORR   : AsI1_bin_irs<0b1100, "orr",
1226                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1227defm EOR   : AsI1_bin_irs<0b0001, "eor",
1228                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1229defm BIC   : AsI1_bin_irs<0b1110, "bic",
1230                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1231
1232def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1233               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1234               "bfc", "\t$dst, $imm", "$src = $dst",
1235               [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1236               Requires<[IsARM, HasV6T2]> {
1237  let Inst{27-21} = 0b0111110;
1238  let Inst{6-0}   = 0b0011111;
1239}
1240
1241def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1242                  "mvn", "\t$dst, $src",
1243                  [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1244  let Inst{11-4} = 0b00000000;
1245}
1246def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1247                  IIC_iMOVsr, "mvn", "\t$dst, $src",
1248                  [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
1249let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1250def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
1251                  IIC_iMOVi, "mvn", "\t$dst, $imm",
1252                  [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1253    let Inst{25} = 1;
1254}
1255
1256def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1257             (BICri GPR:$src, so_imm_not:$imm)>;
1258
1259//===----------------------------------------------------------------------===//
1260//  Multiply Instructions.
1261//
1262
1263let isCommutable = 1 in
1264def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1265                   IIC_iMUL32, "mul", "\t$dst, $a, $b",
1266                   [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1267
1268def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1269                    IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1270                   [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1271
1272def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1273                   IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1274                   [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1275                   Requires<[IsARM, HasV6T2]>;
1276
1277// Extra precision multiplies with low / high results
1278let neverHasSideEffects = 1 in {
1279let isCommutable = 1 in {
1280def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1281                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1282                    "smull", "\t$ldst, $hdst, $a, $b", []>;
1283
1284def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1285                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1286                    "umull", "\t$ldst, $hdst, $a, $b", []>;
1287}
1288
1289// Multiply + accumulate
1290def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1291                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1292                    "smlal", "\t$ldst, $hdst, $a, $b", []>;
1293
1294def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1295                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1296                    "umlal", "\t$ldst, $hdst, $a, $b", []>;
1297
1298def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1299                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1300                    "umaal", "\t$ldst, $hdst, $a, $b", []>,
1301                    Requires<[IsARM, HasV6]>;
1302} // neverHasSideEffects
1303
1304// Most significant word multiply
1305def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1306               IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1307               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1308            Requires<[IsARM, HasV6]> {
1309  let Inst{7-4}   = 0b0001;
1310  let Inst{15-12} = 0b1111;
1311}
1312
1313def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1314               IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1315               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1316            Requires<[IsARM, HasV6]> {
1317  let Inst{7-4}   = 0b0001;
1318}
1319
1320
1321def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1322               IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1323               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1324            Requires<[IsARM, HasV6]> {
1325  let Inst{7-4}   = 0b1101;
1326}
1327
1328multiclass AI_smul<string opc, PatFrag opnode> {
1329  def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1330              IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1331              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1332                                      (sext_inreg GPR:$b, i16)))]>,
1333           Requires<[IsARM, HasV5TE]> {
1334             let Inst{5} = 0;
1335             let Inst{6} = 0;
1336           }
1337
1338  def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1339              IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1340              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1341                                      (sra GPR:$b, (i32 16))))]>,
1342           Requires<[IsARM, HasV5TE]> {
1343             let Inst{5} = 0;
1344             let Inst{6} = 1;
1345           }
1346
1347  def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1348              IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1349              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1350                                      (sext_inreg GPR:$b, i16)))]>,
1351           Requires<[IsARM, HasV5TE]> {
1352             let Inst{5} = 1;
1353             let Inst{6} = 0;
1354           }
1355
1356  def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1357              IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1358              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1359                                      (sra GPR:$b, (i32 16))))]>,
1360            Requires<[IsARM, HasV5TE]> {
1361             let Inst{5} = 1;
1362             let Inst{6} = 1;
1363           }
1364
1365  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1366              IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1367              [(set GPR:$dst, (sra (opnode GPR:$a,
1368                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1369           Requires<[IsARM, HasV5TE]> {
1370             let Inst{5} = 1;
1371             let Inst{6} = 0;
1372           }
1373
1374  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1375              IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1376              [(set GPR:$dst, (sra (opnode GPR:$a,
1377                                    (sra GPR:$b, (i32 16))), (i32 16)))]>,
1378            Requires<[IsARM, HasV5TE]> {
1379             let Inst{5} = 1;
1380             let Inst{6} = 1;
1381           }
1382}
1383
1384
1385multiclass AI_smla<string opc, PatFrag opnode> {
1386  def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1387              IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1388              [(set GPR:$dst, (add GPR:$acc,
1389                               (opnode (sext_inreg GPR:$a, i16),
1390                                       (sext_inreg GPR:$b, i16))))]>,
1391           Requires<[IsARM, HasV5TE]> {
1392             let Inst{5} = 0;
1393             let Inst{6} = 0;
1394           }
1395
1396  def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1397              IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1398              [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1399                                                     (sra GPR:$b, (i32 16)))))]>,
1400           Requires<[IsARM, HasV5TE]> {
1401             let Inst{5} = 0;
1402             let Inst{6} = 1;
1403           }
1404
1405  def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1406              IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1407              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1408                                                 (sext_inreg GPR:$b, i16))))]>,
1409           Requires<[IsARM, HasV5TE]> {
1410             let Inst{5} = 1;
1411             let Inst{6} = 0;
1412           }
1413
1414  def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1415              IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1416             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1417                                                    (sra GPR:$b, (i32 16)))))]>,
1418            Requires<[IsARM, HasV5TE]> {
1419             let Inst{5} = 1;
1420             let Inst{6} = 1;
1421           }
1422
1423  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1424              IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1425              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1426                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1427           Requires<[IsARM, HasV5TE]> {
1428             let Inst{5} = 0;
1429             let Inst{6} = 0;
1430           }
1431
1432  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1433              IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1434              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1435                                         (sra GPR:$b, (i32 16))), (i32 16))))]>,
1436            Requires<[IsARM, HasV5TE]> {
1437             let Inst{5} = 0;
1438             let Inst{6} = 1;
1439           }
1440}
1441
1442defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1443defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1444
1445// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1446// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1447
1448//===----------------------------------------------------------------------===//
1449//  Misc. Arithmetic Instructions.
1450//
1451
1452def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1453              "clz", "\t$dst, $src",
1454              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1455  let Inst{7-4}   = 0b0001;
1456  let Inst{11-8}  = 0b1111;
1457  let Inst{19-16} = 0b1111;
1458}
1459
1460def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1461              "rbit", "\t$dst, $src",
1462              [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1463           Requires<[IsARM, HasV6T2]> {
1464  let Inst{7-4}   = 0b0011;
1465  let Inst{11-8}  = 0b1111;
1466  let Inst{19-16} = 0b1111;
1467}
1468
1469def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1470              "rev", "\t$dst, $src",
1471              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1472  let Inst{7-4}   = 0b0011;
1473  let Inst{11-8}  = 0b1111;
1474  let Inst{19-16} = 0b1111;
1475}
1476
1477def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1478               "rev16", "\t$dst, $src",
1479               [(set GPR:$dst,
1480                   (or (and (srl GPR:$src, (i32 8)), 0xFF),
1481                       (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1482                           (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1483                               (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1484               Requires<[IsARM, HasV6]> {
1485  let Inst{7-4}   = 0b1011;
1486  let Inst{11-8}  = 0b1111;
1487  let Inst{19-16} = 0b1111;
1488}
1489
1490def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1491               "revsh", "\t$dst, $src",
1492               [(set GPR:$dst,
1493                  (sext_inreg
1494                    (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1495                        (shl GPR:$src, (i32 8))), i16))]>,
1496               Requires<[IsARM, HasV6]> {
1497  let Inst{7-4}   = 0b1011;
1498  let Inst{11-8}  = 0b1111;
1499  let Inst{19-16} = 0b1111;
1500}
1501
1502def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1503                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1504               IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1505               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1506                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
1507                                        0xFFFF0000)))]>,
1508               Requires<[IsARM, HasV6]> {
1509  let Inst{6-4} = 0b001;
1510}
1511
1512// Alternate cases for PKHBT where identities eliminate some nodes.
1513def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1514               (PKHBT GPR:$src1, GPR:$src2, 0)>;
1515def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1516               (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1517
1518
1519def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1520                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1521               IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1522               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1523                                   (and (sra GPR:$src2, imm16_31:$shamt),
1524                                        0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1525  let Inst{6-4} = 0b101;
1526}
1527
1528// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1529// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1530def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1531               (PKHTB GPR:$src1, GPR:$src2, 16)>;
1532def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1533                   (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1534               (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1535
1536//===----------------------------------------------------------------------===//
1537//  Comparison Instructions...
1538//
1539
1540defm CMP  : AI1_cmp_irs<0b1010, "cmp",
1541                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1542//FIXME: Disable CMN, as CCodes are backwards from compare expectations
1543//       Compare-to-zero still works out, just not the relationals
1544//defm CMN  : AI1_cmp_irs<0b1011, "cmn",
1545//                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1546
1547// Note that TST/TEQ don't set all the same flags that CMP does!
1548defm TST  : AI1_cmp_irs<0b1000, "tst",
1549                        BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1550defm TEQ  : AI1_cmp_irs<0b1001, "teq",
1551                        BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1552
1553defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
1554                         BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1555defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
1556                         BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1557
1558//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1559//             (CMNri  GPR:$src, so_imm_neg:$imm)>;
1560
1561def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1562             (CMNzri  GPR:$src, so_imm_neg:$imm)>;
1563
1564
1565// Conditional moves
1566// FIXME: should be able to write a pattern for ARMcmov, but can't use
1567// a two-value operand where a dag node expects two operands. :( 
1568def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1569                IIC_iCMOVr, "mov", "\t$dst, $true",
1570      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1571                RegConstraint<"$false = $dst">, UnaryDP {
1572  let Inst{11-4} = 0b00000000;
1573  let Inst{25} = 0;
1574}
1575
1576def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1577                        (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1578                "mov", "\t$dst, $true",
1579   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1580                RegConstraint<"$false = $dst">, UnaryDP {
1581  let Inst{25} = 0;
1582}
1583
1584def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1585                        (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1586                "mov", "\t$dst, $true",
1587   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1588                RegConstraint<"$false = $dst">, UnaryDP {
1589  let Inst{25} = 1;
1590}
1591
1592//===----------------------------------------------------------------------===//
1593// Atomic operations intrinsics
1594//
1595
1596// memory barriers protect the atomic sequences
1597let hasSideEffects = 1 in {
1598def Int_MemBarrierV7 : AInoP<(outs), (ins),
1599                        Pseudo, NoItinerary,
1600                        "dmb", "",
1601                        [(ARMMemBarrierV7)]>,
1602                        Requires<[IsARM, HasV7]> {
1603  let Inst{31-4} = 0xf57ff05;
1604  // FIXME: add support for options other than a full system DMB
1605  let Inst{3-0} = 0b1111;
1606}
1607
1608def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1609                        Pseudo, NoItinerary,
1610                        "dsb", "",
1611                        [(ARMSyncBarrierV7)]>,
1612                        Requires<[IsARM, HasV7]> {
1613  let Inst{31-4} = 0xf57ff04;
1614  // FIXME: add support for options other than a full system DSB
1615  let Inst{3-0} = 0b1111;
1616}
1617
1618def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1619                       Pseudo, NoItinerary,
1620                       "mcr", "\tp15, 0, $zero, c7, c10, 5",
1621                       [(ARMMemBarrierV6 GPR:$zero)]>,
1622                       Requires<[IsARM, HasV6]> {
1623  // FIXME: add support for options other than a full system DMB
1624  // FIXME: add encoding
1625}
1626
1627def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1628                        Pseudo, NoItinerary,
1629                        "mcr", "\tp15, 0, $zero, c7, c10, 4",
1630                        [(ARMSyncBarrierV6 GPR:$zero)]>,
1631                        Requires<[IsARM, HasV6]> {
1632  // FIXME: add support for options other than a full system DSB
1633  // FIXME: add encoding
1634}
1635}
1636
1637let usesCustomInserter = 1 in {
1638  let Uses = [CPSR] in {
1639    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1640      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1641      "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1642      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1643    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1644      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1645      "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1646      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1647    def ATOMIC_LOAD_AND_I8 : PseudoInst<
1648      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1649      "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1650      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1651    def ATOMIC_LOAD_OR_I8 : PseudoInst<
1652      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1653      "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1654      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1655    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1656      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1657      "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1658      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1659    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1660      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1661      "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1662      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1663    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1664      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1665      "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1666      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1667    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1668      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1669      "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1670      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1671    def ATOMIC_LOAD_AND_I16 : PseudoInst<
1672      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1673      "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1674      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1675    def ATOMIC_LOAD_OR_I16 : PseudoInst<
1676      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1677      "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1678      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1679    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1680      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1681      "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1682      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1683    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1684      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1685      "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1686      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1687    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1688      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1689      "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1690      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1691    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1692      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1693      "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1694      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1695    def ATOMIC_LOAD_AND_I32 : PseudoInst<
1696      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1697      "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1698      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1699    def ATOMIC_LOAD_OR_I32 : PseudoInst<
1700      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1701      "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1702      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1703    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1704      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1705      "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1706      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1707    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1708      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1709      "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1710      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1711
1712    def ATOMIC_SWAP_I8 : PseudoInst<
1713      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1714      "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1715      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1716    def ATOMIC_SWAP_I16 : PseudoInst<
1717      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1718      "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1719      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1720    def ATOMIC_SWAP_I32 : PseudoInst<
1721      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1722      "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1723      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1724
1725    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1726      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1727      "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1728      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1729    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1730      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1731      "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1732      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1733    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1734      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1735      "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1736      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1737}
1738}
1739
1740let mayLoad = 1 in {
1741def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1742                    "ldrexb", "\t$dest, [$ptr]",
1743                    []>;
1744def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1745                    "ldrexh", "\t$dest, [$ptr]",
1746                    []>;
1747def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1748                    "ldrex", "\t$dest, [$ptr]",
1749                    []>;
1750def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1751                    NoItinerary,
1752                    "ldrexd", "\t$dest, $dest2, [$ptr]",
1753                    []>;
1754}
1755
1756let mayStore = 1, Constraints = "@earlyclobber $success" in {
1757def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1758                    NoItinerary,
1759                    "strexb", "\t$success, $src, [$ptr]",
1760                    []>;
1761def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1762                    NoItinerary,
1763                    "strexh", "\t$success, $src, [$ptr]",
1764                    []>;
1765def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1766                    NoItinerary,
1767                    "strex", "\t$success, $src, [$ptr]",
1768                    []>;
1769def STREXD : AIstrex<0b01, (outs GPR:$success),
1770                    (ins GPR:$src, GPR:$src2, GPR:$ptr),
1771                    NoItinerary,
1772                    "strexd", "\t$success, $src, $src2, [$ptr]",
1773                    []>;
1774}
1775
1776//===----------------------------------------------------------------------===//
1777// TLS Instructions
1778//
1779
1780// __aeabi_read_tp preserves the registers r1-r3.
1781let isCall = 1,
1782  Defs = [R0, R12, LR, CPSR] in {
1783  def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1784               "bl\t__aeabi_read_tp",
1785               [(set R0, ARMthread_pointer)]>;
1786}
1787
1788//===----------------------------------------------------------------------===//
1789// SJLJ Exception handling intrinsics
1790//   eh_sjlj_setjmp() is an instruction sequence to store the return
1791//   address and save #0 in R0 for the non-longjmp case.
1792//   Since by its nature we may be coming from some other function to get
1793//   here, and we're using the stack frame for the containing function to
1794//   save/restore registers, we can't keep anything live in regs across
1795//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1796//   when we get here from a longjmp(). We force everthing out of registers
1797//   except for our own input by listing the relevant registers in Defs. By
1798//   doing so, we also cause the prologue/epilogue code to actively preserve
1799//   all of the callee-saved resgisters, which is exactly what we want.
1800let Defs = 
1801  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
1802    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
1803    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1804    D31 ] in {
1805  def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
1806                               AddrModeNone, SizeSpecial, IndexModeNone,
1807                               Pseudo, NoItinerary,
1808                               "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1809                               "add\tr12, pc, #8\n\t"
1810                               "str\tr12, [$src, #+4]\n\t"
1811                               "mov\tr0, #0\n\t"
1812                               "add\tpc, pc, #0\n\t"
1813                               "mov\tr0, #1 @ eh_setjmp end", "",
1814                               [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1815}
1816
1817//===----------------------------------------------------------------------===//
1818// Non-Instruction Patterns
1819//
1820
1821// Large immediate handling.
1822
1823// Two piece so_imms.
1824let isReMaterializable = 1 in
1825def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
1826                         Pseudo, IIC_iMOVi,
1827                         "mov", "\t$dst, $src",
1828                         [(set GPR:$dst, so_imm2part:$src)]>,
1829                  Requires<[IsARM, NoV6T2]>;
1830
1831def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1832             (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1833                    (so_imm2part_2 imm:$RHS))>;
1834def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1835             (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1836                    (so_imm2part_2 imm:$RHS))>;
1837def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1838             (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1839                    (so_imm2part_2 imm:$RHS))>;
1840def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1841             (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1842                    (so_neg_imm2part_2 imm:$RHS))>;
1843
1844// 32-bit immediate using movw + movt.
1845// This is a single pseudo instruction, the benefit is that it can be remat'd
1846// as a single unit instead of having to handle reg inputs.
1847// FIXME: Remove this when we can do generalized remat.
1848let isReMaterializable = 1 in
1849def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1850                    "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1851                     [(set GPR:$dst, (i32 imm:$src))]>,
1852               Requires<[IsARM, HasV6T2]>;
1853
1854// ConstantPool, GlobalAddress, and JumpTable
1855def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1856            Requires<[IsARM, DontUseMovt]>;
1857def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
1858def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1859            Requires<[IsARM, UseMovt]>;
1860def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1861             (LEApcrelJT tjumptable:$dst, imm:$id)>;
1862
1863// TODO: add,sub,and, 3-instr forms?
1864
1865
1866// Direct calls
1867def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1868      Requires<[IsARM, IsNotDarwin]>;
1869def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1870      Requires<[IsARM, IsDarwin]>;
1871
1872// zextload i1 -> zextload i8
1873def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1874
1875// extload -> zextload
1876def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1877def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1878def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
1879
1880def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1881def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1882
1883// smul* and smla*
1884def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1885                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
1886                 (SMULBB GPR:$a, GPR:$b)>;
1887def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1888                 (SMULBB GPR:$a, GPR:$b)>;
1889def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1890                      (sra GPR:$b, (i32 16))),
1891                 (SMULBT GPR:$a, GPR:$b)>;
1892def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
1893                 (SMULBT GPR:$a, GPR:$b)>;
1894def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1895                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
1896                 (SMULTB GPR:$a, GPR:$b)>;
1897def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
1898                (SMULTB GPR:$a, GPR:$b)>;
1899def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1900                      (i32 16)),
1901                 (SMULWB GPR:$a, GPR:$b)>;
1902def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
1903                 (SMULWB GPR:$a, GPR:$b)>;
1904
1905def : ARMV5TEPat<(add GPR:$acc,
1906                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1907                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1908                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1909def : ARMV5TEPat<(add GPR:$acc,
1910                      (mul sext_16_node:$a, sext_16_node:$b)),
1911                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1912def : ARMV5TEPat<(add GPR:$acc,
1913                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1914                           (sra GPR:$b, (i32 16)))),
1915                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1916def : ARMV5TEPat<(add GPR:$acc,
1917                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
1918                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1919def : ARMV5TEPat<(add GPR:$acc,
1920                      (mul (sra GPR:$a, (i32 16)),
1921                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1922                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1923def : ARMV5TEPat<(add GPR:$acc,
1924                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
1925                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1926def : ARMV5TEPat<(add GPR:$acc,
1927                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1928                           (i32 16))),
1929                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1930def : ARMV5TEPat<(add GPR:$acc,
1931                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
1932                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1933
1934//===----------------------------------------------------------------------===//
1935// Thumb Support
1936//
1937
1938include "ARMInstrThumb.td"
1939
1940//===----------------------------------------------------------------------===//
1941// Thumb2 Support
1942//
1943
1944include "ARMInstrThumb2.td"
1945
1946//===----------------------------------------------------------------------===//
1947// Floating Point Support
1948//
1949
1950include "ARMInstrVFP.td"
1951
1952//===----------------------------------------------------------------------===//
1953// Advanced SIMD (NEON) Support
1954//
1955
1956include "ARMInstrNEON.td"
1957