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