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