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