ARMInstrInfo.td revision 7cfa51ebd8304eb565d8d6f2b1e50a55ef04d1ca
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()">;
133
134// FIXME: Eventually this will be just "hasV6T2Ops".
135def UseMovt   : Predicate<"Subtarget->useMovt()">;
136def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
137
138//===----------------------------------------------------------------------===//
139// ARM Flag Definitions.
140
141class RegConstraint<string C> {
142  string Constraints = C;
143}
144
145//===----------------------------------------------------------------------===//
146//  ARM specific transformation functions and pattern fragments.
147//
148
149// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
150// so_imm_neg def below.
151def so_imm_neg_XFORM : SDNodeXForm<imm, [{
152  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
153}]>;
154
155// so_imm_not_XFORM - Return a so_imm value packed into the format described for
156// so_imm_not def below.
157def so_imm_not_XFORM : SDNodeXForm<imm, [{
158  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
159}]>;
160
161// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
162def rot_imm : PatLeaf<(i32 imm), [{
163  int32_t v = (int32_t)N->getZExtValue();
164  return v == 8 || v == 16 || v == 24;
165}]>;
166
167/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
168def imm1_15 : PatLeaf<(i32 imm), [{
169  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
170}]>;
171
172/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
173def imm16_31 : PatLeaf<(i32 imm), [{
174  return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
175}]>;
176
177def so_imm_neg :
178  PatLeaf<(imm), [{
179    return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
180  }], so_imm_neg_XFORM>;
181
182def so_imm_not :
183  PatLeaf<(imm), [{
184    return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
185  }], so_imm_not_XFORM>;
186
187// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
188def sext_16_node : PatLeaf<(i32 GPR:$a), [{
189  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
190}]>;
191
192/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
193/// e.g., 0xf000ffff
194def bf_inv_mask_imm : Operand<i32>,
195                      PatLeaf<(imm), [{
196  uint32_t v = (uint32_t)N->getZExtValue();
197  if (v == 0xffffffff)
198    return 0;
199  // there can be 1's on either or both "outsides", all the "inside"
200  // bits must be 0's
201  unsigned int lsb = 0, msb = 31;
202  while (v & (1 << msb)) --msb;
203  while (v & (1 << lsb)) ++lsb;
204  for (unsigned int i = lsb; i <= msb; ++i) {
205    if (v & (1 << i))
206      return 0;
207  }
208  return 1;
209}] > {
210  let PrintMethod = "printBitfieldInvMaskImmOperand";
211}
212
213/// Split a 32-bit immediate into two 16 bit parts.
214def lo16 : SDNodeXForm<imm, [{
215  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
216                                   MVT::i32);
217}]>;
218
219def hi16 : SDNodeXForm<imm, [{
220  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
221}]>;
222
223def lo16AllZero : PatLeaf<(i32 imm), [{
224  // Returns true if all low 16-bits are 0.
225  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
226}], hi16>;
227
228/// imm0_65535 predicate - True if the 32-bit immediate is in the range
229/// [0.65535].
230def imm0_65535 : PatLeaf<(i32 imm), [{
231  return (uint32_t)N->getZExtValue() < 65536;
232}]>;
233
234class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
235class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
236
237/// adde and sube predicates - True based on whether the carry flag output
238/// will be needed or not.
239def adde_dead_carry :
240  PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
241  [{return !N->hasAnyUseOfValue(1);}]>;
242def sube_dead_carry :
243  PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
244  [{return !N->hasAnyUseOfValue(1);}]>;
245def adde_live_carry :
246  PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
247  [{return N->hasAnyUseOfValue(1);}]>;
248def sube_live_carry :
249  PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
250  [{return N->hasAnyUseOfValue(1);}]>;
251
252//===----------------------------------------------------------------------===//
253// Operand Definitions.
254//
255
256// Branch target.
257def brtarget : Operand<OtherVT>;
258
259// A list of registers separated by comma. Used by load/store multiple.
260def reglist : Operand<i32> {
261  let PrintMethod = "printRegisterList";
262}
263
264// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
265def cpinst_operand : Operand<i32> {
266  let PrintMethod = "printCPInstOperand";
267}
268
269def jtblock_operand : Operand<i32> {
270  let PrintMethod = "printJTBlockOperand";
271}
272def jt2block_operand : Operand<i32> {
273  let PrintMethod = "printJT2BlockOperand";
274}
275
276// Local PC labels.
277def pclabel : Operand<i32> {
278  let PrintMethod = "printPCLabel";
279}
280
281// shifter_operand operands: so_reg and so_imm.
282def so_reg : Operand<i32>,    // reg reg imm
283            ComplexPattern<i32, 3, "SelectShifterOperandReg",
284                            [shl,srl,sra,rotr]> {
285  let PrintMethod = "printSORegOperand";
286  let MIOperandInfo = (ops GPR, GPR, i32imm);
287}
288
289// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
290// 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
291// represented in the imm field in the same 12-bit form that they are encoded
292// into so_imm instructions: the 8-bit immediate is the least significant bits
293// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
294def so_imm : Operand<i32>,
295             PatLeaf<(imm), [{
296      return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
297    }]> {
298  let PrintMethod = "printSOImmOperand";
299}
300
301// Break so_imm's up into two pieces.  This handles immediates with up to 16
302// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
303// get the first/second pieces.
304def so_imm2part : Operand<i32>,
305                  PatLeaf<(imm), [{
306      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
307    }]> {
308  let PrintMethod = "printSOImm2PartOperand";
309}
310
311def so_imm2part_1 : SDNodeXForm<imm, [{
312  unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
313  return CurDAG->getTargetConstant(V, MVT::i32);
314}]>;
315
316def so_imm2part_2 : SDNodeXForm<imm, [{
317  unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
318  return CurDAG->getTargetConstant(V, MVT::i32);
319}]>;
320
321def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
322      return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
323    }]> {
324  let PrintMethod = "printSOImm2PartOperand";
325}
326
327def so_neg_imm2part_1 : SDNodeXForm<imm, [{
328  unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
329  return CurDAG->getTargetConstant(V, MVT::i32);
330}]>;
331
332def so_neg_imm2part_2 : SDNodeXForm<imm, [{
333  unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
334  return CurDAG->getTargetConstant(V, MVT::i32);
335}]>;
336
337/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
338def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
339  return (int32_t)N->getZExtValue() < 32;
340}]>;
341
342// Define ARM specific addressing modes.
343
344// addrmode2 := reg +/- reg shop imm
345// addrmode2 := reg +/- imm12
346//
347def addrmode2 : Operand<i32>,
348                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
349  let PrintMethod = "printAddrMode2Operand";
350  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
351}
352
353def am2offset : Operand<i32>,
354                ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
355  let PrintMethod = "printAddrMode2OffsetOperand";
356  let MIOperandInfo = (ops GPR, i32imm);
357}
358
359// addrmode3 := reg +/- reg
360// addrmode3 := reg +/- imm8
361//
362def addrmode3 : Operand<i32>,
363                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
364  let PrintMethod = "printAddrMode3Operand";
365  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
366}
367
368def am3offset : Operand<i32>,
369                ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
370  let PrintMethod = "printAddrMode3OffsetOperand";
371  let MIOperandInfo = (ops GPR, i32imm);
372}
373
374// addrmode4 := reg, <mode|W>
375//
376def addrmode4 : Operand<i32>,
377                ComplexPattern<i32, 2, "SelectAddrMode4", []> {
378  let PrintMethod = "printAddrMode4Operand";
379  let MIOperandInfo = (ops GPR, i32imm);
380}
381
382// addrmode5 := reg +/- imm8*4
383//
384def addrmode5 : Operand<i32>,
385                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
386  let PrintMethod = "printAddrMode5Operand";
387  let MIOperandInfo = (ops GPR, i32imm);
388}
389
390// addrmode6 := reg with optional writeback
391//
392def addrmode6 : Operand<i32>,
393                ComplexPattern<i32, 4, "SelectAddrMode6", []> {
394  let PrintMethod = "printAddrMode6Operand";
395  let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
396}
397
398// addrmodepc := pc + reg
399//
400def addrmodepc : Operand<i32>,
401                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
402  let PrintMethod = "printAddrModePCOperand";
403  let MIOperandInfo = (ops GPR, i32imm);
404}
405
406def nohash_imm : Operand<i32> {
407  let PrintMethod = "printNoHashImmediate";
408}
409
410//===----------------------------------------------------------------------===//
411
412include "ARMInstrFormats.td"
413
414//===----------------------------------------------------------------------===//
415// Multiclass helpers...
416//
417
418/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
419/// binop that produces a value.
420multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
421                        bit Commutable = 0> {
422  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
423               IIC_iALUi, opc, "\t$dst, $a, $b",
424               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
425    let Inst{25} = 1;
426  }
427  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
428               IIC_iALUr, opc, "\t$dst, $a, $b",
429               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
430    let Inst{11-4} = 0b00000000;
431    let Inst{25} = 0;
432    let isCommutable = Commutable;
433  }
434  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
435               IIC_iALUsr, opc, "\t$dst, $a, $b",
436               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
437    let Inst{25} = 0;
438  }
439}
440
441/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
442/// instruction modifies the CPSR register.
443let Defs = [CPSR] in {
444multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
445                         bit Commutable = 0> {
446  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
447               IIC_iALUi, opc, "\t$dst, $a, $b",
448               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
449    let Inst{20} = 1;
450    let Inst{25} = 1;
451  }
452  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
453               IIC_iALUr, opc, "\t$dst, $a, $b",
454               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
455    let isCommutable = Commutable;
456    let Inst{11-4} = 0b00000000;
457    let Inst{20} = 1;
458    let Inst{25} = 0;
459  }
460  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
461               IIC_iALUsr, opc, "\t$dst, $a, $b",
462               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
463    let Inst{20} = 1;
464    let Inst{25} = 0;
465  }
466}
467}
468
469/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
470/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
471/// a explicit result, only implicitly set CPSR.
472let Defs = [CPSR] in {
473multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
474                       bit Commutable = 0> {
475  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
476               opc, "\t$a, $b",
477               [(opnode GPR:$a, so_imm:$b)]> {
478    let Inst{20} = 1;
479    let Inst{25} = 1;
480  }
481  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
482               opc, "\t$a, $b",
483               [(opnode GPR:$a, GPR:$b)]> {
484    let Inst{11-4} = 0b00000000;
485    let Inst{20} = 1;
486    let Inst{25} = 0;
487    let isCommutable = Commutable;
488  }
489  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
490               opc, "\t$a, $b",
491               [(opnode GPR:$a, so_reg:$b)]> {
492    let Inst{20} = 1;
493    let Inst{25} = 0;
494  }
495}
496}
497
498/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
499/// register and one whose operand is a register rotated by 8/16/24.
500/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
501multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
502  def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
503                 IIC_iUNAr, opc, "\t$dst, $src",
504                 [(set GPR:$dst, (opnode GPR:$src))]>,
505              Requires<[IsARM, HasV6]> {
506    let Inst{11-10} = 0b00;
507    let Inst{19-16} = 0b1111;
508  }
509  def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
510                 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
511                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
512              Requires<[IsARM, HasV6]> {
513    let Inst{19-16} = 0b1111;
514  }
515}
516
517multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
518  def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
519                 IIC_iUNAr, opc, "\t$dst, $src",
520                 [/* For disassembly only; pattern left blank */]>,
521              Requires<[IsARM, HasV6]> {
522    let Inst{11-10} = 0b00;
523    let Inst{19-16} = 0b1111;
524  }
525  def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
526                 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
527                 [/* For disassembly only; pattern left blank */]>,
528              Requires<[IsARM, HasV6]> {
529    let Inst{19-16} = 0b1111;
530  }
531}
532
533/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
534/// register and one whose operand is a register rotated by 8/16/24.
535multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
536  def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
537                  IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
538                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
539               Requires<[IsARM, HasV6]> {
540    let Inst{11-10} = 0b00;
541  }
542  def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
543                                              i32imm:$rot),
544                  IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
545                  [(set GPR:$dst, (opnode GPR:$LHS,
546                                          (rotr GPR:$RHS, rot_imm:$rot)))]>,
547                  Requires<[IsARM, HasV6]>;
548}
549
550// For disassembly only.
551multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
552  def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
553                  IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
554                  [/* For disassembly only; pattern left blank */]>,
555               Requires<[IsARM, HasV6]> {
556    let Inst{11-10} = 0b00;
557  }
558  def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
559                                              i32imm:$rot),
560                  IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
561                  [/* For disassembly only; pattern left blank */]>,
562                  Requires<[IsARM, HasV6]>;
563}
564
565/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
566let Uses = [CPSR] in {
567multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
568                             bit Commutable = 0> {
569  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
570                DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
571               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
572               Requires<[IsARM]> {
573    let Inst{25} = 1;
574  }
575  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
576                DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
577               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
578               Requires<[IsARM]> {
579    let isCommutable = Commutable;
580    let Inst{11-4} = 0b00000000;
581    let Inst{25} = 0;
582  }
583  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
584                DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
585               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
586               Requires<[IsARM]> {
587    let Inst{25} = 0;
588  }
589}
590// Carry setting variants
591let Defs = [CPSR] in {
592multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
593                             bit Commutable = 0> {
594  def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
595                DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
596               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
597               Requires<[IsARM]> {
598    let Inst{20} = 1;
599    let Inst{25} = 1;
600  }
601  def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
602                DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
603               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
604               Requires<[IsARM]> {
605    let Inst{11-4} = 0b00000000;
606    let Inst{20} = 1;
607    let Inst{25} = 0;
608  }
609  def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
610                DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
611               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
612               Requires<[IsARM]> {
613    let Inst{20} = 1;
614    let Inst{25} = 0;
615  }
616}
617}
618}
619
620//===----------------------------------------------------------------------===//
621// Instructions
622//===----------------------------------------------------------------------===//
623
624//===----------------------------------------------------------------------===//
625//  Miscellaneous Instructions.
626//
627
628/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
629/// the function.  The first operand is the ID# for this instruction, the second
630/// is the index into the MachineConstantPool that this is, the third is the
631/// size in bytes of this constant pool entry.
632let neverHasSideEffects = 1, isNotDuplicable = 1 in
633def CONSTPOOL_ENTRY :
634PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
635                    i32imm:$size), NoItinerary,
636           "${instid:label} ${cpidx:cpentry}", []>;
637
638// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
639// from removing one half of the matched pairs. That breaks PEI, which assumes
640// these will always be in pairs, and asserts if it finds otherwise. Better way?
641let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
642def ADJCALLSTACKUP :
643PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
644           "@ ADJCALLSTACKUP $amt1",
645           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
646
647def ADJCALLSTACKDOWN :
648PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
649           "@ ADJCALLSTACKDOWN $amt",
650           [(ARMcallseq_start timm:$amt)]>;
651}
652
653def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
654             [/* For disassembly only; pattern left blank */]>,
655          Requires<[IsARM, HasV6T2]> {
656  let Inst{27-16} = 0b001100100000;
657  let Inst{7-0} = 0b00000000;
658}
659
660def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
661             [/* For disassembly only; pattern left blank */]>,
662          Requires<[IsARM, HasV6T2]> {
663  let Inst{27-16} = 0b001100100000;
664  let Inst{7-0} = 0b00000001;
665}
666
667def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
668             [/* For disassembly only; pattern left blank */]>,
669          Requires<[IsARM, HasV6T2]> {
670  let Inst{27-16} = 0b001100100000;
671  let Inst{7-0} = 0b00000010;
672}
673
674def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
675             [/* For disassembly only; pattern left blank */]>,
676          Requires<[IsARM, HasV6T2]> {
677  let Inst{27-16} = 0b001100100000;
678  let Inst{7-0} = 0b00000011;
679}
680
681def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
682             "\t$dst, $a, $b",
683             [/* For disassembly only; pattern left blank */]>,
684          Requires<[IsARM, HasV6]> {
685  let Inst{27-20} = 0b01101000;
686  let Inst{7-4} = 0b1011;
687}
688
689def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
690             [/* For disassembly only; pattern left blank */]>,
691          Requires<[IsARM, HasV6T2]> {
692  let Inst{27-16} = 0b001100100000;
693  let Inst{7-0} = 0b00000100;
694}
695
696// The i32imm operand $val can be used by a debugger to store more information
697// about the breakpoint.
698def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
699              [/* For disassembly only; pattern left blank */]>,
700           Requires<[IsARM]> {
701  let Inst{27-20} = 0b00010010;
702  let Inst{7-4} = 0b0111;
703}
704
705// Change Processor State is a system instruction -- for disassembly only.
706// The singleton $opt operand contains the following information:
707// opt{4-0} = mode from Inst{4-0}
708// opt{5} = changemode from Inst{17}
709// opt{8-6} = AIF from Inst{8-6}
710// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
711def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
712              [/* For disassembly only; pattern left blank */]>,
713          Requires<[IsARM]> {
714  let Inst{31-28} = 0b1111;
715  let Inst{27-20} = 0b00010000;
716  let Inst{16} = 0;
717  let Inst{5} = 0;
718}
719
720// Preload signals the memory system of possible future data/instruction access.
721// These are for disassembly only.
722multiclass APreLoad<bit data, bit read, string opc> {
723
724  def i : AXI<(outs), (ins GPR:$base, i32imm:$imm), MiscFrm, NoItinerary,
725               !strconcat(opc, "\t[$base, $imm]"), []> {
726    let Inst{31-26} = 0b111101;
727    let Inst{25} = 0; // 0 for immediate form
728    let Inst{24} = data;
729    let Inst{22} = read;
730    let Inst{21-20} = 0b01;
731  }
732
733  def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
734               !strconcat(opc, "\t$addr"), []> {
735    let Inst{31-26} = 0b111101;
736    let Inst{25} = 1; // 1 for register form
737    let Inst{24} = data;
738    let Inst{22} = read;
739    let Inst{21-20} = 0b01;
740    let Inst{4} = 0;
741  }
742}
743
744defm PLD  : APreLoad<1, 1, "pld">;
745defm PLDW : APreLoad<1, 0, "pldw">;
746defm PLI  : APreLoad<0, 1, "pli">;
747
748def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
749                   [/* For disassembly only; pattern left blank */]>,
750               Requires<[IsARM]> {
751  let Inst{31-28} = 0b1111;
752  let Inst{27-20} = 0b00010000;
753  let Inst{16} = 1;
754  let Inst{9} = 1;
755  let Inst{7-4} = 0b0000;
756}
757
758def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
759                   [/* For disassembly only; pattern left blank */]>,
760               Requires<[IsARM]> {
761  let Inst{31-28} = 0b1111;
762  let Inst{27-20} = 0b00010000;
763  let Inst{16} = 1;
764  let Inst{9} = 0;
765  let Inst{7-4} = 0b0000;
766}
767
768def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
769             [/* For disassembly only; pattern left blank */]>,
770          Requires<[IsARM, HasV7]> {
771  let Inst{27-16} = 0b001100100000;
772  let Inst{7-4} = 0b1111;
773}
774
775// A5.4 Permanently UNDEFINED instructions.
776def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
777              [/* For disassembly only; pattern left blank */]>,
778           Requires<[IsARM]> {
779  let Inst{27-25} = 0b011;
780  let Inst{24-20} = 0b11111;
781  let Inst{7-5} = 0b111;
782  let Inst{4} = 0b1;
783}
784
785// Address computation and loads and stores in PIC mode.
786let isNotDuplicable = 1 in {
787def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
788                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
789                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
790
791let AddedComplexity = 10 in {
792def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
793                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
794                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
795
796def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
797                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
798                  [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
799
800def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
801                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
802                  [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
803
804def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
805               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
806                  [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
807
808def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
809               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
810                  [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
811}
812let AddedComplexity = 10 in {
813def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
814               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
815               [(store GPR:$src, addrmodepc:$addr)]>;
816
817def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
818               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
819               [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
820
821def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
822               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
823               [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
824}
825} // isNotDuplicable = 1
826
827
828// LEApcrel - Load a pc-relative address into a register without offending the
829// assembler.
830def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
831                    Pseudo, IIC_iALUi,
832           !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
833                                 "${:private}PCRELL${:uid}+8))\n"),
834                      !strconcat("${:private}PCRELL${:uid}:\n\t",
835                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
836                   []>;
837
838def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
839                           (ins i32imm:$label, nohash_imm:$id, pred:$p),
840          Pseudo, IIC_iALUi,
841   !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
842                         "(${label}_${id}-(",
843                                  "${:private}PCRELL${:uid}+8))\n"),
844                       !strconcat("${:private}PCRELL${:uid}:\n\t",
845                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
846                   []> {
847    let Inst{25} = 1;
848}
849
850//===----------------------------------------------------------------------===//
851//  Control Flow Instructions.
852//
853
854let isReturn = 1, isTerminator = 1, isBarrier = 1 in
855  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
856                  "bx", "\tlr", [(ARMretflag)]> {
857  let Inst{3-0}   = 0b1110;
858  let Inst{7-4}   = 0b0001;
859  let Inst{19-8}  = 0b111111111111;
860  let Inst{27-20} = 0b00010010;
861}
862
863// Indirect branches
864let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
865  def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
866                  [(brind GPR:$dst)]> {
867    let Inst{7-4}   = 0b0001;
868    let Inst{19-8}  = 0b111111111111;
869    let Inst{27-20} = 0b00010010;
870    let Inst{31-28} = 0b1110;
871  }
872}
873
874// FIXME: remove when we have a way to marking a MI with these properties.
875// FIXME: Should pc be an implicit operand like PICADD, etc?
876let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
877    hasExtraDefRegAllocReq = 1 in
878  def LDM_RET : AXI4ld<(outs),
879                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
880                    LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
881                    []>;
882
883// On non-Darwin platforms R9 is callee-saved.
884let isCall = 1,
885  Defs = [R0,  R1,  R2,  R3,  R12, LR,
886          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
887          D16, D17, D18, D19, D20, D21, D22, D23,
888          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
889  def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
890                IIC_Br, "bl\t${func:call}",
891                [(ARMcall tglobaladdr:$func)]>,
892            Requires<[IsARM, IsNotDarwin]> {
893    let Inst{31-28} = 0b1110;
894  }
895
896  def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
897                   IIC_Br, "bl", "\t${func:call}",
898                   [(ARMcall_pred tglobaladdr:$func)]>,
899                Requires<[IsARM, IsNotDarwin]>;
900
901  // ARMv5T and above
902  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
903                IIC_Br, "blx\t$func",
904                [(ARMcall GPR:$func)]>,
905            Requires<[IsARM, HasV5T, IsNotDarwin]> {
906    let Inst{7-4}   = 0b0011;
907    let Inst{19-8}  = 0b111111111111;
908    let Inst{27-20} = 0b00010010;
909  }
910
911  // ARMv4T
912  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
913  def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
914                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
915                  [(ARMcall_nolink tGPR:$func)]>,
916           Requires<[IsARM, IsNotDarwin]> {
917    let Inst{7-4}   = 0b0001;
918    let Inst{19-8}  = 0b111111111111;
919    let Inst{27-20} = 0b00010010;
920  }
921}
922
923// On Darwin R9 is call-clobbered.
924let isCall = 1,
925  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
926          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
927          D16, D17, D18, D19, D20, D21, D22, D23,
928          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
929  def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
930                IIC_Br, "bl\t${func:call}",
931                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
932    let Inst{31-28} = 0b1110;
933  }
934
935  def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
936                   IIC_Br, "bl", "\t${func:call}",
937                   [(ARMcall_pred tglobaladdr:$func)]>,
938                  Requires<[IsARM, IsDarwin]>;
939
940  // ARMv5T and above
941  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
942                IIC_Br, "blx\t$func",
943                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
944    let Inst{7-4}   = 0b0011;
945    let Inst{19-8}  = 0b111111111111;
946    let Inst{27-20} = 0b00010010;
947  }
948
949  // ARMv4T
950  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
951  def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
952                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
953                  [(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
954    let Inst{7-4}   = 0b0001;
955    let Inst{19-8}  = 0b111111111111;
956    let Inst{27-20} = 0b00010010;
957  }
958}
959
960let isBranch = 1, isTerminator = 1 in {
961  // B is "predicable" since it can be xformed into a Bcc.
962  let isBarrier = 1 in {
963    let isPredicable = 1 in
964    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
965                "b\t$target", [(br bb:$target)]>;
966
967  let isNotDuplicable = 1, isIndirectBranch = 1 in {
968  def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
969                    IIC_Br, "mov\tpc, $target \n$jt",
970                    [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
971    let Inst{11-4}  = 0b00000000;
972    let Inst{15-12} = 0b1111;
973    let Inst{20}    = 0; // S Bit
974    let Inst{24-21} = 0b1101;
975    let Inst{27-25} = 0b000;
976  }
977  def BR_JTm : JTI<(outs),
978                   (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
979                   IIC_Br, "ldr\tpc, $target \n$jt",
980                   [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
981                     imm:$id)]> {
982    let Inst{15-12} = 0b1111;
983    let Inst{20}    = 1; // L bit
984    let Inst{21}    = 0; // W bit
985    let Inst{22}    = 0; // B bit
986    let Inst{24}    = 1; // P bit
987    let Inst{27-25} = 0b011;
988  }
989  def BR_JTadd : JTI<(outs),
990                   (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
991                    IIC_Br, "add\tpc, $target, $idx \n$jt",
992                    [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
993                      imm:$id)]> {
994    let Inst{15-12} = 0b1111;
995    let Inst{20}    = 0; // S bit
996    let Inst{24-21} = 0b0100;
997    let Inst{27-25} = 0b000;
998  }
999  } // isNotDuplicable = 1, isIndirectBranch = 1
1000  } // isBarrier = 1
1001
1002  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1003  // a two-value operand where a dag node expects two operands. :(
1004  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1005               IIC_Br, "b", "\t$target",
1006               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1007}
1008
1009// Branch and Exchange Jazelle -- for disassembly only
1010def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1011              [/* For disassembly only; pattern left blank */]> {
1012  let Inst{23-20} = 0b0010;
1013  //let Inst{19-8} = 0xfff;
1014  let Inst{7-4} = 0b0010;
1015}
1016
1017// Secure Monitor Call is a system instruction -- for disassembly only
1018def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1019              [/* For disassembly only; pattern left blank */]> {
1020  let Inst{23-20} = 0b0110;
1021  let Inst{7-4} = 0b0111;
1022}
1023
1024// Supervisor Call (Software Interrupt) -- for disassembly only
1025let isCall = 1 in {
1026def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1027              [/* For disassembly only; pattern left blank */]>;
1028}
1029
1030// Store Return State is a system instruction -- for disassembly only
1031def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1032                NoItinerary, "srs${addr:submode}\tsp!, $mode",
1033                [/* For disassembly only; pattern left blank */]> {
1034  let Inst{31-28} = 0b1111;
1035  let Inst{22-20} = 0b110; // W = 1
1036}
1037
1038def SRS  : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1039                NoItinerary, "srs${addr:submode}\tsp, $mode",
1040                [/* For disassembly only; pattern left blank */]> {
1041  let Inst{31-28} = 0b1111;
1042  let Inst{22-20} = 0b100; // W = 0
1043}
1044
1045// Return From Exception is a system instruction -- for disassembly only
1046def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1047                NoItinerary, "rfe${addr:submode}\t$base!",
1048                [/* For disassembly only; pattern left blank */]> {
1049  let Inst{31-28} = 0b1111;
1050  let Inst{22-20} = 0b011; // W = 1
1051}
1052
1053def RFE  : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1054                NoItinerary, "rfe${addr:submode}\t$base",
1055                [/* For disassembly only; pattern left blank */]> {
1056  let Inst{31-28} = 0b1111;
1057  let Inst{22-20} = 0b001; // W = 0
1058}
1059
1060//===----------------------------------------------------------------------===//
1061//  Load / store Instructions.
1062//
1063
1064// Load
1065let canFoldAsLoad = 1, isReMaterializable = 1 in
1066def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1067               "ldr", "\t$dst, $addr",
1068               [(set GPR:$dst, (load addrmode2:$addr))]>;
1069
1070// Special LDR for loads from non-pc-relative constpools.
1071let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
1072def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1073                 "ldr", "\t$dst, $addr", []>;
1074
1075// Loads with zero extension
1076def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1077                  IIC_iLoadr, "ldrh", "\t$dst, $addr",
1078                  [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1079
1080def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1081                  IIC_iLoadr, "ldrb", "\t$dst, $addr",
1082                  [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1083
1084// Loads with sign extension
1085def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1086                   IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1087                   [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1088
1089def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1090                   IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1091                   [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1092
1093let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1094// Load doubleword
1095def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1096                 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1097                 []>, Requires<[IsARM, HasV5TE]>;
1098
1099// Indexed loads
1100def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1101                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1102                     "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1103
1104def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1105                     (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1106                     "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1107
1108def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1109                     (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1110                     "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1111
1112def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1113                     (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1114                    "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1115
1116def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1117                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1118                     "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1119
1120def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1121                     (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1122                    "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1123
1124def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1125                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1126                      "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1127
1128def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1129                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1130                   "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1131
1132def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1133                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1134                      "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1135
1136def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1137                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1138                   "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1139
1140// For disassembly only
1141def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1142                        (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1143                 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1144                Requires<[IsARM, HasV5TE]>;
1145
1146// For disassembly only
1147def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1148                       (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1149            "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1150                Requires<[IsARM, HasV5TE]>;
1151
1152}
1153
1154// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1155
1156def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1157                   (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1158                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1159  let Inst{21} = 1; // overwrite
1160}
1161
1162def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1163                  (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1164                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1165  let Inst{21} = 1; // overwrite
1166}
1167
1168def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1169                 (ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
1170                 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1171  let Inst{21} = 1; // overwrite
1172}
1173
1174def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1175                  (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1176                  "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1177  let Inst{21} = 1; // overwrite
1178}
1179
1180def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1181                 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1182                 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1183  let Inst{21} = 1; // overwrite
1184}
1185
1186// Store
1187def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1188               "str", "\t$src, $addr",
1189               [(store GPR:$src, addrmode2:$addr)]>;
1190
1191// Stores with truncate
1192def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1193               IIC_iStorer, "strh", "\t$src, $addr",
1194               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1195
1196def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1197               "strb", "\t$src, $addr",
1198               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1199
1200// Store doubleword
1201let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1202def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1203               StMiscFrm, IIC_iStorer,
1204               "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1205
1206// Indexed stores
1207def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
1208                     (ins GPR:$src, GPR:$base, am2offset:$offset),
1209                     StFrm, IIC_iStoreru,
1210                    "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1211                    [(set GPR:$base_wb,
1212                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1213
1214def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1215                     (ins GPR:$src, GPR:$base,am2offset:$offset),
1216                     StFrm, IIC_iStoreru,
1217                    "str", "\t$src, [$base], $offset", "$base = $base_wb",
1218                    [(set GPR:$base_wb,
1219                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1220
1221def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1222                     (ins GPR:$src, GPR:$base,am3offset:$offset),
1223                     StMiscFrm, IIC_iStoreru,
1224                     "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1225                    [(set GPR:$base_wb,
1226                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1227
1228def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1229                     (ins GPR:$src, GPR:$base,am3offset:$offset),
1230                     StMiscFrm, IIC_iStoreru,
1231                     "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1232                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1233                                         GPR:$base, am3offset:$offset))]>;
1234
1235def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1236                     (ins GPR:$src, GPR:$base,am2offset:$offset),
1237                     StFrm, IIC_iStoreru,
1238                     "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1239                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1240                                         GPR:$base, am2offset:$offset))]>;
1241
1242def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1243                     (ins GPR:$src, GPR:$base,am2offset:$offset),
1244                     StFrm, IIC_iStoreru,
1245                     "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1246                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1247                                         GPR:$base, am2offset:$offset))]>;
1248
1249// For disassembly only
1250def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1251                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1252                     StMiscFrm, IIC_iStoreru,
1253                     "strd", "\t$src1, $src2, [$base, $offset]!",
1254                     "$base = $base_wb", []>;
1255
1256// For disassembly only
1257def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1258                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1259                     StMiscFrm, IIC_iStoreru,
1260                     "strd", "\t$src1, $src2, [$base], $offset",
1261                     "$base = $base_wb", []>;
1262
1263// STRT, STRBT, and STRHT are for disassembly only.
1264
1265def STRT : AI2stwpo<(outs GPR:$base_wb),
1266                    (ins GPR:$src, GPR:$base,am2offset:$offset),
1267                    StFrm, IIC_iStoreru,
1268                    "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1269                    [/* For disassembly only; pattern left blank */]> {
1270  let Inst{21} = 1; // overwrite
1271}
1272
1273def STRBT : AI2stbpo<(outs GPR:$base_wb),
1274                     (ins GPR:$src, GPR:$base,am2offset:$offset),
1275                     StFrm, IIC_iStoreru,
1276                     "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1277                     [/* For disassembly only; pattern left blank */]> {
1278  let Inst{21} = 1; // overwrite
1279}
1280
1281def STRHT: AI3sthpo<(outs GPR:$base_wb),
1282                    (ins GPR:$src, GPR:$base,am3offset:$offset),
1283                    StMiscFrm, IIC_iStoreru,
1284                    "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1285                    [/* For disassembly only; pattern left blank */]> {
1286  let Inst{21} = 1; // overwrite
1287}
1288
1289//===----------------------------------------------------------------------===//
1290//  Load / store multiple Instructions.
1291//
1292
1293let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1294def LDM : AXI4ld<(outs),
1295               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1296               LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1297               []>;
1298
1299let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1300def STM : AXI4st<(outs),
1301               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1302               LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1303               []>;
1304
1305//===----------------------------------------------------------------------===//
1306//  Move Instructions.
1307//
1308
1309let neverHasSideEffects = 1 in
1310def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1311                "mov", "\t$dst, $src", []>, UnaryDP {
1312  let Inst{11-4} = 0b00000000;
1313  let Inst{25} = 0;
1314}
1315
1316def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1317                DPSoRegFrm, IIC_iMOVsr,
1318                "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1319  let Inst{25} = 0;
1320}
1321
1322let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1323def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1324                "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1325  let Inst{25} = 1;
1326}
1327
1328let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1329def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1330                 DPFrm, IIC_iMOVi,
1331                 "movw", "\t$dst, $src",
1332                 [(set GPR:$dst, imm0_65535:$src)]>,
1333                 Requires<[IsARM, HasV6T2]>, UnaryDP {
1334  let Inst{20} = 0;
1335  let Inst{25} = 1;
1336}
1337
1338let Constraints = "$src = $dst" in
1339def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1340                  DPFrm, IIC_iMOVi,
1341                  "movt", "\t$dst, $imm",
1342                  [(set GPR:$dst,
1343                        (or (and GPR:$src, 0xffff),
1344                            lo16AllZero:$imm))]>, UnaryDP,
1345                  Requires<[IsARM, HasV6T2]> {
1346  let Inst{20} = 0;
1347  let Inst{25} = 1;
1348}
1349
1350def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1351      Requires<[IsARM, HasV6T2]>;
1352
1353let Uses = [CPSR] in
1354def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1355                 "mov", "\t$dst, $src, rrx",
1356                 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1357
1358// These aren't really mov instructions, but we have to define them this way
1359// due to flag operands.
1360
1361let Defs = [CPSR] in {
1362def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1363                      IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1364                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1365def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1366                      IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1367                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1368}
1369
1370//===----------------------------------------------------------------------===//
1371//  Extend Instructions.
1372//
1373
1374// Sign extenders
1375
1376defm SXTB  : AI_unary_rrot<0b01101010,
1377                           "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1378defm SXTH  : AI_unary_rrot<0b01101011,
1379                           "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1380
1381defm SXTAB : AI_bin_rrot<0b01101010,
1382               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1383defm SXTAH : AI_bin_rrot<0b01101011,
1384               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1385
1386// For disassembly only
1387defm SXTB16  : AI_unary_rrot_np<0b01101000, "sxtb16">;
1388
1389// For disassembly only
1390defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1391
1392// Zero extenders
1393
1394let AddedComplexity = 16 in {
1395defm UXTB   : AI_unary_rrot<0b01101110,
1396                            "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1397defm UXTH   : AI_unary_rrot<0b01101111,
1398                            "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1399defm UXTB16 : AI_unary_rrot<0b01101100,
1400                            "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1401
1402def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1403               (UXTB16r_rot GPR:$Src, 24)>;
1404def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1405               (UXTB16r_rot GPR:$Src, 8)>;
1406
1407defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1408                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1409defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1410                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1411}
1412
1413// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1414// For disassembly only
1415defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1416
1417
1418def SBFX  : I<(outs GPR:$dst),
1419              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1420               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1421               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1422               Requires<[IsARM, HasV6T2]> {
1423  let Inst{27-21} = 0b0111101;
1424  let Inst{6-4}   = 0b101;
1425}
1426
1427def UBFX  : I<(outs GPR:$dst),
1428              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1429               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1430               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1431               Requires<[IsARM, HasV6T2]> {
1432  let Inst{27-21} = 0b0111111;
1433  let Inst{6-4}   = 0b101;
1434}
1435
1436//===----------------------------------------------------------------------===//
1437//  Arithmetic Instructions.
1438//
1439
1440defm ADD  : AsI1_bin_irs<0b0100, "add",
1441                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1442defm SUB  : AsI1_bin_irs<0b0010, "sub",
1443                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1444
1445// ADD and SUB with 's' bit set.
1446defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1447                          BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1448defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1449                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1450
1451defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1452                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1453defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1454                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1455defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1456                          BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1457defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1458                          BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1459
1460// These don't define reg/reg forms, because they are handled above.
1461def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1462                  IIC_iALUi, "rsb", "\t$dst, $a, $b",
1463                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1464    let Inst{25} = 1;
1465}
1466
1467def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1468                  IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1469                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1470    let Inst{25} = 0;
1471}
1472
1473// RSB with 's' bit set.
1474let Defs = [CPSR] in {
1475def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1476                 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1477                 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1478    let Inst{20} = 1;
1479    let Inst{25} = 1;
1480}
1481def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1482                 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1483                 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1484    let Inst{20} = 1;
1485    let Inst{25} = 0;
1486}
1487}
1488
1489let Uses = [CPSR] in {
1490def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1491                 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1492                 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1493                 Requires<[IsARM]> {
1494    let Inst{25} = 1;
1495}
1496def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1497                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1498                 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1499                 Requires<[IsARM]> {
1500    let Inst{25} = 0;
1501}
1502}
1503
1504// FIXME: Allow these to be predicated.
1505let Defs = [CPSR], Uses = [CPSR] in {
1506def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1507                  DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1508                  [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1509                  Requires<[IsARM]> {
1510    let Inst{20} = 1;
1511    let Inst{25} = 1;
1512}
1513def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1514                  DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1515                  [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1516                  Requires<[IsARM]> {
1517    let Inst{20} = 1;
1518    let Inst{25} = 0;
1519}
1520}
1521
1522// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1523def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1524             (SUBri  GPR:$src, so_imm_neg:$imm)>;
1525
1526//def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1527//             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1528//def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1529//             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1530
1531// Note: These are implemented in C++ code, because they have to generate
1532// ADD/SUBrs instructions, which use a complex pattern that a xform function
1533// cannot produce.
1534// (mul X, 2^n+1) -> (add (X << n), X)
1535// (mul X, 2^n-1) -> (rsb X, (X << n))
1536
1537// ARM Arithmetic Instruction -- for disassembly only
1538// GPR:$dst = GPR:$a op GPR:$b
1539class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
1540  : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1541       opc, "\t$dst, $a, $b",
1542       [/* For disassembly only; pattern left blank */]> {
1543  let Inst{27-20} = op27_20;
1544  let Inst{7-4} = op7_4;
1545}
1546
1547// Saturating add/subtract -- for disassembly only
1548
1549def QADD    : AAI<0b00010000, 0b0101, "qadd">;
1550def QADD16  : AAI<0b01100010, 0b0001, "qadd16">;
1551def QADD8   : AAI<0b01100010, 0b1001, "qadd8">;
1552def QASX    : AAI<0b01100010, 0b0011, "qasx">;
1553def QDADD   : AAI<0b00010100, 0b0101, "qdadd">;
1554def QDSUB   : AAI<0b00010110, 0b0101, "qdsub">;
1555def QSAX    : AAI<0b01100010, 0b0101, "qsax">;
1556def QSUB    : AAI<0b00010010, 0b0101, "qsub">;
1557def QSUB16  : AAI<0b01100010, 0b0111, "qsub16">;
1558def QSUB8   : AAI<0b01100010, 0b1111, "qsub8">;
1559def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1560def UQADD8  : AAI<0b01100110, 0b1001, "uqadd8">;
1561def UQASX   : AAI<0b01100110, 0b0011, "uqasx">;
1562def UQSAX   : AAI<0b01100110, 0b0101, "uqsax">;
1563def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1564def UQSUB8  : AAI<0b01100110, 0b1111, "uqsub8">;
1565
1566// Signed/Unsigned add/subtract -- for disassembly only
1567
1568def SASX   : AAI<0b01100001, 0b0011, "sasx">;
1569def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1570def SADD8  : AAI<0b01100001, 0b1001, "sadd8">;
1571def SSAX   : AAI<0b01100001, 0b0101, "ssax">;
1572def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1573def SSUB8  : AAI<0b01100001, 0b1111, "ssub8">;
1574def UASX   : AAI<0b01100101, 0b0011, "uasx">;
1575def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1576def UADD8  : AAI<0b01100101, 0b1001, "uadd8">;
1577def USAX   : AAI<0b01100101, 0b0101, "usax">;
1578def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1579def USUB8  : AAI<0b01100101, 0b1111, "usub8">;
1580
1581// Signed/Unsigned halving add/subtract -- for disassembly only
1582
1583def SHASX   : AAI<0b01100011, 0b0011, "shasx">;
1584def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1585def SHADD8  : AAI<0b01100011, 0b1001, "shadd8">;
1586def SHSAX   : AAI<0b01100011, 0b0101, "shsax">;
1587def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1588def SHSUB8  : AAI<0b01100011, 0b1111, "shsub8">;
1589def UHASX   : AAI<0b01100111, 0b0011, "uhasx">;
1590def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1591def UHADD8  : AAI<0b01100111, 0b1001, "uhadd8">;
1592def UHSAX   : AAI<0b01100111, 0b0101, "uhsax">;
1593def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1594def UHSUB8  : AAI<0b01100111, 0b1111, "uhsub8">;
1595
1596// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1597
1598def USAD8  : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1599                MulFrm /* for convenience */, NoItinerary, "usad8",
1600                "\t$dst, $a, $b", []>,
1601             Requires<[IsARM, HasV6]> {
1602  let Inst{27-20} = 0b01111000;
1603  let Inst{15-12} = 0b1111;
1604  let Inst{7-4} = 0b0001;
1605}
1606def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1607                MulFrm /* for convenience */, NoItinerary, "usada8",
1608                "\t$dst, $a, $b, $acc", []>,
1609             Requires<[IsARM, HasV6]> {
1610  let Inst{27-20} = 0b01111000;
1611  let Inst{7-4} = 0b0001;
1612}
1613
1614// Signed/Unsigned saturate -- for disassembly only
1615
1616def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1617                 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1618                 [/* For disassembly only; pattern left blank */]> {
1619  let Inst{27-21} = 0b0110101;
1620  let Inst{6-4} = 0b001;
1621}
1622
1623def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1624                 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1625                 [/* For disassembly only; pattern left blank */]> {
1626  let Inst{27-21} = 0b0110101;
1627  let Inst{6-4} = 0b101;
1628}
1629
1630def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1631                NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1632                [/* For disassembly only; pattern left blank */]> {
1633  let Inst{27-20} = 0b01101010;
1634  let Inst{7-4} = 0b0011;
1635}
1636
1637def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1638                 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1639                 [/* For disassembly only; pattern left blank */]> {
1640  let Inst{27-21} = 0b0110111;
1641  let Inst{6-4} = 0b001;
1642}
1643
1644def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1645                 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1646                 [/* For disassembly only; pattern left blank */]> {
1647  let Inst{27-21} = 0b0110111;
1648  let Inst{6-4} = 0b101;
1649}
1650
1651def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1652                NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1653                [/* For disassembly only; pattern left blank */]> {
1654  let Inst{27-20} = 0b01101110;
1655  let Inst{7-4} = 0b0011;
1656}
1657
1658//===----------------------------------------------------------------------===//
1659//  Bitwise Instructions.
1660//
1661
1662defm AND   : AsI1_bin_irs<0b0000, "and",
1663                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1664defm ORR   : AsI1_bin_irs<0b1100, "orr",
1665                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1666defm EOR   : AsI1_bin_irs<0b0001, "eor",
1667                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1668defm BIC   : AsI1_bin_irs<0b1110, "bic",
1669                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1670
1671def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1672               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1673               "bfc", "\t$dst, $imm", "$src = $dst",
1674               [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1675               Requires<[IsARM, HasV6T2]> {
1676  let Inst{27-21} = 0b0111110;
1677  let Inst{6-0}   = 0b0011111;
1678}
1679
1680// A8.6.18  BFI - Bitfield insert (Encoding A1)
1681// Added for disassembler with the pattern field purposely left blank.
1682def BFI    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1683               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1684               "bfi", "\t$dst, $src, $imm", "",
1685               [/* For disassembly only; pattern left blank */]>,
1686               Requires<[IsARM, HasV6T2]> {
1687  let Inst{27-21} = 0b0111110;
1688  let Inst{6-4}   = 0b001; // Rn: Inst{3-0} != 15
1689}
1690
1691def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1692                  "mvn", "\t$dst, $src",
1693                  [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1694  let Inst{25} = 0;
1695  let Inst{11-4} = 0b00000000;
1696}
1697def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1698                  IIC_iMOVsr, "mvn", "\t$dst, $src",
1699                  [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1700  let Inst{25} = 0;
1701}
1702let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1703def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1704                  IIC_iMOVi, "mvn", "\t$dst, $imm",
1705                  [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1706    let Inst{25} = 1;
1707}
1708
1709def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1710             (BICri GPR:$src, so_imm_not:$imm)>;
1711
1712//===----------------------------------------------------------------------===//
1713//  Multiply Instructions.
1714//
1715
1716let isCommutable = 1 in
1717def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1718                   IIC_iMUL32, "mul", "\t$dst, $a, $b",
1719                   [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1720
1721def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1722                    IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1723                   [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1724
1725def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1726                   IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1727                   [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1728                   Requires<[IsARM, HasV6T2]>;
1729
1730// Extra precision multiplies with low / high results
1731let neverHasSideEffects = 1 in {
1732let isCommutable = 1 in {
1733def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1734                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1735                    "smull", "\t$ldst, $hdst, $a, $b", []>;
1736
1737def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1738                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1739                    "umull", "\t$ldst, $hdst, $a, $b", []>;
1740}
1741
1742// Multiply + accumulate
1743def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1744                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1745                    "smlal", "\t$ldst, $hdst, $a, $b", []>;
1746
1747def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1748                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1749                    "umlal", "\t$ldst, $hdst, $a, $b", []>;
1750
1751def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1752                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1753                    "umaal", "\t$ldst, $hdst, $a, $b", []>,
1754                    Requires<[IsARM, HasV6]>;
1755} // neverHasSideEffects
1756
1757// Most significant word multiply
1758def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1759               IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1760               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1761            Requires<[IsARM, HasV6]> {
1762  let Inst{7-4}   = 0b0001;
1763  let Inst{15-12} = 0b1111;
1764}
1765
1766def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1767               IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1768               [/* For disassembly only; pattern left blank */]>,
1769            Requires<[IsARM, HasV6]> {
1770  let Inst{7-4}   = 0b0011; // R = 1
1771  let Inst{15-12} = 0b1111;
1772}
1773
1774def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1775               IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1776               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1777            Requires<[IsARM, HasV6]> {
1778  let Inst{7-4}   = 0b0001;
1779}
1780
1781def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1782               IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1783               [/* For disassembly only; pattern left blank */]>,
1784            Requires<[IsARM, HasV6]> {
1785  let Inst{7-4}   = 0b0011; // R = 1
1786}
1787
1788def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1789               IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1790               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1791            Requires<[IsARM, HasV6]> {
1792  let Inst{7-4}   = 0b1101;
1793}
1794
1795def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1796               IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1797               [/* For disassembly only; pattern left blank */]>,
1798            Requires<[IsARM, HasV6]> {
1799  let Inst{7-4}   = 0b1111; // R = 1
1800}
1801
1802multiclass AI_smul<string opc, PatFrag opnode> {
1803  def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1804              IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1805              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1806                                      (sext_inreg GPR:$b, i16)))]>,
1807           Requires<[IsARM, HasV5TE]> {
1808             let Inst{5} = 0;
1809             let Inst{6} = 0;
1810           }
1811
1812  def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1813              IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1814              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1815                                      (sra GPR:$b, (i32 16))))]>,
1816           Requires<[IsARM, HasV5TE]> {
1817             let Inst{5} = 0;
1818             let Inst{6} = 1;
1819           }
1820
1821  def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1822              IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1823              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1824                                      (sext_inreg GPR:$b, i16)))]>,
1825           Requires<[IsARM, HasV5TE]> {
1826             let Inst{5} = 1;
1827             let Inst{6} = 0;
1828           }
1829
1830  def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1831              IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1832              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1833                                      (sra GPR:$b, (i32 16))))]>,
1834            Requires<[IsARM, HasV5TE]> {
1835             let Inst{5} = 1;
1836             let Inst{6} = 1;
1837           }
1838
1839  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1840              IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1841              [(set GPR:$dst, (sra (opnode GPR:$a,
1842                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1843           Requires<[IsARM, HasV5TE]> {
1844             let Inst{5} = 1;
1845             let Inst{6} = 0;
1846           }
1847
1848  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1849              IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1850              [(set GPR:$dst, (sra (opnode GPR:$a,
1851                                    (sra GPR:$b, (i32 16))), (i32 16)))]>,
1852            Requires<[IsARM, HasV5TE]> {
1853             let Inst{5} = 1;
1854             let Inst{6} = 1;
1855           }
1856}
1857
1858
1859multiclass AI_smla<string opc, PatFrag opnode> {
1860  def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1861              IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1862              [(set GPR:$dst, (add GPR:$acc,
1863                               (opnode (sext_inreg GPR:$a, i16),
1864                                       (sext_inreg GPR:$b, i16))))]>,
1865           Requires<[IsARM, HasV5TE]> {
1866             let Inst{5} = 0;
1867             let Inst{6} = 0;
1868           }
1869
1870  def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1871              IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1872              [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1873                                                    (sra GPR:$b, (i32 16)))))]>,
1874           Requires<[IsARM, HasV5TE]> {
1875             let Inst{5} = 0;
1876             let Inst{6} = 1;
1877           }
1878
1879  def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1880              IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1881              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1882                                                 (sext_inreg GPR:$b, i16))))]>,
1883           Requires<[IsARM, HasV5TE]> {
1884             let Inst{5} = 1;
1885             let Inst{6} = 0;
1886           }
1887
1888  def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1889              IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1890             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1891                                                    (sra GPR:$b, (i32 16)))))]>,
1892            Requires<[IsARM, HasV5TE]> {
1893             let Inst{5} = 1;
1894             let Inst{6} = 1;
1895           }
1896
1897  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1898              IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1899              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1900                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1901           Requires<[IsARM, HasV5TE]> {
1902             let Inst{5} = 0;
1903             let Inst{6} = 0;
1904           }
1905
1906  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1907              IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1908              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1909                                         (sra GPR:$b, (i32 16))), (i32 16))))]>,
1910            Requires<[IsARM, HasV5TE]> {
1911             let Inst{5} = 0;
1912             let Inst{6} = 1;
1913           }
1914}
1915
1916defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1917defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1918
1919// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1920def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1921                      IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1922                      [/* For disassembly only; pattern left blank */]>,
1923              Requires<[IsARM, HasV5TE]> {
1924  let Inst{5} = 0;
1925  let Inst{6} = 0;
1926}
1927
1928def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1929                      IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1930                      [/* For disassembly only; pattern left blank */]>,
1931              Requires<[IsARM, HasV5TE]> {
1932  let Inst{5} = 0;
1933  let Inst{6} = 1;
1934}
1935
1936def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1937                      IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1938                      [/* For disassembly only; pattern left blank */]>,
1939              Requires<[IsARM, HasV5TE]> {
1940  let Inst{5} = 1;
1941  let Inst{6} = 0;
1942}
1943
1944def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1945                      IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1946                      [/* For disassembly only; pattern left blank */]>,
1947              Requires<[IsARM, HasV5TE]> {
1948  let Inst{5} = 1;
1949  let Inst{6} = 1;
1950}
1951
1952// Helper class for AI_smld -- for disassembly only
1953class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
1954                InstrItinClass itin, string opc, string asm>
1955  : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
1956  let Inst{4}     = 1;
1957  let Inst{5}     = swap;
1958  let Inst{6}     = sub;
1959  let Inst{7}     = 0;
1960  let Inst{21-20} = 0b00;
1961  let Inst{22}    = long;
1962  let Inst{27-23} = 0b01110;
1963}
1964
1965multiclass AI_smld<bit sub, string opc> {
1966
1967  def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1968                  NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
1969
1970  def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1971                  NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
1972
1973  def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
1974                  NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
1975
1976  def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1977                  NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
1978
1979}
1980
1981defm SMLA : AI_smld<0, "smla">;
1982defm SMLS : AI_smld<1, "smls">;
1983
1984multiclass AI_sdml<bit sub, string opc> {
1985
1986  def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1987                    NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
1988    let Inst{15-12} = 0b1111;
1989  }
1990
1991  def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1992                    NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
1993    let Inst{15-12} = 0b1111;
1994  }
1995
1996}
1997
1998defm SMUA : AI_sdml<0, "smua">;
1999defm SMUS : AI_sdml<1, "smus">;
2000
2001//===----------------------------------------------------------------------===//
2002//  Misc. Arithmetic Instructions.
2003//
2004
2005def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2006              "clz", "\t$dst, $src",
2007              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2008  let Inst{7-4}   = 0b0001;
2009  let Inst{11-8}  = 0b1111;
2010  let Inst{19-16} = 0b1111;
2011}
2012
2013def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2014              "rbit", "\t$dst, $src",
2015              [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2016           Requires<[IsARM, HasV6T2]> {
2017  let Inst{7-4}   = 0b0011;
2018  let Inst{11-8}  = 0b1111;
2019  let Inst{19-16} = 0b1111;
2020}
2021
2022def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2023              "rev", "\t$dst, $src",
2024              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2025  let Inst{7-4}   = 0b0011;
2026  let Inst{11-8}  = 0b1111;
2027  let Inst{19-16} = 0b1111;
2028}
2029
2030def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2031               "rev16", "\t$dst, $src",
2032               [(set GPR:$dst,
2033                   (or (and (srl GPR:$src, (i32 8)), 0xFF),
2034                       (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2035                           (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2036                               (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2037               Requires<[IsARM, HasV6]> {
2038  let Inst{7-4}   = 0b1011;
2039  let Inst{11-8}  = 0b1111;
2040  let Inst{19-16} = 0b1111;
2041}
2042
2043def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2044               "revsh", "\t$dst, $src",
2045               [(set GPR:$dst,
2046                  (sext_inreg
2047                    (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2048                        (shl GPR:$src, (i32 8))), i16))]>,
2049               Requires<[IsARM, HasV6]> {
2050  let Inst{7-4}   = 0b1011;
2051  let Inst{11-8}  = 0b1111;
2052  let Inst{19-16} = 0b1111;
2053}
2054
2055def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2056                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2057               IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2058               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2059                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
2060                                        0xFFFF0000)))]>,
2061               Requires<[IsARM, HasV6]> {
2062  let Inst{6-4} = 0b001;
2063}
2064
2065// Alternate cases for PKHBT where identities eliminate some nodes.
2066def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2067               (PKHBT GPR:$src1, GPR:$src2, 0)>;
2068def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2069               (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2070
2071
2072def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2073                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2074               IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2075               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2076                                   (and (sra GPR:$src2, imm16_31:$shamt),
2077                                        0xFFFF)))]>, Requires<[IsARM, HasV6]> {
2078  let Inst{6-4} = 0b101;
2079}
2080
2081// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
2082// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2083def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2084               (PKHTB GPR:$src1, GPR:$src2, 16)>;
2085def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2086                   (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2087               (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2088
2089//===----------------------------------------------------------------------===//
2090//  Comparison Instructions...
2091//
2092
2093defm CMP  : AI1_cmp_irs<0b1010, "cmp",
2094                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2095//FIXME: Disable CMN, as CCodes are backwards from compare expectations
2096//       Compare-to-zero still works out, just not the relationals
2097//defm CMN  : AI1_cmp_irs<0b1011, "cmn",
2098//                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2099
2100// Note that TST/TEQ don't set all the same flags that CMP does!
2101defm TST  : AI1_cmp_irs<0b1000, "tst",
2102                        BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2103defm TEQ  : AI1_cmp_irs<0b1001, "teq",
2104                        BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2105
2106defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
2107                         BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2108defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
2109                         BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2110
2111//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2112//             (CMNri  GPR:$src, so_imm_neg:$imm)>;
2113
2114def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2115             (CMNzri  GPR:$src, so_imm_neg:$imm)>;
2116
2117
2118// Conditional moves
2119// FIXME: should be able to write a pattern for ARMcmov, but can't use
2120// a two-value operand where a dag node expects two operands. :(
2121def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2122                IIC_iCMOVr, "mov", "\t$dst, $true",
2123      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2124                RegConstraint<"$false = $dst">, UnaryDP {
2125  let Inst{11-4} = 0b00000000;
2126  let Inst{25} = 0;
2127}
2128
2129def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2130                        (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2131                "mov", "\t$dst, $true",
2132   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2133                RegConstraint<"$false = $dst">, UnaryDP {
2134  let Inst{25} = 0;
2135}
2136
2137def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2138                        (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2139                "mov", "\t$dst, $true",
2140   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2141                RegConstraint<"$false = $dst">, UnaryDP {
2142  let Inst{25} = 1;
2143}
2144
2145//===----------------------------------------------------------------------===//
2146// Atomic operations intrinsics
2147//
2148
2149// memory barriers protect the atomic sequences
2150let hasSideEffects = 1 in {
2151def Int_MemBarrierV7 : AInoP<(outs), (ins),
2152                        Pseudo, NoItinerary,
2153                        "dmb", "",
2154                        [(ARMMemBarrierV7)]>,
2155                        Requires<[IsARM, HasV7]> {
2156  let Inst{31-4} = 0xf57ff05;
2157  // FIXME: add support for options other than a full system DMB
2158  // See DMB disassembly-only variants below.
2159  let Inst{3-0} = 0b1111;
2160}
2161
2162def Int_SyncBarrierV7 : AInoP<(outs), (ins),
2163                        Pseudo, NoItinerary,
2164                        "dsb", "",
2165                        [(ARMSyncBarrierV7)]>,
2166                        Requires<[IsARM, HasV7]> {
2167  let Inst{31-4} = 0xf57ff04;
2168  // FIXME: add support for options other than a full system DSB
2169  // See DSB disassembly-only variants below.
2170  let Inst{3-0} = 0b1111;
2171}
2172
2173def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2174                       Pseudo, NoItinerary,
2175                       "mcr", "\tp15, 0, $zero, c7, c10, 5",
2176                       [(ARMMemBarrierV6 GPR:$zero)]>,
2177                       Requires<[IsARM, HasV6]> {
2178  // FIXME: add support for options other than a full system DMB
2179  // FIXME: add encoding
2180}
2181
2182def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2183                        Pseudo, NoItinerary,
2184                        "mcr", "\tp15, 0, $zero, c7, c10, 4",
2185                        [(ARMSyncBarrierV6 GPR:$zero)]>,
2186                        Requires<[IsARM, HasV6]> {
2187  // FIXME: add support for options other than a full system DSB
2188  // FIXME: add encoding
2189}
2190}
2191
2192// Helper class for multiclass MemB -- for disassembly only
2193class AMBI<string opc, string asm>
2194  : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
2195          [/* For disassembly only; pattern left blank */]>,
2196    Requires<[IsARM, HasV7]> {
2197  let Inst{31-20} = 0xf57;
2198}
2199
2200multiclass MemB<bits<4> op7_4, string opc> {
2201
2202  def st : AMBI<opc, "\tst"> {
2203    let Inst{7-4} = op7_4;
2204    let Inst{3-0} = 0b1110;
2205  }
2206
2207  def ish : AMBI<opc, "\tish"> {
2208    let Inst{7-4} = op7_4;
2209    let Inst{3-0} = 0b1011;
2210  }
2211
2212  def ishst : AMBI<opc, "\tishst"> {
2213    let Inst{7-4} = op7_4;
2214    let Inst{3-0} = 0b1010;
2215  }
2216
2217  def nsh : AMBI<opc, "\tnsh"> {
2218    let Inst{7-4} = op7_4;
2219    let Inst{3-0} = 0b0111;
2220  }
2221
2222  def nshst : AMBI<opc, "\tnshst"> {
2223    let Inst{7-4} = op7_4;
2224    let Inst{3-0} = 0b0110;
2225  }
2226
2227  def osh : AMBI<opc, "\tosh"> {
2228    let Inst{7-4} = op7_4;
2229    let Inst{3-0} = 0b0011;
2230  }
2231
2232  def oshst : AMBI<opc, "\toshst"> {
2233    let Inst{7-4} = op7_4;
2234    let Inst{3-0} = 0b0010;
2235  }
2236}
2237
2238// These DMB variants are for disassembly only.
2239defm DMB : MemB<0b0101, "dmb">;
2240
2241// These DSB variants are for disassembly only.
2242defm DSB : MemB<0b0100, "dsb">;
2243
2244// ISB has only full system option -- for disassembly only
2245def ISBsy : AMBI<"isb", ""> {
2246  let Inst{7-4} = 0b0110;
2247  let Inst{3-0} = 0b1111;
2248}
2249
2250let usesCustomInserter = 1 in {
2251  let Uses = [CPSR] in {
2252    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2253      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2254      "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2255      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2256    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2257      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2258      "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2259      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2260    def ATOMIC_LOAD_AND_I8 : PseudoInst<
2261      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2262      "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2263      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2264    def ATOMIC_LOAD_OR_I8 : PseudoInst<
2265      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2266      "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2267      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2268    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2269      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2270      "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2271      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2272    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2273      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2274      "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2275      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2276    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2277      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2278      "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2279      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2280    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2281      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2282      "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2283      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2284    def ATOMIC_LOAD_AND_I16 : PseudoInst<
2285      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2286      "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2287      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2288    def ATOMIC_LOAD_OR_I16 : PseudoInst<
2289      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2290      "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2291      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2292    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2293      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2294      "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2295      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2296    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2297      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2298      "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2299      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2300    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2301      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2302      "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2303      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2304    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2305      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2306      "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2307      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2308    def ATOMIC_LOAD_AND_I32 : PseudoInst<
2309      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2310      "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2311      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2312    def ATOMIC_LOAD_OR_I32 : PseudoInst<
2313      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2314      "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2315      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2316    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2317      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2318      "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2319      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2320    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2321      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2322      "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2323      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2324
2325    def ATOMIC_SWAP_I8 : PseudoInst<
2326      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2327      "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2328      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2329    def ATOMIC_SWAP_I16 : PseudoInst<
2330      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2331      "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2332      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2333    def ATOMIC_SWAP_I32 : PseudoInst<
2334      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2335      "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2336      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2337
2338    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2339      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2340      "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2341      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2342    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2343      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2344      "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2345      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2346    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2347      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2348      "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2349      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2350}
2351}
2352
2353let mayLoad = 1 in {
2354def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2355                    "ldrexb", "\t$dest, [$ptr]",
2356                    []>;
2357def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2358                    "ldrexh", "\t$dest, [$ptr]",
2359                    []>;
2360def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2361                    "ldrex", "\t$dest, [$ptr]",
2362                    []>;
2363def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2364                    NoItinerary,
2365                    "ldrexd", "\t$dest, $dest2, [$ptr]",
2366                    []>;
2367}
2368
2369let mayStore = 1, Constraints = "@earlyclobber $success" in {
2370def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2371                    NoItinerary,
2372                    "strexb", "\t$success, $src, [$ptr]",
2373                    []>;
2374def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2375                    NoItinerary,
2376                    "strexh", "\t$success, $src, [$ptr]",
2377                    []>;
2378def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2379                    NoItinerary,
2380                    "strex", "\t$success, $src, [$ptr]",
2381                    []>;
2382def STREXD : AIstrex<0b01, (outs GPR:$success),
2383                    (ins GPR:$src, GPR:$src2, GPR:$ptr),
2384                    NoItinerary,
2385                    "strexd", "\t$success, $src, $src2, [$ptr]",
2386                    []>;
2387}
2388
2389// Clear-Exclusive is for disassembly only.
2390def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2391                [/* For disassembly only; pattern left blank */]>,
2392            Requires<[IsARM, HasV7]>  {
2393  let Inst{31-20} = 0xf57;
2394  let Inst{7-4} = 0b0001;
2395}
2396
2397// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2398let mayLoad = 1 in {
2399def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2400             "swp", "\t$dst, $src, [$ptr]",
2401             [/* For disassembly only; pattern left blank */]> {
2402  let Inst{27-23} = 0b00010;
2403  let Inst{22} = 0; // B = 0
2404  let Inst{21-20} = 0b00;
2405  let Inst{7-4} = 0b1001;
2406}
2407
2408def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2409             "swpb", "\t$dst, $src, [$ptr]",
2410             [/* For disassembly only; pattern left blank */]> {
2411  let Inst{27-23} = 0b00010;
2412  let Inst{22} = 1; // B = 1
2413  let Inst{21-20} = 0b00;
2414  let Inst{7-4} = 0b1001;
2415}
2416}
2417
2418//===----------------------------------------------------------------------===//
2419// TLS Instructions
2420//
2421
2422// __aeabi_read_tp preserves the registers r1-r3.
2423let isCall = 1,
2424  Defs = [R0, R12, LR, CPSR] in {
2425  def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2426               "bl\t__aeabi_read_tp",
2427               [(set R0, ARMthread_pointer)]>;
2428}
2429
2430//===----------------------------------------------------------------------===//
2431// SJLJ Exception handling intrinsics
2432//   eh_sjlj_setjmp() is an instruction sequence to store the return
2433//   address and save #0 in R0 for the non-longjmp case.
2434//   Since by its nature we may be coming from some other function to get
2435//   here, and we're using the stack frame for the containing function to
2436//   save/restore registers, we can't keep anything live in regs across
2437//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2438//   when we get here from a longjmp(). We force everthing out of registers
2439//   except for our own input by listing the relevant registers in Defs. By
2440//   doing so, we also cause the prologue/epilogue code to actively preserve
2441//   all of the callee-saved resgisters, which is exactly what we want.
2442//   A constant value is passed in $val, and we use the location as a scratch.
2443let Defs =
2444  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
2445    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
2446    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2447    D31 ] in {
2448  def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2449                               AddrModeNone, SizeSpecial, IndexModeNone,
2450                               Pseudo, NoItinerary,
2451                               "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2452                               "add\t$val, pc, #8\n\t"
2453                               "str\t$val, [$src, #+4]\n\t"
2454                               "mov\tr0, #0\n\t"
2455                               "add\tpc, pc, #0\n\t"
2456                               "mov\tr0, #1 @ eh_setjmp end", "",
2457                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2458}
2459
2460//===----------------------------------------------------------------------===//
2461// Non-Instruction Patterns
2462//
2463
2464// Large immediate handling.
2465
2466// Two piece so_imms.
2467let isReMaterializable = 1 in
2468def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2469                         Pseudo, IIC_iMOVi,
2470                         "mov", "\t$dst, $src",
2471                         [(set GPR:$dst, so_imm2part:$src)]>,
2472                  Requires<[IsARM, NoV6T2]>;
2473
2474def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2475             (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2476                    (so_imm2part_2 imm:$RHS))>;
2477def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2478             (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2479                    (so_imm2part_2 imm:$RHS))>;
2480def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2481             (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2482                    (so_imm2part_2 imm:$RHS))>;
2483def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2484             (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2485                    (so_neg_imm2part_2 imm:$RHS))>;
2486
2487// 32-bit immediate using movw + movt.
2488// This is a single pseudo instruction, the benefit is that it can be remat'd
2489// as a single unit instead of having to handle reg inputs.
2490// FIXME: Remove this when we can do generalized remat.
2491let isReMaterializable = 1 in
2492def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2493                   "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2494                     [(set GPR:$dst, (i32 imm:$src))]>,
2495               Requires<[IsARM, HasV6T2]>;
2496
2497// ConstantPool, GlobalAddress, and JumpTable
2498def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2499            Requires<[IsARM, DontUseMovt]>;
2500def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
2501def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2502            Requires<[IsARM, UseMovt]>;
2503def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2504             (LEApcrelJT tjumptable:$dst, imm:$id)>;
2505
2506// TODO: add,sub,and, 3-instr forms?
2507
2508
2509// Direct calls
2510def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2511      Requires<[IsARM, IsNotDarwin]>;
2512def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2513      Requires<[IsARM, IsDarwin]>;
2514
2515// zextload i1 -> zextload i8
2516def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2517
2518// extload -> zextload
2519def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2520def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
2521def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
2522
2523def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2524def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2525
2526// smul* and smla*
2527def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2528                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
2529                 (SMULBB GPR:$a, GPR:$b)>;
2530def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2531                 (SMULBB GPR:$a, GPR:$b)>;
2532def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2533                      (sra GPR:$b, (i32 16))),
2534                 (SMULBT GPR:$a, GPR:$b)>;
2535def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2536                 (SMULBT GPR:$a, GPR:$b)>;
2537def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2538                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
2539                 (SMULTB GPR:$a, GPR:$b)>;
2540def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2541                (SMULTB GPR:$a, GPR:$b)>;
2542def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2543                      (i32 16)),
2544                 (SMULWB GPR:$a, GPR:$b)>;
2545def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2546                 (SMULWB GPR:$a, GPR:$b)>;
2547
2548def : ARMV5TEPat<(add GPR:$acc,
2549                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2550                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2551                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2552def : ARMV5TEPat<(add GPR:$acc,
2553                      (mul sext_16_node:$a, sext_16_node:$b)),
2554                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2555def : ARMV5TEPat<(add GPR:$acc,
2556                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2557                           (sra GPR:$b, (i32 16)))),
2558                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2559def : ARMV5TEPat<(add GPR:$acc,
2560                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2561                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2562def : ARMV5TEPat<(add GPR:$acc,
2563                      (mul (sra GPR:$a, (i32 16)),
2564                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2565                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2566def : ARMV5TEPat<(add GPR:$acc,
2567                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2568                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2569def : ARMV5TEPat<(add GPR:$acc,
2570                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2571                           (i32 16))),
2572                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2573def : ARMV5TEPat<(add GPR:$acc,
2574                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2575                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2576
2577//===----------------------------------------------------------------------===//
2578// Thumb Support
2579//
2580
2581include "ARMInstrThumb.td"
2582
2583//===----------------------------------------------------------------------===//
2584// Thumb2 Support
2585//
2586
2587include "ARMInstrThumb2.td"
2588
2589//===----------------------------------------------------------------------===//
2590// Floating Point Support
2591//
2592
2593include "ARMInstrVFP.td"
2594
2595//===----------------------------------------------------------------------===//
2596// Advanced SIMD (NEON) Support
2597//
2598
2599include "ARMInstrNEON.td"
2600
2601//===----------------------------------------------------------------------===//
2602// Coprocessor Instructions.  For disassembly only.
2603//
2604
2605def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2606            nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2607            NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2608              [/* For disassembly only; pattern left blank */]> {
2609  let Inst{4} = 0;
2610}
2611
2612def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2613               nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2614               NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2615               [/* For disassembly only; pattern left blank */]> {
2616  let Inst{31-28} = 0b1111;
2617  let Inst{4} = 0;
2618}
2619
2620class ACI<dag oops, dag iops, string opc, string asm>
2621  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2622      opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2623  let Inst{27-25} = 0b110;
2624}
2625
2626multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2627
2628  def _OFFSET : ACI<(outs),
2629      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2630      opc, "\tp$cop, cr$CRd, $addr"> {
2631    let Inst{31-28} = op31_28;
2632    let Inst{24} = 1; // P = 1
2633    let Inst{21} = 0; // W = 0
2634    let Inst{22} = 0; // D = 0
2635    let Inst{20} = load;
2636  }
2637
2638  def _PRE : ACI<(outs),
2639      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2640      opc, "\tp$cop, cr$CRd, $addr!"> {
2641    let Inst{31-28} = op31_28;
2642    let Inst{24} = 1; // P = 1
2643    let Inst{21} = 1; // W = 1
2644    let Inst{22} = 0; // D = 0
2645    let Inst{20} = load;
2646  }
2647
2648  def _POST : ACI<(outs),
2649      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2650      opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2651    let Inst{31-28} = op31_28;
2652    let Inst{24} = 0; // P = 0
2653    let Inst{21} = 1; // W = 1
2654    let Inst{22} = 0; // D = 0
2655    let Inst{20} = load;
2656  }
2657
2658  def _OPTION : ACI<(outs),
2659      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2660      opc, "\tp$cop, cr$CRd, [$base], $option"> {
2661    let Inst{31-28} = op31_28;
2662    let Inst{24} = 0; // P = 0
2663    let Inst{23} = 1; // U = 1
2664    let Inst{21} = 0; // W = 0
2665    let Inst{22} = 0; // D = 0
2666    let Inst{20} = load;
2667  }
2668
2669  def L_OFFSET : ACI<(outs),
2670      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2671      opc, "l\tp$cop, cr$CRd, $addr"> {
2672    let Inst{31-28} = op31_28;
2673    let Inst{24} = 1; // P = 1
2674    let Inst{21} = 0; // W = 0
2675    let Inst{22} = 1; // D = 1
2676    let Inst{20} = load;
2677  }
2678
2679  def L_PRE : ACI<(outs),
2680      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2681      opc, "l\tp$cop, cr$CRd, $addr!"> {
2682    let Inst{31-28} = op31_28;
2683    let Inst{24} = 1; // P = 1
2684    let Inst{21} = 1; // W = 1
2685    let Inst{22} = 1; // D = 1
2686    let Inst{20} = load;
2687  }
2688
2689  def L_POST : ACI<(outs),
2690      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2691      opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
2692    let Inst{31-28} = op31_28;
2693    let Inst{24} = 0; // P = 0
2694    let Inst{21} = 1; // W = 1
2695    let Inst{22} = 1; // D = 1
2696    let Inst{20} = load;
2697  }
2698
2699  def L_OPTION : ACI<(outs),
2700      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2701      opc, "l\tp$cop, cr$CRd, [$base], $option"> {
2702    let Inst{31-28} = op31_28;
2703    let Inst{24} = 0; // P = 0
2704    let Inst{23} = 1; // U = 1
2705    let Inst{21} = 0; // W = 0
2706    let Inst{22} = 1; // D = 1
2707    let Inst{20} = load;
2708  }
2709}
2710
2711defm LDC  : LdStCop<{?,?,?,?}, 1, "ldc">;
2712defm LDC2 : LdStCop<0b1111,    1, "ldc2">;
2713defm STC  : LdStCop<{?,?,?,?}, 0, "stc">;
2714defm STC2 : LdStCop<0b1111,    0, "stc2">;
2715
2716def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2717              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2718              NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2719              [/* For disassembly only; pattern left blank */]> {
2720  let Inst{20} = 0;
2721  let Inst{4} = 1;
2722}
2723
2724def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2725                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2726                NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2727                [/* For disassembly only; pattern left blank */]> {
2728  let Inst{31-28} = 0b1111;
2729  let Inst{20} = 0;
2730  let Inst{4} = 1;
2731}
2732
2733def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2734              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2735              NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2736              [/* For disassembly only; pattern left blank */]> {
2737  let Inst{20} = 1;
2738  let Inst{4} = 1;
2739}
2740
2741def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2742                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2743                NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2744                [/* For disassembly only; pattern left blank */]> {
2745  let Inst{31-28} = 0b1111;
2746  let Inst{20} = 1;
2747  let Inst{4} = 1;
2748}
2749
2750def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2751               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2752               NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2753               [/* For disassembly only; pattern left blank */]> {
2754  let Inst{23-20} = 0b0100;
2755}
2756
2757def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2758                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2759                 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2760                 [/* For disassembly only; pattern left blank */]> {
2761  let Inst{31-28} = 0b1111;
2762  let Inst{23-20} = 0b0100;
2763}
2764
2765def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2766               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2767               NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2768               [/* For disassembly only; pattern left blank */]> {
2769  let Inst{23-20} = 0b0101;
2770}
2771
2772def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2773                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2774                 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2775                 [/* For disassembly only; pattern left blank */]> {
2776  let Inst{31-28} = 0b1111;
2777  let Inst{23-20} = 0b0101;
2778}
2779
2780//===----------------------------------------------------------------------===//
2781// Move between special register and ARM core register -- for disassembly only
2782//
2783
2784def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2785              [/* For disassembly only; pattern left blank */]> {
2786  let Inst{23-20} = 0b0000;
2787  let Inst{7-4} = 0b0000;
2788}
2789
2790def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2791              [/* For disassembly only; pattern left blank */]> {
2792  let Inst{23-20} = 0b0100;
2793  let Inst{7-4} = 0b0000;
2794}
2795
2796// FIXME: mask is ignored for the time being.
2797def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2798              [/* For disassembly only; pattern left blank */]> {
2799  let Inst{23-20} = 0b0010;
2800  let Inst{7-4} = 0b0000;
2801}
2802
2803// FIXME: mask is ignored for the time being.
2804def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
2805              [/* For disassembly only; pattern left blank */]> {
2806  let Inst{23-20} = 0b0010;
2807  let Inst{7-4} = 0b0000;
2808}
2809
2810// FIXME: mask is ignored for the time being.
2811def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
2812              [/* For disassembly only; pattern left blank */]> {
2813  let Inst{23-20} = 0b0110;
2814  let Inst{7-4} = 0b0000;
2815}
2816
2817// FIXME: mask is ignored for the time being.
2818def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
2819              [/* For disassembly only; pattern left blank */]> {
2820  let Inst{23-20} = 0b0110;
2821  let Inst{7-4} = 0b0000;
2822}
2823