ARMInstrInfo.td revision df89a64cefcd537edf4f117eb777e476d97fe3bf
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 SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
668                   [/* For disassembly only; pattern left blank */]>,
669               Requires<[IsARM]> {
670  let Inst{31-28} = 0b1111;
671  let Inst{27-20} = 0b00010000;
672  let Inst{16} = 1;
673  let Inst{9} = 1;
674  let Inst{7-4} = 0b0000;
675}
676
677def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
678                   [/* For disassembly only; pattern left blank */]>,
679               Requires<[IsARM]> {
680  let Inst{31-28} = 0b1111;
681  let Inst{27-20} = 0b00010000;
682  let Inst{16} = 1;
683  let Inst{9} = 0;
684  let Inst{7-4} = 0b0000;
685}
686
687def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
688             [/* For disassembly only; pattern left blank */]>,
689          Requires<[IsARM, HasV7]> {
690  let Inst{27-16} = 0b001100100000;
691  let Inst{7-4} = 0b1111;
692}
693
694// A5.4 Permanently UNDEFINED instructions.
695def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
696              [/* For disassembly only; pattern left blank */]>,
697           Requires<[IsARM]> {
698  let Inst{27-25} = 0b011;
699  let Inst{24-20} = 0b11111;
700  let Inst{7-5} = 0b111;
701  let Inst{4} = 0b1;
702}
703
704// Address computation and loads and stores in PIC mode.
705let isNotDuplicable = 1 in {
706def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
707                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
708                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
709
710let AddedComplexity = 10 in {
711def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
712                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
713                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
714
715def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
716                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
717                  [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
718
719def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
720                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
721                  [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
722
723def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
724               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
725                  [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
726
727def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
728               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
729                  [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
730}
731let AddedComplexity = 10 in {
732def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
733               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
734               [(store GPR:$src, addrmodepc:$addr)]>;
735
736def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
737               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
738               [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
739
740def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
741               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
742               [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
743}
744} // isNotDuplicable = 1
745
746
747// LEApcrel - Load a pc-relative address into a register without offending the
748// assembler.
749def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
750                    Pseudo, IIC_iALUi,
751           !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
752                                 "${:private}PCRELL${:uid}+8))\n"),
753                      !strconcat("${:private}PCRELL${:uid}:\n\t",
754                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
755                   []>;
756
757def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
758                           (ins i32imm:$label, nohash_imm:$id, pred:$p),
759          Pseudo, IIC_iALUi,
760   !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
761                         "(${label}_${id}-(",
762                                  "${:private}PCRELL${:uid}+8))\n"),
763                       !strconcat("${:private}PCRELL${:uid}:\n\t",
764                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
765                   []> {
766    let Inst{25} = 1;
767}
768
769//===----------------------------------------------------------------------===//
770//  Control Flow Instructions.
771//
772
773let isReturn = 1, isTerminator = 1, isBarrier = 1 in
774  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
775                  "bx", "\tlr", [(ARMretflag)]> {
776  let Inst{3-0}   = 0b1110;
777  let Inst{7-4}   = 0b0001;
778  let Inst{19-8}  = 0b111111111111;
779  let Inst{27-20} = 0b00010010;
780}
781
782// Indirect branches
783let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
784  def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
785                  [(brind GPR:$dst)]> {
786    let Inst{7-4}   = 0b0001;
787    let Inst{19-8}  = 0b111111111111;
788    let Inst{27-20} = 0b00010010;
789    let Inst{31-28} = 0b1110;
790  }
791}
792
793// FIXME: remove when we have a way to marking a MI with these properties.
794// FIXME: Should pc be an implicit operand like PICADD, etc?
795let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
796    hasExtraDefRegAllocReq = 1 in
797  def LDM_RET : AXI4ld<(outs),
798                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
799                    LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
800                    []>;
801
802// On non-Darwin platforms R9 is callee-saved.
803let isCall = 1,
804  Defs = [R0,  R1,  R2,  R3,  R12, LR,
805          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
806          D16, D17, D18, D19, D20, D21, D22, D23,
807          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
808  def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
809                IIC_Br, "bl\t${func:call}",
810                [(ARMcall tglobaladdr:$func)]>,
811            Requires<[IsARM, IsNotDarwin]> {
812    let Inst{31-28} = 0b1110;
813  }
814
815  def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
816                   IIC_Br, "bl", "\t${func:call}",
817                   [(ARMcall_pred tglobaladdr:$func)]>,
818                Requires<[IsARM, IsNotDarwin]>;
819
820  // ARMv5T and above
821  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
822                IIC_Br, "blx\t$func",
823                [(ARMcall GPR:$func)]>,
824            Requires<[IsARM, HasV5T, IsNotDarwin]> {
825    let Inst{7-4}   = 0b0011;
826    let Inst{19-8}  = 0b111111111111;
827    let Inst{27-20} = 0b00010010;
828  }
829
830  // ARMv4T
831  def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
832                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
833                  [(ARMcall_nolink GPR:$func)]>,
834           Requires<[IsARM, IsNotDarwin]> {
835    let Inst{7-4}   = 0b0001;
836    let Inst{19-8}  = 0b111111111111;
837    let Inst{27-20} = 0b00010010;
838  }
839}
840
841// On Darwin R9 is call-clobbered.
842let isCall = 1,
843  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
844          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
845          D16, D17, D18, D19, D20, D21, D22, D23,
846          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
847  def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
848                IIC_Br, "bl\t${func:call}",
849                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
850    let Inst{31-28} = 0b1110;
851  }
852
853  def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
854                   IIC_Br, "bl", "\t${func:call}",
855                   [(ARMcall_pred tglobaladdr:$func)]>,
856                  Requires<[IsARM, IsDarwin]>;
857
858  // ARMv5T and above
859  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
860                IIC_Br, "blx\t$func",
861                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
862    let Inst{7-4}   = 0b0011;
863    let Inst{19-8}  = 0b111111111111;
864    let Inst{27-20} = 0b00010010;
865  }
866
867  // ARMv4T
868  def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
869                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
870                  [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
871    let Inst{7-4}   = 0b0001;
872    let Inst{19-8}  = 0b111111111111;
873    let Inst{27-20} = 0b00010010;
874  }
875}
876
877let isBranch = 1, isTerminator = 1 in {
878  // B is "predicable" since it can be xformed into a Bcc.
879  let isBarrier = 1 in {
880    let isPredicable = 1 in
881    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
882                "b\t$target", [(br bb:$target)]>;
883
884  let isNotDuplicable = 1, isIndirectBranch = 1 in {
885  def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
886                    IIC_Br, "mov\tpc, $target \n$jt",
887                    [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
888    let Inst{11-4}  = 0b00000000;
889    let Inst{15-12} = 0b1111;
890    let Inst{20}    = 0; // S Bit
891    let Inst{24-21} = 0b1101;
892    let Inst{27-25} = 0b000;
893  }
894  def BR_JTm : JTI<(outs),
895                   (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
896                   IIC_Br, "ldr\tpc, $target \n$jt",
897                   [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
898                     imm:$id)]> {
899    let Inst{15-12} = 0b1111;
900    let Inst{20}    = 1; // L bit
901    let Inst{21}    = 0; // W bit
902    let Inst{22}    = 0; // B bit
903    let Inst{24}    = 1; // P bit
904    let Inst{27-25} = 0b011;
905  }
906  def BR_JTadd : JTI<(outs),
907                   (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
908                    IIC_Br, "add\tpc, $target, $idx \n$jt",
909                    [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
910                      imm:$id)]> {
911    let Inst{15-12} = 0b1111;
912    let Inst{20}    = 0; // S bit
913    let Inst{24-21} = 0b0100;
914    let Inst{27-25} = 0b000;
915  }
916  } // isNotDuplicable = 1, isIndirectBranch = 1
917  } // isBarrier = 1
918
919  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
920  // a two-value operand where a dag node expects two operands. :( 
921  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
922               IIC_Br, "b", "\t$target",
923               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
924}
925
926// Branch and Exchange Jazelle -- for disassembly only
927def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
928              [/* For disassembly only; pattern left blank */]> {
929  let Inst{23-20} = 0b0010;
930  //let Inst{19-8} = 0xfff;
931  let Inst{7-4} = 0b0010;
932}
933
934// Supervisor call (software interrupt) -- for disassembly only
935let isCall = 1 in {
936def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
937              [/* For disassembly only; pattern left blank */]>;
938}
939
940//===----------------------------------------------------------------------===//
941//  Load / store Instructions.
942//
943
944// Load
945let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 
946def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
947               "ldr", "\t$dst, $addr",
948               [(set GPR:$dst, (load addrmode2:$addr))]>;
949
950// Special LDR for loads from non-pc-relative constpools.
951let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
952    mayHaveSideEffects = 1  in
953def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
954                 "ldr", "\t$dst, $addr", []>;
955
956// Loads with zero extension
957def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
958                  IIC_iLoadr, "ldrh", "\t$dst, $addr",
959                  [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
960
961def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
962                  IIC_iLoadr, "ldrb", "\t$dst, $addr",
963                  [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
964
965// Loads with sign extension
966def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
967                   IIC_iLoadr, "ldrsh", "\t$dst, $addr",
968                   [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
969
970def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
971                   IIC_iLoadr, "ldrsb", "\t$dst, $addr",
972                   [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
973
974let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
975// Load doubleword
976def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
977                 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
978                 []>, Requires<[IsARM, HasV5TE]>;
979
980// Indexed loads
981def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
982                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
983                     "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
984
985def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
986                     (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
987                     "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
988
989def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
990                     (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
991                     "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
992
993def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
994                     (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
995                    "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
996
997def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
998                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
999                     "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1000
1001def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1002                     (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1003                    "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1004
1005def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1006                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1007                      "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1008
1009def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1010                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1011                   "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1012
1013def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1014                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1015                      "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1016
1017def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1018                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1019                   "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1020}
1021
1022// LDRT and LDRBT are for disassembly only.
1023
1024def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1025                   (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1026                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1027  let Inst{21} = 1; // overwrite
1028}
1029
1030def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1031                   (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1032                   "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1033  let Inst{21} = 1; // overwrite
1034}
1035
1036// Store
1037def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1038               "str", "\t$src, $addr",
1039               [(store GPR:$src, addrmode2:$addr)]>;
1040
1041// Stores with truncate
1042def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
1043               "strh", "\t$src, $addr",
1044               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1045
1046def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1047               "strb", "\t$src, $addr",
1048               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1049
1050// Store doubleword
1051let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1052def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1053               StMiscFrm, IIC_iStorer,
1054               "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1055
1056// Indexed stores
1057def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
1058                     (ins GPR:$src, GPR:$base, am2offset:$offset), 
1059                     StFrm, IIC_iStoreru,
1060                    "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1061                    [(set GPR:$base_wb,
1062                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1063
1064def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1065                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1066                     StFrm, IIC_iStoreru,
1067                    "str", "\t$src, [$base], $offset", "$base = $base_wb",
1068                    [(set GPR:$base_wb,
1069                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1070
1071def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1072                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
1073                     StMiscFrm, IIC_iStoreru,
1074                     "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1075                    [(set GPR:$base_wb,
1076                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1077
1078def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1079                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
1080                     StMiscFrm, IIC_iStoreru,
1081                     "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1082                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1083                                         GPR:$base, am3offset:$offset))]>;
1084
1085def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1086                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1087                     StFrm, IIC_iStoreru,
1088                     "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1089                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1090                                         GPR:$base, am2offset:$offset))]>;
1091
1092def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1093                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1094                     StFrm, IIC_iStoreru,
1095                     "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1096                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1097                                         GPR:$base, am2offset:$offset))]>;
1098
1099// STRT and STRBT are for disassembly only.
1100
1101def STRT : AI2stwpo<(outs GPR:$base_wb),
1102                    (ins GPR:$src, GPR:$base,am2offset:$offset), 
1103                    StFrm, IIC_iStoreru,
1104                    "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1105                    [/* For disassembly only; pattern left blank */]> {
1106  let Inst{21} = 1; // overwrite
1107}
1108
1109def STRBT : AI2stbpo<(outs GPR:$base_wb),
1110                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1111                     StFrm, IIC_iStoreru,
1112                     "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1113                     [/* For disassembly only; pattern left blank */]> {
1114  let Inst{21} = 1; // overwrite
1115}
1116
1117//===----------------------------------------------------------------------===//
1118//  Load / store multiple Instructions.
1119//
1120
1121let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1122def LDM : AXI4ld<(outs),
1123               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1124               LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1125               []>;
1126
1127let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1128def STM : AXI4st<(outs),
1129               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1130               LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1131               []>;
1132
1133//===----------------------------------------------------------------------===//
1134//  Move Instructions.
1135//
1136
1137let neverHasSideEffects = 1 in
1138def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1139                "mov", "\t$dst, $src", []>, UnaryDP {
1140  let Inst{11-4} = 0b00000000;
1141  let Inst{25} = 0;
1142}
1143
1144def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
1145                DPSoRegFrm, IIC_iMOVsr,
1146                "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1147  let Inst{25} = 0;
1148}
1149
1150let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1151def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1152                "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1153  let Inst{25} = 1;
1154}
1155
1156let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1157def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
1158                 DPFrm, IIC_iMOVi,
1159                 "movw", "\t$dst, $src",
1160                 [(set GPR:$dst, imm0_65535:$src)]>,
1161                 Requires<[IsARM, HasV6T2]>, UnaryDP {
1162  let Inst{20} = 0;
1163  let Inst{25} = 1;
1164}
1165
1166let Constraints = "$src = $dst" in
1167def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1168                  DPFrm, IIC_iMOVi,
1169                  "movt", "\t$dst, $imm",
1170                  [(set GPR:$dst,
1171                        (or (and GPR:$src, 0xffff), 
1172                            lo16AllZero:$imm))]>, UnaryDP,
1173                  Requires<[IsARM, HasV6T2]> {
1174  let Inst{20} = 0;
1175  let Inst{25} = 1;
1176}
1177
1178def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1179      Requires<[IsARM, HasV6T2]>;
1180
1181let Uses = [CPSR] in
1182def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1183                 "mov", "\t$dst, $src, rrx",
1184                 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1185
1186// These aren't really mov instructions, but we have to define them this way
1187// due to flag operands.
1188
1189let Defs = [CPSR] in {
1190def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
1191                      IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1192                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1193def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1194                      IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1195                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1196}
1197
1198//===----------------------------------------------------------------------===//
1199//  Extend Instructions.
1200//
1201
1202// Sign extenders
1203
1204defm SXTB  : AI_unary_rrot<0b01101010,
1205                           "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1206defm SXTH  : AI_unary_rrot<0b01101011,
1207                           "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1208
1209defm SXTAB : AI_bin_rrot<0b01101010,
1210               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1211defm SXTAH : AI_bin_rrot<0b01101011,
1212               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1213
1214// TODO: SXT(A){B|H}16
1215
1216// Zero extenders
1217
1218let AddedComplexity = 16 in {
1219defm UXTB   : AI_unary_rrot<0b01101110,
1220                            "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1221defm UXTH   : AI_unary_rrot<0b01101111,
1222                            "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1223defm UXTB16 : AI_unary_rrot<0b01101100,
1224                            "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1225
1226def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1227               (UXTB16r_rot GPR:$Src, 24)>;
1228def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1229               (UXTB16r_rot GPR:$Src, 8)>;
1230
1231defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1232                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1233defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1234                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1235}
1236
1237// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1238//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1239
1240// TODO: UXT(A){B|H}16
1241
1242def SBFX  : I<(outs GPR:$dst),
1243              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1244               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1245               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1246               Requires<[IsARM, HasV6T2]> {
1247  let Inst{27-21} = 0b0111101;
1248  let Inst{6-4}   = 0b101;
1249}
1250
1251def UBFX  : I<(outs GPR:$dst),
1252              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1253               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1254               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1255               Requires<[IsARM, HasV6T2]> {
1256  let Inst{27-21} = 0b0111111;
1257  let Inst{6-4}   = 0b101;
1258}
1259
1260//===----------------------------------------------------------------------===//
1261//  Arithmetic Instructions.
1262//
1263
1264defm ADD  : AsI1_bin_irs<0b0100, "add",
1265                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1266defm SUB  : AsI1_bin_irs<0b0010, "sub",
1267                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1268
1269// ADD and SUB with 's' bit set.
1270defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1271                          BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1272defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1273                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1274
1275defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1276                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1277defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1278                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1279defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1280                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1281defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1282                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1283
1284// These don't define reg/reg forms, because they are handled above.
1285def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1286                  IIC_iALUi, "rsb", "\t$dst, $a, $b",
1287                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1288    let Inst{25} = 1;
1289}
1290
1291def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1292                  IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1293                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1294    let Inst{25} = 0;
1295}
1296
1297// RSB with 's' bit set.
1298let Defs = [CPSR] in {
1299def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1300                 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1301                 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1302    let Inst{20} = 1;
1303    let Inst{25} = 1;
1304}
1305def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1306                 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1307                 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1308    let Inst{20} = 1;
1309    let Inst{25} = 0;
1310}
1311}
1312
1313let Uses = [CPSR] in {
1314def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1315                 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1316                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1317                 Requires<[IsARM, CarryDefIsUnused]> {
1318    let Inst{25} = 1;
1319}
1320def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1321                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1322                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1323                 Requires<[IsARM, CarryDefIsUnused]> {
1324    let Inst{25} = 0;
1325}
1326}
1327
1328// FIXME: Allow these to be predicated.
1329let Defs = [CPSR], Uses = [CPSR] in {
1330def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1331                  DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1332                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1333                  Requires<[IsARM, CarryDefIsUnused]> {
1334    let Inst{20} = 1;
1335    let Inst{25} = 1;
1336}
1337def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1338                  DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1339                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1340                  Requires<[IsARM, CarryDefIsUnused]> {
1341    let Inst{20} = 1;
1342    let Inst{25} = 0;
1343}
1344}
1345
1346// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1347def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1348             (SUBri  GPR:$src, so_imm_neg:$imm)>;
1349
1350//def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1351//             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1352//def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1353//             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1354
1355// Note: These are implemented in C++ code, because they have to generate
1356// ADD/SUBrs instructions, which use a complex pattern that a xform function
1357// cannot produce.
1358// (mul X, 2^n+1) -> (add (X << n), X)
1359// (mul X, 2^n-1) -> (rsb X, (X << n))
1360
1361// Saturating adds/subtracts -- for disassembly only
1362
1363// GPR:$dst = GPR:$a op GPR:$b
1364class AQI<bits<8> op27_20, bits<4> op7_4, string opc>
1365  : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1366       opc, "\t$dst, $a, $b",
1367       [/* For disassembly only; pattern left blank */]> {
1368  let Inst{27-20} = op27_20;
1369  let Inst{7-4} = op7_4;
1370}
1371
1372def QADD    : AQI<0b00010000, 0b0101, "qadd">;
1373def QADD16  : AQI<0b01100010, 0b0001, "qadd16">;
1374def QADD8   : AQI<0b01100010, 0b1001, "qadd8">;
1375def QASX    : AQI<0b01100010, 0b0011, "qasx">;
1376def QDADD   : AQI<0b00010100, 0b0101, "qdadd">;
1377def QDSUB   : AQI<0b00010110, 0b0101, "qdsub">;
1378def QSAX    : AQI<0b01100010, 0b0101, "qsax">;
1379def QSUB    : AQI<0b00010010, 0b0101, "qsub">;
1380def QSUB16  : AQI<0b01100010, 0b0111, "qsub16">;
1381def QSUB8   : AQI<0b01100010, 0b1111, "qsub8">;
1382def UQADD16 : AQI<0b01100110, 0b0001, "uqadd16">;
1383def UQADD8  : AQI<0b01100110, 0b1001, "uqadd8">;
1384def UQASX   : AQI<0b01100110, 0b0011, "uqasx">;
1385def UQSAX   : AQI<0b01100110, 0b0101, "uqsax">;
1386def UQSUB16 : AQI<0b01100110, 0b0111, "uqsub16">;
1387def UQSUB8  : AQI<0b01100110, 0b1111, "uqsub8">;
1388
1389//===----------------------------------------------------------------------===//
1390//  Bitwise Instructions.
1391//
1392
1393defm AND   : AsI1_bin_irs<0b0000, "and",
1394                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1395defm ORR   : AsI1_bin_irs<0b1100, "orr",
1396                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1397defm EOR   : AsI1_bin_irs<0b0001, "eor",
1398                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1399defm BIC   : AsI1_bin_irs<0b1110, "bic",
1400                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1401
1402def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1403               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1404               "bfc", "\t$dst, $imm", "$src = $dst",
1405               [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1406               Requires<[IsARM, HasV6T2]> {
1407  let Inst{27-21} = 0b0111110;
1408  let Inst{6-0}   = 0b0011111;
1409}
1410
1411def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1412                  "mvn", "\t$dst, $src",
1413                  [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1414  let Inst{25} = 0;
1415  let Inst{11-4} = 0b00000000;
1416}
1417def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1418                  IIC_iMOVsr, "mvn", "\t$dst, $src",
1419                  [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1420  let Inst{25} = 0;
1421}
1422let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1423def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
1424                  IIC_iMOVi, "mvn", "\t$dst, $imm",
1425                  [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1426    let Inst{25} = 1;
1427}
1428
1429def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1430             (BICri GPR:$src, so_imm_not:$imm)>;
1431
1432//===----------------------------------------------------------------------===//
1433//  Multiply Instructions.
1434//
1435
1436let isCommutable = 1 in
1437def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1438                   IIC_iMUL32, "mul", "\t$dst, $a, $b",
1439                   [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1440
1441def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1442                    IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1443                   [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1444
1445def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1446                   IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1447                   [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1448                   Requires<[IsARM, HasV6T2]>;
1449
1450// Extra precision multiplies with low / high results
1451let neverHasSideEffects = 1 in {
1452let isCommutable = 1 in {
1453def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1454                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1455                    "smull", "\t$ldst, $hdst, $a, $b", []>;
1456
1457def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1458                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1459                    "umull", "\t$ldst, $hdst, $a, $b", []>;
1460}
1461
1462// Multiply + accumulate
1463def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1464                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1465                    "smlal", "\t$ldst, $hdst, $a, $b", []>;
1466
1467def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1468                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1469                    "umlal", "\t$ldst, $hdst, $a, $b", []>;
1470
1471def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1472                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1473                    "umaal", "\t$ldst, $hdst, $a, $b", []>,
1474                    Requires<[IsARM, HasV6]>;
1475} // neverHasSideEffects
1476
1477// Most significant word multiply
1478def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1479               IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1480               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1481            Requires<[IsARM, HasV6]> {
1482  let Inst{7-4}   = 0b0001;
1483  let Inst{15-12} = 0b1111;
1484}
1485
1486def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1487               IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1488               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1489            Requires<[IsARM, HasV6]> {
1490  let Inst{7-4}   = 0b0001;
1491}
1492
1493
1494def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1495               IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1496               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1497            Requires<[IsARM, HasV6]> {
1498  let Inst{7-4}   = 0b1101;
1499}
1500
1501multiclass AI_smul<string opc, PatFrag opnode> {
1502  def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1503              IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1504              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1505                                      (sext_inreg GPR:$b, i16)))]>,
1506           Requires<[IsARM, HasV5TE]> {
1507             let Inst{5} = 0;
1508             let Inst{6} = 0;
1509           }
1510
1511  def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1512              IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1513              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1514                                      (sra GPR:$b, (i32 16))))]>,
1515           Requires<[IsARM, HasV5TE]> {
1516             let Inst{5} = 0;
1517             let Inst{6} = 1;
1518           }
1519
1520  def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1521              IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1522              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1523                                      (sext_inreg GPR:$b, i16)))]>,
1524           Requires<[IsARM, HasV5TE]> {
1525             let Inst{5} = 1;
1526             let Inst{6} = 0;
1527           }
1528
1529  def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1530              IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1531              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1532                                      (sra GPR:$b, (i32 16))))]>,
1533            Requires<[IsARM, HasV5TE]> {
1534             let Inst{5} = 1;
1535             let Inst{6} = 1;
1536           }
1537
1538  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1539              IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1540              [(set GPR:$dst, (sra (opnode GPR:$a,
1541                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1542           Requires<[IsARM, HasV5TE]> {
1543             let Inst{5} = 1;
1544             let Inst{6} = 0;
1545           }
1546
1547  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1548              IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1549              [(set GPR:$dst, (sra (opnode GPR:$a,
1550                                    (sra GPR:$b, (i32 16))), (i32 16)))]>,
1551            Requires<[IsARM, HasV5TE]> {
1552             let Inst{5} = 1;
1553             let Inst{6} = 1;
1554           }
1555}
1556
1557
1558multiclass AI_smla<string opc, PatFrag opnode> {
1559  def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1560              IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1561              [(set GPR:$dst, (add GPR:$acc,
1562                               (opnode (sext_inreg GPR:$a, i16),
1563                                       (sext_inreg GPR:$b, i16))))]>,
1564           Requires<[IsARM, HasV5TE]> {
1565             let Inst{5} = 0;
1566             let Inst{6} = 0;
1567           }
1568
1569  def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1570              IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1571              [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1572                                                     (sra GPR:$b, (i32 16)))))]>,
1573           Requires<[IsARM, HasV5TE]> {
1574             let Inst{5} = 0;
1575             let Inst{6} = 1;
1576           }
1577
1578  def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1579              IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1580              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1581                                                 (sext_inreg GPR:$b, i16))))]>,
1582           Requires<[IsARM, HasV5TE]> {
1583             let Inst{5} = 1;
1584             let Inst{6} = 0;
1585           }
1586
1587  def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1588              IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1589             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1590                                                    (sra GPR:$b, (i32 16)))))]>,
1591            Requires<[IsARM, HasV5TE]> {
1592             let Inst{5} = 1;
1593             let Inst{6} = 1;
1594           }
1595
1596  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1597              IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1598              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1599                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1600           Requires<[IsARM, HasV5TE]> {
1601             let Inst{5} = 0;
1602             let Inst{6} = 0;
1603           }
1604
1605  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1606              IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1607              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1608                                         (sra GPR:$b, (i32 16))), (i32 16))))]>,
1609            Requires<[IsARM, HasV5TE]> {
1610             let Inst{5} = 0;
1611             let Inst{6} = 1;
1612           }
1613}
1614
1615defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1616defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1617
1618// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1619def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1620                      IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1621                      [/* For disassembly only; pattern left blank */]>,
1622              Requires<[IsARM, HasV5TE]> {
1623  let Inst{5} = 0;
1624  let Inst{6} = 0;
1625}
1626
1627def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1628                      IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1629                      [/* For disassembly only; pattern left blank */]>,
1630              Requires<[IsARM, HasV5TE]> {
1631  let Inst{5} = 0;
1632  let Inst{6} = 1;
1633}
1634
1635def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1636                      IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1637                      [/* For disassembly only; pattern left blank */]>,
1638              Requires<[IsARM, HasV5TE]> {
1639  let Inst{5} = 1;
1640  let Inst{6} = 0;
1641}
1642
1643def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1644                      IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1645                      [/* For disassembly only; pattern left blank */]>,
1646              Requires<[IsARM, HasV5TE]> {
1647  let Inst{5} = 1;
1648  let Inst{6} = 1;
1649}
1650
1651// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1652
1653//===----------------------------------------------------------------------===//
1654//  Misc. Arithmetic Instructions.
1655//
1656
1657def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1658              "clz", "\t$dst, $src",
1659              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1660  let Inst{7-4}   = 0b0001;
1661  let Inst{11-8}  = 0b1111;
1662  let Inst{19-16} = 0b1111;
1663}
1664
1665def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1666              "rbit", "\t$dst, $src",
1667              [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1668           Requires<[IsARM, HasV6T2]> {
1669  let Inst{7-4}   = 0b0011;
1670  let Inst{11-8}  = 0b1111;
1671  let Inst{19-16} = 0b1111;
1672}
1673
1674def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1675              "rev", "\t$dst, $src",
1676              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1677  let Inst{7-4}   = 0b0011;
1678  let Inst{11-8}  = 0b1111;
1679  let Inst{19-16} = 0b1111;
1680}
1681
1682def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1683               "rev16", "\t$dst, $src",
1684               [(set GPR:$dst,
1685                   (or (and (srl GPR:$src, (i32 8)), 0xFF),
1686                       (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1687                           (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1688                               (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1689               Requires<[IsARM, HasV6]> {
1690  let Inst{7-4}   = 0b1011;
1691  let Inst{11-8}  = 0b1111;
1692  let Inst{19-16} = 0b1111;
1693}
1694
1695def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1696               "revsh", "\t$dst, $src",
1697               [(set GPR:$dst,
1698                  (sext_inreg
1699                    (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1700                        (shl GPR:$src, (i32 8))), i16))]>,
1701               Requires<[IsARM, HasV6]> {
1702  let Inst{7-4}   = 0b1011;
1703  let Inst{11-8}  = 0b1111;
1704  let Inst{19-16} = 0b1111;
1705}
1706
1707def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1708                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1709               IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1710               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1711                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
1712                                        0xFFFF0000)))]>,
1713               Requires<[IsARM, HasV6]> {
1714  let Inst{6-4} = 0b001;
1715}
1716
1717// Alternate cases for PKHBT where identities eliminate some nodes.
1718def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1719               (PKHBT GPR:$src1, GPR:$src2, 0)>;
1720def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1721               (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1722
1723
1724def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1725                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1726               IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1727               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1728                                   (and (sra GPR:$src2, imm16_31:$shamt),
1729                                        0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1730  let Inst{6-4} = 0b101;
1731}
1732
1733// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1734// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1735def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1736               (PKHTB GPR:$src1, GPR:$src2, 16)>;
1737def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1738                   (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1739               (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1740
1741//===----------------------------------------------------------------------===//
1742//  Comparison Instructions...
1743//
1744
1745defm CMP  : AI1_cmp_irs<0b1010, "cmp",
1746                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1747//FIXME: Disable CMN, as CCodes are backwards from compare expectations
1748//       Compare-to-zero still works out, just not the relationals
1749//defm CMN  : AI1_cmp_irs<0b1011, "cmn",
1750//                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1751
1752// Note that TST/TEQ don't set all the same flags that CMP does!
1753defm TST  : AI1_cmp_irs<0b1000, "tst",
1754                        BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1755defm TEQ  : AI1_cmp_irs<0b1001, "teq",
1756                        BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1757
1758defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
1759                         BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1760defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
1761                         BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1762
1763//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1764//             (CMNri  GPR:$src, so_imm_neg:$imm)>;
1765
1766def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1767             (CMNzri  GPR:$src, so_imm_neg:$imm)>;
1768
1769
1770// Conditional moves
1771// FIXME: should be able to write a pattern for ARMcmov, but can't use
1772// a two-value operand where a dag node expects two operands. :( 
1773def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1774                IIC_iCMOVr, "mov", "\t$dst, $true",
1775      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1776                RegConstraint<"$false = $dst">, UnaryDP {
1777  let Inst{11-4} = 0b00000000;
1778  let Inst{25} = 0;
1779}
1780
1781def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1782                        (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1783                "mov", "\t$dst, $true",
1784   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1785                RegConstraint<"$false = $dst">, UnaryDP {
1786  let Inst{25} = 0;
1787}
1788
1789def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1790                        (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1791                "mov", "\t$dst, $true",
1792   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1793                RegConstraint<"$false = $dst">, UnaryDP {
1794  let Inst{25} = 1;
1795}
1796
1797//===----------------------------------------------------------------------===//
1798// Atomic operations intrinsics
1799//
1800
1801// memory barriers protect the atomic sequences
1802let hasSideEffects = 1 in {
1803def Int_MemBarrierV7 : AInoP<(outs), (ins),
1804                        Pseudo, NoItinerary,
1805                        "dmb", "",
1806                        [(ARMMemBarrierV7)]>,
1807                        Requires<[IsARM, HasV7]> {
1808  let Inst{31-4} = 0xf57ff05;
1809  // FIXME: add support for options other than a full system DMB
1810  let Inst{3-0} = 0b1111;
1811}
1812
1813def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1814                        Pseudo, NoItinerary,
1815                        "dsb", "",
1816                        [(ARMSyncBarrierV7)]>,
1817                        Requires<[IsARM, HasV7]> {
1818  let Inst{31-4} = 0xf57ff04;
1819  // FIXME: add support for options other than a full system DSB
1820  let Inst{3-0} = 0b1111;
1821}
1822
1823def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1824                       Pseudo, NoItinerary,
1825                       "mcr", "\tp15, 0, $zero, c7, c10, 5",
1826                       [(ARMMemBarrierV6 GPR:$zero)]>,
1827                       Requires<[IsARM, HasV6]> {
1828  // FIXME: add support for options other than a full system DMB
1829  // FIXME: add encoding
1830}
1831
1832def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1833                        Pseudo, NoItinerary,
1834                        "mcr", "\tp15, 0, $zero, c7, c10, 4",
1835                        [(ARMSyncBarrierV6 GPR:$zero)]>,
1836                        Requires<[IsARM, HasV6]> {
1837  // FIXME: add support for options other than a full system DSB
1838  // FIXME: add encoding
1839}
1840}
1841
1842let usesCustomInserter = 1 in {
1843  let Uses = [CPSR] in {
1844    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1845      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1846      "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1847      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1848    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1849      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1850      "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1851      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1852    def ATOMIC_LOAD_AND_I8 : PseudoInst<
1853      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1854      "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1855      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1856    def ATOMIC_LOAD_OR_I8 : PseudoInst<
1857      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1858      "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1859      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1860    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1861      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1862      "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1863      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1864    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1865      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1866      "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1867      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1868    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1869      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1870      "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1871      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1872    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1873      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1874      "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1875      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1876    def ATOMIC_LOAD_AND_I16 : PseudoInst<
1877      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1878      "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1879      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1880    def ATOMIC_LOAD_OR_I16 : PseudoInst<
1881      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1882      "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1883      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1884    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1885      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1886      "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1887      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1888    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1889      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1890      "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1891      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1892    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1893      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1894      "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1895      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1896    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1897      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1898      "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1899      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1900    def ATOMIC_LOAD_AND_I32 : PseudoInst<
1901      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1902      "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1903      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1904    def ATOMIC_LOAD_OR_I32 : PseudoInst<
1905      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1906      "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1907      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1908    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1909      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1910      "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1911      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1912    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1913      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1914      "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1915      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1916
1917    def ATOMIC_SWAP_I8 : PseudoInst<
1918      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1919      "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1920      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1921    def ATOMIC_SWAP_I16 : PseudoInst<
1922      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1923      "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1924      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1925    def ATOMIC_SWAP_I32 : PseudoInst<
1926      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1927      "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1928      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1929
1930    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1931      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1932      "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1933      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1934    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1935      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1936      "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1937      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1938    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1939      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1940      "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1941      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1942}
1943}
1944
1945let mayLoad = 1 in {
1946def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1947                    "ldrexb", "\t$dest, [$ptr]",
1948                    []>;
1949def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1950                    "ldrexh", "\t$dest, [$ptr]",
1951                    []>;
1952def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1953                    "ldrex", "\t$dest, [$ptr]",
1954                    []>;
1955def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1956                    NoItinerary,
1957                    "ldrexd", "\t$dest, $dest2, [$ptr]",
1958                    []>;
1959}
1960
1961let mayStore = 1, Constraints = "@earlyclobber $success" in {
1962def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1963                    NoItinerary,
1964                    "strexb", "\t$success, $src, [$ptr]",
1965                    []>;
1966def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1967                    NoItinerary,
1968                    "strexh", "\t$success, $src, [$ptr]",
1969                    []>;
1970def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1971                    NoItinerary,
1972                    "strex", "\t$success, $src, [$ptr]",
1973                    []>;
1974def STREXD : AIstrex<0b01, (outs GPR:$success),
1975                    (ins GPR:$src, GPR:$src2, GPR:$ptr),
1976                    NoItinerary,
1977                    "strexd", "\t$success, $src, $src2, [$ptr]",
1978                    []>;
1979}
1980
1981// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
1982let mayLoad = 1 in {
1983def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1984             "swp", "\t$dst, $src, [$ptr]",
1985             [/* For disassembly only; pattern left blank */]> {
1986  let Inst{27-23} = 0b00010;
1987  let Inst{22} = 0; // B = 0
1988  let Inst{21-20} = 0b00;
1989  let Inst{7-4} = 0b1001;
1990}
1991
1992def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1993             "swpb", "\t$dst, $src, [$ptr]",
1994             [/* For disassembly only; pattern left blank */]> {
1995  let Inst{27-23} = 0b00010;
1996  let Inst{22} = 1; // B = 1
1997  let Inst{21-20} = 0b00;
1998  let Inst{7-4} = 0b1001;
1999}
2000}
2001
2002//===----------------------------------------------------------------------===//
2003// TLS Instructions
2004//
2005
2006// __aeabi_read_tp preserves the registers r1-r3.
2007let isCall = 1,
2008  Defs = [R0, R12, LR, CPSR] in {
2009  def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2010               "bl\t__aeabi_read_tp",
2011               [(set R0, ARMthread_pointer)]>;
2012}
2013
2014//===----------------------------------------------------------------------===//
2015// SJLJ Exception handling intrinsics
2016//   eh_sjlj_setjmp() is an instruction sequence to store the return
2017//   address and save #0 in R0 for the non-longjmp case.
2018//   Since by its nature we may be coming from some other function to get
2019//   here, and we're using the stack frame for the containing function to
2020//   save/restore registers, we can't keep anything live in regs across
2021//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2022//   when we get here from a longjmp(). We force everthing out of registers
2023//   except for our own input by listing the relevant registers in Defs. By
2024//   doing so, we also cause the prologue/epilogue code to actively preserve
2025//   all of the callee-saved resgisters, which is exactly what we want.
2026//   A constant value is passed in $val, and we use the location as a scratch.
2027let Defs =
2028  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
2029    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
2030    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2031    D31 ] in {
2032  def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2033                               AddrModeNone, SizeSpecial, IndexModeNone,
2034                               Pseudo, NoItinerary,
2035                               "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2036                               "add\t$val, pc, #8\n\t"
2037                               "str\t$val, [$src, #+4]\n\t"
2038                               "mov\tr0, #0\n\t"
2039                               "add\tpc, pc, #0\n\t"
2040                               "mov\tr0, #1 @ eh_setjmp end", "",
2041                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2042}
2043
2044//===----------------------------------------------------------------------===//
2045// Non-Instruction Patterns
2046//
2047
2048// Large immediate handling.
2049
2050// Two piece so_imms.
2051let isReMaterializable = 1 in
2052def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
2053                         Pseudo, IIC_iMOVi,
2054                         "mov", "\t$dst, $src",
2055                         [(set GPR:$dst, so_imm2part:$src)]>,
2056                  Requires<[IsARM, NoV6T2]>;
2057
2058def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2059             (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2060                    (so_imm2part_2 imm:$RHS))>;
2061def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2062             (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2063                    (so_imm2part_2 imm:$RHS))>;
2064def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2065             (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2066                    (so_imm2part_2 imm:$RHS))>;
2067def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2068             (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2069                    (so_neg_imm2part_2 imm:$RHS))>;
2070
2071// 32-bit immediate using movw + movt.
2072// This is a single pseudo instruction, the benefit is that it can be remat'd
2073// as a single unit instead of having to handle reg inputs.
2074// FIXME: Remove this when we can do generalized remat.
2075let isReMaterializable = 1 in
2076def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2077                    "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2078                     [(set GPR:$dst, (i32 imm:$src))]>,
2079               Requires<[IsARM, HasV6T2]>;
2080
2081// ConstantPool, GlobalAddress, and JumpTable
2082def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2083            Requires<[IsARM, DontUseMovt]>;
2084def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
2085def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2086            Requires<[IsARM, UseMovt]>;
2087def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2088             (LEApcrelJT tjumptable:$dst, imm:$id)>;
2089
2090// TODO: add,sub,and, 3-instr forms?
2091
2092
2093// Direct calls
2094def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2095      Requires<[IsARM, IsNotDarwin]>;
2096def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2097      Requires<[IsARM, IsDarwin]>;
2098
2099// zextload i1 -> zextload i8
2100def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2101
2102// extload -> zextload
2103def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2104def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2105def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
2106
2107def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2108def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2109
2110// smul* and smla*
2111def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2112                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
2113                 (SMULBB GPR:$a, GPR:$b)>;
2114def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2115                 (SMULBB GPR:$a, GPR:$b)>;
2116def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2117                      (sra GPR:$b, (i32 16))),
2118                 (SMULBT GPR:$a, GPR:$b)>;
2119def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2120                 (SMULBT GPR:$a, GPR:$b)>;
2121def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2122                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
2123                 (SMULTB GPR:$a, GPR:$b)>;
2124def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2125                (SMULTB GPR:$a, GPR:$b)>;
2126def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2127                      (i32 16)),
2128                 (SMULWB GPR:$a, GPR:$b)>;
2129def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2130                 (SMULWB GPR:$a, GPR:$b)>;
2131
2132def : ARMV5TEPat<(add GPR:$acc,
2133                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2134                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2135                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2136def : ARMV5TEPat<(add GPR:$acc,
2137                      (mul sext_16_node:$a, sext_16_node:$b)),
2138                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2139def : ARMV5TEPat<(add GPR:$acc,
2140                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2141                           (sra GPR:$b, (i32 16)))),
2142                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2143def : ARMV5TEPat<(add GPR:$acc,
2144                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2145                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2146def : ARMV5TEPat<(add GPR:$acc,
2147                      (mul (sra GPR:$a, (i32 16)),
2148                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2149                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2150def : ARMV5TEPat<(add GPR:$acc,
2151                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2152                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2153def : ARMV5TEPat<(add GPR:$acc,
2154                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2155                           (i32 16))),
2156                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2157def : ARMV5TEPat<(add GPR:$acc,
2158                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2159                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2160
2161//===----------------------------------------------------------------------===//
2162// Thumb Support
2163//
2164
2165include "ARMInstrThumb.td"
2166
2167//===----------------------------------------------------------------------===//
2168// Thumb2 Support
2169//
2170
2171include "ARMInstrThumb2.td"
2172
2173//===----------------------------------------------------------------------===//
2174// Floating Point Support
2175//
2176
2177include "ARMInstrVFP.td"
2178
2179//===----------------------------------------------------------------------===//
2180// Advanced SIMD (NEON) Support
2181//
2182
2183include "ARMInstrNEON.td"
2184
2185//===----------------------------------------------------------------------===//
2186// Coprocessor Instructions.  For disassembly only.
2187//
2188
2189def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2190            nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2191            NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2192              [/* For disassembly only; pattern left blank */]> {
2193  let Inst{4} = 0;
2194}
2195
2196def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2197               nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2198               NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2199               [/* For disassembly only; pattern left blank */]> {
2200  let Inst{31-28} = 0b1111;
2201  let Inst{4} = 0;
2202}
2203
2204def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2205              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2206              NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2207              [/* For disassembly only; pattern left blank */]> {
2208  let Inst{20} = 0;
2209  let Inst{4} = 1;
2210}
2211
2212def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2213                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2214                NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2215                [/* For disassembly only; pattern left blank */]> {
2216  let Inst{31-28} = 0b1111;
2217  let Inst{20} = 0;
2218  let Inst{4} = 1;
2219}
2220
2221def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2222              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2223              NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2224              [/* For disassembly only; pattern left blank */]> {
2225  let Inst{20} = 1;
2226  let Inst{4} = 1;
2227}
2228
2229def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2230                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2231                NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2232                [/* For disassembly only; pattern left blank */]> {
2233  let Inst{31-28} = 0b1111;
2234  let Inst{20} = 1;
2235  let Inst{4} = 1;
2236}
2237
2238def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2239               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2240               NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2241               [/* For disassembly only; pattern left blank */]> {
2242  let Inst{23-20} = 0b0100;
2243}
2244
2245def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2246                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2247                 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2248                 [/* For disassembly only; pattern left blank */]> {
2249  let Inst{31-28} = 0b1111;
2250  let Inst{23-20} = 0b0100;
2251}
2252
2253def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2254               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2255               NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2256               [/* For disassembly only; pattern left blank */]> {
2257  let Inst{23-20} = 0b0101;
2258}
2259
2260def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2261                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2262                 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2263                 [/* For disassembly only; pattern left blank */]> {
2264  let Inst{31-28} = 0b1111;
2265  let Inst{23-20} = 0b0101;
2266}
2267
2268//===----------------------------------------------------------------------===//
2269// Move between special register and ARM core register -- for disassembly only
2270//
2271
2272def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2273              [/* For disassembly only; pattern left blank */]> {
2274  let Inst{23-20} = 0b0000;
2275  let Inst{7-4} = 0b0000;
2276}
2277
2278def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2279              [/* For disassembly only; pattern left blank */]> {
2280  let Inst{23-20} = 0b0100;
2281  let Inst{7-4} = 0b0000;
2282}
2283
2284// FIXME: mask is ignored for the time being.
2285def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "mrs", "\tcpsr, $src",
2286              [/* For disassembly only; pattern left blank */]> {
2287  let Inst{23-20} = 0b0010;
2288  let Inst{7-4} = 0b0000;
2289}
2290
2291// FIXME: mask is ignored for the time being.
2292def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"mrs","\tspsr, $src",
2293              [/* For disassembly only; pattern left blank */]> {
2294  let Inst{23-20} = 0b0110;
2295  let Inst{7-4} = 0b0000;
2296}
2297