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