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