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