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