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