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