Add SWP (Swap) and SWPB (Swap Byte) for disassembly only.
[oota-llvm.git] / lib / Target / ARM / ARMInstrInfo.td
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.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
21
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
23
24 def SDT_ARMcall    : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
25
26 def SDT_ARMCMov    : SDTypeProfile<1, 3,
27                                    [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
28                                     SDTCisVT<3, i32>]>;
29
30 def SDT_ARMBrcond  : SDTypeProfile<0, 2,
31                                    [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
32
33 def SDT_ARMBrJT    : SDTypeProfile<0, 3,
34                                   [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
35                                    SDTCisVT<2, i32>]>;
36
37 def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
38                                   [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39                                    SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
40
41 def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
42
43 def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44                                           SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
45
46 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
48                                                  SDTCisInt<2>]>;
49
50 def SDT_ARMMEMBARRIERV7  : SDTypeProfile<0, 0, []>;
51 def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
52 def SDT_ARMMEMBARRIERV6  : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
53 def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
54
55 // Node definitions.
56 def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
57 def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
58
59 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
60                               [SDNPHasChain, SDNPOutFlag]>;
61 def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
62                               [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
63
64 def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
65                               [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
66 def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
67                               [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
68 def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
69                               [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
70
71 def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
72                               [SDNPHasChain, SDNPOptInFlag]>;
73
74 def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
75                               [SDNPInFlag]>;
76 def ARMcneg          : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
77                               [SDNPInFlag]>;
78
79 def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
80                               [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
81
82 def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
83                               [SDNPHasChain]>;
84 def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
85                               [SDNPHasChain]>;
86
87 def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
88                               [SDNPOutFlag]>;
89
90 def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
91                               [SDNPOutFlag,SDNPCommutative]>;
92
93 def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
94
95 def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96 def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
97 def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInFlag ]>;
98
99 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
100 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
101
102 def ARMMemBarrierV7  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
103                               [SDNPHasChain]>;
104 def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
105                               [SDNPHasChain]>;
106 def ARMMemBarrierV6  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
107                               [SDNPHasChain]>;
108 def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
109                               [SDNPHasChain]>;
110
111 def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
112
113 //===----------------------------------------------------------------------===//
114 // ARM Instruction Predicate Definitions.
115 //
116 def HasV5T    : Predicate<"Subtarget->hasV5TOps()">;
117 def HasV5TE   : Predicate<"Subtarget->hasV5TEOps()">;
118 def HasV6     : Predicate<"Subtarget->hasV6Ops()">;
119 def HasV6T2   : Predicate<"Subtarget->hasV6T2Ops()">;
120 def NoV6T2    : Predicate<"!Subtarget->hasV6T2Ops()">;
121 def HasV7     : Predicate<"Subtarget->hasV7Ops()">;
122 def HasVFP2   : Predicate<"Subtarget->hasVFP2()">;
123 def HasVFP3   : Predicate<"Subtarget->hasVFP3()">;
124 def HasNEON   : Predicate<"Subtarget->hasNEON()">;
125 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
126 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
127 def IsThumb   : Predicate<"Subtarget->isThumb()">;
128 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
129 def IsThumb2  : Predicate<"Subtarget->isThumb2()">;
130 def IsARM     : Predicate<"!Subtarget->isThumb()">;
131 def IsDarwin    : Predicate<"Subtarget->isTargetDarwin()">;
132 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
133 def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
134 def CarryDefIsUsed   : Predicate<"N->hasAnyUseOfValue(1)">;
135
136 // FIXME: Eventually this will be just "hasV6T2Ops".
137 def UseMovt   : Predicate<"Subtarget->useMovt()">;
138 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
139
140 //===----------------------------------------------------------------------===//
141 // ARM Flag Definitions.
142
143 class RegConstraint<string C> {
144   string Constraints = C;
145 }
146
147 //===----------------------------------------------------------------------===//
148 //  ARM specific transformation functions and pattern fragments.
149 //
150
151 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
152 // so_imm_neg def below.
153 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
154   return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
155 }]>;
156
157 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
158 // so_imm_not def below.
159 def so_imm_not_XFORM : SDNodeXForm<imm, [{
160   return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
161 }]>;
162
163 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
164 def rot_imm : PatLeaf<(i32 imm), [{
165   int32_t v = (int32_t)N->getZExtValue();
166   return v == 8 || v == 16 || v == 24;
167 }]>;
168
169 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
170 def imm1_15 : PatLeaf<(i32 imm), [{
171   return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
172 }]>;
173
174 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
175 def imm16_31 : PatLeaf<(i32 imm), [{
176   return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
177 }]>;
178
179 def so_imm_neg : 
180   PatLeaf<(imm), [{
181     return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
182   }], so_imm_neg_XFORM>;
183
184 def so_imm_not :
185   PatLeaf<(imm), [{
186     return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
187   }], so_imm_not_XFORM>;
188
189 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
190 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
191   return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
192 }]>;
193
194 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
195 /// e.g., 0xf000ffff
196 def bf_inv_mask_imm : Operand<i32>,
197                       PatLeaf<(imm), [{ 
198   uint32_t v = (uint32_t)N->getZExtValue();
199   if (v == 0xffffffff)
200     return 0;
201   // there can be 1's on either or both "outsides", all the "inside"
202   // bits must be 0's
203   unsigned int lsb = 0, msb = 31;
204   while (v & (1 << msb)) --msb;
205   while (v & (1 << lsb)) ++lsb;
206   for (unsigned int i = lsb; i <= msb; ++i) {
207     if (v & (1 << i))
208       return 0;
209   }
210   return 1;
211 }] > {
212   let PrintMethod = "printBitfieldInvMaskImmOperand";
213 }
214
215 /// Split a 32-bit immediate into two 16 bit parts.
216 def lo16 : SDNodeXForm<imm, [{
217   return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
218                                    MVT::i32);
219 }]>;
220
221 def hi16 : SDNodeXForm<imm, [{
222   return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
223 }]>;
224
225 def lo16AllZero : PatLeaf<(i32 imm), [{
226   // Returns true if all low 16-bits are 0.
227   return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
228 }], hi16>;
229
230 /// imm0_65535 predicate - True if the 32-bit immediate is in the range 
231 /// [0.65535].
232 def imm0_65535 : PatLeaf<(i32 imm), [{
233   return (uint32_t)N->getZExtValue() < 65536;
234 }]>;
235
236 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
237 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
238
239 //===----------------------------------------------------------------------===//
240 // Operand Definitions.
241 //
242
243 // Branch target.
244 def brtarget : Operand<OtherVT>;
245
246 // A list of registers separated by comma. Used by load/store multiple.
247 def reglist : Operand<i32> {
248   let PrintMethod = "printRegisterList";
249 }
250
251 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
252 def cpinst_operand : Operand<i32> {
253   let PrintMethod = "printCPInstOperand";
254 }
255
256 def jtblock_operand : Operand<i32> {
257   let PrintMethod = "printJTBlockOperand";
258 }
259 def jt2block_operand : Operand<i32> {
260   let PrintMethod = "printJT2BlockOperand";
261 }
262
263 // Local PC labels.
264 def pclabel : Operand<i32> {
265   let PrintMethod = "printPCLabel";
266 }
267
268 // shifter_operand operands: so_reg and so_imm.
269 def so_reg : Operand<i32>,    // reg reg imm
270             ComplexPattern<i32, 3, "SelectShifterOperandReg",
271                             [shl,srl,sra,rotr]> {
272   let PrintMethod = "printSORegOperand";
273   let MIOperandInfo = (ops GPR, GPR, i32imm);
274 }
275
276 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
277 // 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
278 // represented in the imm field in the same 12-bit form that they are encoded
279 // into so_imm instructions: the 8-bit immediate is the least significant bits
280 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
281 def so_imm : Operand<i32>,
282              PatLeaf<(imm), [{
283       return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
284     }]> {
285   let PrintMethod = "printSOImmOperand";
286 }
287
288 // Break so_imm's up into two pieces.  This handles immediates with up to 16
289 // bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
290 // get the first/second pieces.
291 def so_imm2part : Operand<i32>,
292                   PatLeaf<(imm), [{
293       return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
294     }]> {
295   let PrintMethod = "printSOImm2PartOperand";
296 }
297
298 def so_imm2part_1 : SDNodeXForm<imm, [{
299   unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
300   return CurDAG->getTargetConstant(V, MVT::i32);
301 }]>;
302
303 def so_imm2part_2 : SDNodeXForm<imm, [{
304   unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
305   return CurDAG->getTargetConstant(V, MVT::i32);
306 }]>;
307
308 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
309       return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
310     }]> {
311   let PrintMethod = "printSOImm2PartOperand";
312 }
313
314 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
315   unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
316   return CurDAG->getTargetConstant(V, MVT::i32);
317 }]>;
318
319 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
320   unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
321   return CurDAG->getTargetConstant(V, MVT::i32);
322 }]>;
323
324 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
325 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
326   return (int32_t)N->getZExtValue() < 32;
327 }]>;
328
329 // Define ARM specific addressing modes.
330
331 // addrmode2 := reg +/- reg shop imm
332 // addrmode2 := reg +/- imm12
333 //
334 def addrmode2 : Operand<i32>,
335                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
336   let PrintMethod = "printAddrMode2Operand";
337   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
338 }
339
340 def am2offset : Operand<i32>,
341                 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
342   let PrintMethod = "printAddrMode2OffsetOperand";
343   let MIOperandInfo = (ops GPR, i32imm);
344 }
345
346 // addrmode3 := reg +/- reg
347 // addrmode3 := reg +/- imm8
348 //
349 def addrmode3 : Operand<i32>,
350                 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
351   let PrintMethod = "printAddrMode3Operand";
352   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
353 }
354
355 def am3offset : Operand<i32>,
356                 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
357   let PrintMethod = "printAddrMode3OffsetOperand";
358   let MIOperandInfo = (ops GPR, i32imm);
359 }
360
361 // addrmode4 := reg, <mode|W>
362 //
363 def addrmode4 : Operand<i32>,
364                 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
365   let PrintMethod = "printAddrMode4Operand";
366   let MIOperandInfo = (ops GPR, i32imm);
367 }
368
369 // addrmode5 := reg +/- imm8*4
370 //
371 def addrmode5 : Operand<i32>,
372                 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
373   let PrintMethod = "printAddrMode5Operand";
374   let MIOperandInfo = (ops GPR, i32imm);
375 }
376
377 // addrmode6 := reg with optional writeback
378 //
379 def addrmode6 : Operand<i32>,
380                 ComplexPattern<i32, 4, "SelectAddrMode6", []> {
381   let PrintMethod = "printAddrMode6Operand";
382   let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
383 }
384
385 // addrmodepc := pc + reg
386 //
387 def addrmodepc : Operand<i32>,
388                  ComplexPattern<i32, 2, "SelectAddrModePC", []> {
389   let PrintMethod = "printAddrModePCOperand";
390   let MIOperandInfo = (ops GPR, i32imm);
391 }
392
393 def nohash_imm : Operand<i32> {
394   let PrintMethod = "printNoHashImmediate";
395 }
396
397 //===----------------------------------------------------------------------===//
398
399 include "ARMInstrFormats.td"
400
401 //===----------------------------------------------------------------------===//
402 // Multiclass helpers...
403 //
404
405 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
406 /// binop that produces a value.
407 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
408                         bit Commutable = 0> {
409   def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
410                IIC_iALUi, opc, "\t$dst, $a, $b",
411                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
412     let Inst{25} = 1;
413   }
414   def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
415                IIC_iALUr, opc, "\t$dst, $a, $b",
416                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
417     let Inst{11-4} = 0b00000000;
418     let Inst{25} = 0;
419     let isCommutable = Commutable;
420   }
421   def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
422                IIC_iALUsr, opc, "\t$dst, $a, $b",
423                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
424     let Inst{25} = 0;
425   }
426 }
427
428 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
429 /// instruction modifies the CPSR register.
430 let Defs = [CPSR] in {
431 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
432                          bit Commutable = 0> {
433   def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
434                IIC_iALUi, opc, "\t$dst, $a, $b",
435                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
436     let Inst{20} = 1;
437     let Inst{25} = 1;
438   }
439   def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
440                IIC_iALUr, opc, "\t$dst, $a, $b",
441                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
442     let isCommutable = Commutable;
443     let Inst{11-4} = 0b00000000;
444     let Inst{20} = 1;
445     let Inst{25} = 0;
446   }
447   def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
448                IIC_iALUsr, opc, "\t$dst, $a, $b",
449                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
450     let Inst{20} = 1;
451     let Inst{25} = 0;
452   }
453 }
454 }
455
456 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
457 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
458 /// a explicit result, only implicitly set CPSR.
459 let Defs = [CPSR] in {
460 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
461                        bit Commutable = 0> {
462   def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
463                opc, "\t$a, $b",
464                [(opnode GPR:$a, so_imm:$b)]> {
465     let Inst{20} = 1;
466     let Inst{25} = 1;
467   }
468   def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
469                opc, "\t$a, $b",
470                [(opnode GPR:$a, GPR:$b)]> {
471     let Inst{11-4} = 0b00000000;
472     let Inst{20} = 1;
473     let Inst{25} = 0;
474     let isCommutable = Commutable;
475   }
476   def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
477                opc, "\t$a, $b",
478                [(opnode GPR:$a, so_reg:$b)]> {
479     let Inst{20} = 1;
480     let Inst{25} = 0;
481   }
482 }
483 }
484
485 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
486 /// register and one whose operand is a register rotated by 8/16/24.
487 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
488 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
489   def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
490                  IIC_iUNAr, opc, "\t$dst, $src",
491                  [(set GPR:$dst, (opnode GPR:$src))]>,
492               Requires<[IsARM, HasV6]> {
493     let Inst{11-10} = 0b00;
494     let Inst{19-16} = 0b1111;
495   }
496   def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
497                  IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
498                  [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
499               Requires<[IsARM, HasV6]> {
500     let Inst{19-16} = 0b1111;
501   }
502 }
503
504 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
505 /// register and one whose operand is a register rotated by 8/16/24.
506 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
507   def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
508                   IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
509                   [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
510                Requires<[IsARM, HasV6]> {
511     let Inst{11-10} = 0b00;
512   }
513   def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
514                   IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
515                   [(set GPR:$dst, (opnode GPR:$LHS,
516                                           (rotr GPR:$RHS, rot_imm:$rot)))]>,
517                   Requires<[IsARM, HasV6]>;
518 }
519
520 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
521 let Uses = [CPSR] in {
522 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
523                              bit Commutable = 0> {
524   def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
525                 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
526                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
527                Requires<[IsARM, CarryDefIsUnused]> {
528     let Inst{25} = 1;
529   }
530   def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
531                 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
532                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
533                Requires<[IsARM, CarryDefIsUnused]> {
534     let isCommutable = Commutable;
535     let Inst{11-4} = 0b00000000;
536     let Inst{25} = 0;
537   }
538   def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
539                 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
540                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
541                Requires<[IsARM, CarryDefIsUnused]> {
542     let Inst{25} = 0;
543   }
544 }
545 // Carry setting variants
546 let Defs = [CPSR] in {
547 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
548                              bit Commutable = 0> {
549   def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
550                 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
551                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
552                Requires<[IsARM, CarryDefIsUsed]> {
553     let Defs = [CPSR];
554     let Inst{20} = 1;
555     let Inst{25} = 1;
556   }
557   def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
558                 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
559                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
560                Requires<[IsARM, CarryDefIsUsed]> {
561     let Defs = [CPSR];
562     let Inst{11-4} = 0b00000000;
563     let Inst{20} = 1;
564     let Inst{25} = 0;
565   }
566   def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
567                 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
568                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
569                Requires<[IsARM, CarryDefIsUsed]> {
570     let Defs = [CPSR];
571     let Inst{20} = 1;
572     let Inst{25} = 0;
573   }
574 }
575 }
576 }
577
578 //===----------------------------------------------------------------------===//
579 // Instructions
580 //===----------------------------------------------------------------------===//
581
582 //===----------------------------------------------------------------------===//
583 //  Miscellaneous Instructions.
584 //
585
586 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
587 /// the function.  The first operand is the ID# for this instruction, the second
588 /// is the index into the MachineConstantPool that this is, the third is the
589 /// size in bytes of this constant pool entry.
590 let neverHasSideEffects = 1, isNotDuplicable = 1 in
591 def CONSTPOOL_ENTRY :
592 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
593                     i32imm:$size), NoItinerary,
594            "${instid:label} ${cpidx:cpentry}", []>;
595
596 let Defs = [SP], Uses = [SP] in {
597 def ADJCALLSTACKUP :
598 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
599            "@ ADJCALLSTACKUP $amt1",
600            [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
601
602 def ADJCALLSTACKDOWN : 
603 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
604            "@ ADJCALLSTACKDOWN $amt",
605            [(ARMcallseq_start timm:$amt)]>;
606 }
607
608 def NOP : AI<(outs), (ins), Pseudo, NoItinerary, "nop", "",
609              [/* For disassembly only; pattern left blank */]>,
610           Requires<[IsARM, HasV6T2]> {
611   let Inst{27-16} = 0b001100100000;
612   let Inst{7-0} = 0b00000000;
613 }
614
615 // The i32imm operand $val can be used by a debugger to store more information
616 // about the breakpoint.
617 def BKPT : AI<(outs), (ins i32imm:$val), Pseudo, NoItinerary, "bkpt", "\t$val",
618               [/* For disassembly only; pattern left blank */]>,
619            Requires<[IsARM]> {
620   let Inst{27-20} = 0b00010010;
621   let Inst{7-4} = 0b0111;
622 }
623
624 // Change Processor State is a system instruction -- for disassembly only.
625 // The singleton $opt operand contains the following information:
626 // opt{4-0} = mode from Inst{4-0}
627 // opt{5} = changemode from Inst{17}
628 // opt{8-6} = AIF from Inst{8-6}
629 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
630 def CPS : AXI<(outs),(ins i32imm:$opt), Pseudo, NoItinerary, "cps${opt:cps}",
631               [/* For disassembly only; pattern left blank */]>,
632           Requires<[IsARM]> {
633   let Inst{31-28} = 0b1111;
634   let Inst{27-20} = 0b00010000;
635   let Inst{16} = 0;
636   let Inst{5} = 0;
637 }
638
639 def DBG : AI<(outs), (ins i32imm:$opt), Pseudo, NoItinerary, "dbg", "\t$opt",
640              [/* For disassembly only; pattern left blank */]>,
641           Requires<[IsARM, HasV7]> {
642   let Inst{27-16} = 0b001100100000;
643   let Inst{7-4} = 0b1111;
644 }
645
646 // A5.4 Permanently UNDEFINED instructions.
647 def TRAP : AI<(outs), (ins), Pseudo, NoItinerary, "trap", "",
648               [/* For disassembly only; pattern left blank */]>,
649            Requires<[IsARM]> {
650   let Inst{27-25} = 0b011;
651   let Inst{24-20} = 0b11111;
652   let Inst{7-5} = 0b111;
653   let Inst{4} = 0b1;
654 }
655
656 // Address computation and loads and stores in PIC mode.
657 let isNotDuplicable = 1 in {
658 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
659                   Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
660                    [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
661
662 let AddedComplexity = 10 in {
663 def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
664                   Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
665                   [(set GPR:$dst, (load addrmodepc:$addr))]>;
666
667 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
668                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
669                   [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
670
671 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
672                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
673                   [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
674
675 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
676                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
677                   [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
678
679 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
680                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
681                   [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
682 }
683 let AddedComplexity = 10 in {
684 def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
685                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
686                [(store GPR:$src, addrmodepc:$addr)]>;
687
688 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
689                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
690                [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
691
692 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
693                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
694                [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
695 }
696 } // isNotDuplicable = 1
697
698
699 // LEApcrel - Load a pc-relative address into a register without offending the
700 // assembler.
701 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
702                     Pseudo, IIC_iALUi,
703            !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
704                                  "${:private}PCRELL${:uid}+8))\n"),
705                       !strconcat("${:private}PCRELL${:uid}:\n\t",
706                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
707                    []>;
708
709 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
710                            (ins i32imm:$label, nohash_imm:$id, pred:$p),
711           Pseudo, IIC_iALUi,
712    !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
713                          "(${label}_${id}-(",
714                                   "${:private}PCRELL${:uid}+8))\n"),
715                        !strconcat("${:private}PCRELL${:uid}:\n\t",
716                                   "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
717                    []> {
718     let Inst{25} = 1;
719 }
720
721 //===----------------------------------------------------------------------===//
722 //  Control Flow Instructions.
723 //
724
725 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
726   def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
727                   "bx", "\tlr", [(ARMretflag)]> {
728   let Inst{3-0}   = 0b1110;
729   let Inst{7-4}   = 0b0001;
730   let Inst{19-8}  = 0b111111111111;
731   let Inst{27-20} = 0b00010010;
732 }
733
734 // Indirect branches
735 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
736   def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
737                   [(brind GPR:$dst)]> {
738     let Inst{7-4}   = 0b0001;
739     let Inst{19-8}  = 0b111111111111;
740     let Inst{27-20} = 0b00010010;
741     let Inst{31-28} = 0b1110;
742   }
743 }
744
745 // FIXME: remove when we have a way to marking a MI with these properties.
746 // FIXME: Should pc be an implicit operand like PICADD, etc?
747 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
748     hasExtraDefRegAllocReq = 1 in
749   def LDM_RET : AXI4ld<(outs),
750                     (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
751                     LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
752                     []>;
753
754 // On non-Darwin platforms R9 is callee-saved.
755 let isCall = 1,
756   Defs = [R0,  R1,  R2,  R3,  R12, LR,
757           D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
758           D16, D17, D18, D19, D20, D21, D22, D23,
759           D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
760   def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
761                 IIC_Br, "bl\t${func:call}",
762                 [(ARMcall tglobaladdr:$func)]>,
763             Requires<[IsARM, IsNotDarwin]> {
764     let Inst{31-28} = 0b1110;
765   }
766
767   def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
768                    IIC_Br, "bl", "\t${func:call}",
769                    [(ARMcall_pred tglobaladdr:$func)]>,
770                 Requires<[IsARM, IsNotDarwin]>;
771
772   // ARMv5T and above
773   def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
774                 IIC_Br, "blx\t$func",
775                 [(ARMcall GPR:$func)]>,
776             Requires<[IsARM, HasV5T, IsNotDarwin]> {
777     let Inst{7-4}   = 0b0011;
778     let Inst{19-8}  = 0b111111111111;
779     let Inst{27-20} = 0b00010010;
780   }
781
782   // ARMv4T
783   def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
784                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
785                   [(ARMcall_nolink GPR:$func)]>,
786            Requires<[IsARM, IsNotDarwin]> {
787     let Inst{7-4}   = 0b0001;
788     let Inst{19-8}  = 0b111111111111;
789     let Inst{27-20} = 0b00010010;
790   }
791 }
792
793 // On Darwin R9 is call-clobbered.
794 let isCall = 1,
795   Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
796           D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
797           D16, D17, D18, D19, D20, D21, D22, D23,
798           D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
799   def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
800                 IIC_Br, "bl\t${func:call}",
801                 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
802     let Inst{31-28} = 0b1110;
803   }
804
805   def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
806                    IIC_Br, "bl", "\t${func:call}",
807                    [(ARMcall_pred tglobaladdr:$func)]>,
808                   Requires<[IsARM, IsDarwin]>;
809
810   // ARMv5T and above
811   def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
812                 IIC_Br, "blx\t$func",
813                 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
814     let Inst{7-4}   = 0b0011;
815     let Inst{19-8}  = 0b111111111111;
816     let Inst{27-20} = 0b00010010;
817   }
818
819   // ARMv4T
820   def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
821                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
822                   [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
823     let Inst{7-4}   = 0b0001;
824     let Inst{19-8}  = 0b111111111111;
825     let Inst{27-20} = 0b00010010;
826   }
827 }
828
829 let isBranch = 1, isTerminator = 1 in {
830   // B is "predicable" since it can be xformed into a Bcc.
831   let isBarrier = 1 in {
832     let isPredicable = 1 in
833     def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
834                 "b\t$target", [(br bb:$target)]>;
835
836   let isNotDuplicable = 1, isIndirectBranch = 1 in {
837   def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
838                     IIC_Br, "mov\tpc, $target \n$jt",
839                     [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
840     let Inst{11-4}  = 0b00000000;
841     let Inst{15-12} = 0b1111;
842     let Inst{20}    = 0; // S Bit
843     let Inst{24-21} = 0b1101;
844     let Inst{27-25} = 0b000;
845   }
846   def BR_JTm : JTI<(outs),
847                    (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
848                    IIC_Br, "ldr\tpc, $target \n$jt",
849                    [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
850                      imm:$id)]> {
851     let Inst{15-12} = 0b1111;
852     let Inst{20}    = 1; // L bit
853     let Inst{21}    = 0; // W bit
854     let Inst{22}    = 0; // B bit
855     let Inst{24}    = 1; // P bit
856     let Inst{27-25} = 0b011;
857   }
858   def BR_JTadd : JTI<(outs),
859                    (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
860                     IIC_Br, "add\tpc, $target, $idx \n$jt",
861                     [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
862                       imm:$id)]> {
863     let Inst{15-12} = 0b1111;
864     let Inst{20}    = 0; // S bit
865     let Inst{24-21} = 0b0100;
866     let Inst{27-25} = 0b000;
867   }
868   } // isNotDuplicable = 1, isIndirectBranch = 1
869   } // isBarrier = 1
870
871   // FIXME: should be able to write a pattern for ARMBrcond, but can't use
872   // a two-value operand where a dag node expects two operands. :( 
873   def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
874                IIC_Br, "b", "\t$target",
875                [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
876 }
877
878 // Supervisor call (software interrupt) -- for disassembly only
879 let isCall = 1 in {
880 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
881               [/* For disassembly only; pattern left blank */]>;
882 }
883
884 //===----------------------------------------------------------------------===//
885 //  Load / store Instructions.
886 //
887
888 // Load
889 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 
890 def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
891                "ldr", "\t$dst, $addr",
892                [(set GPR:$dst, (load addrmode2:$addr))]>;
893
894 // Special LDR for loads from non-pc-relative constpools.
895 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
896     mayHaveSideEffects = 1  in
897 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
898                  "ldr", "\t$dst, $addr", []>;
899
900 // Loads with zero extension
901 def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
902                   IIC_iLoadr, "ldrh", "\t$dst, $addr",
903                   [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
904
905 def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
906                   IIC_iLoadr, "ldrb", "\t$dst, $addr",
907                   [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
908
909 // Loads with sign extension
910 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
911                    IIC_iLoadr, "ldrsh", "\t$dst, $addr",
912                    [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
913
914 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
915                    IIC_iLoadr, "ldrsb", "\t$dst, $addr",
916                    [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
917
918 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
919 // Load doubleword
920 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
921                  IIC_iLoadr, "ldrd", "\t$dst1, $addr",
922                  []>, Requires<[IsARM, HasV5TE]>;
923
924 // Indexed loads
925 def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
926                      (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
927                      "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
928
929 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
930                      (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
931                      "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
932
933 def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
934                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
935                      "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
936
937 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
938                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
939                     "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
940
941 def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
942                      (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
943                      "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
944
945 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
946                      (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
947                     "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
948
949 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
950                       (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
951                       "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
952
953 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
954                       (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
955                    "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
956
957 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
958                       (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
959                       "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
960
961 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
962                       (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
963                    "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
964 }
965
966 // LDRT and LDRBT are for disassembly only.
967
968 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
969                    (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
970                    "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
971   let Inst{21} = 1; // overwrite
972 }
973
974 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
975                    (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
976                    "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
977   let Inst{21} = 1; // overwrite
978 }
979
980 // Store
981 def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
982                "str", "\t$src, $addr",
983                [(store GPR:$src, addrmode2:$addr)]>;
984
985 // Stores with truncate
986 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
987                "strh", "\t$src, $addr",
988                [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
989
990 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
991                "strb", "\t$src, $addr",
992                [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
993
994 // Store doubleword
995 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
996 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
997                StMiscFrm, IIC_iStorer,
998                "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
999
1000 // Indexed stores
1001 def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
1002                      (ins GPR:$src, GPR:$base, am2offset:$offset), 
1003                      StFrm, IIC_iStoreru,
1004                     "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1005                     [(set GPR:$base_wb,
1006                       (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1007
1008 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1009                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
1010                      StFrm, IIC_iStoreru,
1011                     "str", "\t$src, [$base], $offset", "$base = $base_wb",
1012                     [(set GPR:$base_wb,
1013                       (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1014
1015 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1016                      (ins GPR:$src, GPR:$base,am3offset:$offset), 
1017                      StMiscFrm, IIC_iStoreru,
1018                      "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1019                     [(set GPR:$base_wb,
1020                       (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1021
1022 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1023                      (ins GPR:$src, GPR:$base,am3offset:$offset), 
1024                      StMiscFrm, IIC_iStoreru,
1025                      "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1026                     [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1027                                          GPR:$base, am3offset:$offset))]>;
1028
1029 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1030                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
1031                      StFrm, IIC_iStoreru,
1032                      "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1033                     [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1034                                          GPR:$base, am2offset:$offset))]>;
1035
1036 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1037                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
1038                      StFrm, IIC_iStoreru,
1039                      "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1040                     [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1041                                          GPR:$base, am2offset:$offset))]>;
1042
1043 // STRT and STRBT are for disassembly only.
1044
1045 def STRT : AI2stwpo<(outs GPR:$base_wb),
1046                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1047                     StFrm, IIC_iStoreru,
1048                     "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1049                     [/* For disassembly only; pattern left blank */]> {
1050   let Inst{21} = 1; // overwrite
1051 }
1052
1053 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1054                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
1055                      StFrm, IIC_iStoreru,
1056                      "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1057                      [/* For disassembly only; pattern left blank */]> {
1058   let Inst{21} = 1; // overwrite
1059 }
1060
1061 //===----------------------------------------------------------------------===//
1062 //  Load / store multiple Instructions.
1063 //
1064
1065 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1066 def LDM : AXI4ld<(outs),
1067                (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1068                LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1069                []>;
1070
1071 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1072 def STM : AXI4st<(outs),
1073                (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1074                LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1075                []>;
1076
1077 //===----------------------------------------------------------------------===//
1078 //  Move Instructions.
1079 //
1080
1081 let neverHasSideEffects = 1 in
1082 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1083                 "mov", "\t$dst, $src", []>, UnaryDP {
1084   let Inst{11-4} = 0b00000000;
1085   let Inst{25} = 0;
1086 }
1087
1088 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
1089                 DPSoRegFrm, IIC_iMOVsr,
1090                 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1091   let Inst{25} = 0;
1092 }
1093
1094 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1095 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1096                 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1097   let Inst{25} = 1;
1098 }
1099
1100 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1101 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
1102                  DPFrm, IIC_iMOVi,
1103                  "movw", "\t$dst, $src",
1104                  [(set GPR:$dst, imm0_65535:$src)]>,
1105                  Requires<[IsARM, HasV6T2]>, UnaryDP {
1106   let Inst{20} = 0;
1107   let Inst{25} = 1;
1108 }
1109
1110 let Constraints = "$src = $dst" in
1111 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1112                   DPFrm, IIC_iMOVi,
1113                   "movt", "\t$dst, $imm",
1114                   [(set GPR:$dst,
1115                         (or (and GPR:$src, 0xffff), 
1116                             lo16AllZero:$imm))]>, UnaryDP,
1117                   Requires<[IsARM, HasV6T2]> {
1118   let Inst{20} = 0;
1119   let Inst{25} = 1;
1120 }
1121
1122 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1123       Requires<[IsARM, HasV6T2]>;
1124
1125 let Uses = [CPSR] in
1126 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1127                  "mov", "\t$dst, $src, rrx",
1128                  [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1129
1130 // These aren't really mov instructions, but we have to define them this way
1131 // due to flag operands.
1132
1133 let Defs = [CPSR] in {
1134 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
1135                       IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1136                       [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1137 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1138                       IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1139                       [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1140 }
1141
1142 //===----------------------------------------------------------------------===//
1143 //  Extend Instructions.
1144 //
1145
1146 // Sign extenders
1147
1148 defm SXTB  : AI_unary_rrot<0b01101010,
1149                            "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1150 defm SXTH  : AI_unary_rrot<0b01101011,
1151                            "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1152
1153 defm SXTAB : AI_bin_rrot<0b01101010,
1154                "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1155 defm SXTAH : AI_bin_rrot<0b01101011,
1156                "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1157
1158 // TODO: SXT(A){B|H}16
1159
1160 // Zero extenders
1161
1162 let AddedComplexity = 16 in {
1163 defm UXTB   : AI_unary_rrot<0b01101110,
1164                             "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1165 defm UXTH   : AI_unary_rrot<0b01101111,
1166                             "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1167 defm UXTB16 : AI_unary_rrot<0b01101100,
1168                             "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1169
1170 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1171                (UXTB16r_rot GPR:$Src, 24)>;
1172 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1173                (UXTB16r_rot GPR:$Src, 8)>;
1174
1175 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1176                         BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1177 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1178                         BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1179 }
1180
1181 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1182 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1183
1184 // TODO: UXT(A){B|H}16
1185
1186 def SBFX  : I<(outs GPR:$dst),
1187               (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1188                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1189                "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1190                Requires<[IsARM, HasV6T2]> {
1191   let Inst{27-21} = 0b0111101;
1192   let Inst{6-4}   = 0b101;
1193 }
1194
1195 def UBFX  : I<(outs GPR:$dst),
1196               (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1197                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1198                "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1199                Requires<[IsARM, HasV6T2]> {
1200   let Inst{27-21} = 0b0111111;
1201   let Inst{6-4}   = 0b101;
1202 }
1203
1204 //===----------------------------------------------------------------------===//
1205 //  Arithmetic Instructions.
1206 //
1207
1208 defm ADD  : AsI1_bin_irs<0b0100, "add",
1209                          BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1210 defm SUB  : AsI1_bin_irs<0b0010, "sub",
1211                          BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1212
1213 // ADD and SUB with 's' bit set.
1214 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1215                           BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1216 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1217                           BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1218
1219 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1220                              BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1221 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1222                              BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1223 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1224                              BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1225 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1226                              BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1227
1228 // These don't define reg/reg forms, because they are handled above.
1229 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1230                   IIC_iALUi, "rsb", "\t$dst, $a, $b",
1231                   [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1232     let Inst{25} = 1;
1233 }
1234
1235 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1236                   IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1237                   [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1238     let Inst{25} = 0;
1239 }
1240
1241 // RSB with 's' bit set.
1242 let Defs = [CPSR] in {
1243 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1244                  IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1245                  [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1246     let Inst{20} = 1;
1247     let Inst{25} = 1;
1248 }
1249 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1250                  IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1251                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1252     let Inst{20} = 1;
1253     let Inst{25} = 0;
1254 }
1255 }
1256
1257 let Uses = [CPSR] in {
1258 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1259                  DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1260                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1261                  Requires<[IsARM, CarryDefIsUnused]> {
1262     let Inst{25} = 1;
1263 }
1264 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1265                  DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1266                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1267                  Requires<[IsARM, CarryDefIsUnused]> {
1268     let Inst{25} = 0;
1269 }
1270 }
1271
1272 // FIXME: Allow these to be predicated.
1273 let Defs = [CPSR], Uses = [CPSR] in {
1274 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1275                   DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1276                   [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1277                   Requires<[IsARM, CarryDefIsUnused]> {
1278     let Inst{20} = 1;
1279     let Inst{25} = 1;
1280 }
1281 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1282                   DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1283                   [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1284                   Requires<[IsARM, CarryDefIsUnused]> {
1285     let Inst{20} = 1;
1286     let Inst{25} = 0;
1287 }
1288 }
1289
1290 // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1291 def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1292              (SUBri  GPR:$src, so_imm_neg:$imm)>;
1293
1294 //def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1295 //             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1296 //def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1297 //             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1298
1299 // Note: These are implemented in C++ code, because they have to generate
1300 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1301 // cannot produce.
1302 // (mul X, 2^n+1) -> (add (X << n), X)
1303 // (mul X, 2^n-1) -> (rsb X, (X << n))
1304
1305
1306 //===----------------------------------------------------------------------===//
1307 //  Bitwise Instructions.
1308 //
1309
1310 defm AND   : AsI1_bin_irs<0b0000, "and",
1311                           BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1312 defm ORR   : AsI1_bin_irs<0b1100, "orr",
1313                           BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1314 defm EOR   : AsI1_bin_irs<0b0001, "eor",
1315                           BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1316 defm BIC   : AsI1_bin_irs<0b1110, "bic",
1317                           BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1318
1319 def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1320                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1321                "bfc", "\t$dst, $imm", "$src = $dst",
1322                [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1323                Requires<[IsARM, HasV6T2]> {
1324   let Inst{27-21} = 0b0111110;
1325   let Inst{6-0}   = 0b0011111;
1326 }
1327
1328 def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1329                   "mvn", "\t$dst, $src",
1330                   [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1331   let Inst{25} = 0;
1332   let Inst{11-4} = 0b00000000;
1333 }
1334 def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1335                   IIC_iMOVsr, "mvn", "\t$dst, $src",
1336                   [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1337   let Inst{25} = 0;
1338 }
1339 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1340 def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
1341                   IIC_iMOVi, "mvn", "\t$dst, $imm",
1342                   [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1343     let Inst{25} = 1;
1344 }
1345
1346 def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1347              (BICri GPR:$src, so_imm_not:$imm)>;
1348
1349 //===----------------------------------------------------------------------===//
1350 //  Multiply Instructions.
1351 //
1352
1353 let isCommutable = 1 in
1354 def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1355                    IIC_iMUL32, "mul", "\t$dst, $a, $b",
1356                    [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1357
1358 def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1359                     IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1360                    [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1361
1362 def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1363                    IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1364                    [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1365                    Requires<[IsARM, HasV6T2]>;
1366
1367 // Extra precision multiplies with low / high results
1368 let neverHasSideEffects = 1 in {
1369 let isCommutable = 1 in {
1370 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1371                                (ins GPR:$a, GPR:$b), IIC_iMUL64,
1372                     "smull", "\t$ldst, $hdst, $a, $b", []>;
1373
1374 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1375                                (ins GPR:$a, GPR:$b), IIC_iMUL64,
1376                     "umull", "\t$ldst, $hdst, $a, $b", []>;
1377 }
1378
1379 // Multiply + accumulate
1380 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1381                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1382                     "smlal", "\t$ldst, $hdst, $a, $b", []>;
1383
1384 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1385                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1386                     "umlal", "\t$ldst, $hdst, $a, $b", []>;
1387
1388 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1389                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1390                     "umaal", "\t$ldst, $hdst, $a, $b", []>,
1391                     Requires<[IsARM, HasV6]>;
1392 } // neverHasSideEffects
1393
1394 // Most significant word multiply
1395 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1396                IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1397                [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1398             Requires<[IsARM, HasV6]> {
1399   let Inst{7-4}   = 0b0001;
1400   let Inst{15-12} = 0b1111;
1401 }
1402
1403 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1404                IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1405                [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1406             Requires<[IsARM, HasV6]> {
1407   let Inst{7-4}   = 0b0001;
1408 }
1409
1410
1411 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1412                IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1413                [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1414             Requires<[IsARM, HasV6]> {
1415   let Inst{7-4}   = 0b1101;
1416 }
1417
1418 multiclass AI_smul<string opc, PatFrag opnode> {
1419   def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1420               IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1421               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1422                                       (sext_inreg GPR:$b, i16)))]>,
1423            Requires<[IsARM, HasV5TE]> {
1424              let Inst{5} = 0;
1425              let Inst{6} = 0;
1426            }
1427
1428   def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1429               IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1430               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1431                                       (sra GPR:$b, (i32 16))))]>,
1432            Requires<[IsARM, HasV5TE]> {
1433              let Inst{5} = 0;
1434              let Inst{6} = 1;
1435            }
1436
1437   def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1438               IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1439               [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1440                                       (sext_inreg GPR:$b, i16)))]>,
1441            Requires<[IsARM, HasV5TE]> {
1442              let Inst{5} = 1;
1443              let Inst{6} = 0;
1444            }
1445
1446   def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1447               IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1448               [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1449                                       (sra GPR:$b, (i32 16))))]>,
1450             Requires<[IsARM, HasV5TE]> {
1451              let Inst{5} = 1;
1452              let Inst{6} = 1;
1453            }
1454
1455   def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1456               IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1457               [(set GPR:$dst, (sra (opnode GPR:$a,
1458                                     (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1459            Requires<[IsARM, HasV5TE]> {
1460              let Inst{5} = 1;
1461              let Inst{6} = 0;
1462            }
1463
1464   def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1465               IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1466               [(set GPR:$dst, (sra (opnode GPR:$a,
1467                                     (sra GPR:$b, (i32 16))), (i32 16)))]>,
1468             Requires<[IsARM, HasV5TE]> {
1469              let Inst{5} = 1;
1470              let Inst{6} = 1;
1471            }
1472 }
1473
1474
1475 multiclass AI_smla<string opc, PatFrag opnode> {
1476   def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1477               IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1478               [(set GPR:$dst, (add GPR:$acc,
1479                                (opnode (sext_inreg GPR:$a, i16),
1480                                        (sext_inreg GPR:$b, i16))))]>,
1481            Requires<[IsARM, HasV5TE]> {
1482              let Inst{5} = 0;
1483              let Inst{6} = 0;
1484            }
1485
1486   def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1487               IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1488               [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1489                                                      (sra GPR:$b, (i32 16)))))]>,
1490            Requires<[IsARM, HasV5TE]> {
1491              let Inst{5} = 0;
1492              let Inst{6} = 1;
1493            }
1494
1495   def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1496               IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1497               [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1498                                                  (sext_inreg GPR:$b, i16))))]>,
1499            Requires<[IsARM, HasV5TE]> {
1500              let Inst{5} = 1;
1501              let Inst{6} = 0;
1502            }
1503
1504   def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1505               IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1506              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1507                                                     (sra GPR:$b, (i32 16)))))]>,
1508             Requires<[IsARM, HasV5TE]> {
1509              let Inst{5} = 1;
1510              let Inst{6} = 1;
1511            }
1512
1513   def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1514               IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1515               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1516                                        (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1517            Requires<[IsARM, HasV5TE]> {
1518              let Inst{5} = 0;
1519              let Inst{6} = 0;
1520            }
1521
1522   def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1523               IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1524               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1525                                          (sra GPR:$b, (i32 16))), (i32 16))))]>,
1526             Requires<[IsARM, HasV5TE]> {
1527              let Inst{5} = 0;
1528              let Inst{6} = 1;
1529            }
1530 }
1531
1532 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1533 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1534
1535 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1536 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1537
1538 //===----------------------------------------------------------------------===//
1539 //  Misc. Arithmetic Instructions.
1540 //
1541
1542 def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1543               "clz", "\t$dst, $src",
1544               [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1545   let Inst{7-4}   = 0b0001;
1546   let Inst{11-8}  = 0b1111;
1547   let Inst{19-16} = 0b1111;
1548 }
1549
1550 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1551               "rbit", "\t$dst, $src",
1552               [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1553            Requires<[IsARM, HasV6T2]> {
1554   let Inst{7-4}   = 0b0011;
1555   let Inst{11-8}  = 0b1111;
1556   let Inst{19-16} = 0b1111;
1557 }
1558
1559 def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1560               "rev", "\t$dst, $src",
1561               [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1562   let Inst{7-4}   = 0b0011;
1563   let Inst{11-8}  = 0b1111;
1564   let Inst{19-16} = 0b1111;
1565 }
1566
1567 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1568                "rev16", "\t$dst, $src",
1569                [(set GPR:$dst,
1570                    (or (and (srl GPR:$src, (i32 8)), 0xFF),
1571                        (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1572                            (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1573                                (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1574                Requires<[IsARM, HasV6]> {
1575   let Inst{7-4}   = 0b1011;
1576   let Inst{11-8}  = 0b1111;
1577   let Inst{19-16} = 0b1111;
1578 }
1579
1580 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1581                "revsh", "\t$dst, $src",
1582                [(set GPR:$dst,
1583                   (sext_inreg
1584                     (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1585                         (shl GPR:$src, (i32 8))), i16))]>,
1586                Requires<[IsARM, HasV6]> {
1587   let Inst{7-4}   = 0b1011;
1588   let Inst{11-8}  = 0b1111;
1589   let Inst{19-16} = 0b1111;
1590 }
1591
1592 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1593                                  (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1594                IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1595                [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1596                                    (and (shl GPR:$src2, (i32 imm:$shamt)),
1597                                         0xFFFF0000)))]>,
1598                Requires<[IsARM, HasV6]> {
1599   let Inst{6-4} = 0b001;
1600 }
1601
1602 // Alternate cases for PKHBT where identities eliminate some nodes.
1603 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1604                (PKHBT GPR:$src1, GPR:$src2, 0)>;
1605 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1606                (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1607
1608
1609 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1610                                  (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1611                IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1612                [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1613                                    (and (sra GPR:$src2, imm16_31:$shamt),
1614                                         0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1615   let Inst{6-4} = 0b101;
1616 }
1617
1618 // Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1619 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1620 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1621                (PKHTB GPR:$src1, GPR:$src2, 16)>;
1622 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1623                    (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1624                (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1625
1626 //===----------------------------------------------------------------------===//
1627 //  Comparison Instructions...
1628 //
1629
1630 defm CMP  : AI1_cmp_irs<0b1010, "cmp",
1631                         BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1632 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
1633 //       Compare-to-zero still works out, just not the relationals
1634 //defm CMN  : AI1_cmp_irs<0b1011, "cmn",
1635 //                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1636
1637 // Note that TST/TEQ don't set all the same flags that CMP does!
1638 defm TST  : AI1_cmp_irs<0b1000, "tst",
1639                         BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1640 defm TEQ  : AI1_cmp_irs<0b1001, "teq",
1641                         BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1642
1643 defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
1644                          BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1645 defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
1646                          BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1647
1648 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1649 //             (CMNri  GPR:$src, so_imm_neg:$imm)>;
1650
1651 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1652              (CMNzri  GPR:$src, so_imm_neg:$imm)>;
1653
1654
1655 // Conditional moves
1656 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1657 // a two-value operand where a dag node expects two operands. :( 
1658 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1659                 IIC_iCMOVr, "mov", "\t$dst, $true",
1660       [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1661                 RegConstraint<"$false = $dst">, UnaryDP {
1662   let Inst{11-4} = 0b00000000;
1663   let Inst{25} = 0;
1664 }
1665
1666 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1667                         (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1668                 "mov", "\t$dst, $true",
1669    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1670                 RegConstraint<"$false = $dst">, UnaryDP {
1671   let Inst{25} = 0;
1672 }
1673
1674 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1675                         (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1676                 "mov", "\t$dst, $true",
1677    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1678                 RegConstraint<"$false = $dst">, UnaryDP {
1679   let Inst{25} = 1;
1680 }
1681
1682 //===----------------------------------------------------------------------===//
1683 // Atomic operations intrinsics
1684 //
1685
1686 // memory barriers protect the atomic sequences
1687 let hasSideEffects = 1 in {
1688 def Int_MemBarrierV7 : AInoP<(outs), (ins),
1689                         Pseudo, NoItinerary,
1690                         "dmb", "",
1691                         [(ARMMemBarrierV7)]>,
1692                         Requires<[IsARM, HasV7]> {
1693   let Inst{31-4} = 0xf57ff05;
1694   // FIXME: add support for options other than a full system DMB
1695   let Inst{3-0} = 0b1111;
1696 }
1697
1698 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1699                         Pseudo, NoItinerary,
1700                         "dsb", "",
1701                         [(ARMSyncBarrierV7)]>,
1702                         Requires<[IsARM, HasV7]> {
1703   let Inst{31-4} = 0xf57ff04;
1704   // FIXME: add support for options other than a full system DSB
1705   let Inst{3-0} = 0b1111;
1706 }
1707
1708 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1709                        Pseudo, NoItinerary,
1710                        "mcr", "\tp15, 0, $zero, c7, c10, 5",
1711                        [(ARMMemBarrierV6 GPR:$zero)]>,
1712                        Requires<[IsARM, HasV6]> {
1713   // FIXME: add support for options other than a full system DMB
1714   // FIXME: add encoding
1715 }
1716
1717 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1718                         Pseudo, NoItinerary,
1719                         "mcr", "\tp15, 0, $zero, c7, c10, 4",
1720                         [(ARMSyncBarrierV6 GPR:$zero)]>,
1721                         Requires<[IsARM, HasV6]> {
1722   // FIXME: add support for options other than a full system DSB
1723   // FIXME: add encoding
1724 }
1725 }
1726
1727 let usesCustomInserter = 1 in {
1728   let Uses = [CPSR] in {
1729     def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1730       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1731       "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1732       [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1733     def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1734       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1735       "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1736       [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1737     def ATOMIC_LOAD_AND_I8 : PseudoInst<
1738       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1739       "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1740       [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1741     def ATOMIC_LOAD_OR_I8 : PseudoInst<
1742       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1743       "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1744       [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1745     def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1746       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1747       "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1748       [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1749     def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1750       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1751       "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1752       [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1753     def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1754       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1755       "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1756       [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1757     def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1758       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1759       "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1760       [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1761     def ATOMIC_LOAD_AND_I16 : PseudoInst<
1762       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1763       "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1764       [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1765     def ATOMIC_LOAD_OR_I16 : PseudoInst<
1766       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1767       "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1768       [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1769     def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1770       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1771       "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1772       [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1773     def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1774       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1775       "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1776       [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1777     def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1778       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1779       "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1780       [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1781     def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1782       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1783       "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1784       [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1785     def ATOMIC_LOAD_AND_I32 : PseudoInst<
1786       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1787       "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1788       [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1789     def ATOMIC_LOAD_OR_I32 : PseudoInst<
1790       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1791       "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1792       [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1793     def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1794       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1795       "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1796       [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1797     def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1798       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1799       "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1800       [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1801
1802     def ATOMIC_SWAP_I8 : PseudoInst<
1803       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1804       "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1805       [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1806     def ATOMIC_SWAP_I16 : PseudoInst<
1807       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1808       "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1809       [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1810     def ATOMIC_SWAP_I32 : PseudoInst<
1811       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1812       "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1813       [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1814
1815     def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1816       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1817       "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1818       [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1819     def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1820       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1821       "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1822       [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1823     def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1824       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1825       "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1826       [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1827 }
1828 }
1829
1830 let mayLoad = 1 in {
1831 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1832                     "ldrexb", "\t$dest, [$ptr]",
1833                     []>;
1834 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1835                     "ldrexh", "\t$dest, [$ptr]",
1836                     []>;
1837 def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1838                     "ldrex", "\t$dest, [$ptr]",
1839                     []>;
1840 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1841                     NoItinerary,
1842                     "ldrexd", "\t$dest, $dest2, [$ptr]",
1843                     []>;
1844 }
1845
1846 let mayStore = 1, Constraints = "@earlyclobber $success" in {
1847 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1848                     NoItinerary,
1849                     "strexb", "\t$success, $src, [$ptr]",
1850                     []>;
1851 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1852                     NoItinerary,
1853                     "strexh", "\t$success, $src, [$ptr]",
1854                     []>;
1855 def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1856                     NoItinerary,
1857                     "strex", "\t$success, $src, [$ptr]",
1858                     []>;
1859 def STREXD : AIstrex<0b01, (outs GPR:$success),
1860                     (ins GPR:$src, GPR:$src2, GPR:$ptr),
1861                     NoItinerary,
1862                     "strexd", "\t$success, $src, $src2, [$ptr]",
1863                     []>;
1864 }
1865
1866 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
1867 let mayLoad = 1 in {
1868 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1869              "swp", "\t$dst, $src, [$ptr]",
1870              [/* For disassembly only; pattern left blank */]> {
1871   let Inst{27-23} = 0b00010;
1872   let Inst{22} = 0; // B = 0
1873   let Inst{21-20} = 0b00;
1874   let Inst{7-4} = 0b1001;
1875 }
1876
1877 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1878              "swpb", "\t$dst, $src, [$ptr]",
1879              [/* For disassembly only; pattern left blank */]> {
1880   let Inst{27-23} = 0b00010;
1881   let Inst{22} = 1; // B = 1
1882   let Inst{21-20} = 0b00;
1883   let Inst{7-4} = 0b1001;
1884 }
1885 }
1886
1887 //===----------------------------------------------------------------------===//
1888 // TLS Instructions
1889 //
1890
1891 // __aeabi_read_tp preserves the registers r1-r3.
1892 let isCall = 1,
1893   Defs = [R0, R12, LR, CPSR] in {
1894   def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1895                "bl\t__aeabi_read_tp",
1896                [(set R0, ARMthread_pointer)]>;
1897 }
1898
1899 //===----------------------------------------------------------------------===//
1900 // SJLJ Exception handling intrinsics
1901 //   eh_sjlj_setjmp() is an instruction sequence to store the return
1902 //   address and save #0 in R0 for the non-longjmp case.
1903 //   Since by its nature we may be coming from some other function to get
1904 //   here, and we're using the stack frame for the containing function to
1905 //   save/restore registers, we can't keep anything live in regs across
1906 //   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1907 //   when we get here from a longjmp(). We force everthing out of registers
1908 //   except for our own input by listing the relevant registers in Defs. By
1909 //   doing so, we also cause the prologue/epilogue code to actively preserve
1910 //   all of the callee-saved resgisters, which is exactly what we want.
1911 //   A constant value is passed in $val, and we use the location as a scratch.
1912 let Defs =
1913   [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
1914     D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
1915     D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1916     D31 ] in {
1917   def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
1918                                AddrModeNone, SizeSpecial, IndexModeNone,
1919                                Pseudo, NoItinerary,
1920                                "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1921                                "add\t$val, pc, #8\n\t"
1922                                "str\t$val, [$src, #+4]\n\t"
1923                                "mov\tr0, #0\n\t"
1924                                "add\tpc, pc, #0\n\t"
1925                                "mov\tr0, #1 @ eh_setjmp end", "",
1926                          [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
1927 }
1928
1929 //===----------------------------------------------------------------------===//
1930 // Non-Instruction Patterns
1931 //
1932
1933 // Large immediate handling.
1934
1935 // Two piece so_imms.
1936 let isReMaterializable = 1 in
1937 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
1938                          Pseudo, IIC_iMOVi,
1939                          "mov", "\t$dst, $src",
1940                          [(set GPR:$dst, so_imm2part:$src)]>,
1941                   Requires<[IsARM, NoV6T2]>;
1942
1943 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1944              (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1945                     (so_imm2part_2 imm:$RHS))>;
1946 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1947              (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1948                     (so_imm2part_2 imm:$RHS))>;
1949 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1950              (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1951                     (so_imm2part_2 imm:$RHS))>;
1952 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1953              (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1954                     (so_neg_imm2part_2 imm:$RHS))>;
1955
1956 // 32-bit immediate using movw + movt.
1957 // This is a single pseudo instruction, the benefit is that it can be remat'd
1958 // as a single unit instead of having to handle reg inputs.
1959 // FIXME: Remove this when we can do generalized remat.
1960 let isReMaterializable = 1 in
1961 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1962                     "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1963                      [(set GPR:$dst, (i32 imm:$src))]>,
1964                Requires<[IsARM, HasV6T2]>;
1965
1966 // ConstantPool, GlobalAddress, and JumpTable
1967 def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1968             Requires<[IsARM, DontUseMovt]>;
1969 def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
1970 def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1971             Requires<[IsARM, UseMovt]>;
1972 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1973              (LEApcrelJT tjumptable:$dst, imm:$id)>;
1974
1975 // TODO: add,sub,and, 3-instr forms?
1976
1977
1978 // Direct calls
1979 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1980       Requires<[IsARM, IsNotDarwin]>;
1981 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1982       Requires<[IsARM, IsDarwin]>;
1983
1984 // zextload i1 -> zextload i8
1985 def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1986
1987 // extload -> zextload
1988 def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1989 def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1990 def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
1991
1992 def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1993 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1994
1995 // smul* and smla*
1996 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1997                       (sra (shl GPR:$b, (i32 16)), (i32 16))),
1998                  (SMULBB GPR:$a, GPR:$b)>;
1999 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2000                  (SMULBB GPR:$a, GPR:$b)>;
2001 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2002                       (sra GPR:$b, (i32 16))),
2003                  (SMULBT GPR:$a, GPR:$b)>;
2004 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2005                  (SMULBT GPR:$a, GPR:$b)>;
2006 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2007                       (sra (shl GPR:$b, (i32 16)), (i32 16))),
2008                  (SMULTB GPR:$a, GPR:$b)>;
2009 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2010                 (SMULTB GPR:$a, GPR:$b)>;
2011 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2012                       (i32 16)),
2013                  (SMULWB GPR:$a, GPR:$b)>;
2014 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2015                  (SMULWB GPR:$a, GPR:$b)>;
2016
2017 def : ARMV5TEPat<(add GPR:$acc,
2018                       (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2019                            (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2020                  (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2021 def : ARMV5TEPat<(add GPR:$acc,
2022                       (mul sext_16_node:$a, sext_16_node:$b)),
2023                  (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2024 def : ARMV5TEPat<(add GPR:$acc,
2025                       (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2026                            (sra GPR:$b, (i32 16)))),
2027                  (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2028 def : ARMV5TEPat<(add GPR:$acc,
2029                       (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2030                  (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2031 def : ARMV5TEPat<(add GPR:$acc,
2032                       (mul (sra GPR:$a, (i32 16)),
2033                            (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2034                  (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2035 def : ARMV5TEPat<(add GPR:$acc,
2036                       (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2037                  (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2038 def : ARMV5TEPat<(add GPR:$acc,
2039                       (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2040                            (i32 16))),
2041                  (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2042 def : ARMV5TEPat<(add GPR:$acc,
2043                       (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2044                  (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2045
2046 //===----------------------------------------------------------------------===//
2047 // Thumb Support
2048 //
2049
2050 include "ARMInstrThumb.td"
2051
2052 //===----------------------------------------------------------------------===//
2053 // Thumb2 Support
2054 //
2055
2056 include "ARMInstrThumb2.td"
2057
2058 //===----------------------------------------------------------------------===//
2059 // Floating Point Support
2060 //
2061
2062 include "ARMInstrVFP.td"
2063
2064 //===----------------------------------------------------------------------===//
2065 // Advanced SIMD (NEON) Support
2066 //
2067
2068 include "ARMInstrNEON.td"
2069
2070 //===----------------------------------------------------------------------===//
2071 // Coprocessor Instructions.  For disassembly only.
2072 //
2073
2074 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2075             nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2076             NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2077               [/* For disassembly only; pattern left blank */]> {
2078   let Inst{4} = 0;
2079 }
2080
2081 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2082                nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2083                NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2084                [/* For disassembly only; pattern left blank */]> {
2085   let Inst{31-28} = 0b1111;
2086   let Inst{4} = 0;
2087 }
2088
2089 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2090               GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2091               NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2092               [/* For disassembly only; pattern left blank */]> {
2093   let Inst{20} = 0;
2094   let Inst{4} = 1;
2095 }
2096
2097 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2098                 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2099                 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2100                 [/* For disassembly only; pattern left blank */]> {
2101   let Inst{31-28} = 0b1111;
2102   let Inst{20} = 0;
2103   let Inst{4} = 1;
2104 }
2105
2106 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2107               GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2108               NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2109               [/* For disassembly only; pattern left blank */]> {
2110   let Inst{20} = 1;
2111   let Inst{4} = 1;
2112 }
2113
2114 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2115                 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2116                 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2117                 [/* For disassembly only; pattern left blank */]> {
2118   let Inst{31-28} = 0b1111;
2119   let Inst{20} = 1;
2120   let Inst{4} = 1;
2121 }
2122
2123 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2124                GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2125                NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2126                [/* For disassembly only; pattern left blank */]> {
2127   let Inst{23-20} = 0b0100;
2128 }
2129
2130 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2131                  GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2132                  NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2133                  [/* For disassembly only; pattern left blank */]> {
2134   let Inst{31-28} = 0b1111;
2135   let Inst{23-20} = 0b0100;
2136 }
2137
2138 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2139                GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2140                NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2141                [/* For disassembly only; pattern left blank */]> {
2142   let Inst{23-20} = 0b0101;
2143 }
2144
2145 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2146                  GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2147                  NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2148                  [/* For disassembly only; pattern left blank */]> {
2149   let Inst{31-28} = 0b1111;
2150   let Inst{23-20} = 0b0101;
2151 }
2152
2153 //===----------------------------------------------------------------------===//
2154 // Move between special register and ARM core register -- for disassembly only
2155 //
2156
2157 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2158               [/* For disassembly only; pattern left blank */]> {
2159   let Inst{23-20} = 0b0000;
2160   let Inst{7-4} = 0b0000;
2161 }
2162
2163 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2164               [/* For disassembly only; pattern left blank */]> {
2165   let Inst{23-20} = 0b0100;
2166   let Inst{7-4} = 0b0000;
2167 }
2168
2169 // FIXME: mask is ignored for the time being.
2170 def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "mrs", "\tcpsr, $src",
2171               [/* For disassembly only; pattern left blank */]> {
2172   let Inst{23-20} = 0b0010;
2173   let Inst{7-4} = 0b0000;
2174 }
2175
2176 // FIXME: mask is ignored for the time being.
2177 def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"mrs","\tspsr, $src",
2178               [/* For disassembly only; pattern left blank */]> {
2179   let Inst{23-20} = 0b0110;
2180   let Inst{7-4} = 0b0000;
2181 }