eb7d4e40446984dfb5c76071391830a4ef7f6c56
[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 def DBG : AI<(outs), (ins i32imm:$opt), Pseudo, NoItinerary, "dbg", "\t$opt",
616              [/* For disassembly only; pattern left blank */]>,
617           Requires<[IsARM, HasV7]> {
618   let Inst{27-16} = 0b001100100000;
619   let Inst{7-4} = 0b1111;
620 }
621
622 // Address computation and loads and stores in PIC mode.
623 let isNotDuplicable = 1 in {
624 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
625                   Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
626                    [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
627
628 let AddedComplexity = 10 in {
629 def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
630                   Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
631                   [(set GPR:$dst, (load addrmodepc:$addr))]>;
632
633 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
634                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
635                   [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
636
637 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
638                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
639                   [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
640
641 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
642                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
643                   [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
644
645 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
646                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
647                   [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
648 }
649 let AddedComplexity = 10 in {
650 def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
651                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
652                [(store GPR:$src, addrmodepc:$addr)]>;
653
654 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
655                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
656                [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
657
658 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
659                Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
660                [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
661 }
662 } // isNotDuplicable = 1
663
664
665 // LEApcrel - Load a pc-relative address into a register without offending the
666 // assembler.
667 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
668                     Pseudo, IIC_iALUi,
669            !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
670                                  "${:private}PCRELL${:uid}+8))\n"),
671                       !strconcat("${:private}PCRELL${:uid}:\n\t",
672                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
673                    []>;
674
675 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
676                            (ins i32imm:$label, nohash_imm:$id, pred:$p),
677           Pseudo, IIC_iALUi,
678    !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
679                          "(${label}_${id}-(",
680                                   "${:private}PCRELL${:uid}+8))\n"),
681                        !strconcat("${:private}PCRELL${:uid}:\n\t",
682                                   "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
683                    []> {
684     let Inst{25} = 1;
685 }
686
687 //===----------------------------------------------------------------------===//
688 //  Control Flow Instructions.
689 //
690
691 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
692   def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
693                   "bx", "\tlr", [(ARMretflag)]> {
694   let Inst{3-0}   = 0b1110;
695   let Inst{7-4}   = 0b0001;
696   let Inst{19-8}  = 0b111111111111;
697   let Inst{27-20} = 0b00010010;
698 }
699
700 // Indirect branches
701 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
702   def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
703                   [(brind GPR:$dst)]> {
704     let Inst{7-4}   = 0b0001;
705     let Inst{19-8}  = 0b111111111111;
706     let Inst{27-20} = 0b00010010;
707     let Inst{31-28} = 0b1110;
708   }
709 }
710
711 // FIXME: remove when we have a way to marking a MI with these properties.
712 // FIXME: Should pc be an implicit operand like PICADD, etc?
713 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
714     hasExtraDefRegAllocReq = 1 in
715   def LDM_RET : AXI4ld<(outs),
716                     (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
717                     LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
718                     []>;
719
720 // On non-Darwin platforms R9 is callee-saved.
721 let isCall = 1,
722   Defs = [R0,  R1,  R2,  R3,  R12, LR,
723           D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
724           D16, D17, D18, D19, D20, D21, D22, D23,
725           D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
726   def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
727                 IIC_Br, "bl\t${func:call}",
728                 [(ARMcall tglobaladdr:$func)]>,
729             Requires<[IsARM, IsNotDarwin]> {
730     let Inst{31-28} = 0b1110;
731   }
732
733   def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
734                    IIC_Br, "bl", "\t${func:call}",
735                    [(ARMcall_pred tglobaladdr:$func)]>,
736                 Requires<[IsARM, IsNotDarwin]>;
737
738   // ARMv5T and above
739   def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
740                 IIC_Br, "blx\t$func",
741                 [(ARMcall GPR:$func)]>,
742             Requires<[IsARM, HasV5T, IsNotDarwin]> {
743     let Inst{7-4}   = 0b0011;
744     let Inst{19-8}  = 0b111111111111;
745     let Inst{27-20} = 0b00010010;
746   }
747
748   // ARMv4T
749   def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
750                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
751                   [(ARMcall_nolink GPR:$func)]>,
752            Requires<[IsARM, IsNotDarwin]> {
753     let Inst{7-4}   = 0b0001;
754     let Inst{19-8}  = 0b111111111111;
755     let Inst{27-20} = 0b00010010;
756   }
757 }
758
759 // On Darwin R9 is call-clobbered.
760 let isCall = 1,
761   Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
762           D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
763           D16, D17, D18, D19, D20, D21, D22, D23,
764           D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
765   def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
766                 IIC_Br, "bl\t${func:call}",
767                 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
768     let Inst{31-28} = 0b1110;
769   }
770
771   def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
772                    IIC_Br, "bl", "\t${func:call}",
773                    [(ARMcall_pred tglobaladdr:$func)]>,
774                   Requires<[IsARM, IsDarwin]>;
775
776   // ARMv5T and above
777   def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
778                 IIC_Br, "blx\t$func",
779                 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
780     let Inst{7-4}   = 0b0011;
781     let Inst{19-8}  = 0b111111111111;
782     let Inst{27-20} = 0b00010010;
783   }
784
785   // ARMv4T
786   def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
787                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
788                   [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
789     let Inst{7-4}   = 0b0001;
790     let Inst{19-8}  = 0b111111111111;
791     let Inst{27-20} = 0b00010010;
792   }
793 }
794
795 let isBranch = 1, isTerminator = 1 in {
796   // B is "predicable" since it can be xformed into a Bcc.
797   let isBarrier = 1 in {
798     let isPredicable = 1 in
799     def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
800                 "b\t$target", [(br bb:$target)]>;
801
802   let isNotDuplicable = 1, isIndirectBranch = 1 in {
803   def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
804                     IIC_Br, "mov\tpc, $target \n$jt",
805                     [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
806     let Inst{11-4}  = 0b00000000;
807     let Inst{15-12} = 0b1111;
808     let Inst{20}    = 0; // S Bit
809     let Inst{24-21} = 0b1101;
810     let Inst{27-25} = 0b000;
811   }
812   def BR_JTm : JTI<(outs),
813                    (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
814                    IIC_Br, "ldr\tpc, $target \n$jt",
815                    [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
816                      imm:$id)]> {
817     let Inst{15-12} = 0b1111;
818     let Inst{20}    = 1; // L bit
819     let Inst{21}    = 0; // W bit
820     let Inst{22}    = 0; // B bit
821     let Inst{24}    = 1; // P bit
822     let Inst{27-25} = 0b011;
823   }
824   def BR_JTadd : JTI<(outs),
825                    (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
826                     IIC_Br, "add\tpc, $target, $idx \n$jt",
827                     [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
828                       imm:$id)]> {
829     let Inst{15-12} = 0b1111;
830     let Inst{20}    = 0; // S bit
831     let Inst{24-21} = 0b0100;
832     let Inst{27-25} = 0b000;
833   }
834   } // isNotDuplicable = 1, isIndirectBranch = 1
835   } // isBarrier = 1
836
837   // FIXME: should be able to write a pattern for ARMBrcond, but can't use
838   // a two-value operand where a dag node expects two operands. :( 
839   def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
840                IIC_Br, "b", "\t$target",
841                [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
842 }
843
844 // Supervisor call (software interrupt) -- for disassembly only
845 let isCall = 1 in {
846 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
847               [/* For disassembly only; pattern left blank */]>;
848 }
849
850 //===----------------------------------------------------------------------===//
851 //  Load / store Instructions.
852 //
853
854 // Load
855 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 
856 def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
857                "ldr", "\t$dst, $addr",
858                [(set GPR:$dst, (load addrmode2:$addr))]>;
859
860 // Special LDR for loads from non-pc-relative constpools.
861 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
862     mayHaveSideEffects = 1  in
863 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
864                  "ldr", "\t$dst, $addr", []>;
865
866 // Loads with zero extension
867 def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
868                   IIC_iLoadr, "ldrh", "\t$dst, $addr",
869                   [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
870
871 def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
872                   IIC_iLoadr, "ldrb", "\t$dst, $addr",
873                   [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
874
875 // Loads with sign extension
876 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
877                    IIC_iLoadr, "ldrsh", "\t$dst, $addr",
878                    [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
879
880 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
881                    IIC_iLoadr, "ldrsb", "\t$dst, $addr",
882                    [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
883
884 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
885 // Load doubleword
886 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
887                  IIC_iLoadr, "ldrd", "\t$dst1, $addr",
888                  []>, Requires<[IsARM, HasV5TE]>;
889
890 // Indexed loads
891 def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
892                      (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
893                      "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
894
895 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
896                      (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
897                      "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
898
899 def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
900                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
901                      "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
902
903 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
904                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
905                     "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
906
907 def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
908                      (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
909                      "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
910
911 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
912                      (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
913                     "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
914
915 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
916                       (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
917                       "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
918
919 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
920                       (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
921                    "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
922
923 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
924                       (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
925                       "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
926
927 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
928                       (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
929                    "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
930 }
931
932 // Store
933 def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
934                "str", "\t$src, $addr",
935                [(store GPR:$src, addrmode2:$addr)]>;
936
937 // Stores with truncate
938 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
939                "strh", "\t$src, $addr",
940                [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
941
942 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
943                "strb", "\t$src, $addr",
944                [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
945
946 // Store doubleword
947 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
948 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
949                StMiscFrm, IIC_iStorer,
950                "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
951
952 // Indexed stores
953 def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
954                      (ins GPR:$src, GPR:$base, am2offset:$offset), 
955                      StFrm, IIC_iStoreru,
956                     "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
957                     [(set GPR:$base_wb,
958                       (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
959
960 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
961                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
962                      StFrm, IIC_iStoreru,
963                     "str", "\t$src, [$base], $offset", "$base = $base_wb",
964                     [(set GPR:$base_wb,
965                       (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
966
967 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
968                      (ins GPR:$src, GPR:$base,am3offset:$offset), 
969                      StMiscFrm, IIC_iStoreru,
970                      "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
971                     [(set GPR:$base_wb,
972                       (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
973
974 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
975                      (ins GPR:$src, GPR:$base,am3offset:$offset), 
976                      StMiscFrm, IIC_iStoreru,
977                      "strh", "\t$src, [$base], $offset", "$base = $base_wb",
978                     [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
979                                          GPR:$base, am3offset:$offset))]>;
980
981 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
982                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
983                      StFrm, IIC_iStoreru,
984                      "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
985                     [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
986                                          GPR:$base, am2offset:$offset))]>;
987
988 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
989                      (ins GPR:$src, GPR:$base,am2offset:$offset), 
990                      StFrm, IIC_iStoreru,
991                      "strb", "\t$src, [$base], $offset", "$base = $base_wb",
992                     [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
993                                          GPR:$base, am2offset:$offset))]>;
994
995 //===----------------------------------------------------------------------===//
996 //  Load / store multiple Instructions.
997 //
998
999 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1000 def LDM : AXI4ld<(outs),
1001                (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1002                LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1003                []>;
1004
1005 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1006 def STM : AXI4st<(outs),
1007                (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1008                LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1009                []>;
1010
1011 //===----------------------------------------------------------------------===//
1012 //  Move Instructions.
1013 //
1014
1015 let neverHasSideEffects = 1 in
1016 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1017                 "mov", "\t$dst, $src", []>, UnaryDP {
1018   let Inst{11-4} = 0b00000000;
1019   let Inst{25} = 0;
1020 }
1021
1022 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
1023                 DPSoRegFrm, IIC_iMOVsr,
1024                 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1025   let Inst{25} = 0;
1026 }
1027
1028 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1029 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1030                 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1031   let Inst{25} = 1;
1032 }
1033
1034 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1035 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
1036                  DPFrm, IIC_iMOVi,
1037                  "movw", "\t$dst, $src",
1038                  [(set GPR:$dst, imm0_65535:$src)]>,
1039                  Requires<[IsARM, HasV6T2]>, UnaryDP {
1040   let Inst{20} = 0;
1041   let Inst{25} = 1;
1042 }
1043
1044 let Constraints = "$src = $dst" in
1045 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1046                   DPFrm, IIC_iMOVi,
1047                   "movt", "\t$dst, $imm",
1048                   [(set GPR:$dst,
1049                         (or (and GPR:$src, 0xffff), 
1050                             lo16AllZero:$imm))]>, UnaryDP,
1051                   Requires<[IsARM, HasV6T2]> {
1052   let Inst{20} = 0;
1053   let Inst{25} = 1;
1054 }
1055
1056 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1057       Requires<[IsARM, HasV6T2]>;
1058
1059 let Uses = [CPSR] in
1060 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1061                  "mov", "\t$dst, $src, rrx",
1062                  [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1063
1064 // These aren't really mov instructions, but we have to define them this way
1065 // due to flag operands.
1066
1067 let Defs = [CPSR] in {
1068 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
1069                       IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1070                       [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1071 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1072                       IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1073                       [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1074 }
1075
1076 //===----------------------------------------------------------------------===//
1077 //  Extend Instructions.
1078 //
1079
1080 // Sign extenders
1081
1082 defm SXTB  : AI_unary_rrot<0b01101010,
1083                            "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1084 defm SXTH  : AI_unary_rrot<0b01101011,
1085                            "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1086
1087 defm SXTAB : AI_bin_rrot<0b01101010,
1088                "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1089 defm SXTAH : AI_bin_rrot<0b01101011,
1090                "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1091
1092 // TODO: SXT(A){B|H}16
1093
1094 // Zero extenders
1095
1096 let AddedComplexity = 16 in {
1097 defm UXTB   : AI_unary_rrot<0b01101110,
1098                             "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1099 defm UXTH   : AI_unary_rrot<0b01101111,
1100                             "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1101 defm UXTB16 : AI_unary_rrot<0b01101100,
1102                             "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1103
1104 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1105                (UXTB16r_rot GPR:$Src, 24)>;
1106 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1107                (UXTB16r_rot GPR:$Src, 8)>;
1108
1109 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1110                         BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1111 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1112                         BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1113 }
1114
1115 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1116 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1117
1118 // TODO: UXT(A){B|H}16
1119
1120 def SBFX  : I<(outs GPR:$dst),
1121               (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1122                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1123                "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1124                Requires<[IsARM, HasV6T2]> {
1125   let Inst{27-21} = 0b0111101;
1126   let Inst{6-4}   = 0b101;
1127 }
1128
1129 def UBFX  : I<(outs GPR:$dst),
1130               (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1131                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1132                "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1133                Requires<[IsARM, HasV6T2]> {
1134   let Inst{27-21} = 0b0111111;
1135   let Inst{6-4}   = 0b101;
1136 }
1137
1138 //===----------------------------------------------------------------------===//
1139 //  Arithmetic Instructions.
1140 //
1141
1142 defm ADD  : AsI1_bin_irs<0b0100, "add",
1143                          BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1144 defm SUB  : AsI1_bin_irs<0b0010, "sub",
1145                          BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1146
1147 // ADD and SUB with 's' bit set.
1148 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1149                           BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1150 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1151                           BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1152
1153 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1154                              BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1155 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1156                              BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1157 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1158                              BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1159 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1160                              BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1161
1162 // These don't define reg/reg forms, because they are handled above.
1163 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1164                   IIC_iALUi, "rsb", "\t$dst, $a, $b",
1165                   [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1166     let Inst{25} = 1;
1167 }
1168
1169 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1170                   IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1171                   [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1172     let Inst{25} = 0;
1173 }
1174
1175 // RSB with 's' bit set.
1176 let Defs = [CPSR] in {
1177 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1178                  IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1179                  [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1180     let Inst{20} = 1;
1181     let Inst{25} = 1;
1182 }
1183 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1184                  IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1185                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1186     let Inst{20} = 1;
1187     let Inst{25} = 0;
1188 }
1189 }
1190
1191 let Uses = [CPSR] in {
1192 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1193                  DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1194                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1195                  Requires<[IsARM, CarryDefIsUnused]> {
1196     let Inst{25} = 1;
1197 }
1198 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1199                  DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1200                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1201                  Requires<[IsARM, CarryDefIsUnused]> {
1202     let Inst{25} = 0;
1203 }
1204 }
1205
1206 // FIXME: Allow these to be predicated.
1207 let Defs = [CPSR], Uses = [CPSR] in {
1208 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1209                   DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1210                   [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1211                   Requires<[IsARM, CarryDefIsUnused]> {
1212     let Inst{20} = 1;
1213     let Inst{25} = 1;
1214 }
1215 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1216                   DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1217                   [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1218                   Requires<[IsARM, CarryDefIsUnused]> {
1219     let Inst{20} = 1;
1220     let Inst{25} = 0;
1221 }
1222 }
1223
1224 // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1225 def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1226              (SUBri  GPR:$src, so_imm_neg:$imm)>;
1227
1228 //def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1229 //             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1230 //def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1231 //             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1232
1233 // Note: These are implemented in C++ code, because they have to generate
1234 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1235 // cannot produce.
1236 // (mul X, 2^n+1) -> (add (X << n), X)
1237 // (mul X, 2^n-1) -> (rsb X, (X << n))
1238
1239
1240 //===----------------------------------------------------------------------===//
1241 //  Bitwise Instructions.
1242 //
1243
1244 defm AND   : AsI1_bin_irs<0b0000, "and",
1245                           BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1246 defm ORR   : AsI1_bin_irs<0b1100, "orr",
1247                           BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1248 defm EOR   : AsI1_bin_irs<0b0001, "eor",
1249                           BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1250 defm BIC   : AsI1_bin_irs<0b1110, "bic",
1251                           BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1252
1253 def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1254                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1255                "bfc", "\t$dst, $imm", "$src = $dst",
1256                [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1257                Requires<[IsARM, HasV6T2]> {
1258   let Inst{27-21} = 0b0111110;
1259   let Inst{6-0}   = 0b0011111;
1260 }
1261
1262 def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1263                   "mvn", "\t$dst, $src",
1264                   [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1265   let Inst{25} = 0;
1266   let Inst{11-4} = 0b00000000;
1267 }
1268 def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1269                   IIC_iMOVsr, "mvn", "\t$dst, $src",
1270                   [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1271   let Inst{25} = 0;
1272 }
1273 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1274 def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
1275                   IIC_iMOVi, "mvn", "\t$dst, $imm",
1276                   [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1277     let Inst{25} = 1;
1278 }
1279
1280 def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1281              (BICri GPR:$src, so_imm_not:$imm)>;
1282
1283 //===----------------------------------------------------------------------===//
1284 //  Multiply Instructions.
1285 //
1286
1287 let isCommutable = 1 in
1288 def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1289                    IIC_iMUL32, "mul", "\t$dst, $a, $b",
1290                    [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1291
1292 def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1293                     IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1294                    [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1295
1296 def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1297                    IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1298                    [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1299                    Requires<[IsARM, HasV6T2]>;
1300
1301 // Extra precision multiplies with low / high results
1302 let neverHasSideEffects = 1 in {
1303 let isCommutable = 1 in {
1304 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1305                                (ins GPR:$a, GPR:$b), IIC_iMUL64,
1306                     "smull", "\t$ldst, $hdst, $a, $b", []>;
1307
1308 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1309                                (ins GPR:$a, GPR:$b), IIC_iMUL64,
1310                     "umull", "\t$ldst, $hdst, $a, $b", []>;
1311 }
1312
1313 // Multiply + accumulate
1314 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1315                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1316                     "smlal", "\t$ldst, $hdst, $a, $b", []>;
1317
1318 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1319                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1320                     "umlal", "\t$ldst, $hdst, $a, $b", []>;
1321
1322 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1323                                (ins GPR:$a, GPR:$b), IIC_iMAC64,
1324                     "umaal", "\t$ldst, $hdst, $a, $b", []>,
1325                     Requires<[IsARM, HasV6]>;
1326 } // neverHasSideEffects
1327
1328 // Most significant word multiply
1329 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1330                IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1331                [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1332             Requires<[IsARM, HasV6]> {
1333   let Inst{7-4}   = 0b0001;
1334   let Inst{15-12} = 0b1111;
1335 }
1336
1337 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1338                IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1339                [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1340             Requires<[IsARM, HasV6]> {
1341   let Inst{7-4}   = 0b0001;
1342 }
1343
1344
1345 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1346                IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1347                [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1348             Requires<[IsARM, HasV6]> {
1349   let Inst{7-4}   = 0b1101;
1350 }
1351
1352 multiclass AI_smul<string opc, PatFrag opnode> {
1353   def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1354               IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1355               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1356                                       (sext_inreg GPR:$b, i16)))]>,
1357            Requires<[IsARM, HasV5TE]> {
1358              let Inst{5} = 0;
1359              let Inst{6} = 0;
1360            }
1361
1362   def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1363               IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1364               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1365                                       (sra GPR:$b, (i32 16))))]>,
1366            Requires<[IsARM, HasV5TE]> {
1367              let Inst{5} = 0;
1368              let Inst{6} = 1;
1369            }
1370
1371   def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1372               IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1373               [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1374                                       (sext_inreg GPR:$b, i16)))]>,
1375            Requires<[IsARM, HasV5TE]> {
1376              let Inst{5} = 1;
1377              let Inst{6} = 0;
1378            }
1379
1380   def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1381               IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1382               [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1383                                       (sra GPR:$b, (i32 16))))]>,
1384             Requires<[IsARM, HasV5TE]> {
1385              let Inst{5} = 1;
1386              let Inst{6} = 1;
1387            }
1388
1389   def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1390               IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1391               [(set GPR:$dst, (sra (opnode GPR:$a,
1392                                     (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1393            Requires<[IsARM, HasV5TE]> {
1394              let Inst{5} = 1;
1395              let Inst{6} = 0;
1396            }
1397
1398   def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1399               IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1400               [(set GPR:$dst, (sra (opnode GPR:$a,
1401                                     (sra GPR:$b, (i32 16))), (i32 16)))]>,
1402             Requires<[IsARM, HasV5TE]> {
1403              let Inst{5} = 1;
1404              let Inst{6} = 1;
1405            }
1406 }
1407
1408
1409 multiclass AI_smla<string opc, PatFrag opnode> {
1410   def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1411               IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1412               [(set GPR:$dst, (add GPR:$acc,
1413                                (opnode (sext_inreg GPR:$a, i16),
1414                                        (sext_inreg GPR:$b, i16))))]>,
1415            Requires<[IsARM, HasV5TE]> {
1416              let Inst{5} = 0;
1417              let Inst{6} = 0;
1418            }
1419
1420   def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1421               IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1422               [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1423                                                      (sra GPR:$b, (i32 16)))))]>,
1424            Requires<[IsARM, HasV5TE]> {
1425              let Inst{5} = 0;
1426              let Inst{6} = 1;
1427            }
1428
1429   def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1430               IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1431               [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1432                                                  (sext_inreg GPR:$b, i16))))]>,
1433            Requires<[IsARM, HasV5TE]> {
1434              let Inst{5} = 1;
1435              let Inst{6} = 0;
1436            }
1437
1438   def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1439               IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1440              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1441                                                     (sra GPR:$b, (i32 16)))))]>,
1442             Requires<[IsARM, HasV5TE]> {
1443              let Inst{5} = 1;
1444              let Inst{6} = 1;
1445            }
1446
1447   def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1448               IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1449               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1450                                        (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1451            Requires<[IsARM, HasV5TE]> {
1452              let Inst{5} = 0;
1453              let Inst{6} = 0;
1454            }
1455
1456   def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1457               IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1458               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1459                                          (sra GPR:$b, (i32 16))), (i32 16))))]>,
1460             Requires<[IsARM, HasV5TE]> {
1461              let Inst{5} = 0;
1462              let Inst{6} = 1;
1463            }
1464 }
1465
1466 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1467 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1468
1469 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1470 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1471
1472 //===----------------------------------------------------------------------===//
1473 //  Misc. Arithmetic Instructions.
1474 //
1475
1476 def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1477               "clz", "\t$dst, $src",
1478               [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1479   let Inst{7-4}   = 0b0001;
1480   let Inst{11-8}  = 0b1111;
1481   let Inst{19-16} = 0b1111;
1482 }
1483
1484 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1485               "rbit", "\t$dst, $src",
1486               [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1487            Requires<[IsARM, HasV6T2]> {
1488   let Inst{7-4}   = 0b0011;
1489   let Inst{11-8}  = 0b1111;
1490   let Inst{19-16} = 0b1111;
1491 }
1492
1493 def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1494               "rev", "\t$dst, $src",
1495               [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1496   let Inst{7-4}   = 0b0011;
1497   let Inst{11-8}  = 0b1111;
1498   let Inst{19-16} = 0b1111;
1499 }
1500
1501 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1502                "rev16", "\t$dst, $src",
1503                [(set GPR:$dst,
1504                    (or (and (srl GPR:$src, (i32 8)), 0xFF),
1505                        (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1506                            (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1507                                (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1508                Requires<[IsARM, HasV6]> {
1509   let Inst{7-4}   = 0b1011;
1510   let Inst{11-8}  = 0b1111;
1511   let Inst{19-16} = 0b1111;
1512 }
1513
1514 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1515                "revsh", "\t$dst, $src",
1516                [(set GPR:$dst,
1517                   (sext_inreg
1518                     (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1519                         (shl GPR:$src, (i32 8))), i16))]>,
1520                Requires<[IsARM, HasV6]> {
1521   let Inst{7-4}   = 0b1011;
1522   let Inst{11-8}  = 0b1111;
1523   let Inst{19-16} = 0b1111;
1524 }
1525
1526 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1527                                  (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1528                IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1529                [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1530                                    (and (shl GPR:$src2, (i32 imm:$shamt)),
1531                                         0xFFFF0000)))]>,
1532                Requires<[IsARM, HasV6]> {
1533   let Inst{6-4} = 0b001;
1534 }
1535
1536 // Alternate cases for PKHBT where identities eliminate some nodes.
1537 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1538                (PKHBT GPR:$src1, GPR:$src2, 0)>;
1539 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1540                (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1541
1542
1543 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1544                                  (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1545                IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1546                [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1547                                    (and (sra GPR:$src2, imm16_31:$shamt),
1548                                         0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1549   let Inst{6-4} = 0b101;
1550 }
1551
1552 // Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1553 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1554 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1555                (PKHTB GPR:$src1, GPR:$src2, 16)>;
1556 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1557                    (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1558                (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1559
1560 //===----------------------------------------------------------------------===//
1561 //  Comparison Instructions...
1562 //
1563
1564 defm CMP  : AI1_cmp_irs<0b1010, "cmp",
1565                         BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1566 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
1567 //       Compare-to-zero still works out, just not the relationals
1568 //defm CMN  : AI1_cmp_irs<0b1011, "cmn",
1569 //                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1570
1571 // Note that TST/TEQ don't set all the same flags that CMP does!
1572 defm TST  : AI1_cmp_irs<0b1000, "tst",
1573                         BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1574 defm TEQ  : AI1_cmp_irs<0b1001, "teq",
1575                         BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1576
1577 defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
1578                          BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1579 defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
1580                          BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1581
1582 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1583 //             (CMNri  GPR:$src, so_imm_neg:$imm)>;
1584
1585 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1586              (CMNzri  GPR:$src, so_imm_neg:$imm)>;
1587
1588
1589 // Conditional moves
1590 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1591 // a two-value operand where a dag node expects two operands. :( 
1592 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1593                 IIC_iCMOVr, "mov", "\t$dst, $true",
1594       [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1595                 RegConstraint<"$false = $dst">, UnaryDP {
1596   let Inst{11-4} = 0b00000000;
1597   let Inst{25} = 0;
1598 }
1599
1600 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1601                         (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1602                 "mov", "\t$dst, $true",
1603    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1604                 RegConstraint<"$false = $dst">, UnaryDP {
1605   let Inst{25} = 0;
1606 }
1607
1608 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1609                         (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1610                 "mov", "\t$dst, $true",
1611    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1612                 RegConstraint<"$false = $dst">, UnaryDP {
1613   let Inst{25} = 1;
1614 }
1615
1616 //===----------------------------------------------------------------------===//
1617 // Atomic operations intrinsics
1618 //
1619
1620 // memory barriers protect the atomic sequences
1621 let hasSideEffects = 1 in {
1622 def Int_MemBarrierV7 : AInoP<(outs), (ins),
1623                         Pseudo, NoItinerary,
1624                         "dmb", "",
1625                         [(ARMMemBarrierV7)]>,
1626                         Requires<[IsARM, HasV7]> {
1627   let Inst{31-4} = 0xf57ff05;
1628   // FIXME: add support for options other than a full system DMB
1629   let Inst{3-0} = 0b1111;
1630 }
1631
1632 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1633                         Pseudo, NoItinerary,
1634                         "dsb", "",
1635                         [(ARMSyncBarrierV7)]>,
1636                         Requires<[IsARM, HasV7]> {
1637   let Inst{31-4} = 0xf57ff04;
1638   // FIXME: add support for options other than a full system DSB
1639   let Inst{3-0} = 0b1111;
1640 }
1641
1642 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1643                        Pseudo, NoItinerary,
1644                        "mcr", "\tp15, 0, $zero, c7, c10, 5",
1645                        [(ARMMemBarrierV6 GPR:$zero)]>,
1646                        Requires<[IsARM, HasV6]> {
1647   // FIXME: add support for options other than a full system DMB
1648   // FIXME: add encoding
1649 }
1650
1651 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1652                         Pseudo, NoItinerary,
1653                         "mcr", "\tp15, 0, $zero, c7, c10, 4",
1654                         [(ARMSyncBarrierV6 GPR:$zero)]>,
1655                         Requires<[IsARM, HasV6]> {
1656   // FIXME: add support for options other than a full system DSB
1657   // FIXME: add encoding
1658 }
1659 }
1660
1661 let usesCustomInserter = 1 in {
1662   let Uses = [CPSR] in {
1663     def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1664       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1665       "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1666       [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1667     def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1668       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1669       "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1670       [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1671     def ATOMIC_LOAD_AND_I8 : PseudoInst<
1672       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1673       "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1674       [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1675     def ATOMIC_LOAD_OR_I8 : PseudoInst<
1676       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1677       "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1678       [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1679     def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1680       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1681       "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1682       [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1683     def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1684       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1685       "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1686       [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1687     def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1688       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1689       "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1690       [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1691     def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1692       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1693       "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1694       [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1695     def ATOMIC_LOAD_AND_I16 : PseudoInst<
1696       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1697       "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1698       [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1699     def ATOMIC_LOAD_OR_I16 : PseudoInst<
1700       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1701       "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1702       [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1703     def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1704       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1705       "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1706       [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1707     def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1708       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1709       "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1710       [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1711     def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1712       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1713       "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1714       [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1715     def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1716       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1717       "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1718       [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1719     def ATOMIC_LOAD_AND_I32 : PseudoInst<
1720       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1721       "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1722       [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1723     def ATOMIC_LOAD_OR_I32 : PseudoInst<
1724       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1725       "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1726       [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1727     def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1728       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1729       "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1730       [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1731     def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1732       (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1733       "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1734       [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1735
1736     def ATOMIC_SWAP_I8 : PseudoInst<
1737       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1738       "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1739       [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1740     def ATOMIC_SWAP_I16 : PseudoInst<
1741       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1742       "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1743       [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1744     def ATOMIC_SWAP_I32 : PseudoInst<
1745       (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1746       "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1747       [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1748
1749     def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1750       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1751       "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1752       [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1753     def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1754       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1755       "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1756       [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1757     def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1758       (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1759       "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1760       [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1761 }
1762 }
1763
1764 let mayLoad = 1 in {
1765 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1766                     "ldrexb", "\t$dest, [$ptr]",
1767                     []>;
1768 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1769                     "ldrexh", "\t$dest, [$ptr]",
1770                     []>;
1771 def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1772                     "ldrex", "\t$dest, [$ptr]",
1773                     []>;
1774 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1775                     NoItinerary,
1776                     "ldrexd", "\t$dest, $dest2, [$ptr]",
1777                     []>;
1778 }
1779
1780 let mayStore = 1, Constraints = "@earlyclobber $success" in {
1781 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1782                     NoItinerary,
1783                     "strexb", "\t$success, $src, [$ptr]",
1784                     []>;
1785 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1786                     NoItinerary,
1787                     "strexh", "\t$success, $src, [$ptr]",
1788                     []>;
1789 def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1790                     NoItinerary,
1791                     "strex", "\t$success, $src, [$ptr]",
1792                     []>;
1793 def STREXD : AIstrex<0b01, (outs GPR:$success),
1794                     (ins GPR:$src, GPR:$src2, GPR:$ptr),
1795                     NoItinerary,
1796                     "strexd", "\t$success, $src, $src2, [$ptr]",
1797                     []>;
1798 }
1799
1800 //===----------------------------------------------------------------------===//
1801 // TLS Instructions
1802 //
1803
1804 // __aeabi_read_tp preserves the registers r1-r3.
1805 let isCall = 1,
1806   Defs = [R0, R12, LR, CPSR] in {
1807   def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1808                "bl\t__aeabi_read_tp",
1809                [(set R0, ARMthread_pointer)]>;
1810 }
1811
1812 //===----------------------------------------------------------------------===//
1813 // SJLJ Exception handling intrinsics
1814 //   eh_sjlj_setjmp() is an instruction sequence to store the return
1815 //   address and save #0 in R0 for the non-longjmp case.
1816 //   Since by its nature we may be coming from some other function to get
1817 //   here, and we're using the stack frame for the containing function to
1818 //   save/restore registers, we can't keep anything live in regs across
1819 //   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1820 //   when we get here from a longjmp(). We force everthing out of registers
1821 //   except for our own input by listing the relevant registers in Defs. By
1822 //   doing so, we also cause the prologue/epilogue code to actively preserve
1823 //   all of the callee-saved resgisters, which is exactly what we want.
1824 //   A constant value is passed in $val, and we use the location as a scratch.
1825 let Defs =
1826   [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
1827     D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
1828     D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1829     D31 ] in {
1830   def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
1831                                AddrModeNone, SizeSpecial, IndexModeNone,
1832                                Pseudo, NoItinerary,
1833                                "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1834                                "add\t$val, pc, #8\n\t"
1835                                "str\t$val, [$src, #+4]\n\t"
1836                                "mov\tr0, #0\n\t"
1837                                "add\tpc, pc, #0\n\t"
1838                                "mov\tr0, #1 @ eh_setjmp end", "",
1839                          [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
1840 }
1841
1842 //===----------------------------------------------------------------------===//
1843 // Non-Instruction Patterns
1844 //
1845
1846 // Large immediate handling.
1847
1848 // Two piece so_imms.
1849 let isReMaterializable = 1 in
1850 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
1851                          Pseudo, IIC_iMOVi,
1852                          "mov", "\t$dst, $src",
1853                          [(set GPR:$dst, so_imm2part:$src)]>,
1854                   Requires<[IsARM, NoV6T2]>;
1855
1856 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1857              (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1858                     (so_imm2part_2 imm:$RHS))>;
1859 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1860              (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1861                     (so_imm2part_2 imm:$RHS))>;
1862 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1863              (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1864                     (so_imm2part_2 imm:$RHS))>;
1865 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1866              (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1867                     (so_neg_imm2part_2 imm:$RHS))>;
1868
1869 // 32-bit immediate using movw + movt.
1870 // This is a single pseudo instruction, the benefit is that it can be remat'd
1871 // as a single unit instead of having to handle reg inputs.
1872 // FIXME: Remove this when we can do generalized remat.
1873 let isReMaterializable = 1 in
1874 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1875                     "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1876                      [(set GPR:$dst, (i32 imm:$src))]>,
1877                Requires<[IsARM, HasV6T2]>;
1878
1879 // ConstantPool, GlobalAddress, and JumpTable
1880 def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1881             Requires<[IsARM, DontUseMovt]>;
1882 def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
1883 def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1884             Requires<[IsARM, UseMovt]>;
1885 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1886              (LEApcrelJT tjumptable:$dst, imm:$id)>;
1887
1888 // TODO: add,sub,and, 3-instr forms?
1889
1890
1891 // Direct calls
1892 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1893       Requires<[IsARM, IsNotDarwin]>;
1894 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1895       Requires<[IsARM, IsDarwin]>;
1896
1897 // zextload i1 -> zextload i8
1898 def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1899
1900 // extload -> zextload
1901 def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1902 def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1903 def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
1904
1905 def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1906 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1907
1908 // smul* and smla*
1909 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1910                       (sra (shl GPR:$b, (i32 16)), (i32 16))),
1911                  (SMULBB GPR:$a, GPR:$b)>;
1912 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1913                  (SMULBB GPR:$a, GPR:$b)>;
1914 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1915                       (sra GPR:$b, (i32 16))),
1916                  (SMULBT GPR:$a, GPR:$b)>;
1917 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
1918                  (SMULBT GPR:$a, GPR:$b)>;
1919 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1920                       (sra (shl GPR:$b, (i32 16)), (i32 16))),
1921                  (SMULTB GPR:$a, GPR:$b)>;
1922 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
1923                 (SMULTB GPR:$a, GPR:$b)>;
1924 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1925                       (i32 16)),
1926                  (SMULWB GPR:$a, GPR:$b)>;
1927 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
1928                  (SMULWB GPR:$a, GPR:$b)>;
1929
1930 def : ARMV5TEPat<(add GPR:$acc,
1931                       (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1932                            (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1933                  (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1934 def : ARMV5TEPat<(add GPR:$acc,
1935                       (mul sext_16_node:$a, sext_16_node:$b)),
1936                  (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1937 def : ARMV5TEPat<(add GPR:$acc,
1938                       (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1939                            (sra GPR:$b, (i32 16)))),
1940                  (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1941 def : ARMV5TEPat<(add GPR:$acc,
1942                       (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
1943                  (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1944 def : ARMV5TEPat<(add GPR:$acc,
1945                       (mul (sra GPR:$a, (i32 16)),
1946                            (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1947                  (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1948 def : ARMV5TEPat<(add GPR:$acc,
1949                       (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
1950                  (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1951 def : ARMV5TEPat<(add GPR:$acc,
1952                       (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1953                            (i32 16))),
1954                  (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1955 def : ARMV5TEPat<(add GPR:$acc,
1956                       (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
1957                  (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1958
1959 //===----------------------------------------------------------------------===//
1960 // Thumb Support
1961 //
1962
1963 include "ARMInstrThumb.td"
1964
1965 //===----------------------------------------------------------------------===//
1966 // Thumb2 Support
1967 //
1968
1969 include "ARMInstrThumb2.td"
1970
1971 //===----------------------------------------------------------------------===//
1972 // Floating Point Support
1973 //
1974
1975 include "ARMInstrVFP.td"
1976
1977 //===----------------------------------------------------------------------===//
1978 // Advanced SIMD (NEON) Support
1979 //
1980
1981 include "ARMInstrNEON.td"