ARMInstrInfo.td revision e0231413225cf47aaf3238bf21afd0d59025028d
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> ]>;
21def SDT_ARMStructByVal : SDTypeProfile<0, 4,
22                                       [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
23                                        SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
24
25def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
26
27def SDT_ARMcall    : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
28
29def SDT_ARMCMov    : SDTypeProfile<1, 3,
30                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
31                                    SDTCisVT<3, i32>]>;
32
33def SDT_ARMBrcond  : SDTypeProfile<0, 2,
34                                   [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
35
36def SDT_ARMBrJT    : SDTypeProfile<0, 3,
37                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
38                                   SDTCisVT<2, i32>]>;
39
40def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
41                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
42                                   SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
43
44def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
45                                  [SDTCisVT<0, i32>,
46                                   SDTCisVT<1, i32>, SDTCisVT<2, i32>,
47                                   SDTCisVT<3, i32>, SDTCisVT<4, i32>,
48                                   SDTCisVT<5, OtherVT>]>;
49
50def SDT_ARMAnd     : SDTypeProfile<1, 2,
51                                   [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
52                                    SDTCisVT<2, i32>]>;
53
54def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
55
56def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
57                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
58
59def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
60def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
61                                                 SDTCisInt<2>]>;
62def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
63
64def SDT_ARMMEMBARRIER     : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65
66def SDT_ARMPREFETCH : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>,
67                                           SDTCisInt<1>]>;
68
69def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
70
71def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
72                                      SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
73
74def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
75                                            [SDTCisSameAs<0, 2>,
76                                             SDTCisSameAs<0, 3>,
77                                             SDTCisInt<0>, SDTCisVT<1, i32>]>;
78
79// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR
80def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
81                                            [SDTCisSameAs<0, 2>,
82                                             SDTCisSameAs<0, 3>,
83                                             SDTCisInt<0>,
84                                             SDTCisVT<1, i32>,
85                                             SDTCisVT<4, i32>]>;
86// Node definitions.
87def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
88def ARMWrapperDYN    : SDNode<"ARMISD::WrapperDYN",  SDTIntUnaryOp>;
89def ARMWrapperPIC    : SDNode<"ARMISD::WrapperPIC",  SDTIntUnaryOp>;
90def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
91
92def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
93                              [SDNPHasChain, SDNPOutGlue]>;
94def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
95                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
96def ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" ,
97                                SDT_ARMStructByVal,
98                                [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
99                                 SDNPMayStore, SDNPMayLoad]>;
100
101def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
102                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
103                               SDNPVariadic]>;
104def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
105                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
106                               SDNPVariadic]>;
107def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
108                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
109                               SDNPVariadic]>;
110
111def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
112                              [SDNPHasChain, SDNPOptInGlue]>;
113
114def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
115                              [SDNPInGlue]>;
116
117def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
118                              [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
119
120def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
121                              [SDNPHasChain]>;
122def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
123                              [SDNPHasChain]>;
124
125def ARMBcci64        : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
126                              [SDNPHasChain]>;
127
128def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
129                              [SDNPOutGlue]>;
130
131def ARMcmn           : SDNode<"ARMISD::CMN", SDT_ARMCmp,
132                              [SDNPOutGlue]>;
133
134def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
135                              [SDNPOutGlue, SDNPCommutative]>;
136
137def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
138
139def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
140def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
141def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInGlue ]>;
142
143def ARMaddc          : SDNode<"ARMISD::ADDC",  SDTBinaryArithWithFlags,
144                              [SDNPCommutative]>;
145def ARMsubc          : SDNode<"ARMISD::SUBC",  SDTBinaryArithWithFlags>;
146def ARMadde          : SDNode<"ARMISD::ADDE",  SDTBinaryArithWithFlagsInOut>;
147def ARMsube          : SDNode<"ARMISD::SUBE",  SDTBinaryArithWithFlagsInOut>;
148
149def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
150def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
151                               SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
152def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
153                               SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
154
155def ARMMemBarrier     : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
156                               [SDNPHasChain]>;
157def ARMMemBarrierMCR  : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
158                               [SDNPHasChain]>;
159def ARMPreload        : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH,
160                               [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
161
162def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
163
164def ARMtcret         : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
165                        [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
166
167
168def ARMbfi           : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
169
170//===----------------------------------------------------------------------===//
171// ARM Instruction Predicate Definitions.
172//
173def HasV4T           : Predicate<"Subtarget->hasV4TOps()">,
174                                 AssemblerPredicate<"HasV4TOps", "armv4t">;
175def NoV4T            : Predicate<"!Subtarget->hasV4TOps()">;
176def HasV5T           : Predicate<"Subtarget->hasV5TOps()">;
177def HasV5TE          : Predicate<"Subtarget->hasV5TEOps()">,
178                                 AssemblerPredicate<"HasV5TEOps", "armv5te">;
179def HasV6            : Predicate<"Subtarget->hasV6Ops()">,
180                                 AssemblerPredicate<"HasV6Ops", "armv6">;
181def NoV6             : Predicate<"!Subtarget->hasV6Ops()">;
182def HasV6T2          : Predicate<"Subtarget->hasV6T2Ops()">,
183                                 AssemblerPredicate<"HasV6T2Ops", "armv6t2">;
184def NoV6T2           : Predicate<"!Subtarget->hasV6T2Ops()">;
185def HasV7            : Predicate<"Subtarget->hasV7Ops()">,
186                                 AssemblerPredicate<"HasV7Ops", "armv7">;
187def NoVFP            : Predicate<"!Subtarget->hasVFP2()">;
188def HasVFP2          : Predicate<"Subtarget->hasVFP2()">,
189                                 AssemblerPredicate<"FeatureVFP2", "VFP2">;
190def HasVFP3          : Predicate<"Subtarget->hasVFP3()">,
191                                 AssemblerPredicate<"FeatureVFP3", "VFP3">;
192def HasVFP4          : Predicate<"Subtarget->hasVFP4()">,
193                                 AssemblerPredicate<"FeatureVFP4", "VFP4">;
194def HasNEON          : Predicate<"Subtarget->hasNEON()">,
195                                 AssemblerPredicate<"FeatureNEON", "NEON">;
196def HasFP16          : Predicate<"Subtarget->hasFP16()">,
197                                 AssemblerPredicate<"FeatureFP16","half-float">;
198def HasDivide        : Predicate<"Subtarget->hasDivide()">,
199                                 AssemblerPredicate<"FeatureHWDiv", "divide">;
200def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
201                                 AssemblerPredicate<"FeatureT2XtPk",
202                                                     "pack/extract">;
203def HasThumb2DSP     : Predicate<"Subtarget->hasThumb2DSP()">,
204                                 AssemblerPredicate<"FeatureDSPThumb2",
205                                                    "thumb2-dsp">;
206def HasDB            : Predicate<"Subtarget->hasDataBarrier()">,
207                                 AssemblerPredicate<"FeatureDB",
208                                                    "data-barriers">;
209def HasMP            : Predicate<"Subtarget->hasMPExtension()">,
210                                 AssemblerPredicate<"FeatureMP",
211                                                    "mp-extensions">;
212def UseNEONForFP     : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
213def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
214def IsThumb          : Predicate<"Subtarget->isThumb()">,
215                                 AssemblerPredicate<"ModeThumb", "thumb">;
216def IsThumb1Only     : Predicate<"Subtarget->isThumb1Only()">;
217def IsThumb2         : Predicate<"Subtarget->isThumb2()">,
218                                 AssemblerPredicate<"ModeThumb,FeatureThumb2",
219                                                    "thumb2">;
220def IsMClass         : Predicate<"Subtarget->isMClass()">,
221                                 AssemblerPredicate<"FeatureMClass", "armv7m">;
222def IsARClass        : Predicate<"!Subtarget->isMClass()">,
223                                 AssemblerPredicate<"!FeatureMClass",
224                                                    "armv7a/r">;
225def IsARM            : Predicate<"!Subtarget->isThumb()">,
226                                 AssemblerPredicate<"!ModeThumb", "arm-mode">;
227def IsIOS            : Predicate<"Subtarget->isTargetIOS()">;
228def IsNotIOS         : Predicate<"!Subtarget->isTargetIOS()">;
229def IsNaCl           : Predicate<"Subtarget->isTargetNaCl()">;
230
231// FIXME: Eventually this will be just "hasV6T2Ops".
232def UseMovt          : Predicate<"Subtarget->useMovt()">;
233def DontUseMovt      : Predicate<"!Subtarget->useMovt()">;
234def UseFPVMLx        : Predicate<"Subtarget->useFPVMLx()">;
235
236// Prefer fused MAC for fp mul + add over fp VMLA / VMLS if they are available.
237// But only select them if more precision in FP computation is allowed.
238// Do not use them for Darwin platforms.
239def UseFusedMAC      : Predicate<"(TM.Options.AllowFPOpFusion =="
240                                 " FPOpFusion::Fast) && "
241                                 "!Subtarget->isTargetDarwin()">;
242def DontUseFusedMAC  : Predicate<"!Subtarget->hasVFP4() || "
243                                 "Subtarget->isTargetDarwin()">;
244
245//===----------------------------------------------------------------------===//
246// ARM Flag Definitions.
247
248class RegConstraint<string C> {
249  string Constraints = C;
250}
251
252//===----------------------------------------------------------------------===//
253//  ARM specific transformation functions and pattern fragments.
254//
255
256// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
257// so_imm_neg def below.
258def so_imm_neg_XFORM : SDNodeXForm<imm, [{
259  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
260}]>;
261
262// so_imm_not_XFORM - Return a so_imm value packed into the format described for
263// so_imm_not def below.
264def so_imm_not_XFORM : SDNodeXForm<imm, [{
265  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
266}]>;
267
268/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
269def imm16_31 : ImmLeaf<i32, [{
270  return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
271}]>;
272
273def so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; }
274def so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
275    int64_t Value = -(int)N->getZExtValue();
276    return Value && ARM_AM::getSOImmVal(Value) != -1;
277  }], so_imm_neg_XFORM> {
278  let ParserMatchClass = so_imm_neg_asmoperand;
279}
280
281// Note: this pattern doesn't require an encoder method and such, as it's
282// only used on aliases (Pat<> and InstAlias<>). The actual encoding
283// is handled by the destination instructions, which use so_imm.
284def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; }
285def so_imm_not : Operand<i32>, PatLeaf<(imm), [{
286    return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
287  }], so_imm_not_XFORM> {
288  let ParserMatchClass = so_imm_not_asmoperand;
289}
290
291// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
292def sext_16_node : PatLeaf<(i32 GPR:$a), [{
293  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
294}]>;
295
296/// Split a 32-bit immediate into two 16 bit parts.
297def hi16 : SDNodeXForm<imm, [{
298  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
299}]>;
300
301def lo16AllZero : PatLeaf<(i32 imm), [{
302  // Returns true if all low 16-bits are 0.
303  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
304}], hi16>;
305
306class BinOpWithFlagFrag<dag res> :
307      PatFrag<(ops node:$LHS, node:$RHS, node:$FLAG), res>;
308class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
309class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
310
311// An 'and' node with a single use.
312def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
313  return N->hasOneUse();
314}]>;
315
316// An 'xor' node with a single use.
317def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
318  return N->hasOneUse();
319}]>;
320
321// An 'fmul' node with a single use.
322def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
323  return N->hasOneUse();
324}]>;
325
326// An 'fadd' node which checks for single non-hazardous use.
327def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
328  return hasNoVMLxHazardUse(N);
329}]>;
330
331// An 'fsub' node which checks for single non-hazardous use.
332def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
333  return hasNoVMLxHazardUse(N);
334}]>;
335
336//===----------------------------------------------------------------------===//
337// Operand Definitions.
338//
339
340// Immediate operands with a shared generic asm render method.
341class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; }
342
343// Branch target.
344// FIXME: rename brtarget to t2_brtarget
345def brtarget : Operand<OtherVT> {
346  let EncoderMethod = "getBranchTargetOpValue";
347  let OperandType = "OPERAND_PCREL";
348  let DecoderMethod = "DecodeT2BROperand";
349}
350
351// FIXME: get rid of this one?
352def uncondbrtarget : Operand<OtherVT> {
353  let EncoderMethod = "getUnconditionalBranchTargetOpValue";
354  let OperandType = "OPERAND_PCREL";
355}
356
357// Branch target for ARM. Handles conditional/unconditional
358def br_target : Operand<OtherVT> {
359  let EncoderMethod = "getARMBranchTargetOpValue";
360  let OperandType = "OPERAND_PCREL";
361}
362
363// Call target.
364// FIXME: rename bltarget to t2_bl_target?
365def bltarget : Operand<i32> {
366  // Encoded the same as branch targets.
367  let EncoderMethod = "getBranchTargetOpValue";
368  let OperandType = "OPERAND_PCREL";
369}
370
371// Call target for ARM. Handles conditional/unconditional
372// FIXME: rename bl_target to t2_bltarget?
373def bl_target : Operand<i32> {
374  let EncoderMethod = "getARMBLTargetOpValue";
375  let OperandType = "OPERAND_PCREL";
376}
377
378def blx_target : Operand<i32> {
379  let EncoderMethod = "getARMBLXTargetOpValue";
380  let OperandType = "OPERAND_PCREL";
381}
382
383// A list of registers separated by comma. Used by load/store multiple.
384def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; }
385def reglist : Operand<i32> {
386  let EncoderMethod = "getRegisterListOpValue";
387  let ParserMatchClass = RegListAsmOperand;
388  let PrintMethod = "printRegisterList";
389  let DecoderMethod = "DecodeRegListOperand";
390}
391
392def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; }
393def dpr_reglist : Operand<i32> {
394  let EncoderMethod = "getRegisterListOpValue";
395  let ParserMatchClass = DPRRegListAsmOperand;
396  let PrintMethod = "printRegisterList";
397  let DecoderMethod = "DecodeDPRRegListOperand";
398}
399
400def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; }
401def spr_reglist : Operand<i32> {
402  let EncoderMethod = "getRegisterListOpValue";
403  let ParserMatchClass = SPRRegListAsmOperand;
404  let PrintMethod = "printRegisterList";
405  let DecoderMethod = "DecodeSPRRegListOperand";
406}
407
408// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
409def cpinst_operand : Operand<i32> {
410  let PrintMethod = "printCPInstOperand";
411}
412
413// Local PC labels.
414def pclabel : Operand<i32> {
415  let PrintMethod = "printPCLabel";
416}
417
418// ADR instruction labels.
419def adrlabel : Operand<i32> {
420  let EncoderMethod = "getAdrLabelOpValue";
421}
422
423def neon_vcvt_imm32 : Operand<i32> {
424  let EncoderMethod = "getNEONVcvtImm32OpValue";
425  let DecoderMethod = "DecodeVCVTImmOperand";
426}
427
428// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
429def rot_imm_XFORM: SDNodeXForm<imm, [{
430  switch (N->getZExtValue()){
431  default: assert(0);
432  case 0:  return CurDAG->getTargetConstant(0, MVT::i32);
433  case 8:  return CurDAG->getTargetConstant(1, MVT::i32);
434  case 16: return CurDAG->getTargetConstant(2, MVT::i32);
435  case 24: return CurDAG->getTargetConstant(3, MVT::i32);
436  }
437}]>;
438def RotImmAsmOperand : AsmOperandClass {
439  let Name = "RotImm";
440  let ParserMethod = "parseRotImm";
441}
442def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
443    int32_t v = N->getZExtValue();
444    return v == 8 || v == 16 || v == 24; }],
445    rot_imm_XFORM> {
446  let PrintMethod = "printRotImmOperand";
447  let ParserMatchClass = RotImmAsmOperand;
448}
449
450// shift_imm: An integer that encodes a shift amount and the type of shift
451// (asr or lsl). The 6-bit immediate encodes as:
452//    {5}     0 ==> lsl
453//            1     asr
454//    {4-0}   imm5 shift amount.
455//            asr #32 encoded as imm5 == 0.
456def ShifterImmAsmOperand : AsmOperandClass {
457  let Name = "ShifterImm";
458  let ParserMethod = "parseShifterImm";
459}
460def shift_imm : Operand<i32> {
461  let PrintMethod = "printShiftImmOperand";
462  let ParserMatchClass = ShifterImmAsmOperand;
463}
464
465// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm.
466def ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; }
467def so_reg_reg : Operand<i32>,  // reg reg imm
468                 ComplexPattern<i32, 3, "SelectRegShifterOperand",
469                                [shl, srl, sra, rotr]> {
470  let EncoderMethod = "getSORegRegOpValue";
471  let PrintMethod = "printSORegRegOperand";
472  let DecoderMethod = "DecodeSORegRegOperand";
473  let ParserMatchClass = ShiftedRegAsmOperand;
474  let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm);
475}
476
477def ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; }
478def so_reg_imm : Operand<i32>, // reg imm
479                 ComplexPattern<i32, 2, "SelectImmShifterOperand",
480                                [shl, srl, sra, rotr]> {
481  let EncoderMethod = "getSORegImmOpValue";
482  let PrintMethod = "printSORegImmOperand";
483  let DecoderMethod = "DecodeSORegImmOperand";
484  let ParserMatchClass = ShiftedImmAsmOperand;
485  let MIOperandInfo = (ops GPR, i32imm);
486}
487
488// FIXME: Does this need to be distinct from so_reg?
489def shift_so_reg_reg : Operand<i32>,    // reg reg imm
490                   ComplexPattern<i32, 3, "SelectShiftRegShifterOperand",
491                                  [shl,srl,sra,rotr]> {
492  let EncoderMethod = "getSORegRegOpValue";
493  let PrintMethod = "printSORegRegOperand";
494  let DecoderMethod = "DecodeSORegRegOperand";
495  let ParserMatchClass = ShiftedRegAsmOperand;
496  let MIOperandInfo = (ops GPR, GPR, i32imm);
497}
498
499// FIXME: Does this need to be distinct from so_reg?
500def shift_so_reg_imm : Operand<i32>,    // reg reg imm
501                   ComplexPattern<i32, 2, "SelectShiftImmShifterOperand",
502                                  [shl,srl,sra,rotr]> {
503  let EncoderMethod = "getSORegImmOpValue";
504  let PrintMethod = "printSORegImmOperand";
505  let DecoderMethod = "DecodeSORegImmOperand";
506  let ParserMatchClass = ShiftedImmAsmOperand;
507  let MIOperandInfo = (ops GPR, i32imm);
508}
509
510
511// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
512// 8-bit immediate rotated by an arbitrary number of bits.
513def SOImmAsmOperand: ImmAsmOperand { let Name = "ARMSOImm"; }
514def so_imm : Operand<i32>, ImmLeaf<i32, [{
515    return ARM_AM::getSOImmVal(Imm) != -1;
516  }]> {
517  let EncoderMethod = "getSOImmOpValue";
518  let ParserMatchClass = SOImmAsmOperand;
519  let DecoderMethod = "DecodeSOImmOperand";
520}
521
522// Break so_imm's up into two pieces.  This handles immediates with up to 16
523// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
524// get the first/second pieces.
525def so_imm2part : PatLeaf<(imm), [{
526      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
527}]>;
528
529/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
530///
531def arm_i32imm : PatLeaf<(imm), [{
532  if (Subtarget->hasV6T2Ops())
533    return true;
534  return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
535}]>;
536
537/// imm0_1 predicate - Immediate in the range [0,1].
538def Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; }
539def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
540
541/// imm0_3 predicate - Immediate in the range [0,3].
542def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; }
543def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; }
544
545/// imm0_7 predicate - Immediate in the range [0,7].
546def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; }
547def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
548  return Imm >= 0 && Imm < 8;
549}]> {
550  let ParserMatchClass = Imm0_7AsmOperand;
551}
552
553/// imm8 predicate - Immediate is exactly 8.
554def Imm8AsmOperand: ImmAsmOperand { let Name = "Imm8"; }
555def imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> {
556  let ParserMatchClass = Imm8AsmOperand;
557}
558
559/// imm16 predicate - Immediate is exactly 16.
560def Imm16AsmOperand: ImmAsmOperand { let Name = "Imm16"; }
561def imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> {
562  let ParserMatchClass = Imm16AsmOperand;
563}
564
565/// imm32 predicate - Immediate is exactly 32.
566def Imm32AsmOperand: ImmAsmOperand { let Name = "Imm32"; }
567def imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> {
568  let ParserMatchClass = Imm32AsmOperand;
569}
570
571/// imm1_7 predicate - Immediate in the range [1,7].
572def Imm1_7AsmOperand: ImmAsmOperand { let Name = "Imm1_7"; }
573def imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> {
574  let ParserMatchClass = Imm1_7AsmOperand;
575}
576
577/// imm1_15 predicate - Immediate in the range [1,15].
578def Imm1_15AsmOperand: ImmAsmOperand { let Name = "Imm1_15"; }
579def imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> {
580  let ParserMatchClass = Imm1_15AsmOperand;
581}
582
583/// imm1_31 predicate - Immediate in the range [1,31].
584def Imm1_31AsmOperand: ImmAsmOperand { let Name = "Imm1_31"; }
585def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> {
586  let ParserMatchClass = Imm1_31AsmOperand;
587}
588
589/// imm0_15 predicate - Immediate in the range [0,15].
590def Imm0_15AsmOperand: ImmAsmOperand { let Name = "Imm0_15"; }
591def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
592  return Imm >= 0 && Imm < 16;
593}]> {
594  let ParserMatchClass = Imm0_15AsmOperand;
595}
596
597/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
598def Imm0_31AsmOperand: ImmAsmOperand { let Name = "Imm0_31"; }
599def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
600  return Imm >= 0 && Imm < 32;
601}]> {
602  let ParserMatchClass = Imm0_31AsmOperand;
603}
604
605/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32].
606def Imm0_32AsmOperand: ImmAsmOperand { let Name = "Imm0_32"; }
607def imm0_32 : Operand<i32>, ImmLeaf<i32, [{
608  return Imm >= 0 && Imm < 32;
609}]> {
610  let ParserMatchClass = Imm0_32AsmOperand;
611}
612
613/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63].
614def Imm0_63AsmOperand: ImmAsmOperand { let Name = "Imm0_63"; }
615def imm0_63 : Operand<i32>, ImmLeaf<i32, [{
616  return Imm >= 0 && Imm < 64;
617}]> {
618  let ParserMatchClass = Imm0_63AsmOperand;
619}
620
621/// imm0_255 predicate - Immediate in the range [0,255].
622def Imm0_255AsmOperand : ImmAsmOperand { let Name = "Imm0_255"; }
623def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
624  let ParserMatchClass = Imm0_255AsmOperand;
625}
626
627/// imm0_65535 - An immediate is in the range [0.65535].
628def Imm0_65535AsmOperand: ImmAsmOperand { let Name = "Imm0_65535"; }
629def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
630  return Imm >= 0 && Imm < 65536;
631}]> {
632  let ParserMatchClass = Imm0_65535AsmOperand;
633}
634
635// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference
636// a relocatable expression.
637//
638// FIXME: This really needs a Thumb version separate from the ARM version.
639// While the range is the same, and can thus use the same match class,
640// the encoding is different so it should have a different encoder method.
641def Imm0_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm0_65535Expr"; }
642def imm0_65535_expr : Operand<i32> {
643  let EncoderMethod = "getHiLo16ImmOpValue";
644  let ParserMatchClass = Imm0_65535ExprAsmOperand;
645}
646
647/// imm24b - True if the 32-bit immediate is encodable in 24 bits.
648def Imm24bitAsmOperand: ImmAsmOperand { let Name = "Imm24bit"; }
649def imm24b : Operand<i32>, ImmLeaf<i32, [{
650  return Imm >= 0 && Imm <= 0xffffff;
651}]> {
652  let ParserMatchClass = Imm24bitAsmOperand;
653}
654
655
656/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
657/// e.g., 0xf000ffff
658def BitfieldAsmOperand : AsmOperandClass {
659  let Name = "Bitfield";
660  let ParserMethod = "parseBitfield";
661}
662
663def bf_inv_mask_imm : Operand<i32>,
664                      PatLeaf<(imm), [{
665  return ARM::isBitFieldInvertedMask(N->getZExtValue());
666}] > {
667  let EncoderMethod = "getBitfieldInvertedMaskOpValue";
668  let PrintMethod = "printBitfieldInvMaskImmOperand";
669  let DecoderMethod = "DecodeBitfieldMaskOperand";
670  let ParserMatchClass = BitfieldAsmOperand;
671}
672
673def imm1_32_XFORM: SDNodeXForm<imm, [{
674  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
675}]>;
676def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
677def imm1_32 : Operand<i32>, PatLeaf<(imm), [{
678   uint64_t Imm = N->getZExtValue();
679   return Imm > 0 && Imm <= 32;
680 }],
681    imm1_32_XFORM> {
682  let PrintMethod = "printImmPlusOneOperand";
683  let ParserMatchClass = Imm1_32AsmOperand;
684}
685
686def imm1_16_XFORM: SDNodeXForm<imm, [{
687  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
688}]>;
689def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; }
690def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }],
691    imm1_16_XFORM> {
692  let PrintMethod = "printImmPlusOneOperand";
693  let ParserMatchClass = Imm1_16AsmOperand;
694}
695
696// Define ARM specific addressing modes.
697// addrmode_imm12 := reg +/- imm12
698//
699def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; }
700def addrmode_imm12 : Operand<i32>,
701                     ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
702  // 12-bit immediate operand. Note that instructions using this encode
703  // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
704  // immediate values are as normal.
705
706  let EncoderMethod = "getAddrModeImm12OpValue";
707  let PrintMethod = "printAddrModeImm12Operand";
708  let DecoderMethod = "DecodeAddrModeImm12Operand";
709  let ParserMatchClass = MemImm12OffsetAsmOperand;
710  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
711}
712// ldst_so_reg := reg +/- reg shop imm
713//
714def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; }
715def ldst_so_reg : Operand<i32>,
716                  ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
717  let EncoderMethod = "getLdStSORegOpValue";
718  // FIXME: Simplify the printer
719  let PrintMethod = "printAddrMode2Operand";
720  let DecoderMethod = "DecodeSORegMemOperand";
721  let ParserMatchClass = MemRegOffsetAsmOperand;
722  let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift);
723}
724
725// postidx_imm8 := +/- [0,255]
726//
727// 9 bit value:
728//  {8}       1 is imm8 is non-negative. 0 otherwise.
729//  {7-0}     [0,255] imm8 value.
730def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; }
731def postidx_imm8 : Operand<i32> {
732  let PrintMethod = "printPostIdxImm8Operand";
733  let ParserMatchClass = PostIdxImm8AsmOperand;
734  let MIOperandInfo = (ops i32imm);
735}
736
737// postidx_imm8s4 := +/- [0,1020]
738//
739// 9 bit value:
740//  {8}       1 is imm8 is non-negative. 0 otherwise.
741//  {7-0}     [0,255] imm8 value, scaled by 4.
742def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; }
743def postidx_imm8s4 : Operand<i32> {
744  let PrintMethod = "printPostIdxImm8s4Operand";
745  let ParserMatchClass = PostIdxImm8s4AsmOperand;
746  let MIOperandInfo = (ops i32imm);
747}
748
749
750// postidx_reg := +/- reg
751//
752def PostIdxRegAsmOperand : AsmOperandClass {
753  let Name = "PostIdxReg";
754  let ParserMethod = "parsePostIdxReg";
755}
756def postidx_reg : Operand<i32> {
757  let EncoderMethod = "getPostIdxRegOpValue";
758  let DecoderMethod = "DecodePostIdxReg";
759  let PrintMethod = "printPostIdxRegOperand";
760  let ParserMatchClass = PostIdxRegAsmOperand;
761  let MIOperandInfo = (ops GPRnopc, i32imm);
762}
763
764
765// addrmode2 := reg +/- imm12
766//           := reg +/- reg shop imm
767//
768// FIXME: addrmode2 should be refactored the rest of the way to always
769// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg).
770def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; }
771def addrmode2 : Operand<i32>,
772                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
773  let EncoderMethod = "getAddrMode2OpValue";
774  let PrintMethod = "printAddrMode2Operand";
775  let ParserMatchClass = AddrMode2AsmOperand;
776  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
777}
778
779def PostIdxRegShiftedAsmOperand : AsmOperandClass {
780  let Name = "PostIdxRegShifted";
781  let ParserMethod = "parsePostIdxReg";
782}
783def am2offset_reg : Operand<i32>,
784                ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
785                [], [SDNPWantRoot]> {
786  let EncoderMethod = "getAddrMode2OffsetOpValue";
787  let PrintMethod = "printAddrMode2OffsetOperand";
788  // When using this for assembly, it's always as a post-index offset.
789  let ParserMatchClass = PostIdxRegShiftedAsmOperand;
790  let MIOperandInfo = (ops GPRnopc, i32imm);
791}
792
793// FIXME: am2offset_imm should only need the immediate, not the GPR. Having
794// the GPR is purely vestigal at this point.
795def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; }
796def am2offset_imm : Operand<i32>,
797                ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm",
798                [], [SDNPWantRoot]> {
799  let EncoderMethod = "getAddrMode2OffsetOpValue";
800  let PrintMethod = "printAddrMode2OffsetOperand";
801  let ParserMatchClass = AM2OffsetImmAsmOperand;
802  let MIOperandInfo = (ops GPRnopc, i32imm);
803}
804
805
806// addrmode3 := reg +/- reg
807// addrmode3 := reg +/- imm8
808//
809// FIXME: split into imm vs. reg versions.
810def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; }
811def addrmode3 : Operand<i32>,
812                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
813  let EncoderMethod = "getAddrMode3OpValue";
814  let PrintMethod = "printAddrMode3Operand";
815  let ParserMatchClass = AddrMode3AsmOperand;
816  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
817}
818
819// FIXME: split into imm vs. reg versions.
820// FIXME: parser method to handle +/- register.
821def AM3OffsetAsmOperand : AsmOperandClass {
822  let Name = "AM3Offset";
823  let ParserMethod = "parseAM3Offset";
824}
825def am3offset : Operand<i32>,
826                ComplexPattern<i32, 2, "SelectAddrMode3Offset",
827                               [], [SDNPWantRoot]> {
828  let EncoderMethod = "getAddrMode3OffsetOpValue";
829  let PrintMethod = "printAddrMode3OffsetOperand";
830  let ParserMatchClass = AM3OffsetAsmOperand;
831  let MIOperandInfo = (ops GPR, i32imm);
832}
833
834// ldstm_mode := {ia, ib, da, db}
835//
836def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
837  let EncoderMethod = "getLdStmModeOpValue";
838  let PrintMethod = "printLdStmModeOperand";
839}
840
841// addrmode5 := reg +/- imm8*4
842//
843def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; }
844def addrmode5 : Operand<i32>,
845                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
846  let PrintMethod = "printAddrMode5Operand";
847  let EncoderMethod = "getAddrMode5OpValue";
848  let DecoderMethod = "DecodeAddrMode5Operand";
849  let ParserMatchClass = AddrMode5AsmOperand;
850  let MIOperandInfo = (ops GPR:$base, i32imm);
851}
852
853// addrmode6 := reg with optional alignment
854//
855def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; }
856def addrmode6 : Operand<i32>,
857                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
858  let PrintMethod = "printAddrMode6Operand";
859  let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
860  let EncoderMethod = "getAddrMode6AddressOpValue";
861  let DecoderMethod = "DecodeAddrMode6Operand";
862  let ParserMatchClass = AddrMode6AsmOperand;
863}
864
865def am6offset : Operand<i32>,
866                ComplexPattern<i32, 1, "SelectAddrMode6Offset",
867                               [], [SDNPWantRoot]> {
868  let PrintMethod = "printAddrMode6OffsetOperand";
869  let MIOperandInfo = (ops GPR);
870  let EncoderMethod = "getAddrMode6OffsetOpValue";
871  let DecoderMethod = "DecodeGPRRegisterClass";
872}
873
874// Special version of addrmode6 to handle alignment encoding for VST1/VLD1
875// (single element from one lane) for size 32.
876def addrmode6oneL32 : Operand<i32>,
877                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
878  let PrintMethod = "printAddrMode6Operand";
879  let MIOperandInfo = (ops GPR:$addr, i32imm);
880  let EncoderMethod = "getAddrMode6OneLane32AddressOpValue";
881}
882
883// Special version of addrmode6 to handle alignment encoding for VLD-dup
884// instructions, specifically VLD4-dup.
885def addrmode6dup : Operand<i32>,
886                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
887  let PrintMethod = "printAddrMode6Operand";
888  let MIOperandInfo = (ops GPR:$addr, i32imm);
889  let EncoderMethod = "getAddrMode6DupAddressOpValue";
890  // FIXME: This is close, but not quite right. The alignment specifier is
891  // different.
892  let ParserMatchClass = AddrMode6AsmOperand;
893}
894
895// addrmodepc := pc + reg
896//
897def addrmodepc : Operand<i32>,
898                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
899  let PrintMethod = "printAddrModePCOperand";
900  let MIOperandInfo = (ops GPR, i32imm);
901}
902
903// addr_offset_none := reg
904//
905def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; }
906def addr_offset_none : Operand<i32>,
907                       ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> {
908  let PrintMethod = "printAddrMode7Operand";
909  let DecoderMethod = "DecodeAddrMode7Operand";
910  let ParserMatchClass = MemNoOffsetAsmOperand;
911  let MIOperandInfo = (ops GPR:$base);
912}
913
914def nohash_imm : Operand<i32> {
915  let PrintMethod = "printNoHashImmediate";
916}
917
918def CoprocNumAsmOperand : AsmOperandClass {
919  let Name = "CoprocNum";
920  let ParserMethod = "parseCoprocNumOperand";
921}
922def p_imm : Operand<i32> {
923  let PrintMethod = "printPImmediate";
924  let ParserMatchClass = CoprocNumAsmOperand;
925  let DecoderMethod = "DecodeCoprocessor";
926}
927
928def pf_imm : Operand<i32> {
929  let PrintMethod = "printPImmediate";
930  let ParserMatchClass = CoprocNumAsmOperand;
931}
932
933def CoprocRegAsmOperand : AsmOperandClass {
934  let Name = "CoprocReg";
935  let ParserMethod = "parseCoprocRegOperand";
936}
937def c_imm : Operand<i32> {
938  let PrintMethod = "printCImmediate";
939  let ParserMatchClass = CoprocRegAsmOperand;
940}
941def CoprocOptionAsmOperand : AsmOperandClass {
942  let Name = "CoprocOption";
943  let ParserMethod = "parseCoprocOptionOperand";
944}
945def coproc_option_imm : Operand<i32> {
946  let PrintMethod = "printCoprocOptionImm";
947  let ParserMatchClass = CoprocOptionAsmOperand;
948}
949
950//===----------------------------------------------------------------------===//
951
952include "ARMInstrFormats.td"
953
954//===----------------------------------------------------------------------===//
955// Multiclass helpers...
956//
957
958/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
959/// binop that produces a value.
960let TwoOperandAliasConstraint = "$Rn = $Rd" in
961multiclass AsI1_bin_irs<bits<4> opcod, string opc,
962                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
963                        PatFrag opnode, string baseOpc, bit Commutable = 0> {
964  // The register-immediate version is re-materializable. This is useful
965  // in particular for taking the address of a local.
966  let isReMaterializable = 1 in {
967  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
968               iii, opc, "\t$Rd, $Rn, $imm",
969               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
970    bits<4> Rd;
971    bits<4> Rn;
972    bits<12> imm;
973    let Inst{25} = 1;
974    let Inst{19-16} = Rn;
975    let Inst{15-12} = Rd;
976    let Inst{11-0} = imm;
977  }
978  }
979  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
980               iir, opc, "\t$Rd, $Rn, $Rm",
981               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
982    bits<4> Rd;
983    bits<4> Rn;
984    bits<4> Rm;
985    let Inst{25} = 0;
986    let isCommutable = Commutable;
987    let Inst{19-16} = Rn;
988    let Inst{15-12} = Rd;
989    let Inst{11-4} = 0b00000000;
990    let Inst{3-0} = Rm;
991  }
992
993  def rsi : AsI1<opcod, (outs GPR:$Rd),
994               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
995               iis, opc, "\t$Rd, $Rn, $shift",
996               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
997    bits<4> Rd;
998    bits<4> Rn;
999    bits<12> shift;
1000    let Inst{25} = 0;
1001    let Inst{19-16} = Rn;
1002    let Inst{15-12} = Rd;
1003    let Inst{11-5} = shift{11-5};
1004    let Inst{4} = 0;
1005    let Inst{3-0} = shift{3-0};
1006  }
1007
1008  def rsr : AsI1<opcod, (outs GPR:$Rd),
1009               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
1010               iis, opc, "\t$Rd, $Rn, $shift",
1011               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
1012    bits<4> Rd;
1013    bits<4> Rn;
1014    bits<12> shift;
1015    let Inst{25} = 0;
1016    let Inst{19-16} = Rn;
1017    let Inst{15-12} = Rd;
1018    let Inst{11-8} = shift{11-8};
1019    let Inst{7} = 0;
1020    let Inst{6-5} = shift{6-5};
1021    let Inst{4} = 1;
1022    let Inst{3-0} = shift{3-0};
1023  }
1024}
1025
1026/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are
1027/// reversed.  The 'rr' form is only defined for the disassembler; for codegen
1028/// it is equivalent to the AsI1_bin_irs counterpart.
1029let TwoOperandAliasConstraint = "$Rn = $Rd" in
1030multiclass AsI1_rbin_irs<bits<4> opcod, string opc,
1031                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
1032                        PatFrag opnode, string baseOpc, bit Commutable = 0> {
1033  // The register-immediate version is re-materializable. This is useful
1034  // in particular for taking the address of a local.
1035  let isReMaterializable = 1 in {
1036  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1037               iii, opc, "\t$Rd, $Rn, $imm",
1038               [(set GPR:$Rd, (opnode so_imm:$imm, GPR:$Rn))]> {
1039    bits<4> Rd;
1040    bits<4> Rn;
1041    bits<12> imm;
1042    let Inst{25} = 1;
1043    let Inst{19-16} = Rn;
1044    let Inst{15-12} = Rd;
1045    let Inst{11-0} = imm;
1046  }
1047  }
1048  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1049               iir, opc, "\t$Rd, $Rn, $Rm",
1050               [/* pattern left blank */]> {
1051    bits<4> Rd;
1052    bits<4> Rn;
1053    bits<4> Rm;
1054    let Inst{11-4} = 0b00000000;
1055    let Inst{25} = 0;
1056    let Inst{3-0} = Rm;
1057    let Inst{15-12} = Rd;
1058    let Inst{19-16} = Rn;
1059  }
1060
1061  def rsi : AsI1<opcod, (outs GPR:$Rd),
1062               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
1063               iis, opc, "\t$Rd, $Rn, $shift",
1064               [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]> {
1065    bits<4> Rd;
1066    bits<4> Rn;
1067    bits<12> shift;
1068    let Inst{25} = 0;
1069    let Inst{19-16} = Rn;
1070    let Inst{15-12} = Rd;
1071    let Inst{11-5} = shift{11-5};
1072    let Inst{4} = 0;
1073    let Inst{3-0} = shift{3-0};
1074  }
1075
1076  def rsr : AsI1<opcod, (outs GPR:$Rd),
1077               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
1078               iis, opc, "\t$Rd, $Rn, $shift",
1079               [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]> {
1080    bits<4> Rd;
1081    bits<4> Rn;
1082    bits<12> shift;
1083    let Inst{25} = 0;
1084    let Inst{19-16} = Rn;
1085    let Inst{15-12} = Rd;
1086    let Inst{11-8} = shift{11-8};
1087    let Inst{7} = 0;
1088    let Inst{6-5} = shift{6-5};
1089    let Inst{4} = 1;
1090    let Inst{3-0} = shift{3-0};
1091  }
1092}
1093
1094/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
1095///
1096/// These opcodes will be converted to the real non-S opcodes by
1097/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand.
1098let hasPostISelHook = 1, Defs = [CPSR] in {
1099multiclass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
1100                          InstrItinClass iis, PatFrag opnode,
1101                          bit Commutable = 0> {
1102  def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
1103                         4, iii,
1104                         [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>;
1105
1106  def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p),
1107                         4, iir,
1108                         [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]> {
1109    let isCommutable = Commutable;
1110  }
1111  def rsi : ARMPseudoInst<(outs GPR:$Rd),
1112                          (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
1113                          4, iis,
1114                          [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
1115                                                so_reg_imm:$shift))]>;
1116
1117  def rsr : ARMPseudoInst<(outs GPR:$Rd),
1118                          (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
1119                          4, iis,
1120                          [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
1121                                                so_reg_reg:$shift))]>;
1122}
1123}
1124
1125/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG
1126/// operands are reversed.
1127let hasPostISelHook = 1, Defs = [CPSR] in {
1128multiclass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir,
1129                          InstrItinClass iis, PatFrag opnode,
1130                          bit Commutable = 0> {
1131  def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
1132                         4, iii,
1133                         [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>;
1134
1135  def rsi : ARMPseudoInst<(outs GPR:$Rd),
1136                          (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
1137                          4, iis,
1138                          [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift,
1139                                             GPR:$Rn))]>;
1140
1141  def rsr : ARMPseudoInst<(outs GPR:$Rd),
1142                          (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
1143                          4, iis,
1144                          [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift,
1145                                             GPR:$Rn))]>;
1146}
1147}
1148
1149/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
1150/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
1151/// a explicit result, only implicitly set CPSR.
1152let isCompare = 1, Defs = [CPSR] in {
1153multiclass AI1_cmp_irs<bits<4> opcod, string opc,
1154                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
1155                       PatFrag opnode, bit Commutable = 0> {
1156  def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
1157               opc, "\t$Rn, $imm",
1158               [(opnode GPR:$Rn, so_imm:$imm)]> {
1159    bits<4> Rn;
1160    bits<12> imm;
1161    let Inst{25} = 1;
1162    let Inst{20} = 1;
1163    let Inst{19-16} = Rn;
1164    let Inst{15-12} = 0b0000;
1165    let Inst{11-0} = imm;
1166
1167    let Unpredictable{15-12} = 0b1111;
1168  }
1169  def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
1170               opc, "\t$Rn, $Rm",
1171               [(opnode GPR:$Rn, GPR:$Rm)]> {
1172    bits<4> Rn;
1173    bits<4> Rm;
1174    let isCommutable = Commutable;
1175    let Inst{25} = 0;
1176    let Inst{20} = 1;
1177    let Inst{19-16} = Rn;
1178    let Inst{15-12} = 0b0000;
1179    let Inst{11-4} = 0b00000000;
1180    let Inst{3-0} = Rm;
1181
1182    let Unpredictable{15-12} = 0b1111;
1183  }
1184  def rsi : AI1<opcod, (outs),
1185               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis,
1186               opc, "\t$Rn, $shift",
1187               [(opnode GPR:$Rn, so_reg_imm:$shift)]> {
1188    bits<4> Rn;
1189    bits<12> shift;
1190    let Inst{25} = 0;
1191    let Inst{20} = 1;
1192    let Inst{19-16} = Rn;
1193    let Inst{15-12} = 0b0000;
1194    let Inst{11-5} = shift{11-5};
1195    let Inst{4} = 0;
1196    let Inst{3-0} = shift{3-0};
1197
1198    let Unpredictable{15-12} = 0b1111;
1199  }
1200  def rsr : AI1<opcod, (outs),
1201               (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis,
1202               opc, "\t$Rn, $shift",
1203               [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]> {
1204    bits<4> Rn;
1205    bits<12> shift;
1206    let Inst{25} = 0;
1207    let Inst{20} = 1;
1208    let Inst{19-16} = Rn;
1209    let Inst{15-12} = 0b0000;
1210    let Inst{11-8} = shift{11-8};
1211    let Inst{7} = 0;
1212    let Inst{6-5} = shift{6-5};
1213    let Inst{4} = 1;
1214    let Inst{3-0} = shift{3-0};
1215
1216    let Unpredictable{15-12} = 0b1111;
1217  }
1218
1219}
1220}
1221
1222/// AI_ext_rrot - A unary operation with two forms: one whose operand is a
1223/// register and one whose operand is a register rotated by 8/16/24.
1224/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
1225class AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode>
1226  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
1227          IIC_iEXTr, opc, "\t$Rd, $Rm$rot",
1228          [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
1229       Requires<[IsARM, HasV6]> {
1230  bits<4> Rd;
1231  bits<4> Rm;
1232  bits<2> rot;
1233  let Inst{19-16} = 0b1111;
1234  let Inst{15-12} = Rd;
1235  let Inst{11-10} = rot;
1236  let Inst{3-0}   = Rm;
1237}
1238
1239class AI_ext_rrot_np<bits<8> opcod, string opc>
1240  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
1241          IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>,
1242       Requires<[IsARM, HasV6]> {
1243  bits<2> rot;
1244  let Inst{19-16} = 0b1111;
1245  let Inst{11-10} = rot;
1246}
1247
1248/// AI_exta_rrot - A binary operation with two forms: one whose operand is a
1249/// register and one whose operand is a register rotated by 8/16/24.
1250class AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode>
1251  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
1252          IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot",
1253          [(set GPRnopc:$Rd, (opnode GPR:$Rn,
1254                                     (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
1255        Requires<[IsARM, HasV6]> {
1256  bits<4> Rd;
1257  bits<4> Rm;
1258  bits<4> Rn;
1259  bits<2> rot;
1260  let Inst{19-16} = Rn;
1261  let Inst{15-12} = Rd;
1262  let Inst{11-10} = rot;
1263  let Inst{9-4}   = 0b000111;
1264  let Inst{3-0}   = Rm;
1265}
1266
1267class AI_exta_rrot_np<bits<8> opcod, string opc>
1268  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
1269          IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>,
1270       Requires<[IsARM, HasV6]> {
1271  bits<4> Rn;
1272  bits<2> rot;
1273  let Inst{19-16} = Rn;
1274  let Inst{11-10} = rot;
1275}
1276
1277/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
1278let TwoOperandAliasConstraint = "$Rn = $Rd" in
1279multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
1280                             string baseOpc, bit Commutable = 0> {
1281  let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
1282  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1283                DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
1284               [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>,
1285               Requires<[IsARM]> {
1286    bits<4> Rd;
1287    bits<4> Rn;
1288    bits<12> imm;
1289    let Inst{25} = 1;
1290    let Inst{15-12} = Rd;
1291    let Inst{19-16} = Rn;
1292    let Inst{11-0} = imm;
1293  }
1294  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1295                DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
1296               [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>,
1297               Requires<[IsARM]> {
1298    bits<4> Rd;
1299    bits<4> Rn;
1300    bits<4> Rm;
1301    let Inst{11-4} = 0b00000000;
1302    let Inst{25} = 0;
1303    let isCommutable = Commutable;
1304    let Inst{3-0} = Rm;
1305    let Inst{15-12} = Rd;
1306    let Inst{19-16} = Rn;
1307  }
1308  def rsi : AsI1<opcod, (outs GPR:$Rd),
1309                (ins GPR:$Rn, so_reg_imm:$shift),
1310                DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1311              [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>,
1312               Requires<[IsARM]> {
1313    bits<4> Rd;
1314    bits<4> Rn;
1315    bits<12> shift;
1316    let Inst{25} = 0;
1317    let Inst{19-16} = Rn;
1318    let Inst{15-12} = Rd;
1319    let Inst{11-5} = shift{11-5};
1320    let Inst{4} = 0;
1321    let Inst{3-0} = shift{3-0};
1322  }
1323  def rsr : AsI1<opcod, (outs GPRnopc:$Rd),
1324                (ins GPRnopc:$Rn, so_reg_reg:$shift),
1325                DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1326              [(set GPRnopc:$Rd, CPSR,
1327                    (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>,
1328               Requires<[IsARM]> {
1329    bits<4> Rd;
1330    bits<4> Rn;
1331    bits<12> shift;
1332    let Inst{25} = 0;
1333    let Inst{19-16} = Rn;
1334    let Inst{15-12} = Rd;
1335    let Inst{11-8} = shift{11-8};
1336    let Inst{7} = 0;
1337    let Inst{6-5} = shift{6-5};
1338    let Inst{4} = 1;
1339    let Inst{3-0} = shift{3-0};
1340  }
1341  }
1342}
1343
1344/// AI1_rsc_irs - Define instructions and patterns for rsc
1345let TwoOperandAliasConstraint = "$Rn = $Rd" in
1346multiclass AI1_rsc_irs<bits<4> opcod, string opc, PatFrag opnode,
1347                       string baseOpc> {
1348  let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
1349  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1350                DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
1351               [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn, CPSR))]>,
1352               Requires<[IsARM]> {
1353    bits<4> Rd;
1354    bits<4> Rn;
1355    bits<12> imm;
1356    let Inst{25} = 1;
1357    let Inst{15-12} = Rd;
1358    let Inst{19-16} = Rn;
1359    let Inst{11-0} = imm;
1360  }
1361  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1362                DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
1363               [/* pattern left blank */]> {
1364    bits<4> Rd;
1365    bits<4> Rn;
1366    bits<4> Rm;
1367    let Inst{11-4} = 0b00000000;
1368    let Inst{25} = 0;
1369    let Inst{3-0} = Rm;
1370    let Inst{15-12} = Rd;
1371    let Inst{19-16} = Rn;
1372  }
1373  def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
1374                DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1375              [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>,
1376               Requires<[IsARM]> {
1377    bits<4> Rd;
1378    bits<4> Rn;
1379    bits<12> shift;
1380    let Inst{25} = 0;
1381    let Inst{19-16} = Rn;
1382    let Inst{15-12} = Rd;
1383    let Inst{11-5} = shift{11-5};
1384    let Inst{4} = 0;
1385    let Inst{3-0} = shift{3-0};
1386  }
1387  def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
1388                DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1389              [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>,
1390               Requires<[IsARM]> {
1391    bits<4> Rd;
1392    bits<4> Rn;
1393    bits<12> shift;
1394    let Inst{25} = 0;
1395    let Inst{19-16} = Rn;
1396    let Inst{15-12} = Rd;
1397    let Inst{11-8} = shift{11-8};
1398    let Inst{7} = 0;
1399    let Inst{6-5} = shift{6-5};
1400    let Inst{4} = 1;
1401    let Inst{3-0} = shift{3-0};
1402  }
1403  }
1404}
1405
1406let canFoldAsLoad = 1, isReMaterializable = 1 in {
1407multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
1408           InstrItinClass iir, PatFrag opnode> {
1409  // Note: We use the complex addrmode_imm12 rather than just an input
1410  // GPR and a constrained immediate so that we can use this to match
1411  // frame index references and avoid matching constant pool references.
1412  def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1413                   AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
1414                  [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
1415    bits<4>  Rt;
1416    bits<17> addr;
1417    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1418    let Inst{19-16} = addr{16-13};  // Rn
1419    let Inst{15-12} = Rt;
1420    let Inst{11-0}  = addr{11-0};   // imm12
1421  }
1422  def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
1423                  AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
1424                 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
1425    bits<4>  Rt;
1426    bits<17> shift;
1427    let shift{4}    = 0;            // Inst{4} = 0
1428    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1429    let Inst{19-16} = shift{16-13}; // Rn
1430    let Inst{15-12} = Rt;
1431    let Inst{11-0}  = shift{11-0};
1432  }
1433}
1434}
1435
1436let canFoldAsLoad = 1, isReMaterializable = 1 in {
1437multiclass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii,
1438           InstrItinClass iir, PatFrag opnode> {
1439  // Note: We use the complex addrmode_imm12 rather than just an input
1440  // GPR and a constrained immediate so that we can use this to match
1441  // frame index references and avoid matching constant pool references.
1442  def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt),
1443                   (ins addrmode_imm12:$addr),
1444                   AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
1445                   [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> {
1446    bits<4>  Rt;
1447    bits<17> addr;
1448    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1449    let Inst{19-16} = addr{16-13};  // Rn
1450    let Inst{15-12} = Rt;
1451    let Inst{11-0}  = addr{11-0};   // imm12
1452  }
1453  def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt),
1454                   (ins ldst_so_reg:$shift),
1455                   AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
1456                   [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> {
1457    bits<4>  Rt;
1458    bits<17> shift;
1459    let shift{4}    = 0;            // Inst{4} = 0
1460    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1461    let Inst{19-16} = shift{16-13}; // Rn
1462    let Inst{15-12} = Rt;
1463    let Inst{11-0}  = shift{11-0};
1464  }
1465}
1466}
1467
1468
1469multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
1470           InstrItinClass iir, PatFrag opnode> {
1471  // Note: We use the complex addrmode_imm12 rather than just an input
1472  // GPR and a constrained immediate so that we can use this to match
1473  // frame index references and avoid matching constant pool references.
1474  def i12 : AI2ldst<0b010, 0, isByte, (outs),
1475                   (ins GPR:$Rt, addrmode_imm12:$addr),
1476                   AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
1477                  [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
1478    bits<4> Rt;
1479    bits<17> addr;
1480    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1481    let Inst{19-16} = addr{16-13};  // Rn
1482    let Inst{15-12} = Rt;
1483    let Inst{11-0}  = addr{11-0};   // imm12
1484  }
1485  def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
1486                  AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
1487                 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1488    bits<4> Rt;
1489    bits<17> shift;
1490    let shift{4}    = 0;            // Inst{4} = 0
1491    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1492    let Inst{19-16} = shift{16-13}; // Rn
1493    let Inst{15-12} = Rt;
1494    let Inst{11-0}  = shift{11-0};
1495  }
1496}
1497
1498multiclass AI_str1nopc<bit isByte, string opc, InstrItinClass iii,
1499           InstrItinClass iir, PatFrag opnode> {
1500  // Note: We use the complex addrmode_imm12 rather than just an input
1501  // GPR and a constrained immediate so that we can use this to match
1502  // frame index references and avoid matching constant pool references.
1503  def i12 : AI2ldst<0b010, 0, isByte, (outs),
1504                   (ins GPRnopc:$Rt, addrmode_imm12:$addr),
1505                   AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
1506                  [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> {
1507    bits<4> Rt;
1508    bits<17> addr;
1509    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1510    let Inst{19-16} = addr{16-13};  // Rn
1511    let Inst{15-12} = Rt;
1512    let Inst{11-0}  = addr{11-0};   // imm12
1513  }
1514  def rs : AI2ldst<0b011, 0, isByte, (outs),
1515                   (ins GPRnopc:$Rt, ldst_so_reg:$shift),
1516                   AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
1517                   [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> {
1518    bits<4> Rt;
1519    bits<17> shift;
1520    let shift{4}    = 0;            // Inst{4} = 0
1521    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1522    let Inst{19-16} = shift{16-13}; // Rn
1523    let Inst{15-12} = Rt;
1524    let Inst{11-0}  = shift{11-0};
1525  }
1526}
1527
1528
1529//===----------------------------------------------------------------------===//
1530// Instructions
1531//===----------------------------------------------------------------------===//
1532
1533//===----------------------------------------------------------------------===//
1534//  Miscellaneous Instructions.
1535//
1536
1537/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1538/// the function.  The first operand is the ID# for this instruction, the second
1539/// is the index into the MachineConstantPool that this is, the third is the
1540/// size in bytes of this constant pool entry.
1541let neverHasSideEffects = 1, isNotDuplicable = 1 in
1542def CONSTPOOL_ENTRY :
1543PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1544                    i32imm:$size), NoItinerary, []>;
1545
1546// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1547// from removing one half of the matched pairs. That breaks PEI, which assumes
1548// these will always be in pairs, and asserts if it finds otherwise. Better way?
1549let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1550def ADJCALLSTACKUP :
1551PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1552           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1553
1554def ADJCALLSTACKDOWN :
1555PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1556           [(ARMcallseq_start timm:$amt)]>;
1557}
1558
1559// Atomic pseudo-insts which will be lowered to ldrexd/strexd loops.
1560// (These pseudos use a hand-written selection code).
1561let usesCustomInserter = 1, Defs = [CPSR], mayLoad = 1, mayStore = 1 in {
1562def ATOMOR6432   : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1563                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1564                              NoItinerary, []>;
1565def ATOMXOR6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1566                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1567                              NoItinerary, []>;
1568def ATOMADD6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1569                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1570                              NoItinerary, []>;
1571def ATOMSUB6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1572                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1573                              NoItinerary, []>;
1574def ATOMNAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1575                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1576                              NoItinerary, []>;
1577def ATOMAND6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1578                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1579                              NoItinerary, []>;
1580def ATOMSWAP6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1581                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1582                              NoItinerary, []>;
1583def ATOMCMPXCHG6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1584                                 (ins GPR:$addr, GPR:$cmp1, GPR:$cmp2,
1585                                      GPR:$set1, GPR:$set2),
1586                                 NoItinerary, []>;
1587}
1588
1589def HINT : AI<(outs), (ins imm0_255:$imm), MiscFrm, NoItinerary,
1590              "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> {
1591  bits<8> imm;
1592  let Inst{27-8} = 0b00110010000011110000;
1593  let Inst{7-0} = imm;
1594}
1595
1596def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1597def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1598def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1599def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1600def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1601
1602def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
1603             "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> {
1604  bits<4> Rd;
1605  bits<4> Rn;
1606  bits<4> Rm;
1607  let Inst{3-0} = Rm;
1608  let Inst{15-12} = Rd;
1609  let Inst{19-16} = Rn;
1610  let Inst{27-20} = 0b01101000;
1611  let Inst{7-4} = 0b1011;
1612  let Inst{11-8} = 0b1111;
1613  let Unpredictable{11-8} = 0b1111;
1614}
1615
1616// The 16-bit operand $val can be used by a debugger to store more information
1617// about the breakpoint.
1618def BKPT : AI<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
1619              "bkpt", "\t$val", []>, Requires<[IsARM]> {
1620  bits<16> val;
1621  let Inst{3-0} = val{3-0};
1622  let Inst{19-8} = val{15-4};
1623  let Inst{27-20} = 0b00010010;
1624  let Inst{7-4} = 0b0111;
1625}
1626
1627// Change Processor State
1628// FIXME: We should use InstAlias to handle the optional operands.
1629class CPS<dag iops, string asm_ops>
1630  : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
1631        []>, Requires<[IsARM]> {
1632  bits<2> imod;
1633  bits<3> iflags;
1634  bits<5> mode;
1635  bit M;
1636
1637  let Inst{31-28} = 0b1111;
1638  let Inst{27-20} = 0b00010000;
1639  let Inst{19-18} = imod;
1640  let Inst{17}    = M; // Enabled if mode is set;
1641  let Inst{16-9}  = 0b00000000;
1642  let Inst{8-6}   = iflags;
1643  let Inst{5}     = 0;
1644  let Inst{4-0}   = mode;
1645}
1646
1647let DecoderMethod = "DecodeCPSInstruction" in {
1648let M = 1 in
1649  def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode),
1650                  "$imod\t$iflags, $mode">;
1651let mode = 0, M = 0 in
1652  def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
1653
1654let imod = 0, iflags = 0, M = 1 in
1655  def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">;
1656}
1657
1658// Preload signals the memory system of possible future data/instruction access.
1659multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1660
1661  def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1662                !strconcat(opc, "\t$addr"),
1663                [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1664    bits<4> Rt;
1665    bits<17> addr;
1666    let Inst{31-26} = 0b111101;
1667    let Inst{25} = 0; // 0 for immediate form
1668    let Inst{24} = data;
1669    let Inst{23} = addr{12};        // U (add = ('U' == 1))
1670    let Inst{22} = read;
1671    let Inst{21-20} = 0b01;
1672    let Inst{19-16} = addr{16-13};  // Rn
1673    let Inst{15-12} = 0b1111;
1674    let Inst{11-0}  = addr{11-0};   // imm12
1675  }
1676
1677  def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1678               !strconcat(opc, "\t$shift"),
1679               [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1680    bits<17> shift;
1681    let Inst{31-26} = 0b111101;
1682    let Inst{25} = 1; // 1 for register form
1683    let Inst{24} = data;
1684    let Inst{23} = shift{12};    // U (add = ('U' == 1))
1685    let Inst{22} = read;
1686    let Inst{21-20} = 0b01;
1687    let Inst{19-16} = shift{16-13}; // Rn
1688    let Inst{15-12} = 0b1111;
1689    let Inst{11-0}  = shift{11-0};
1690    let Inst{4} = 0;
1691  }
1692}
1693
1694defm PLD  : APreLoad<1, 1, "pld">,  Requires<[IsARM]>;
1695defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1696defm PLI  : APreLoad<1, 0, "pli">,  Requires<[IsARM,HasV7]>;
1697
1698def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary,
1699                 "setend\t$end", []>, Requires<[IsARM]> {
1700  bits<1> end;
1701  let Inst{31-10} = 0b1111000100000001000000;
1702  let Inst{9} = end;
1703  let Inst{8-0} = 0;
1704}
1705
1706def DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1707             []>, Requires<[IsARM, HasV7]> {
1708  bits<4> opt;
1709  let Inst{27-4} = 0b001100100000111100001111;
1710  let Inst{3-0} = opt;
1711}
1712
1713// A5.4 Permanently UNDEFINED instructions.
1714let isBarrier = 1, isTerminator = 1 in
1715def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1716               "trap", [(trap)]>,
1717           Requires<[IsARM]> {
1718  let Inst = 0xe7ffdefe;
1719}
1720
1721// Address computation and loads and stores in PIC mode.
1722let isNotDuplicable = 1 in {
1723def PICADD  : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1724                            4, IIC_iALUr,
1725                            [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1726
1727let AddedComplexity = 10 in {
1728def PICLDR  : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1729                            4, IIC_iLoad_r,
1730                            [(set GPR:$dst, (load addrmodepc:$addr))]>;
1731
1732def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1733                            4, IIC_iLoad_bh_r,
1734                            [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1735
1736def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1737                            4, IIC_iLoad_bh_r,
1738                            [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1739
1740def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1741                            4, IIC_iLoad_bh_r,
1742                            [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1743
1744def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1745                            4, IIC_iLoad_bh_r,
1746                            [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1747}
1748let AddedComplexity = 10 in {
1749def PICSTR  : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1750      4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1751
1752def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1753      4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1754                                                   addrmodepc:$addr)]>;
1755
1756def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1757      4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1758}
1759} // isNotDuplicable = 1
1760
1761
1762// LEApcrel - Load a pc-relative address into a register without offending the
1763// assembler.
1764let neverHasSideEffects = 1, isReMaterializable = 1 in
1765// The 'adr' mnemonic encodes differently if the label is before or after
1766// the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1767// know until then which form of the instruction will be used.
1768def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
1769                 MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []> {
1770  bits<4> Rd;
1771  bits<14> label;
1772  let Inst{27-25} = 0b001;
1773  let Inst{24} = 0;
1774  let Inst{23-22} = label{13-12};
1775  let Inst{21} = 0;
1776  let Inst{20} = 0;
1777  let Inst{19-16} = 0b1111;
1778  let Inst{15-12} = Rd;
1779  let Inst{11-0} = label{11-0};
1780}
1781def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1782                    4, IIC_iALUi, []>;
1783
1784def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1785                      (ins i32imm:$label, nohash_imm:$id, pred:$p),
1786                      4, IIC_iALUi, []>;
1787
1788//===----------------------------------------------------------------------===//
1789//  Control Flow Instructions.
1790//
1791
1792let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1793  // ARMV4T and above
1794  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1795                  "bx", "\tlr", [(ARMretflag)]>,
1796               Requires<[IsARM, HasV4T]> {
1797    let Inst{27-0}  = 0b0001001011111111111100011110;
1798  }
1799
1800  // ARMV4 only
1801  def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1802                  "mov", "\tpc, lr", [(ARMretflag)]>,
1803               Requires<[IsARM, NoV4T]> {
1804    let Inst{27-0} = 0b0001101000001111000000001110;
1805  }
1806}
1807
1808// Indirect branches
1809let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1810  // ARMV4T and above
1811  def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1812                  [(brind GPR:$dst)]>,
1813              Requires<[IsARM, HasV4T]> {
1814    bits<4> dst;
1815    let Inst{31-4} = 0b1110000100101111111111110001;
1816    let Inst{3-0}  = dst;
1817  }
1818
1819  def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br,
1820                  "bx", "\t$dst", [/* pattern left blank */]>,
1821              Requires<[IsARM, HasV4T]> {
1822    bits<4> dst;
1823    let Inst{27-4} = 0b000100101111111111110001;
1824    let Inst{3-0}  = dst;
1825  }
1826}
1827
1828// SP is marked as a use to prevent stack-pointer assignments that appear
1829// immediately before calls from potentially appearing dead.
1830let isCall = 1,
1831  // FIXME:  Do we really need a non-predicated version? If so, it should
1832  // at least be a pseudo instruction expanding to the predicated version
1833  // at MC lowering time.
1834  Defs = [LR], Uses = [SP] in {
1835  def BL  : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1836                IIC_Br, "bl\t$func",
1837                [(ARMcall tglobaladdr:$func)]>,
1838            Requires<[IsARM]> {
1839    let Inst{31-28} = 0b1110;
1840    bits<24> func;
1841    let Inst{23-0} = func;
1842    let DecoderMethod = "DecodeBranchImmInstruction";
1843  }
1844
1845  def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1846                   IIC_Br, "bl", "\t$func",
1847                   [(ARMcall_pred tglobaladdr:$func)]>,
1848                Requires<[IsARM]> {
1849    bits<24> func;
1850    let Inst{23-0} = func;
1851    let DecoderMethod = "DecodeBranchImmInstruction";
1852  }
1853
1854  // ARMv5T and above
1855  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1856                IIC_Br, "blx\t$func",
1857                [(ARMcall GPR:$func)]>,
1858            Requires<[IsARM, HasV5T]> {
1859    bits<4> func;
1860    let Inst{31-4} = 0b1110000100101111111111110011;
1861    let Inst{3-0}  = func;
1862  }
1863
1864  def BLX_pred : AI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1865                    IIC_Br, "blx", "\t$func",
1866                    [(ARMcall_pred GPR:$func)]>,
1867                 Requires<[IsARM, HasV5T]> {
1868    bits<4> func;
1869    let Inst{27-4} = 0b000100101111111111110011;
1870    let Inst{3-0}  = func;
1871  }
1872
1873  // ARMv4T
1874  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1875  def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1876                   8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1877                   Requires<[IsARM, HasV4T]>;
1878
1879  // ARMv4
1880  def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1881                   8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1882                   Requires<[IsARM, NoV4T]>;
1883
1884  // mov lr, pc; b if callee is marked noreturn to avoid confusing the
1885  // return stack predictor.
1886  def BMOVPCB_CALL : ARMPseudoInst<(outs),
1887                                   (ins bl_target:$func, variable_ops),
1888                               8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>,
1889                      Requires<[IsARM]>;
1890}
1891
1892let isBranch = 1, isTerminator = 1 in {
1893  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1894  // a two-value operand where a dag node expects two operands. :(
1895  def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1896               IIC_Br, "b", "\t$target",
1897               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1898    bits<24> target;
1899    let Inst{23-0} = target;
1900    let DecoderMethod = "DecodeBranchImmInstruction";
1901  }
1902
1903  let isBarrier = 1 in {
1904    // B is "predicable" since it's just a Bcc with an 'always' condition.
1905    let isPredicable = 1 in
1906    // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
1907    // should be sufficient.
1908    // FIXME: Is B really a Barrier? That doesn't seem right.
1909    def B : ARMPseudoExpand<(outs), (ins br_target:$target), 4, IIC_Br,
1910                [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>;
1911
1912    let isNotDuplicable = 1, isIndirectBranch = 1 in {
1913    def BR_JTr : ARMPseudoInst<(outs),
1914                      (ins GPR:$target, i32imm:$jt, i32imm:$id),
1915                      0, IIC_Br,
1916                      [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1917    // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1918    // into i12 and rs suffixed versions.
1919    def BR_JTm : ARMPseudoInst<(outs),
1920                     (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1921                     0, IIC_Br,
1922                     [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1923                       imm:$id)]>;
1924    def BR_JTadd : ARMPseudoInst<(outs),
1925                   (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1926                   0, IIC_Br,
1927                   [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1928                     imm:$id)]>;
1929    } // isNotDuplicable = 1, isIndirectBranch = 1
1930  } // isBarrier = 1
1931
1932}
1933
1934// BLX (immediate)
1935def BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary,
1936               "blx\t$target", []>,
1937           Requires<[IsARM, HasV5T]> {
1938  let Inst{31-25} = 0b1111101;
1939  bits<25> target;
1940  let Inst{23-0} = target{24-1};
1941  let Inst{24} = target{0};
1942}
1943
1944// Branch and Exchange Jazelle
1945def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1946              [/* pattern left blank */]> {
1947  bits<4> func;
1948  let Inst{23-20} = 0b0010;
1949  let Inst{19-8} = 0xfff;
1950  let Inst{7-4} = 0b0010;
1951  let Inst{3-0} = func;
1952}
1953
1954// Tail calls.
1955
1956let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
1957  def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1958                              IIC_Br, []>;
1959
1960  def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1961                              IIC_Br, []>;
1962
1963  def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst, variable_ops),
1964                                 4, IIC_Br, [],
1965                                 (Bcc br_target:$dst, (ops 14, zero_reg))>,
1966                                 Requires<[IsARM]>;
1967
1968  def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
1969                                 4, IIC_Br, [],
1970                                 (BX GPR:$dst)>,
1971                                 Requires<[IsARM]>;
1972}
1973
1974// Secure Monitor Call is a system instruction.
1975def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt",
1976              []> {
1977  bits<4> opt;
1978  let Inst{23-4} = 0b01100000000000000111;
1979  let Inst{3-0} = opt;
1980}
1981
1982// Supervisor Call (Software Interrupt)
1983let isCall = 1, Uses = [SP] in {
1984def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> {
1985  bits<24> svc;
1986  let Inst{23-0} = svc;
1987}
1988}
1989
1990// Store Return State
1991class SRSI<bit wb, string asm>
1992  : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm,
1993       NoItinerary, asm, "", []> {
1994  bits<5> mode;
1995  let Inst{31-28} = 0b1111;
1996  let Inst{27-25} = 0b100;
1997  let Inst{22} = 1;
1998  let Inst{21} = wb;
1999  let Inst{20} = 0;
2000  let Inst{19-16} = 0b1101;  // SP
2001  let Inst{15-5} = 0b00000101000;
2002  let Inst{4-0} = mode;
2003}
2004
2005def SRSDA : SRSI<0, "srsda\tsp, $mode"> {
2006  let Inst{24-23} = 0;
2007}
2008def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> {
2009  let Inst{24-23} = 0;
2010}
2011def SRSDB : SRSI<0, "srsdb\tsp, $mode"> {
2012  let Inst{24-23} = 0b10;
2013}
2014def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> {
2015  let Inst{24-23} = 0b10;
2016}
2017def SRSIA : SRSI<0, "srsia\tsp, $mode"> {
2018  let Inst{24-23} = 0b01;
2019}
2020def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> {
2021  let Inst{24-23} = 0b01;
2022}
2023def SRSIB : SRSI<0, "srsib\tsp, $mode"> {
2024  let Inst{24-23} = 0b11;
2025}
2026def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> {
2027  let Inst{24-23} = 0b11;
2028}
2029
2030// Return From Exception
2031class RFEI<bit wb, string asm>
2032  : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm,
2033       NoItinerary, asm, "", []> {
2034  bits<4> Rn;
2035  let Inst{31-28} = 0b1111;
2036  let Inst{27-25} = 0b100;
2037  let Inst{22} = 0;
2038  let Inst{21} = wb;
2039  let Inst{20} = 1;
2040  let Inst{19-16} = Rn;
2041  let Inst{15-0} = 0xa00;
2042}
2043
2044def RFEDA : RFEI<0, "rfeda\t$Rn"> {
2045  let Inst{24-23} = 0;
2046}
2047def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> {
2048  let Inst{24-23} = 0;
2049}
2050def RFEDB : RFEI<0, "rfedb\t$Rn"> {
2051  let Inst{24-23} = 0b10;
2052}
2053def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> {
2054  let Inst{24-23} = 0b10;
2055}
2056def RFEIA : RFEI<0, "rfeia\t$Rn"> {
2057  let Inst{24-23} = 0b01;
2058}
2059def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> {
2060  let Inst{24-23} = 0b01;
2061}
2062def RFEIB : RFEI<0, "rfeib\t$Rn"> {
2063  let Inst{24-23} = 0b11;
2064}
2065def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
2066  let Inst{24-23} = 0b11;
2067}
2068
2069//===----------------------------------------------------------------------===//
2070//  Load / Store Instructions.
2071//
2072
2073// Load
2074
2075
2076defm LDR  : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
2077                    UnOpFrag<(load node:$Src)>>;
2078defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
2079                    UnOpFrag<(zextloadi8 node:$Src)>>;
2080defm STR  : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
2081                   BinOpFrag<(store node:$LHS, node:$RHS)>>;
2082defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
2083                   BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
2084
2085// Special LDR for loads from non-pc-relative constpools.
2086let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
2087    isReMaterializable = 1, isCodeGenOnly = 1 in
2088def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
2089                 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
2090                 []> {
2091  bits<4> Rt;
2092  bits<17> addr;
2093  let Inst{23}    = addr{12};     // U (add = ('U' == 1))
2094  let Inst{19-16} = 0b1111;
2095  let Inst{15-12} = Rt;
2096  let Inst{11-0}  = addr{11-0};   // imm12
2097}
2098
2099// Loads with zero extension
2100def LDRH  : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2101                  IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
2102                  [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
2103
2104// Loads with sign extension
2105def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2106                   IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
2107                   [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
2108
2109def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2110                   IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
2111                   [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
2112
2113let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
2114// Load doubleword
2115def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
2116                 (ins addrmode3:$addr), LdMiscFrm,
2117                 IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr",
2118                 []>, Requires<[IsARM, HasV5TE]>;
2119}
2120
2121// Indexed loads
2122multiclass AI2_ldridx<bit isByte, string opc,
2123                      InstrItinClass iii, InstrItinClass iir> {
2124  def _PRE_IMM  : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2125                      (ins addrmode_imm12:$addr), IndexModePre, LdFrm, iii,
2126                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2127    bits<17> addr;
2128    let Inst{25} = 0;
2129    let Inst{23} = addr{12};
2130    let Inst{19-16} = addr{16-13};
2131    let Inst{11-0} = addr{11-0};
2132    let DecoderMethod = "DecodeLDRPreImm";
2133    let AsmMatchConverter = "cvtLdWriteBackRegAddrModeImm12";
2134  }
2135
2136  def _PRE_REG  : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2137                      (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir,
2138                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2139    bits<17> addr;
2140    let Inst{25} = 1;
2141    let Inst{23} = addr{12};
2142    let Inst{19-16} = addr{16-13};
2143    let Inst{11-0} = addr{11-0};
2144    let Inst{4} = 0;
2145    let DecoderMethod = "DecodeLDRPreReg";
2146    let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
2147  }
2148
2149  def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2150                       (ins addr_offset_none:$addr, am2offset_reg:$offset),
2151                       IndexModePost, LdFrm, iir,
2152                       opc, "\t$Rt, $addr, $offset",
2153                       "$addr.base = $Rn_wb", []> {
2154     // {12}     isAdd
2155     // {11-0}   imm12/Rm
2156     bits<14> offset;
2157     bits<4> addr;
2158     let Inst{25} = 1;
2159     let Inst{23} = offset{12};
2160     let Inst{19-16} = addr;
2161     let Inst{11-0} = offset{11-0};
2162
2163    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2164   }
2165
2166   def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2167                       (ins addr_offset_none:$addr, am2offset_imm:$offset),
2168                      IndexModePost, LdFrm, iii,
2169                      opc, "\t$Rt, $addr, $offset",
2170                      "$addr.base = $Rn_wb", []> {
2171    // {12}     isAdd
2172    // {11-0}   imm12/Rm
2173    bits<14> offset;
2174    bits<4> addr;
2175    let Inst{25} = 0;
2176    let Inst{23} = offset{12};
2177    let Inst{19-16} = addr;
2178    let Inst{11-0} = offset{11-0};
2179
2180    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2181  }
2182
2183}
2184
2185let mayLoad = 1, neverHasSideEffects = 1 in {
2186// FIXME: for LDR_PRE_REG etc. the itineray should be either IIC_iLoad_ru or
2187// IIC_iLoad_siu depending on whether it the offset register is shifted.
2188defm LDR  : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>;
2189defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>;
2190}
2191
2192multiclass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> {
2193  def _PRE  : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2194                        (ins addrmode3:$addr), IndexModePre,
2195                        LdMiscFrm, itin,
2196                        opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2197    bits<14> addr;
2198    let Inst{23}    = addr{8};      // U bit
2199    let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2200    let Inst{19-16} = addr{12-9};   // Rn
2201    let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2202    let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2203    let AsmMatchConverter = "cvtLdWriteBackRegAddrMode3";
2204    let DecoderMethod = "DecodeAddrMode3Instruction";
2205  }
2206  def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2207                        (ins addr_offset_none:$addr, am3offset:$offset),
2208                        IndexModePost, LdMiscFrm, itin,
2209                        opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb",
2210                        []> {
2211    bits<10> offset;
2212    bits<4> addr;
2213    let Inst{23}    = offset{8};      // U bit
2214    let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2215    let Inst{19-16} = addr;
2216    let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2217    let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2218    let DecoderMethod = "DecodeAddrMode3Instruction";
2219  }
2220}
2221
2222let mayLoad = 1, neverHasSideEffects = 1 in {
2223defm LDRH  : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>;
2224defm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>;
2225defm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>;
2226let hasExtraDefRegAllocReq = 1 in {
2227def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
2228                          (ins addrmode3:$addr), IndexModePre,
2229                          LdMiscFrm, IIC_iLoad_d_ru,
2230                          "ldrd", "\t$Rt, $Rt2, $addr!",
2231                          "$addr.base = $Rn_wb", []> {
2232  bits<14> addr;
2233  let Inst{23}    = addr{8};      // U bit
2234  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2235  let Inst{19-16} = addr{12-9};   // Rn
2236  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2237  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2238  let DecoderMethod = "DecodeAddrMode3Instruction";
2239  let AsmMatchConverter = "cvtLdrdPre";
2240}
2241def LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
2242                          (ins addr_offset_none:$addr, am3offset:$offset),
2243                          IndexModePost, LdMiscFrm, IIC_iLoad_d_ru,
2244                          "ldrd", "\t$Rt, $Rt2, $addr, $offset",
2245                          "$addr.base = $Rn_wb", []> {
2246  bits<10> offset;
2247  bits<4> addr;
2248  let Inst{23}    = offset{8};      // U bit
2249  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2250  let Inst{19-16} = addr;
2251  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2252  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2253  let DecoderMethod = "DecodeAddrMode3Instruction";
2254}
2255} // hasExtraDefRegAllocReq = 1
2256} // mayLoad = 1, neverHasSideEffects = 1
2257
2258// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT.
2259let mayLoad = 1, neverHasSideEffects = 1 in {
2260def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2261                    (ins addr_offset_none:$addr, am2offset_reg:$offset),
2262                    IndexModePost, LdFrm, IIC_iLoad_ru,
2263                    "ldrt", "\t$Rt, $addr, $offset",
2264                    "$addr.base = $Rn_wb", []> {
2265  // {12}     isAdd
2266  // {11-0}   imm12/Rm
2267  bits<14> offset;
2268  bits<4> addr;
2269  let Inst{25} = 1;
2270  let Inst{23} = offset{12};
2271  let Inst{21} = 1; // overwrite
2272  let Inst{19-16} = addr;
2273  let Inst{11-5} = offset{11-5};
2274  let Inst{4} = 0;
2275  let Inst{3-0} = offset{3-0};
2276  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2277}
2278
2279def LDRT_POST_IMM : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2280                    (ins addr_offset_none:$addr, am2offset_imm:$offset),
2281                   IndexModePost, LdFrm, IIC_iLoad_ru,
2282                   "ldrt", "\t$Rt, $addr, $offset",
2283                   "$addr.base = $Rn_wb", []> {
2284  // {12}     isAdd
2285  // {11-0}   imm12/Rm
2286  bits<14> offset;
2287  bits<4> addr;
2288  let Inst{25} = 0;
2289  let Inst{23} = offset{12};
2290  let Inst{21} = 1; // overwrite
2291  let Inst{19-16} = addr;
2292  let Inst{11-0} = offset{11-0};
2293  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2294}
2295
2296def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2297                     (ins addr_offset_none:$addr, am2offset_reg:$offset),
2298                     IndexModePost, LdFrm, IIC_iLoad_bh_ru,
2299                     "ldrbt", "\t$Rt, $addr, $offset",
2300                     "$addr.base = $Rn_wb", []> {
2301  // {12}     isAdd
2302  // {11-0}   imm12/Rm
2303  bits<14> offset;
2304  bits<4> addr;
2305  let Inst{25} = 1;
2306  let Inst{23} = offset{12};
2307  let Inst{21} = 1; // overwrite
2308  let Inst{19-16} = addr;
2309  let Inst{11-5} = offset{11-5};
2310  let Inst{4} = 0;
2311  let Inst{3-0} = offset{3-0};
2312  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2313}
2314
2315def LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2316                     (ins addr_offset_none:$addr, am2offset_imm:$offset),
2317                    IndexModePost, LdFrm, IIC_iLoad_bh_ru,
2318                    "ldrbt", "\t$Rt, $addr, $offset",
2319                    "$addr.base = $Rn_wb", []> {
2320  // {12}     isAdd
2321  // {11-0}   imm12/Rm
2322  bits<14> offset;
2323  bits<4> addr;
2324  let Inst{25} = 0;
2325  let Inst{23} = offset{12};
2326  let Inst{21} = 1; // overwrite
2327  let Inst{19-16} = addr;
2328  let Inst{11-0} = offset{11-0};
2329  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2330}
2331
2332multiclass AI3ldrT<bits<4> op, string opc> {
2333  def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb),
2334                      (ins addr_offset_none:$addr, postidx_imm8:$offset),
2335                      IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
2336                      "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
2337    bits<9> offset;
2338    let Inst{23} = offset{8};
2339    let Inst{22} = 1;
2340    let Inst{11-8} = offset{7-4};
2341    let Inst{3-0} = offset{3-0};
2342    let AsmMatchConverter = "cvtLdExtTWriteBackImm";
2343  }
2344  def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb),
2345                      (ins addr_offset_none:$addr, postidx_reg:$Rm),
2346                      IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
2347                      "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
2348    bits<5> Rm;
2349    let Inst{23} = Rm{4};
2350    let Inst{22} = 0;
2351    let Inst{11-8} = 0;
2352    let Unpredictable{11-8} = 0b1111;
2353    let Inst{3-0} = Rm{3-0};
2354    let AsmMatchConverter = "cvtLdExtTWriteBackReg";
2355    let DecoderMethod = "DecodeLDR";
2356  }
2357}
2358
2359defm LDRSBT : AI3ldrT<0b1101, "ldrsbt">;
2360defm LDRHT  : AI3ldrT<0b1011, "ldrht">;
2361defm LDRSHT : AI3ldrT<0b1111, "ldrsht">;
2362}
2363
2364// Store
2365
2366// Stores with truncate
2367def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
2368               IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
2369               [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
2370
2371// Store doubleword
2372let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
2373def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr),
2374               StMiscFrm, IIC_iStore_d_r,
2375               "strd", "\t$Rt, $src2, $addr", []>,
2376           Requires<[IsARM, HasV5TE]> {
2377  let Inst{21} = 0;
2378}
2379
2380// Indexed stores
2381multiclass AI2_stridx<bit isByte, string opc,
2382                      InstrItinClass iii, InstrItinClass iir> {
2383  def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
2384                            (ins GPR:$Rt, addrmode_imm12:$addr), IndexModePre,
2385                            StFrm, iii,
2386                            opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2387    bits<17> addr;
2388    let Inst{25} = 0;
2389    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
2390    let Inst{19-16} = addr{16-13};  // Rn
2391    let Inst{11-0}  = addr{11-0};   // imm12
2392    let AsmMatchConverter = "cvtStWriteBackRegAddrModeImm12";
2393    let DecoderMethod = "DecodeSTRPreImm";
2394  }
2395
2396  def _PRE_REG  : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
2397                      (ins GPR:$Rt, ldst_so_reg:$addr),
2398                      IndexModePre, StFrm, iir,
2399                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2400    bits<17> addr;
2401    let Inst{25} = 1;
2402    let Inst{23}    = addr{12};    // U (add = ('U' == 1))
2403    let Inst{19-16} = addr{16-13}; // Rn
2404    let Inst{11-0}  = addr{11-0};
2405    let Inst{4}     = 0;           // Inst{4} = 0
2406    let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
2407    let DecoderMethod = "DecodeSTRPreReg";
2408  }
2409  def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
2410                (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2411                IndexModePost, StFrm, iir,
2412                opc, "\t$Rt, $addr, $offset",
2413                "$addr.base = $Rn_wb", []> {
2414     // {12}     isAdd
2415     // {11-0}   imm12/Rm
2416     bits<14> offset;
2417     bits<4> addr;
2418     let Inst{25} = 1;
2419     let Inst{23} = offset{12};
2420     let Inst{19-16} = addr;
2421     let Inst{11-0} = offset{11-0};
2422     let Inst{4} = 0;
2423
2424    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2425   }
2426
2427   def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
2428                (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2429                IndexModePost, StFrm, iii,
2430                opc, "\t$Rt, $addr, $offset",
2431                "$addr.base = $Rn_wb", []> {
2432    // {12}     isAdd
2433    // {11-0}   imm12/Rm
2434    bits<14> offset;
2435    bits<4> addr;
2436    let Inst{25} = 0;
2437    let Inst{23} = offset{12};
2438    let Inst{19-16} = addr;
2439    let Inst{11-0} = offset{11-0};
2440
2441    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2442  }
2443}
2444
2445let mayStore = 1, neverHasSideEffects = 1 in {
2446// FIXME: for STR_PRE_REG etc. the itineray should be either IIC_iStore_ru or
2447// IIC_iStore_siu depending on whether it the offset register is shifted.
2448defm STR  : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>;
2449defm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>;
2450}
2451
2452def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
2453                         am2offset_reg:$offset),
2454             (STR_POST_REG GPR:$Rt, addr_offset_none:$addr,
2455                           am2offset_reg:$offset)>;
2456def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
2457                         am2offset_imm:$offset),
2458             (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr,
2459                           am2offset_imm:$offset)>;
2460def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
2461                             am2offset_reg:$offset),
2462             (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr,
2463                            am2offset_reg:$offset)>;
2464def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
2465                             am2offset_imm:$offset),
2466             (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr,
2467                            am2offset_imm:$offset)>;
2468
2469// Pseudo-instructions for pattern matching the pre-indexed stores. We can't
2470// put the patterns on the instruction definitions directly as ISel wants
2471// the address base and offset to be separate operands, not a single
2472// complex operand like we represent the instructions themselves. The
2473// pseudos map between the two.
2474let usesCustomInserter = 1,
2475    Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in {
2476def STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2477               (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
2478               4, IIC_iStore_ru,
2479            [(set GPR:$Rn_wb,
2480                  (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
2481def STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2482               (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
2483               4, IIC_iStore_ru,
2484            [(set GPR:$Rn_wb,
2485                  (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
2486def STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2487               (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
2488               4, IIC_iStore_ru,
2489            [(set GPR:$Rn_wb,
2490                  (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
2491def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2492               (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
2493               4, IIC_iStore_ru,
2494            [(set GPR:$Rn_wb,
2495                  (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
2496def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2497               (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p),
2498               4, IIC_iStore_ru,
2499            [(set GPR:$Rn_wb,
2500                  (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
2501}
2502
2503
2504
2505def STRH_PRE  : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb),
2506                           (ins GPR:$Rt, addrmode3:$addr), IndexModePre,
2507                           StMiscFrm, IIC_iStore_bh_ru,
2508                           "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2509  bits<14> addr;
2510  let Inst{23}    = addr{8};      // U bit
2511  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2512  let Inst{19-16} = addr{12-9};   // Rn
2513  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2514  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2515  let AsmMatchConverter = "cvtStWriteBackRegAddrMode3";
2516  let DecoderMethod = "DecodeAddrMode3Instruction";
2517}
2518
2519def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb),
2520                       (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset),
2521                       IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
2522                       "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb",
2523                   [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
2524                                                      addr_offset_none:$addr,
2525                                                      am3offset:$offset))]> {
2526  bits<10> offset;
2527  bits<4> addr;
2528  let Inst{23}    = offset{8};      // U bit
2529  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2530  let Inst{19-16} = addr;
2531  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2532  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2533  let DecoderMethod = "DecodeAddrMode3Instruction";
2534}
2535
2536let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
2537def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb),
2538                          (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
2539                          IndexModePre, StMiscFrm, IIC_iStore_d_ru,
2540                          "strd", "\t$Rt, $Rt2, $addr!",
2541                          "$addr.base = $Rn_wb", []> {
2542  bits<14> addr;
2543  let Inst{23}    = addr{8};      // U bit
2544  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2545  let Inst{19-16} = addr{12-9};   // Rn
2546  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2547  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2548  let DecoderMethod = "DecodeAddrMode3Instruction";
2549  let AsmMatchConverter = "cvtStrdPre";
2550}
2551
2552def STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb),
2553                          (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr,
2554                               am3offset:$offset),
2555                          IndexModePost, StMiscFrm, IIC_iStore_d_ru,
2556                          "strd", "\t$Rt, $Rt2, $addr, $offset",
2557                          "$addr.base = $Rn_wb", []> {
2558  bits<10> offset;
2559  bits<4> addr;
2560  let Inst{23}    = offset{8};      // U bit
2561  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2562  let Inst{19-16} = addr;
2563  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2564  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2565  let DecoderMethod = "DecodeAddrMode3Instruction";
2566}
2567} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
2568
2569// STRT, STRBT, and STRHT
2570
2571def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
2572                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2573                   IndexModePost, StFrm, IIC_iStore_bh_ru,
2574                   "strbt", "\t$Rt, $addr, $offset",
2575                   "$addr.base = $Rn_wb", []> {
2576  // {12}     isAdd
2577  // {11-0}   imm12/Rm
2578  bits<14> offset;
2579  bits<4> addr;
2580  let Inst{25} = 1;
2581  let Inst{23} = offset{12};
2582  let Inst{21} = 1; // overwrite
2583  let Inst{19-16} = addr;
2584  let Inst{11-5} = offset{11-5};
2585  let Inst{4} = 0;
2586  let Inst{3-0} = offset{3-0};
2587  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2588}
2589
2590def STRBT_POST_IMM : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
2591                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2592                   IndexModePost, StFrm, IIC_iStore_bh_ru,
2593                   "strbt", "\t$Rt, $addr, $offset",
2594                   "$addr.base = $Rn_wb", []> {
2595  // {12}     isAdd
2596  // {11-0}   imm12/Rm
2597  bits<14> offset;
2598  bits<4> addr;
2599  let Inst{25} = 0;
2600  let Inst{23} = offset{12};
2601  let Inst{21} = 1; // overwrite
2602  let Inst{19-16} = addr;
2603  let Inst{11-0} = offset{11-0};
2604  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2605}
2606
2607let mayStore = 1, neverHasSideEffects = 1 in {
2608def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
2609                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2610                   IndexModePost, StFrm, IIC_iStore_ru,
2611                   "strt", "\t$Rt, $addr, $offset",
2612                   "$addr.base = $Rn_wb", []> {
2613  // {12}     isAdd
2614  // {11-0}   imm12/Rm
2615  bits<14> offset;
2616  bits<4> addr;
2617  let Inst{25} = 1;
2618  let Inst{23} = offset{12};
2619  let Inst{21} = 1; // overwrite
2620  let Inst{19-16} = addr;
2621  let Inst{11-5} = offset{11-5};
2622  let Inst{4} = 0;
2623  let Inst{3-0} = offset{3-0};
2624  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2625}
2626
2627def STRT_POST_IMM : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
2628                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2629                   IndexModePost, StFrm, IIC_iStore_ru,
2630                   "strt", "\t$Rt, $addr, $offset",
2631                   "$addr.base = $Rn_wb", []> {
2632  // {12}     isAdd
2633  // {11-0}   imm12/Rm
2634  bits<14> offset;
2635  bits<4> addr;
2636  let Inst{25} = 0;
2637  let Inst{23} = offset{12};
2638  let Inst{21} = 1; // overwrite
2639  let Inst{19-16} = addr;
2640  let Inst{11-0} = offset{11-0};
2641  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2642}
2643}
2644
2645
2646multiclass AI3strT<bits<4> op, string opc> {
2647  def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
2648                    (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset),
2649                    IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
2650                    "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
2651    bits<9> offset;
2652    let Inst{23} = offset{8};
2653    let Inst{22} = 1;
2654    let Inst{11-8} = offset{7-4};
2655    let Inst{3-0} = offset{3-0};
2656    let AsmMatchConverter = "cvtStExtTWriteBackImm";
2657  }
2658  def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
2659                      (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm),
2660                      IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
2661                      "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
2662    bits<5> Rm;
2663    let Inst{23} = Rm{4};
2664    let Inst{22} = 0;
2665    let Inst{11-8} = 0;
2666    let Inst{3-0} = Rm{3-0};
2667    let AsmMatchConverter = "cvtStExtTWriteBackReg";
2668  }
2669}
2670
2671
2672defm STRHT : AI3strT<0b1011, "strht">;
2673
2674
2675//===----------------------------------------------------------------------===//
2676//  Load / store multiple Instructions.
2677//
2678
2679multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f,
2680                         InstrItinClass itin, InstrItinClass itin_upd> {
2681  // IA is the default, so no need for an explicit suffix on the
2682  // mnemonic here. Without it is the canonical spelling.
2683  def IA :
2684    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2685         IndexModeNone, f, itin,
2686         !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> {
2687    let Inst{24-23} = 0b01;       // Increment After
2688    let Inst{22}    = P_bit;
2689    let Inst{21}    = 0;          // No writeback
2690    let Inst{20}    = L_bit;
2691  }
2692  def IA_UPD :
2693    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2694         IndexModeUpd, f, itin_upd,
2695         !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2696    let Inst{24-23} = 0b01;       // Increment After
2697    let Inst{22}    = P_bit;
2698    let Inst{21}    = 1;          // Writeback
2699    let Inst{20}    = L_bit;
2700
2701    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2702  }
2703  def DA :
2704    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2705         IndexModeNone, f, itin,
2706         !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> {
2707    let Inst{24-23} = 0b00;       // Decrement After
2708    let Inst{22}    = P_bit;
2709    let Inst{21}    = 0;          // No writeback
2710    let Inst{20}    = L_bit;
2711  }
2712  def DA_UPD :
2713    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2714         IndexModeUpd, f, itin_upd,
2715         !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2716    let Inst{24-23} = 0b00;       // Decrement After
2717    let Inst{22}    = P_bit;
2718    let Inst{21}    = 1;          // Writeback
2719    let Inst{20}    = L_bit;
2720
2721    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2722  }
2723  def DB :
2724    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2725         IndexModeNone, f, itin,
2726         !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> {
2727    let Inst{24-23} = 0b10;       // Decrement Before
2728    let Inst{22}    = P_bit;
2729    let Inst{21}    = 0;          // No writeback
2730    let Inst{20}    = L_bit;
2731  }
2732  def DB_UPD :
2733    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2734         IndexModeUpd, f, itin_upd,
2735         !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2736    let Inst{24-23} = 0b10;       // Decrement Before
2737    let Inst{22}    = P_bit;
2738    let Inst{21}    = 1;          // Writeback
2739    let Inst{20}    = L_bit;
2740
2741    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2742  }
2743  def IB :
2744    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2745         IndexModeNone, f, itin,
2746         !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> {
2747    let Inst{24-23} = 0b11;       // Increment Before
2748    let Inst{22}    = P_bit;
2749    let Inst{21}    = 0;          // No writeback
2750    let Inst{20}    = L_bit;
2751  }
2752  def IB_UPD :
2753    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2754         IndexModeUpd, f, itin_upd,
2755         !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2756    let Inst{24-23} = 0b11;       // Increment Before
2757    let Inst{22}    = P_bit;
2758    let Inst{21}    = 1;          // Writeback
2759    let Inst{20}    = L_bit;
2760
2761    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2762  }
2763}
2764
2765let neverHasSideEffects = 1 in {
2766
2767let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
2768defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
2769                         IIC_iLoad_mu>;
2770
2771let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
2772defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m,
2773                         IIC_iStore_mu>;
2774
2775} // neverHasSideEffects
2776
2777// FIXME: remove when we have a way to marking a MI with these properties.
2778// FIXME: Should pc be an implicit operand like PICADD, etc?
2779let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2780    hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2781def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2782                                                 reglist:$regs, variable_ops),
2783                     4, IIC_iLoad_mBr, [],
2784                     (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
2785      RegConstraint<"$Rn = $wb">;
2786
2787let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
2788defm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m,
2789                               IIC_iLoad_mu>;
2790
2791let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
2792defm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m,
2793                               IIC_iStore_mu>;
2794
2795
2796
2797//===----------------------------------------------------------------------===//
2798//  Move Instructions.
2799//
2800
2801let neverHasSideEffects = 1 in
2802def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
2803                "mov", "\t$Rd, $Rm", []>, UnaryDP {
2804  bits<4> Rd;
2805  bits<4> Rm;
2806
2807  let Inst{19-16} = 0b0000;
2808  let Inst{11-4} = 0b00000000;
2809  let Inst{25} = 0;
2810  let Inst{3-0} = Rm;
2811  let Inst{15-12} = Rd;
2812}
2813
2814def : ARMInstAlias<"movs${p} $Rd, $Rm",
2815                   (MOVr GPR:$Rd, GPR:$Rm, pred:$p, CPSR)>;
2816
2817// A version for the smaller set of tail call registers.
2818let neverHasSideEffects = 1 in
2819def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
2820                IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
2821  bits<4> Rd;
2822  bits<4> Rm;
2823
2824  let Inst{11-4} = 0b00000000;
2825  let Inst{25} = 0;
2826  let Inst{3-0} = Rm;
2827  let Inst{15-12} = Rd;
2828}
2829
2830def MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src),
2831                DPSoRegRegFrm, IIC_iMOVsr,
2832                "mov", "\t$Rd, $src",
2833                [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP {
2834  bits<4> Rd;
2835  bits<12> src;
2836  let Inst{15-12} = Rd;
2837  let Inst{19-16} = 0b0000;
2838  let Inst{11-8} = src{11-8};
2839  let Inst{7} = 0;
2840  let Inst{6-5} = src{6-5};
2841  let Inst{4} = 1;
2842  let Inst{3-0} = src{3-0};
2843  let Inst{25} = 0;
2844}
2845
2846def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src),
2847                DPSoRegImmFrm, IIC_iMOVsr,
2848                "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>,
2849                UnaryDP {
2850  bits<4> Rd;
2851  bits<12> src;
2852  let Inst{15-12} = Rd;
2853  let Inst{19-16} = 0b0000;
2854  let Inst{11-5} = src{11-5};
2855  let Inst{4} = 0;
2856  let Inst{3-0} = src{3-0};
2857  let Inst{25} = 0;
2858}
2859
2860let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2861def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
2862                "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
2863  bits<4> Rd;
2864  bits<12> imm;
2865  let Inst{25} = 1;
2866  let Inst{15-12} = Rd;
2867  let Inst{19-16} = 0b0000;
2868  let Inst{11-0} = imm;
2869}
2870
2871let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2872def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm),
2873                 DPFrm, IIC_iMOVi,
2874                 "movw", "\t$Rd, $imm",
2875                 [(set GPR:$Rd, imm0_65535:$imm)]>,
2876                 Requires<[IsARM, HasV6T2]>, UnaryDP {
2877  bits<4> Rd;
2878  bits<16> imm;
2879  let Inst{15-12} = Rd;
2880  let Inst{11-0}  = imm{11-0};
2881  let Inst{19-16} = imm{15-12};
2882  let Inst{20} = 0;
2883  let Inst{25} = 1;
2884  let DecoderMethod = "DecodeArmMOVTWInstruction";
2885}
2886
2887def : InstAlias<"mov${p} $Rd, $imm",
2888                (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p)>,
2889        Requires<[IsARM]>;
2890
2891def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2892                                (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2893
2894let Constraints = "$src = $Rd" in {
2895def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd),
2896                  (ins GPR:$src, imm0_65535_expr:$imm),
2897                  DPFrm, IIC_iMOVi,
2898                  "movt", "\t$Rd, $imm",
2899                  [(set GPRnopc:$Rd,
2900                        (or (and GPR:$src, 0xffff),
2901                            lo16AllZero:$imm))]>, UnaryDP,
2902                  Requires<[IsARM, HasV6T2]> {
2903  bits<4> Rd;
2904  bits<16> imm;
2905  let Inst{15-12} = Rd;
2906  let Inst{11-0}  = imm{11-0};
2907  let Inst{19-16} = imm{15-12};
2908  let Inst{20} = 0;
2909  let Inst{25} = 1;
2910  let DecoderMethod = "DecodeArmMOVTWInstruction";
2911}
2912
2913def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2914                      (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2915
2916} // Constraints
2917
2918def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2919      Requires<[IsARM, HasV6T2]>;
2920
2921let Uses = [CPSR] in
2922def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2923                    [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2924                    Requires<[IsARM]>;
2925
2926// These aren't really mov instructions, but we have to define them this way
2927// due to flag operands.
2928
2929let Defs = [CPSR] in {
2930def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2931                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2932                      Requires<[IsARM]>;
2933def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2934                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2935                      Requires<[IsARM]>;
2936}
2937
2938//===----------------------------------------------------------------------===//
2939//  Extend Instructions.
2940//
2941
2942// Sign extenders
2943
2944def SXTB  : AI_ext_rrot<0b01101010,
2945                         "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2946def SXTH  : AI_ext_rrot<0b01101011,
2947                         "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2948
2949def SXTAB : AI_exta_rrot<0b01101010,
2950               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2951def SXTAH : AI_exta_rrot<0b01101011,
2952               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2953
2954def SXTB16  : AI_ext_rrot_np<0b01101000, "sxtb16">;
2955
2956def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2957
2958// Zero extenders
2959
2960let AddedComplexity = 16 in {
2961def UXTB   : AI_ext_rrot<0b01101110,
2962                          "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2963def UXTH   : AI_ext_rrot<0b01101111,
2964                          "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2965def UXTB16 : AI_ext_rrot<0b01101100,
2966                          "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2967
2968// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2969//        The transformation should probably be done as a combiner action
2970//        instead so we can include a check for masking back in the upper
2971//        eight bits of the source into the lower eight bits of the result.
2972//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2973//               (UXTB16r_rot GPR:$Src, 3)>;
2974def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2975               (UXTB16 GPR:$Src, 1)>;
2976
2977def UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2978                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2979def UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2980                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2981}
2982
2983// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2984def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2985
2986
2987def SBFX  : I<(outs GPRnopc:$Rd),
2988              (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width),
2989               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
2990               "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2991               Requires<[IsARM, HasV6T2]> {
2992  bits<4> Rd;
2993  bits<4> Rn;
2994  bits<5> lsb;
2995  bits<5> width;
2996  let Inst{27-21} = 0b0111101;
2997  let Inst{6-4}   = 0b101;
2998  let Inst{20-16} = width;
2999  let Inst{15-12} = Rd;
3000  let Inst{11-7}  = lsb;
3001  let Inst{3-0}   = Rn;
3002}
3003
3004def UBFX  : I<(outs GPR:$Rd),
3005              (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
3006               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3007               "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
3008               Requires<[IsARM, HasV6T2]> {
3009  bits<4> Rd;
3010  bits<4> Rn;
3011  bits<5> lsb;
3012  bits<5> width;
3013  let Inst{27-21} = 0b0111111;
3014  let Inst{6-4}   = 0b101;
3015  let Inst{20-16} = width;
3016  let Inst{15-12} = Rd;
3017  let Inst{11-7}  = lsb;
3018  let Inst{3-0}   = Rn;
3019}
3020
3021//===----------------------------------------------------------------------===//
3022//  Arithmetic Instructions.
3023//
3024
3025defm ADD  : AsI1_bin_irs<0b0100, "add",
3026                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3027                         BinOpFrag<(add  node:$LHS, node:$RHS)>, "ADD", 1>;
3028defm SUB  : AsI1_bin_irs<0b0010, "sub",
3029                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3030                         BinOpFrag<(sub  node:$LHS, node:$RHS)>, "SUB">;
3031
3032// ADD and SUB with 's' bit set.
3033//
3034// Currently, ADDS/SUBS are pseudo opcodes that exist only in the
3035// selection DAG. They are "lowered" to real ADD/SUB opcodes by
3036// AdjustInstrPostInstrSelection where we determine whether or not to
3037// set the "s" bit based on CPSR liveness.
3038//
3039// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
3040// support for an optional CPSR definition that corresponds to the DAG
3041// node's second value. We can then eliminate the implicit def of CPSR.
3042defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3043                           BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
3044defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3045                           BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
3046
3047defm ADC : AI1_adde_sube_irs<0b0101, "adc",
3048                  BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>,
3049                          "ADC", 1>;
3050defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
3051                  BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>,
3052                          "SBC">;
3053
3054defm RSB  : AsI1_rbin_irs <0b0011, "rsb",
3055                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3056                         BinOpFrag<(sub node:$LHS, node:$RHS)>, "RSB">;
3057
3058// FIXME: Eliminate them if we can write def : Pat patterns which defines
3059// CPSR and the implicit def of CPSR is not needed.
3060defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3061                           BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
3062
3063defm RSC : AI1_rsc_irs<0b0111, "rsc",
3064                  BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>,
3065                       "RSC">;
3066
3067// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
3068// The assume-no-carry-in form uses the negation of the input since add/sub
3069// assume opposite meanings of the carry flag (i.e., carry == !borrow).
3070// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
3071// details.
3072def : ARMPat<(add     GPR:$src, so_imm_neg:$imm),
3073             (SUBri   GPR:$src, so_imm_neg:$imm)>;
3074def : ARMPat<(ARMaddc GPR:$src, so_imm_neg:$imm),
3075             (SUBSri  GPR:$src, so_imm_neg:$imm)>;
3076
3077// The with-carry-in form matches bitwise not instead of the negation.
3078// Effectively, the inverse interpretation of the carry flag already accounts
3079// for part of the negation.
3080def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR),
3081             (SBCri   GPR:$src, so_imm_not:$imm)>;
3082
3083// Note: These are implemented in C++ code, because they have to generate
3084// ADD/SUBrs instructions, which use a complex pattern that a xform function
3085// cannot produce.
3086// (mul X, 2^n+1) -> (add (X << n), X)
3087// (mul X, 2^n-1) -> (rsb X, (X << n))
3088
3089// ARM Arithmetic Instruction
3090// GPR:$dst = GPR:$a op GPR:$b
3091class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
3092          list<dag> pattern = [],
3093          dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm),
3094          string asm = "\t$Rd, $Rn, $Rm">
3095  : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
3096  bits<4> Rn;
3097  bits<4> Rd;
3098  bits<4> Rm;
3099  let Inst{27-20} = op27_20;
3100  let Inst{11-4} = op11_4;
3101  let Inst{19-16} = Rn;
3102  let Inst{15-12} = Rd;
3103  let Inst{3-0}   = Rm;
3104
3105  let Unpredictable{11-8} = 0b1111;
3106}
3107
3108// Saturating add/subtract
3109
3110def QADD    : AAI<0b00010000, 0b00000101, "qadd",
3111                  [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))],
3112                  (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
3113def QSUB    : AAI<0b00010010, 0b00000101, "qsub",
3114                  [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))],
3115                  (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
3116def QDADD   : AAI<0b00010100, 0b00000101, "qdadd", [],
3117                  (ins GPRnopc:$Rm, GPRnopc:$Rn),
3118                  "\t$Rd, $Rm, $Rn">;
3119def QDSUB   : AAI<0b00010110, 0b00000101, "qdsub", [],
3120                  (ins GPRnopc:$Rm, GPRnopc:$Rn),
3121                  "\t$Rd, $Rm, $Rn">;
3122
3123def QADD16  : AAI<0b01100010, 0b11110001, "qadd16">;
3124def QADD8   : AAI<0b01100010, 0b11111001, "qadd8">;
3125def QASX    : AAI<0b01100010, 0b11110011, "qasx">;
3126def QSAX    : AAI<0b01100010, 0b11110101, "qsax">;
3127def QSUB16  : AAI<0b01100010, 0b11110111, "qsub16">;
3128def QSUB8   : AAI<0b01100010, 0b11111111, "qsub8">;
3129def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
3130def UQADD8  : AAI<0b01100110, 0b11111001, "uqadd8">;
3131def UQASX   : AAI<0b01100110, 0b11110011, "uqasx">;
3132def UQSAX   : AAI<0b01100110, 0b11110101, "uqsax">;
3133def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
3134def UQSUB8  : AAI<0b01100110, 0b11111111, "uqsub8">;
3135
3136// Signed/Unsigned add/subtract
3137
3138def SASX   : AAI<0b01100001, 0b11110011, "sasx">;
3139def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
3140def SADD8  : AAI<0b01100001, 0b11111001, "sadd8">;
3141def SSAX   : AAI<0b01100001, 0b11110101, "ssax">;
3142def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
3143def SSUB8  : AAI<0b01100001, 0b11111111, "ssub8">;
3144def UASX   : AAI<0b01100101, 0b11110011, "uasx">;
3145def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
3146def UADD8  : AAI<0b01100101, 0b11111001, "uadd8">;
3147def USAX   : AAI<0b01100101, 0b11110101, "usax">;
3148def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
3149def USUB8  : AAI<0b01100101, 0b11111111, "usub8">;
3150
3151// Signed/Unsigned halving add/subtract
3152
3153def SHASX   : AAI<0b01100011, 0b11110011, "shasx">;
3154def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
3155def SHADD8  : AAI<0b01100011, 0b11111001, "shadd8">;
3156def SHSAX   : AAI<0b01100011, 0b11110101, "shsax">;
3157def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
3158def SHSUB8  : AAI<0b01100011, 0b11111111, "shsub8">;
3159def UHASX   : AAI<0b01100111, 0b11110011, "uhasx">;
3160def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
3161def UHADD8  : AAI<0b01100111, 0b11111001, "uhadd8">;
3162def UHSAX   : AAI<0b01100111, 0b11110101, "uhsax">;
3163def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
3164def UHSUB8  : AAI<0b01100111, 0b11111111, "uhsub8">;
3165
3166// Unsigned Sum of Absolute Differences [and Accumulate].
3167
3168def USAD8  : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3169                MulFrm /* for convenience */, NoItinerary, "usad8",
3170                "\t$Rd, $Rn, $Rm", []>,
3171             Requires<[IsARM, HasV6]> {
3172  bits<4> Rd;
3173  bits<4> Rn;
3174  bits<4> Rm;
3175  let Inst{27-20} = 0b01111000;
3176  let Inst{15-12} = 0b1111;
3177  let Inst{7-4} = 0b0001;
3178  let Inst{19-16} = Rd;
3179  let Inst{11-8} = Rm;
3180  let Inst{3-0} = Rn;
3181}
3182def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3183                MulFrm /* for convenience */, NoItinerary, "usada8",
3184                "\t$Rd, $Rn, $Rm, $Ra", []>,
3185             Requires<[IsARM, HasV6]> {
3186  bits<4> Rd;
3187  bits<4> Rn;
3188  bits<4> Rm;
3189  bits<4> Ra;
3190  let Inst{27-20} = 0b01111000;
3191  let Inst{7-4} = 0b0001;
3192  let Inst{19-16} = Rd;
3193  let Inst{15-12} = Ra;
3194  let Inst{11-8} = Rm;
3195  let Inst{3-0} = Rn;
3196}
3197
3198// Signed/Unsigned saturate
3199
3200def SSAT : AI<(outs GPRnopc:$Rd),
3201              (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
3202              SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
3203  bits<4> Rd;
3204  bits<5> sat_imm;
3205  bits<4> Rn;
3206  bits<8> sh;
3207  let Inst{27-21} = 0b0110101;
3208  let Inst{5-4} = 0b01;
3209  let Inst{20-16} = sat_imm;
3210  let Inst{15-12} = Rd;
3211  let Inst{11-7} = sh{4-0};
3212  let Inst{6} = sh{5};
3213  let Inst{3-0} = Rn;
3214}
3215
3216def SSAT16 : AI<(outs GPRnopc:$Rd),
3217                (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm,
3218                NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
3219  bits<4> Rd;
3220  bits<4> sat_imm;
3221  bits<4> Rn;
3222  let Inst{27-20} = 0b01101010;
3223  let Inst{11-4} = 0b11110011;
3224  let Inst{15-12} = Rd;
3225  let Inst{19-16} = sat_imm;
3226  let Inst{3-0} = Rn;
3227}
3228
3229def USAT : AI<(outs GPRnopc:$Rd),
3230              (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
3231              SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
3232  bits<4> Rd;
3233  bits<5> sat_imm;
3234  bits<4> Rn;
3235  bits<8> sh;
3236  let Inst{27-21} = 0b0110111;
3237  let Inst{5-4} = 0b01;
3238  let Inst{15-12} = Rd;
3239  let Inst{11-7} = sh{4-0};
3240  let Inst{6} = sh{5};
3241  let Inst{20-16} = sat_imm;
3242  let Inst{3-0} = Rn;
3243}
3244
3245def USAT16 : AI<(outs GPRnopc:$Rd),
3246                (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm,
3247                NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> {
3248  bits<4> Rd;
3249  bits<4> sat_imm;
3250  bits<4> Rn;
3251  let Inst{27-20} = 0b01101110;
3252  let Inst{11-4} = 0b11110011;
3253  let Inst{15-12} = Rd;
3254  let Inst{19-16} = sat_imm;
3255  let Inst{3-0} = Rn;
3256}
3257
3258def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm:$pos),
3259               (SSAT imm:$pos, GPRnopc:$a, 0)>;
3260def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm:$pos),
3261               (USAT imm:$pos, GPRnopc:$a, 0)>;
3262
3263//===----------------------------------------------------------------------===//
3264//  Bitwise Instructions.
3265//
3266
3267defm AND   : AsI1_bin_irs<0b0000, "and",
3268                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3269                          BinOpFrag<(and node:$LHS, node:$RHS)>, "AND", 1>;
3270defm ORR   : AsI1_bin_irs<0b1100, "orr",
3271                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3272                          BinOpFrag<(or  node:$LHS, node:$RHS)>, "ORR", 1>;
3273defm EOR   : AsI1_bin_irs<0b0001, "eor",
3274                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3275                          BinOpFrag<(xor node:$LHS, node:$RHS)>, "EOR", 1>;
3276defm BIC   : AsI1_bin_irs<0b1110, "bic",
3277                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3278                          BinOpFrag<(and node:$LHS, (not node:$RHS))>, "BIC">;
3279
3280// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just
3281// like in the actual instruction encoding. The complexity of mapping the mask
3282// to the lsb/msb pair should be handled by ISel, not encapsulated in the
3283// instruction description.
3284def BFC    : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
3285               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3286               "bfc", "\t$Rd, $imm", "$src = $Rd",
3287               [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
3288               Requires<[IsARM, HasV6T2]> {
3289  bits<4> Rd;
3290  bits<10> imm;
3291  let Inst{27-21} = 0b0111110;
3292  let Inst{6-0}   = 0b0011111;
3293  let Inst{15-12} = Rd;
3294  let Inst{11-7}  = imm{4-0}; // lsb
3295  let Inst{20-16} = imm{9-5}; // msb
3296}
3297
3298// A8.6.18  BFI - Bitfield insert (Encoding A1)
3299def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
3300          AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3301          "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
3302          [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn,
3303                           bf_inv_mask_imm:$imm))]>,
3304          Requires<[IsARM, HasV6T2]> {
3305  bits<4> Rd;
3306  bits<4> Rn;
3307  bits<10> imm;
3308  let Inst{27-21} = 0b0111110;
3309  let Inst{6-4}   = 0b001; // Rn: Inst{3-0} != 15
3310  let Inst{15-12} = Rd;
3311  let Inst{11-7}  = imm{4-0}; // lsb
3312  let Inst{20-16} = imm{9-5}; // width
3313  let Inst{3-0}   = Rn;
3314}
3315
3316def  MVNr  : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
3317                  "mvn", "\t$Rd, $Rm",
3318                  [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
3319  bits<4> Rd;
3320  bits<4> Rm;
3321  let Inst{25} = 0;
3322  let Inst{19-16} = 0b0000;
3323  let Inst{11-4} = 0b00000000;
3324  let Inst{15-12} = Rd;
3325  let Inst{3-0} = Rm;
3326}
3327def  MVNsi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift),
3328                  DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
3329                  [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP {
3330  bits<4> Rd;
3331  bits<12> shift;
3332  let Inst{25} = 0;
3333  let Inst{19-16} = 0b0000;
3334  let Inst{15-12} = Rd;
3335  let Inst{11-5} = shift{11-5};
3336  let Inst{4} = 0;
3337  let Inst{3-0} = shift{3-0};
3338}
3339def  MVNsr  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift),
3340                  DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
3341                  [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP {
3342  bits<4> Rd;
3343  bits<12> shift;
3344  let Inst{25} = 0;
3345  let Inst{19-16} = 0b0000;
3346  let Inst{15-12} = Rd;
3347  let Inst{11-8} = shift{11-8};
3348  let Inst{7} = 0;
3349  let Inst{6-5} = shift{6-5};
3350  let Inst{4} = 1;
3351  let Inst{3-0} = shift{3-0};
3352}
3353let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
3354def  MVNi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
3355                  IIC_iMVNi, "mvn", "\t$Rd, $imm",
3356                  [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
3357  bits<4> Rd;
3358  bits<12> imm;
3359  let Inst{25} = 1;
3360  let Inst{19-16} = 0b0000;
3361  let Inst{15-12} = Rd;
3362  let Inst{11-0} = imm;
3363}
3364
3365def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
3366             (BICri GPR:$src, so_imm_not:$imm)>;
3367
3368//===----------------------------------------------------------------------===//
3369//  Multiply Instructions.
3370//
3371class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
3372             string opc, string asm, list<dag> pattern>
3373  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
3374  bits<4> Rd;
3375  bits<4> Rm;
3376  bits<4> Rn;
3377  let Inst{19-16} = Rd;
3378  let Inst{11-8}  = Rm;
3379  let Inst{3-0}   = Rn;
3380}
3381class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
3382             string opc, string asm, list<dag> pattern>
3383  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
3384  bits<4> RdLo;
3385  bits<4> RdHi;
3386  bits<4> Rm;
3387  bits<4> Rn;
3388  let Inst{19-16} = RdHi;
3389  let Inst{15-12} = RdLo;
3390  let Inst{11-8}  = Rm;
3391  let Inst{3-0}   = Rn;
3392}
3393
3394// FIXME: The v5 pseudos are only necessary for the additional Constraint
3395//        property. Remove them when it's possible to add those properties
3396//        on an individual MachineInstr, not just an instruction description.
3397let isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in {
3398def MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd),
3399                    (ins GPRnopc:$Rn, GPRnopc:$Rm),
3400                    IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
3401                  [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>,
3402                  Requires<[IsARM, HasV6]> {
3403  let Inst{15-12} = 0b0000;
3404  let Unpredictable{15-12} = 0b1111;
3405}
3406
3407let Constraints = "@earlyclobber $Rd" in
3408def MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm,
3409                                                    pred:$p, cc_out:$s),
3410                           4, IIC_iMUL32,
3411               [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))],
3412               (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>,
3413               Requires<[IsARM, NoV6]>;
3414}
3415
3416def MLA  : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3417                     IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
3418                   [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
3419                   Requires<[IsARM, HasV6]> {
3420  bits<4> Ra;
3421  let Inst{15-12} = Ra;
3422}
3423
3424let Constraints = "@earlyclobber $Rd" in
3425def MLAv5: ARMPseudoExpand<(outs GPR:$Rd),
3426                           (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
3427                           4, IIC_iMAC32,
3428                        [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))],
3429                  (MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>,
3430                        Requires<[IsARM, NoV6]>;
3431
3432def MLS  : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3433                   IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
3434                   [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
3435                   Requires<[IsARM, HasV6T2]> {
3436  bits<4> Rd;
3437  bits<4> Rm;
3438  bits<4> Rn;
3439  bits<4> Ra;
3440  let Inst{19-16} = Rd;
3441  let Inst{15-12} = Ra;
3442  let Inst{11-8}  = Rm;
3443  let Inst{3-0}   = Rn;
3444}
3445
3446// Extra precision multiplies with low / high results
3447let neverHasSideEffects = 1 in {
3448let isCommutable = 1 in {
3449def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
3450                                 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
3451                    "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3452                    Requires<[IsARM, HasV6]>;
3453
3454def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
3455                                 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
3456                    "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3457                    Requires<[IsARM, HasV6]>;
3458
3459let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
3460def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3461                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3462                            4, IIC_iMUL64, [],
3463          (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3464                           Requires<[IsARM, NoV6]>;
3465
3466def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3467                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3468                            4, IIC_iMUL64, [],
3469          (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3470                           Requires<[IsARM, NoV6]>;
3471}
3472}
3473
3474// Multiply + accumulate
3475def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
3476                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3477                    "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3478                    Requires<[IsARM, HasV6]>;
3479def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
3480                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3481                    "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3482                    Requires<[IsARM, HasV6]>;
3483
3484def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
3485                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3486                    "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3487                    Requires<[IsARM, HasV6]> {
3488  bits<4> RdLo;
3489  bits<4> RdHi;
3490  bits<4> Rm;
3491  bits<4> Rn;
3492  let Inst{19-16} = RdHi;
3493  let Inst{15-12} = RdLo;
3494  let Inst{11-8}  = Rm;
3495  let Inst{3-0}   = Rn;
3496}
3497
3498let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
3499def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3500                              (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3501                              4, IIC_iMAC64, [],
3502          (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3503                           Requires<[IsARM, NoV6]>;
3504def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3505                              (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3506                              4, IIC_iMAC64, [],
3507          (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3508                           Requires<[IsARM, NoV6]>;
3509def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3510                              (ins GPR:$Rn, GPR:$Rm, pred:$p),
3511                              4, IIC_iMAC64, [],
3512          (UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>,
3513                           Requires<[IsARM, NoV6]>;
3514}
3515
3516} // neverHasSideEffects
3517
3518// Most significant word multiply
3519def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3520               IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
3521               [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
3522            Requires<[IsARM, HasV6]> {
3523  let Inst{15-12} = 0b1111;
3524}
3525
3526def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3527               IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", []>,
3528            Requires<[IsARM, HasV6]> {
3529  let Inst{15-12} = 0b1111;
3530}
3531
3532def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
3533               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3534               IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
3535               [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
3536            Requires<[IsARM, HasV6]>;
3537
3538def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
3539               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3540               IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>,
3541            Requires<[IsARM, HasV6]>;
3542
3543def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
3544               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3545               IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>,
3546            Requires<[IsARM, HasV6]>;
3547
3548def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
3549               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3550               IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>,
3551            Requires<[IsARM, HasV6]>;
3552
3553multiclass AI_smul<string opc, PatFrag opnode> {
3554  def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3555              IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
3556              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
3557                                      (sext_inreg GPR:$Rm, i16)))]>,
3558           Requires<[IsARM, HasV5TE]>;
3559
3560  def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3561              IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
3562              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
3563                                      (sra GPR:$Rm, (i32 16))))]>,
3564           Requires<[IsARM, HasV5TE]>;
3565
3566  def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3567              IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
3568              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
3569                                      (sext_inreg GPR:$Rm, i16)))]>,
3570           Requires<[IsARM, HasV5TE]>;
3571
3572  def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3573              IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
3574              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
3575                                      (sra GPR:$Rm, (i32 16))))]>,
3576            Requires<[IsARM, HasV5TE]>;
3577
3578  def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3579              IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
3580              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
3581                                    (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
3582           Requires<[IsARM, HasV5TE]>;
3583
3584  def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3585              IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
3586              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
3587                                    (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
3588            Requires<[IsARM, HasV5TE]>;
3589}
3590
3591
3592multiclass AI_smla<string opc, PatFrag opnode> {
3593  let DecoderMethod = "DecodeSMLAInstruction" in {
3594  def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd),
3595              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3596              IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
3597              [(set GPRnopc:$Rd, (add GPR:$Ra,
3598                               (opnode (sext_inreg GPRnopc:$Rn, i16),
3599                                       (sext_inreg GPRnopc:$Rm, i16))))]>,
3600           Requires<[IsARM, HasV5TE]>;
3601
3602  def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd),
3603              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3604              IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
3605              [(set GPRnopc:$Rd,
3606                    (add GPR:$Ra, (opnode (sext_inreg GPRnopc:$Rn, i16),
3607                                          (sra GPRnopc:$Rm, (i32 16)))))]>,
3608           Requires<[IsARM, HasV5TE]>;
3609
3610  def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd),
3611              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3612              IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
3613              [(set GPRnopc:$Rd,
3614                    (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)),
3615                                          (sext_inreg GPRnopc:$Rm, i16))))]>,
3616           Requires<[IsARM, HasV5TE]>;
3617
3618  def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd),
3619              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3620              IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
3621             [(set GPRnopc:$Rd,
3622                   (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)),
3623                                         (sra GPRnopc:$Rm, (i32 16)))))]>,
3624            Requires<[IsARM, HasV5TE]>;
3625
3626  def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd),
3627              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3628              IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
3629              [(set GPRnopc:$Rd,
3630                    (add GPR:$Ra, (sra (opnode GPRnopc:$Rn,
3631                                  (sext_inreg GPRnopc:$Rm, i16)), (i32 16))))]>,
3632           Requires<[IsARM, HasV5TE]>;
3633
3634  def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd),
3635              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3636              IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
3637              [(set GPRnopc:$Rd,
3638                 (add GPR:$Ra, (sra (opnode GPRnopc:$Rn,
3639                                    (sra GPRnopc:$Rm, (i32 16))), (i32 16))))]>,
3640            Requires<[IsARM, HasV5TE]>;
3641  }
3642}
3643
3644defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
3645defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
3646
3647// Halfword multiply accumulate long: SMLAL<x><y>.
3648def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3649                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3650                      IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3651              Requires<[IsARM, HasV5TE]>;
3652
3653def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3654                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3655                      IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3656              Requires<[IsARM, HasV5TE]>;
3657
3658def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3659                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3660                      IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3661              Requires<[IsARM, HasV5TE]>;
3662
3663def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3664                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3665                      IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3666              Requires<[IsARM, HasV5TE]>;
3667
3668// Helper class for AI_smld.
3669class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
3670                    InstrItinClass itin, string opc, string asm>
3671  : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
3672  bits<4> Rn;
3673  bits<4> Rm;
3674  let Inst{27-23} = 0b01110;
3675  let Inst{22}    = long;
3676  let Inst{21-20} = 0b00;
3677  let Inst{11-8}  = Rm;
3678  let Inst{7}     = 0;
3679  let Inst{6}     = sub;
3680  let Inst{5}     = swap;
3681  let Inst{4}     = 1;
3682  let Inst{3-0}   = Rn;
3683}
3684class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
3685                InstrItinClass itin, string opc, string asm>
3686  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3687  bits<4> Rd;
3688  let Inst{15-12} = 0b1111;
3689  let Inst{19-16} = Rd;
3690}
3691class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
3692                InstrItinClass itin, string opc, string asm>
3693  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3694  bits<4> Ra;
3695  bits<4> Rd;
3696  let Inst{19-16} = Rd;
3697  let Inst{15-12} = Ra;
3698}
3699class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
3700                  InstrItinClass itin, string opc, string asm>
3701  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3702  bits<4> RdLo;
3703  bits<4> RdHi;
3704  let Inst{19-16} = RdHi;
3705  let Inst{15-12} = RdLo;
3706}
3707
3708multiclass AI_smld<bit sub, string opc> {
3709
3710  def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd),
3711                  (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3712                  NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
3713
3714  def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd),
3715                  (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3716                  NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
3717
3718  def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3719                  (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary,
3720                  !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
3721
3722  def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3723                  (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary,
3724                  !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
3725
3726}
3727
3728defm SMLA : AI_smld<0, "smla">;
3729defm SMLS : AI_smld<1, "smls">;
3730
3731multiclass AI_sdml<bit sub, string opc> {
3732
3733  def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm),
3734                  NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
3735  def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm),
3736                  NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
3737}
3738
3739defm SMUA : AI_sdml<0, "smua">;
3740defm SMUS : AI_sdml<1, "smus">;
3741
3742//===----------------------------------------------------------------------===//
3743//  Misc. Arithmetic Instructions.
3744//
3745
3746def CLZ  : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
3747              IIC_iUNAr, "clz", "\t$Rd, $Rm",
3748              [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
3749
3750def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
3751              IIC_iUNAr, "rbit", "\t$Rd, $Rm",
3752              [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
3753           Requires<[IsARM, HasV6T2]>;
3754
3755def REV  : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
3756              IIC_iUNAr, "rev", "\t$Rd, $Rm",
3757              [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
3758
3759let AddedComplexity = 5 in
3760def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
3761               IIC_iUNAr, "rev16", "\t$Rd, $Rm",
3762               [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>,
3763               Requires<[IsARM, HasV6]>;
3764
3765let AddedComplexity = 5 in
3766def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
3767               IIC_iUNAr, "revsh", "\t$Rd, $Rm",
3768               [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>,
3769               Requires<[IsARM, HasV6]>;
3770
3771def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)),
3772                   (and (srl GPR:$Rm, (i32 8)), 0xFF)),
3773               (REVSH GPR:$Rm)>;
3774
3775def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd),
3776                              (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh),
3777               IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
3778               [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF),
3779                                      (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh),
3780                                           0xFFFF0000)))]>,
3781               Requires<[IsARM, HasV6]>;
3782
3783// Alternate cases for PKHBT where identities eliminate some nodes.
3784def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)),
3785               (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>;
3786def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)),
3787               (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>;
3788
3789// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3790// will match the pattern below.
3791def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd),
3792                              (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh),
3793               IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3794               [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000),
3795                                      (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh),
3796                                           0xFFFF)))]>,
3797               Requires<[IsARM, HasV6]>;
3798
3799// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
3800// a shift amount of 0 is *not legal* here, it is PKHBT instead.
3801def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
3802                   (srl GPRnopc:$src2, imm16_31:$sh)),
3803               (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>;
3804def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
3805                   (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)),
3806               (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>;
3807
3808//===----------------------------------------------------------------------===//
3809//  Comparison Instructions...
3810//
3811
3812defm CMP  : AI1_cmp_irs<0b1010, "cmp",
3813                        IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3814                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3815
3816// ARMcmpZ can re-use the above instruction definitions.
3817def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3818             (CMPri   GPR:$src, so_imm:$imm)>;
3819def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3820             (CMPrr   GPR:$src, GPR:$rhs)>;
3821def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs),
3822             (CMPrsi   GPR:$src, so_reg_imm:$rhs)>;
3823def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs),
3824             (CMPrsr   GPR:$src, so_reg_reg:$rhs)>;
3825
3826// CMN register-integer
3827let isCompare = 1, Defs = [CPSR] in {
3828def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iCMPi,
3829                "cmn", "\t$Rn, $imm",
3830                [(ARMcmn GPR:$Rn, so_imm:$imm)]> {
3831  bits<4> Rn;
3832  bits<12> imm;
3833  let Inst{25} = 1;
3834  let Inst{20} = 1;
3835  let Inst{19-16} = Rn;
3836  let Inst{15-12} = 0b0000;
3837  let Inst{11-0} = imm;
3838
3839  let Unpredictable{15-12} = 0b1111;
3840}
3841
3842// CMN register-register/shift
3843def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
3844                 "cmn", "\t$Rn, $Rm",
3845                 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3846                   GPR:$Rn, GPR:$Rm)]> {
3847  bits<4> Rn;
3848  bits<4> Rm;
3849  let isCommutable = 1;
3850  let Inst{25} = 0;
3851  let Inst{20} = 1;
3852  let Inst{19-16} = Rn;
3853  let Inst{15-12} = 0b0000;
3854  let Inst{11-4} = 0b00000000;
3855  let Inst{3-0} = Rm;
3856
3857  let Unpredictable{15-12} = 0b1111;
3858}
3859
3860def CMNzrsi : AI1<0b1011, (outs),
3861                  (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr,
3862                  "cmn", "\t$Rn, $shift",
3863                  [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3864                    GPR:$Rn, so_reg_imm:$shift)]> {
3865  bits<4> Rn;
3866  bits<12> shift;
3867  let Inst{25} = 0;
3868  let Inst{20} = 1;
3869  let Inst{19-16} = Rn;
3870  let Inst{15-12} = 0b0000;
3871  let Inst{11-5} = shift{11-5};
3872  let Inst{4} = 0;
3873  let Inst{3-0} = shift{3-0};
3874
3875  let Unpredictable{15-12} = 0b1111;
3876}
3877
3878def CMNzrsr : AI1<0b1011, (outs),
3879                  (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr,
3880                  "cmn", "\t$Rn, $shift",
3881                  [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3882                    GPRnopc:$Rn, so_reg_reg:$shift)]> {
3883  bits<4> Rn;
3884  bits<12> shift;
3885  let Inst{25} = 0;
3886  let Inst{20} = 1;
3887  let Inst{19-16} = Rn;
3888  let Inst{15-12} = 0b0000;
3889  let Inst{11-8} = shift{11-8};
3890  let Inst{7} = 0;
3891  let Inst{6-5} = shift{6-5};
3892  let Inst{4} = 1;
3893  let Inst{3-0} = shift{3-0};
3894
3895  let Unpredictable{15-12} = 0b1111;
3896}
3897
3898}
3899
3900def : ARMPat<(ARMcmp  GPR:$src, so_imm_neg:$imm),
3901             (CMNri   GPR:$src, so_imm_neg:$imm)>;
3902
3903def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3904             (CMNri   GPR:$src, so_imm_neg:$imm)>;
3905
3906// Note that TST/TEQ don't set all the same flags that CMP does!
3907defm TST  : AI1_cmp_irs<0b1000, "tst",
3908                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3909                      BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3910defm TEQ  : AI1_cmp_irs<0b1001, "teq",
3911                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3912                      BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3913
3914// Pseudo i64 compares for some floating point compares.
3915let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3916    Defs = [CPSR] in {
3917def BCCi64 : PseudoInst<(outs),
3918    (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3919     IIC_Br,
3920    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3921
3922def BCCZi64 : PseudoInst<(outs),
3923     (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3924    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3925} // usesCustomInserter
3926
3927
3928// Conditional moves
3929// FIXME: should be able to write a pattern for ARMcmov, but can't use
3930// a two-value operand where a dag node expects two operands. :(
3931let neverHasSideEffects = 1 in {
3932
3933let isCommutable = 1 in
3934def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p),
3935                           4, IIC_iCMOVr,
3936  [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3937      RegConstraint<"$false = $Rd">;
3938
3939def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd),
3940                           (ins GPR:$false, so_reg_imm:$shift, pred:$p),
3941                           4, IIC_iCMOVsr,
3942  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_imm:$shift,
3943                            imm:$cc, CCR:$ccr))*/]>,
3944      RegConstraint<"$false = $Rd">;
3945def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd),
3946                           (ins GPR:$false, so_reg_reg:$shift, pred:$p),
3947                           4, IIC_iCMOVsr,
3948  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift,
3949                            imm:$cc, CCR:$ccr))*/]>,
3950      RegConstraint<"$false = $Rd">;
3951
3952
3953let isMoveImm = 1 in
3954def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd),
3955                             (ins GPR:$false, imm0_65535_expr:$imm, pred:$p),
3956                             4, IIC_iMOVi,
3957                             []>,
3958      RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>;
3959
3960let isMoveImm = 1 in
3961def MOVCCi : ARMPseudoInst<(outs GPR:$Rd),
3962                           (ins GPR:$false, so_imm:$imm, pred:$p),
3963                           4, IIC_iCMOVi,
3964   [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3965      RegConstraint<"$false = $Rd">;
3966
3967// Two instruction predicate mov immediate.
3968let isMoveImm = 1 in
3969def MOVCCi32imm : ARMPseudoInst<(outs GPR:$Rd),
3970                                (ins GPR:$false, i32imm:$src, pred:$p),
3971                  8, IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3972
3973let isMoveImm = 1 in
3974def MVNCCi : ARMPseudoInst<(outs GPR:$Rd),
3975                           (ins GPR:$false, so_imm:$imm, pred:$p),
3976                           4, IIC_iCMOVi,
3977 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3978                RegConstraint<"$false = $Rd">;
3979
3980// Conditional instructions
3981multiclass AsI1_bincc_irs<Instruction iri, Instruction irr, Instruction irsi,
3982                          Instruction irsr,
3983                          InstrItinClass iii, InstrItinClass iir,
3984                          InstrItinClass iis> {
3985  def ri  : ARMPseudoExpand<(outs GPR:$Rd),
3986                            (ins GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s),
3987                            4, iii, [],
3988                       (iri GPR:$Rd, GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s)>,
3989                            RegConstraint<"$Rn = $Rd">;
3990  def rr  : ARMPseudoExpand<(outs GPR:$Rd),
3991                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3992                            4, iir, [],
3993                           (irr GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3994                            RegConstraint<"$Rn = $Rd">;
3995  def rsi : ARMPseudoExpand<(outs GPR:$Rd),
3996                           (ins GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s),
3997                            4, iis, [],
3998                (irsi GPR:$Rd, GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s)>,
3999                            RegConstraint<"$Rn = $Rd">;
4000  def rsr : ARMPseudoExpand<(outs GPRnopc:$Rd),
4001                       (ins GPRnopc:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s),
4002                            4, iis, [],
4003                (irsr GPR:$Rd, GPR:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s)>,
4004                            RegConstraint<"$Rn = $Rd">;
4005}
4006
4007defm ANDCC : AsI1_bincc_irs<ANDri, ANDrr, ANDrsi, ANDrsr,
4008                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4009defm ORRCC : AsI1_bincc_irs<ORRri, ORRrr, ORRrsi, ORRrsr,
4010                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4011defm EORCC : AsI1_bincc_irs<EORri, EORrr, EORrsi, EORrsr,
4012                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4013
4014} // neverHasSideEffects
4015
4016
4017//===----------------------------------------------------------------------===//
4018// Atomic operations intrinsics
4019//
4020
4021def MemBarrierOptOperand : AsmOperandClass {
4022  let Name = "MemBarrierOpt";
4023  let ParserMethod = "parseMemBarrierOptOperand";
4024}
4025def memb_opt : Operand<i32> {
4026  let PrintMethod = "printMemBOption";
4027  let ParserMatchClass = MemBarrierOptOperand;
4028  let DecoderMethod = "DecodeMemBarrierOption";
4029}
4030
4031// memory barriers protect the atomic sequences
4032let hasSideEffects = 1 in {
4033def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4034                "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
4035                Requires<[IsARM, HasDB]> {
4036  bits<4> opt;
4037  let Inst{31-4} = 0xf57ff05;
4038  let Inst{3-0} = opt;
4039}
4040}
4041
4042def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4043                "dsb", "\t$opt", []>,
4044                Requires<[IsARM, HasDB]> {
4045  bits<4> opt;
4046  let Inst{31-4} = 0xf57ff04;
4047  let Inst{3-0} = opt;
4048}
4049
4050// ISB has only full system option
4051def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4052                "isb", "\t$opt", []>,
4053                Requires<[IsARM, HasDB]> {
4054  bits<4> opt;
4055  let Inst{31-4} = 0xf57ff06;
4056  let Inst{3-0} = opt;
4057}
4058
4059// Pseudo instruction that combines movs + predicated rsbmi
4060// to implement integer ABS
4061let usesCustomInserter = 1, Defs = [CPSR] in {
4062def ABS : ARMPseudoInst<
4063  (outs GPR:$dst), (ins GPR:$src),
4064  8, NoItinerary, []>;
4065}
4066
4067let usesCustomInserter = 1 in {
4068  let Defs = [CPSR] in {
4069    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
4070      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4071      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
4072    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
4073      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4074      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
4075    def ATOMIC_LOAD_AND_I8 : PseudoInst<
4076      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4077      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
4078    def ATOMIC_LOAD_OR_I8 : PseudoInst<
4079      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4080      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
4081    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
4082      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4083      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
4084    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
4085      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4086      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
4087    def ATOMIC_LOAD_MIN_I8 : PseudoInst<
4088      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4089      [(set GPR:$dst, (atomic_load_min_8 GPR:$ptr, GPR:$val))]>;
4090    def ATOMIC_LOAD_MAX_I8 : PseudoInst<
4091      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4092      [(set GPR:$dst, (atomic_load_max_8 GPR:$ptr, GPR:$val))]>;
4093    def ATOMIC_LOAD_UMIN_I8 : PseudoInst<
4094      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4095      [(set GPR:$dst, (atomic_load_umin_8 GPR:$ptr, GPR:$val))]>;
4096    def ATOMIC_LOAD_UMAX_I8 : PseudoInst<
4097      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4098      [(set GPR:$dst, (atomic_load_umax_8 GPR:$ptr, GPR:$val))]>;
4099    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
4100      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4101      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
4102    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
4103      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4104      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
4105    def ATOMIC_LOAD_AND_I16 : PseudoInst<
4106      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4107      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
4108    def ATOMIC_LOAD_OR_I16 : PseudoInst<
4109      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4110      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
4111    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
4112      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4113      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
4114    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
4115      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4116      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
4117    def ATOMIC_LOAD_MIN_I16 : PseudoInst<
4118      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4119      [(set GPR:$dst, (atomic_load_min_16 GPR:$ptr, GPR:$val))]>;
4120    def ATOMIC_LOAD_MAX_I16 : PseudoInst<
4121      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4122      [(set GPR:$dst, (atomic_load_max_16 GPR:$ptr, GPR:$val))]>;
4123    def ATOMIC_LOAD_UMIN_I16 : PseudoInst<
4124      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4125      [(set GPR:$dst, (atomic_load_umin_16 GPR:$ptr, GPR:$val))]>;
4126    def ATOMIC_LOAD_UMAX_I16 : PseudoInst<
4127      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4128      [(set GPR:$dst, (atomic_load_umax_16 GPR:$ptr, GPR:$val))]>;
4129    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
4130      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4131      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
4132    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
4133      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4134      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
4135    def ATOMIC_LOAD_AND_I32 : PseudoInst<
4136      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4137      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
4138    def ATOMIC_LOAD_OR_I32 : PseudoInst<
4139      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4140      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
4141    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
4142      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4143      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
4144    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
4145      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4146      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
4147    def ATOMIC_LOAD_MIN_I32 : PseudoInst<
4148      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4149      [(set GPR:$dst, (atomic_load_min_32 GPR:$ptr, GPR:$val))]>;
4150    def ATOMIC_LOAD_MAX_I32 : PseudoInst<
4151      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4152      [(set GPR:$dst, (atomic_load_max_32 GPR:$ptr, GPR:$val))]>;
4153    def ATOMIC_LOAD_UMIN_I32 : PseudoInst<
4154      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4155      [(set GPR:$dst, (atomic_load_umin_32 GPR:$ptr, GPR:$val))]>;
4156    def ATOMIC_LOAD_UMAX_I32 : PseudoInst<
4157      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4158      [(set GPR:$dst, (atomic_load_umax_32 GPR:$ptr, GPR:$val))]>;
4159
4160    def ATOMIC_SWAP_I8 : PseudoInst<
4161      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4162      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
4163    def ATOMIC_SWAP_I16 : PseudoInst<
4164      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4165      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
4166    def ATOMIC_SWAP_I32 : PseudoInst<
4167      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4168      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
4169
4170    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
4171      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4172      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
4173    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
4174      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4175      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
4176    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
4177      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4178      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
4179}
4180}
4181
4182let usesCustomInserter = 1 in {
4183    def COPY_STRUCT_BYVAL_I32 : PseudoInst<
4184      (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment),
4185      NoItinerary,
4186      [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>;
4187}
4188
4189let mayLoad = 1 in {
4190def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4191                     NoItinerary,
4192                    "ldrexb", "\t$Rt, $addr", []>;
4193def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4194                     NoItinerary, "ldrexh", "\t$Rt, $addr", []>;
4195def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4196                     NoItinerary, "ldrex", "\t$Rt, $addr", []>;
4197let hasExtraDefRegAllocReq = 1 in
4198def LDREXD: AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2),(ins addr_offset_none:$addr),
4199                      NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []> {
4200  let DecoderMethod = "DecodeDoubleRegLoad";
4201}
4202}
4203
4204let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
4205def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4206                    NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>;
4207def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4208                    NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>;
4209def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4210                    NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>;
4211let hasExtraSrcRegAllocReq = 1 in
4212def STREXD : AIstrex<0b01, (outs GPR:$Rd),
4213                    (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr),
4214                    NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []> {
4215  let DecoderMethod = "DecodeDoubleRegStore";
4216}
4217}
4218
4219
4220def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", []>,
4221            Requires<[IsARM, HasV7]>  {
4222  let Inst{31-0} = 0b11110101011111111111000000011111;
4223}
4224
4225// SWP/SWPB are deprecated in V6/V7.
4226let mayLoad = 1, mayStore = 1 in {
4227def SWP : AIswp<0, (outs GPRnopc:$Rt),
4228                (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>;
4229def SWPB: AIswp<1, (outs GPRnopc:$Rt),
4230                (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>;
4231}
4232
4233//===----------------------------------------------------------------------===//
4234// Coprocessor Instructions.
4235//
4236
4237def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4238            c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4239            NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4240            [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4241                          imm:$CRm, imm:$opc2)]> {
4242  bits<4> opc1;
4243  bits<4> CRn;
4244  bits<4> CRd;
4245  bits<4> cop;
4246  bits<3> opc2;
4247  bits<4> CRm;
4248
4249  let Inst{3-0}   = CRm;
4250  let Inst{4}     = 0;
4251  let Inst{7-5}   = opc2;
4252  let Inst{11-8}  = cop;
4253  let Inst{15-12} = CRd;
4254  let Inst{19-16} = CRn;
4255  let Inst{23-20} = opc1;
4256}
4257
4258def CDP2 : ABXI<0b1110, (outs), (ins pf_imm:$cop, imm0_15:$opc1,
4259               c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4260               NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4261               [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4262                              imm:$CRm, imm:$opc2)]> {
4263  let Inst{31-28} = 0b1111;
4264  bits<4> opc1;
4265  bits<4> CRn;
4266  bits<4> CRd;
4267  bits<4> cop;
4268  bits<3> opc2;
4269  bits<4> CRm;
4270
4271  let Inst{3-0}   = CRm;
4272  let Inst{4}     = 0;
4273  let Inst{7-5}   = opc2;
4274  let Inst{11-8}  = cop;
4275  let Inst{15-12} = CRd;
4276  let Inst{19-16} = CRn;
4277  let Inst{23-20} = opc1;
4278}
4279
4280class ACI<dag oops, dag iops, string opc, string asm,
4281          IndexMode im = IndexModeNone>
4282  : I<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
4283      opc, asm, "", []> {
4284  let Inst{27-25} = 0b110;
4285}
4286class ACInoP<dag oops, dag iops, string opc, string asm,
4287          IndexMode im = IndexModeNone>
4288  : InoP<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
4289         opc, asm, "", []> {
4290  let Inst{31-28} = 0b1111;
4291  let Inst{27-25} = 0b110;
4292}
4293multiclass LdStCop<bit load, bit Dbit, string asm> {
4294  def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4295                    asm, "\t$cop, $CRd, $addr"> {
4296    bits<13> addr;
4297    bits<4> cop;
4298    bits<4> CRd;
4299    let Inst{24} = 1; // P = 1
4300    let Inst{23} = addr{8};
4301    let Inst{22} = Dbit;
4302    let Inst{21} = 0; // W = 0
4303    let Inst{20} = load;
4304    let Inst{19-16} = addr{12-9};
4305    let Inst{15-12} = CRd;
4306    let Inst{11-8} = cop;
4307    let Inst{7-0} = addr{7-0};
4308    let DecoderMethod = "DecodeCopMemInstruction";
4309  }
4310  def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4311                 asm, "\t$cop, $CRd, $addr!", IndexModePre> {
4312    bits<13> addr;
4313    bits<4> cop;
4314    bits<4> CRd;
4315    let Inst{24} = 1; // P = 1
4316    let Inst{23} = addr{8};
4317    let Inst{22} = Dbit;
4318    let Inst{21} = 1; // W = 1
4319    let Inst{20} = load;
4320    let Inst{19-16} = addr{12-9};
4321    let Inst{15-12} = CRd;
4322    let Inst{11-8} = cop;
4323    let Inst{7-0} = addr{7-0};
4324    let DecoderMethod = "DecodeCopMemInstruction";
4325  }
4326  def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4327                              postidx_imm8s4:$offset),
4328                 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> {
4329    bits<9> offset;
4330    bits<4> addr;
4331    bits<4> cop;
4332    bits<4> CRd;
4333    let Inst{24} = 0; // P = 0
4334    let Inst{23} = offset{8};
4335    let Inst{22} = Dbit;
4336    let Inst{21} = 1; // W = 1
4337    let Inst{20} = load;
4338    let Inst{19-16} = addr;
4339    let Inst{15-12} = CRd;
4340    let Inst{11-8} = cop;
4341    let Inst{7-0} = offset{7-0};
4342    let DecoderMethod = "DecodeCopMemInstruction";
4343  }
4344  def _OPTION : ACI<(outs),
4345                    (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4346                         coproc_option_imm:$option),
4347      asm, "\t$cop, $CRd, $addr, $option"> {
4348    bits<8> option;
4349    bits<4> addr;
4350    bits<4> cop;
4351    bits<4> CRd;
4352    let Inst{24} = 0; // P = 0
4353    let Inst{23} = 1; // U = 1
4354    let Inst{22} = Dbit;
4355    let Inst{21} = 0; // W = 0
4356    let Inst{20} = load;
4357    let Inst{19-16} = addr;
4358    let Inst{15-12} = CRd;
4359    let Inst{11-8} = cop;
4360    let Inst{7-0} = option;
4361    let DecoderMethod = "DecodeCopMemInstruction";
4362  }
4363}
4364multiclass LdSt2Cop<bit load, bit Dbit, string asm> {
4365  def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4366                       asm, "\t$cop, $CRd, $addr"> {
4367    bits<13> addr;
4368    bits<4> cop;
4369    bits<4> CRd;
4370    let Inst{24} = 1; // P = 1
4371    let Inst{23} = addr{8};
4372    let Inst{22} = Dbit;
4373    let Inst{21} = 0; // W = 0
4374    let Inst{20} = load;
4375    let Inst{19-16} = addr{12-9};
4376    let Inst{15-12} = CRd;
4377    let Inst{11-8} = cop;
4378    let Inst{7-0} = addr{7-0};
4379    let DecoderMethod = "DecodeCopMemInstruction";
4380  }
4381  def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4382                    asm, "\t$cop, $CRd, $addr!", IndexModePre> {
4383    bits<13> addr;
4384    bits<4> cop;
4385    bits<4> CRd;
4386    let Inst{24} = 1; // P = 1
4387    let Inst{23} = addr{8};
4388    let Inst{22} = Dbit;
4389    let Inst{21} = 1; // W = 1
4390    let Inst{20} = load;
4391    let Inst{19-16} = addr{12-9};
4392    let Inst{15-12} = CRd;
4393    let Inst{11-8} = cop;
4394    let Inst{7-0} = addr{7-0};
4395    let DecoderMethod = "DecodeCopMemInstruction";
4396  }
4397  def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4398                                 postidx_imm8s4:$offset),
4399                 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> {
4400    bits<9> offset;
4401    bits<4> addr;
4402    bits<4> cop;
4403    bits<4> CRd;
4404    let Inst{24} = 0; // P = 0
4405    let Inst{23} = offset{8};
4406    let Inst{22} = Dbit;
4407    let Inst{21} = 1; // W = 1
4408    let Inst{20} = load;
4409    let Inst{19-16} = addr;
4410    let Inst{15-12} = CRd;
4411    let Inst{11-8} = cop;
4412    let Inst{7-0} = offset{7-0};
4413    let DecoderMethod = "DecodeCopMemInstruction";
4414  }
4415  def _OPTION : ACInoP<(outs),
4416                       (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4417                            coproc_option_imm:$option),
4418      asm, "\t$cop, $CRd, $addr, $option"> {
4419    bits<8> option;
4420    bits<4> addr;
4421    bits<4> cop;
4422    bits<4> CRd;
4423    let Inst{24} = 0; // P = 0
4424    let Inst{23} = 1; // U = 1
4425    let Inst{22} = Dbit;
4426    let Inst{21} = 0; // W = 0
4427    let Inst{20} = load;
4428    let Inst{19-16} = addr;
4429    let Inst{15-12} = CRd;
4430    let Inst{11-8} = cop;
4431    let Inst{7-0} = option;
4432    let DecoderMethod = "DecodeCopMemInstruction";
4433  }
4434}
4435
4436defm LDC   : LdStCop <1, 0, "ldc">;
4437defm LDCL  : LdStCop <1, 1, "ldcl">;
4438defm STC   : LdStCop <0, 0, "stc">;
4439defm STCL  : LdStCop <0, 1, "stcl">;
4440defm LDC2  : LdSt2Cop<1, 0, "ldc2">;
4441defm LDC2L : LdSt2Cop<1, 1, "ldc2l">;
4442defm STC2  : LdSt2Cop<0, 0, "stc2">;
4443defm STC2L : LdSt2Cop<0, 1, "stc2l">;
4444
4445//===----------------------------------------------------------------------===//
4446// Move between coprocessor and ARM core register.
4447//
4448
4449class MovRCopro<string opc, bit direction, dag oops, dag iops,
4450                list<dag> pattern>
4451  : ABI<0b1110, oops, iops, NoItinerary, opc,
4452        "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> {
4453  let Inst{20} = direction;
4454  let Inst{4} = 1;
4455
4456  bits<4> Rt;
4457  bits<4> cop;
4458  bits<3> opc1;
4459  bits<3> opc2;
4460  bits<4> CRm;
4461  bits<4> CRn;
4462
4463  let Inst{15-12} = Rt;
4464  let Inst{11-8}  = cop;
4465  let Inst{23-21} = opc1;
4466  let Inst{7-5}   = opc2;
4467  let Inst{3-0}   = CRm;
4468  let Inst{19-16} = CRn;
4469}
4470
4471def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */,
4472                    (outs),
4473                    (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4474                         c_imm:$CRm, imm0_7:$opc2),
4475                    [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4476                                  imm:$CRm, imm:$opc2)]>;
4477def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
4478                   (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4479                        c_imm:$CRm, 0, pred:$p)>;
4480def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */,
4481                    (outs GPR:$Rt),
4482                    (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
4483                         imm0_7:$opc2), []>;
4484def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm",
4485                   (MRC GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4486                        c_imm:$CRm, 0, pred:$p)>;
4487
4488def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
4489             (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4490
4491class MovRCopro2<string opc, bit direction, dag oops, dag iops,
4492                 list<dag> pattern>
4493  : ABXI<0b1110, oops, iops, NoItinerary,
4494         !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> {
4495  let Inst{31-28} = 0b1111;
4496  let Inst{20} = direction;
4497  let Inst{4} = 1;
4498
4499  bits<4> Rt;
4500  bits<4> cop;
4501  bits<3> opc1;
4502  bits<3> opc2;
4503  bits<4> CRm;
4504  bits<4> CRn;
4505
4506  let Inst{15-12} = Rt;
4507  let Inst{11-8}  = cop;
4508  let Inst{23-21} = opc1;
4509  let Inst{7-5}   = opc2;
4510  let Inst{3-0}   = CRm;
4511  let Inst{19-16} = CRn;
4512}
4513
4514def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */,
4515                      (outs),
4516                      (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4517                           c_imm:$CRm, imm0_7:$opc2),
4518                      [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4519                                     imm:$CRm, imm:$opc2)]>;
4520def : ARMInstAlias<"mcr2$ $cop, $opc1, $Rt, $CRn, $CRm",
4521                   (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4522                         c_imm:$CRm, 0)>;
4523def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */,
4524                      (outs GPR:$Rt),
4525                      (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
4526                           imm0_7:$opc2), []>;
4527def : ARMInstAlias<"mrc2$ $cop, $opc1, $Rt, $CRn, $CRm",
4528                   (MRC2 GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4529                         c_imm:$CRm, 0)>;
4530
4531def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn,
4532                              imm:$CRm, imm:$opc2),
4533                (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4534
4535class MovRRCopro<string opc, bit direction, list<dag> pattern = []>
4536  : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4537        GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm),
4538        NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> {
4539  let Inst{23-21} = 0b010;
4540  let Inst{20} = direction;
4541
4542  bits<4> Rt;
4543  bits<4> Rt2;
4544  bits<4> cop;
4545  bits<4> opc1;
4546  bits<4> CRm;
4547
4548  let Inst{15-12} = Rt;
4549  let Inst{19-16} = Rt2;
4550  let Inst{11-8}  = cop;
4551  let Inst{7-4}   = opc1;
4552  let Inst{3-0}   = CRm;
4553}
4554
4555def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */,
4556                      [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt,
4557                                     GPRnopc:$Rt2, imm:$CRm)]>;
4558def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
4559
4560class MovRRCopro2<string opc, bit direction, list<dag> pattern = []>
4561  : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4562         GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary,
4563         !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> {
4564  let Inst{31-28} = 0b1111;
4565  let Inst{23-21} = 0b010;
4566  let Inst{20} = direction;
4567
4568  bits<4> Rt;
4569  bits<4> Rt2;
4570  bits<4> cop;
4571  bits<4> opc1;
4572  bits<4> CRm;
4573
4574  let Inst{15-12} = Rt;
4575  let Inst{19-16} = Rt2;
4576  let Inst{11-8}  = cop;
4577  let Inst{7-4}   = opc1;
4578  let Inst{3-0}   = CRm;
4579
4580  let DecoderMethod = "DecodeMRRC2";
4581}
4582
4583def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */,
4584                        [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt,
4585                                        GPRnopc:$Rt2, imm:$CRm)]>;
4586def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
4587
4588//===----------------------------------------------------------------------===//
4589// Move between special register and ARM core register
4590//
4591
4592// Move to ARM core register from Special Register
4593def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
4594              "mrs", "\t$Rd, apsr", []> {
4595  bits<4> Rd;
4596  let Inst{23-16} = 0b00001111;
4597  let Unpredictable{19-17} = 0b111;
4598
4599  let Inst{15-12} = Rd;
4600
4601  let Inst{11-0} = 0b000000000000;
4602  let Unpredictable{11-0} = 0b110100001111;
4603}
4604
4605def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p)>,
4606         Requires<[IsARM]>;
4607
4608// The MRSsys instruction is the MRS instruction from the ARM ARM,
4609// section B9.3.9, with the R bit set to 1.
4610def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
4611                 "mrs", "\t$Rd, spsr", []> {
4612  bits<4> Rd;
4613  let Inst{23-16} = 0b01001111;
4614  let Unpredictable{19-16} = 0b1111;
4615
4616  let Inst{15-12} = Rd;
4617
4618  let Inst{11-0} = 0b000000000000;
4619  let Unpredictable{11-0} = 0b110100001111;
4620}
4621
4622// Move from ARM core register to Special Register
4623//
4624// No need to have both system and application versions, the encodings are the
4625// same and the assembly parser has no way to distinguish between them. The mask
4626// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
4627// the mask with the fields to be accessed in the special register.
4628def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
4629              "msr", "\t$mask, $Rn", []> {
4630  bits<5> mask;
4631  bits<4> Rn;
4632
4633  let Inst{23} = 0;
4634  let Inst{22} = mask{4}; // R bit
4635  let Inst{21-20} = 0b10;
4636  let Inst{19-16} = mask{3-0};
4637  let Inst{15-12} = 0b1111;
4638  let Inst{11-4} = 0b00000000;
4639  let Inst{3-0} = Rn;
4640}
4641
4642def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask,  so_imm:$a), NoItinerary,
4643               "msr", "\t$mask, $a", []> {
4644  bits<5> mask;
4645  bits<12> a;
4646
4647  let Inst{23} = 0;
4648  let Inst{22} = mask{4}; // R bit
4649  let Inst{21-20} = 0b10;
4650  let Inst{19-16} = mask{3-0};
4651  let Inst{15-12} = 0b1111;
4652  let Inst{11-0} = a;
4653}
4654
4655//===----------------------------------------------------------------------===//
4656// TLS Instructions
4657//
4658
4659// __aeabi_read_tp preserves the registers r1-r3.
4660// This is a pseudo inst so that we can get the encoding right,
4661// complete with fixup for the aeabi_read_tp function.
4662let isCall = 1,
4663  Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
4664  def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
4665               [(set R0, ARMthread_pointer)]>;
4666}
4667
4668//===----------------------------------------------------------------------===//
4669// SJLJ Exception handling intrinsics
4670//   eh_sjlj_setjmp() is an instruction sequence to store the return
4671//   address and save #0 in R0 for the non-longjmp case.
4672//   Since by its nature we may be coming from some other function to get
4673//   here, and we're using the stack frame for the containing function to
4674//   save/restore registers, we can't keep anything live in regs across
4675//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
4676//   when we get here from a longjmp(). We force everything out of registers
4677//   except for our own input by listing the relevant registers in Defs. By
4678//   doing so, we also cause the prologue/epilogue code to actively preserve
4679//   all of the callee-saved resgisters, which is exactly what we want.
4680//   A constant value is passed in $val, and we use the location as a scratch.
4681//
4682// These are pseudo-instructions and are lowered to individual MC-insts, so
4683// no encoding information is necessary.
4684let Defs =
4685  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR,
4686    Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
4687  hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
4688  def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
4689                               NoItinerary,
4690                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
4691                           Requires<[IsARM, HasVFP2]>;
4692}
4693
4694let Defs =
4695  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR ],
4696  hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
4697  def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
4698                                   NoItinerary,
4699                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
4700                                Requires<[IsARM, NoVFP]>;
4701}
4702
4703// FIXME: Non-IOS version(s)
4704let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
4705    Defs = [ R7, LR, SP ] in {
4706def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
4707                             NoItinerary,
4708                         [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
4709                                Requires<[IsARM, IsIOS]>;
4710}
4711
4712// eh.sjlj.dispatchsetup pseudo-instructions.
4713// These pseudos are used for both ARM and Thumb2. Any differences are
4714// handled when the pseudo is expanded (which happens before any passes
4715// that need the instruction size).
4716let Defs =
4717  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR,
4718    Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
4719  isBarrier = 1 in
4720def Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>;
4721
4722let Defs =
4723  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR ],
4724  isBarrier = 1 in
4725def Int_eh_sjlj_dispatchsetup_nofp : PseudoInst<(outs), (ins), NoItinerary, []>;
4726
4727
4728//===----------------------------------------------------------------------===//
4729// Non-Instruction Patterns
4730//
4731
4732// ARMv4 indirect branch using (MOVr PC, dst)
4733let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
4734  def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst),
4735                    4, IIC_Br, [(brind GPR:$dst)],
4736                    (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
4737                  Requires<[IsARM, NoV4T]>;
4738
4739// Large immediate handling.
4740
4741// 32-bit immediate using two piece so_imms or movw + movt.
4742// This is a single pseudo instruction, the benefit is that it can be remat'd
4743// as a single unit instead of having to handle reg inputs.
4744// FIXME: Remove this when we can do generalized remat.
4745let isReMaterializable = 1, isMoveImm = 1 in
4746def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
4747                           [(set GPR:$dst, (arm_i32imm:$src))]>,
4748                           Requires<[IsARM]>;
4749
4750// Pseudo instruction that combines movw + movt + add pc (if PIC).
4751// It also makes it possible to rematerialize the instructions.
4752// FIXME: Remove this when we can do generalized remat and when machine licm
4753// can properly the instructions.
4754let isReMaterializable = 1 in {
4755def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4756                              IIC_iMOVix2addpc,
4757                        [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
4758                        Requires<[IsARM, UseMovt]>;
4759
4760def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4761                             IIC_iMOVix2,
4762                        [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
4763                        Requires<[IsARM, UseMovt]>;
4764
4765let AddedComplexity = 10 in
4766def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4767                                IIC_iMOVix2ld,
4768                    [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
4769                    Requires<[IsARM, UseMovt]>;
4770} // isReMaterializable
4771
4772// ConstantPool, GlobalAddress, and JumpTable
4773def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
4774            Requires<[IsARM, DontUseMovt]>;
4775def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
4776def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
4777            Requires<[IsARM, UseMovt]>;
4778def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
4779             (LEApcrelJT tjumptable:$dst, imm:$id)>;
4780
4781// TODO: add,sub,and, 3-instr forms?
4782
4783// Tail calls. These patterns also apply to Thumb mode.
4784def : Pat<(ARMtcret tcGPR:$dst), (TCRETURNri tcGPR:$dst)>;
4785def : Pat<(ARMtcret (i32 tglobaladdr:$dst)), (TCRETURNdi texternalsym:$dst)>;
4786def : Pat<(ARMtcret (i32 texternalsym:$dst)), (TCRETURNdi texternalsym:$dst)>;
4787
4788// Direct calls
4789def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
4790def : ARMPat<(ARMcall_nolink texternalsym:$func),
4791             (BMOVPCB_CALL texternalsym:$func)>;
4792
4793// zextload i1 -> zextload i8
4794def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
4795def : ARMPat<(zextloadi1 ldst_so_reg:$addr),    (LDRBrs ldst_so_reg:$addr)>;
4796
4797// extload -> zextload
4798def : ARMPat<(extloadi1 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
4799def : ARMPat<(extloadi1 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
4800def : ARMPat<(extloadi8 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
4801def : ARMPat<(extloadi8 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
4802
4803def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
4804
4805def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
4806def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
4807
4808// smul* and smla*
4809def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4810                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
4811                 (SMULBB GPR:$a, GPR:$b)>;
4812def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
4813                 (SMULBB GPR:$a, GPR:$b)>;
4814def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4815                      (sra GPR:$b, (i32 16))),
4816                 (SMULBT GPR:$a, GPR:$b)>;
4817def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
4818                 (SMULBT GPR:$a, GPR:$b)>;
4819def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
4820                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
4821                 (SMULTB GPR:$a, GPR:$b)>;
4822def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
4823                (SMULTB GPR:$a, GPR:$b)>;
4824def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
4825                      (i32 16)),
4826                 (SMULWB GPR:$a, GPR:$b)>;
4827def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
4828                 (SMULWB GPR:$a, GPR:$b)>;
4829
4830def : ARMV5TEPat<(add GPR:$acc,
4831                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4832                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
4833                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
4834def : ARMV5TEPat<(add GPR:$acc,
4835                      (mul sext_16_node:$a, sext_16_node:$b)),
4836                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
4837def : ARMV5TEPat<(add GPR:$acc,
4838                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4839                           (sra GPR:$b, (i32 16)))),
4840                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
4841def : ARMV5TEPat<(add GPR:$acc,
4842                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
4843                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
4844def : ARMV5TEPat<(add GPR:$acc,
4845                      (mul (sra GPR:$a, (i32 16)),
4846                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
4847                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
4848def : ARMV5TEPat<(add GPR:$acc,
4849                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
4850                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
4851def : ARMV5TEPat<(add GPR:$acc,
4852                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
4853                           (i32 16))),
4854                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
4855def : ARMV5TEPat<(add GPR:$acc,
4856                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
4857                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
4858
4859
4860// Pre-v7 uses MCR for synchronization barriers.
4861def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>,
4862         Requires<[IsARM, HasV6]>;
4863
4864// SXT/UXT with no rotate
4865let AddedComplexity = 16 in {
4866def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>;
4867def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>;
4868def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>;
4869def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)),
4870               (UXTAB GPR:$Rn, GPR:$Rm, 0)>;
4871def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)),
4872               (UXTAH GPR:$Rn, GPR:$Rm, 0)>;
4873}
4874
4875def : ARMV6Pat<(sext_inreg GPR:$Src, i8),  (SXTB GPR:$Src, 0)>;
4876def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>;
4877
4878def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)),
4879               (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>;
4880def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)),
4881               (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>;
4882
4883// Atomic load/store patterns
4884def : ARMPat<(atomic_load_8 ldst_so_reg:$src),
4885             (LDRBrs ldst_so_reg:$src)>;
4886def : ARMPat<(atomic_load_8 addrmode_imm12:$src),
4887             (LDRBi12 addrmode_imm12:$src)>;
4888def : ARMPat<(atomic_load_16 addrmode3:$src),
4889             (LDRH addrmode3:$src)>;
4890def : ARMPat<(atomic_load_32 ldst_so_reg:$src),
4891             (LDRrs ldst_so_reg:$src)>;
4892def : ARMPat<(atomic_load_32 addrmode_imm12:$src),
4893             (LDRi12 addrmode_imm12:$src)>;
4894def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val),
4895             (STRBrs GPR:$val, ldst_so_reg:$ptr)>;
4896def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val),
4897             (STRBi12 GPR:$val, addrmode_imm12:$ptr)>;
4898def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val),
4899             (STRH GPR:$val, addrmode3:$ptr)>;
4900def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val),
4901             (STRrs GPR:$val, ldst_so_reg:$ptr)>;
4902def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val),
4903             (STRi12 GPR:$val, addrmode_imm12:$ptr)>;
4904
4905
4906//===----------------------------------------------------------------------===//
4907// Thumb Support
4908//
4909
4910include "ARMInstrThumb.td"
4911
4912//===----------------------------------------------------------------------===//
4913// Thumb2 Support
4914//
4915
4916include "ARMInstrThumb2.td"
4917
4918//===----------------------------------------------------------------------===//
4919// Floating Point Support
4920//
4921
4922include "ARMInstrVFP.td"
4923
4924//===----------------------------------------------------------------------===//
4925// Advanced SIMD (NEON) Support
4926//
4927
4928include "ARMInstrNEON.td"
4929
4930//===----------------------------------------------------------------------===//
4931// Assembler aliases
4932//
4933
4934// Memory barriers
4935def : InstAlias<"dmb", (DMB 0xf)>, Requires<[IsARM, HasDB]>;
4936def : InstAlias<"dsb", (DSB 0xf)>, Requires<[IsARM, HasDB]>;
4937def : InstAlias<"isb", (ISB 0xf)>, Requires<[IsARM, HasDB]>;
4938
4939// System instructions
4940def : MnemonicAlias<"swi", "svc">;
4941
4942// Load / Store Multiple
4943def : MnemonicAlias<"ldmfd", "ldm">;
4944def : MnemonicAlias<"ldmia", "ldm">;
4945def : MnemonicAlias<"ldmea", "ldmdb">;
4946def : MnemonicAlias<"stmfd", "stmdb">;
4947def : MnemonicAlias<"stmia", "stm">;
4948def : MnemonicAlias<"stmea", "stm">;
4949
4950// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the
4951// shift amount is zero (i.e., unspecified).
4952def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm",
4953                (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>,
4954        Requires<[IsARM, HasV6]>;
4955def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm",
4956                (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>,
4957        Requires<[IsARM, HasV6]>;
4958
4959// PUSH/POP aliases for STM/LDM
4960def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>;
4961def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>;
4962
4963// SSAT/USAT optional shift operand.
4964def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn",
4965                (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
4966def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn",
4967                (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
4968
4969
4970// Extend instruction optional rotate operand.
4971def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm",
4972                (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4973def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm",
4974                (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4975def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm",
4976                (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4977def : ARMInstAlias<"sxtb${p} $Rd, $Rm",
4978                (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4979def : ARMInstAlias<"sxtb16${p} $Rd, $Rm",
4980                (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4981def : ARMInstAlias<"sxth${p} $Rd, $Rm",
4982                (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4983
4984def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm",
4985                (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4986def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm",
4987                (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4988def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
4989                (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4990def : ARMInstAlias<"uxtb${p} $Rd, $Rm",
4991                (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4992def : ARMInstAlias<"uxtb16${p} $Rd, $Rm",
4993                (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4994def : ARMInstAlias<"uxth${p} $Rd, $Rm",
4995                (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4996
4997
4998// RFE aliases
4999def : MnemonicAlias<"rfefa", "rfeda">;
5000def : MnemonicAlias<"rfeea", "rfedb">;
5001def : MnemonicAlias<"rfefd", "rfeia">;
5002def : MnemonicAlias<"rfeed", "rfeib">;
5003def : MnemonicAlias<"rfe", "rfeia">;
5004
5005// SRS aliases
5006def : MnemonicAlias<"srsfa", "srsda">;
5007def : MnemonicAlias<"srsea", "srsdb">;
5008def : MnemonicAlias<"srsfd", "srsia">;
5009def : MnemonicAlias<"srsed", "srsib">;
5010def : MnemonicAlias<"srs", "srsia">;
5011
5012// QSAX == QSUBADDX
5013def : MnemonicAlias<"qsubaddx", "qsax">;
5014// SASX == SADDSUBX
5015def : MnemonicAlias<"saddsubx", "sasx">;
5016// SHASX == SHADDSUBX
5017def : MnemonicAlias<"shaddsubx", "shasx">;
5018// SHSAX == SHSUBADDX
5019def : MnemonicAlias<"shsubaddx", "shsax">;
5020// SSAX == SSUBADDX
5021def : MnemonicAlias<"ssubaddx", "ssax">;
5022// UASX == UADDSUBX
5023def : MnemonicAlias<"uaddsubx", "uasx">;
5024// UHASX == UHADDSUBX
5025def : MnemonicAlias<"uhaddsubx", "uhasx">;
5026// UHSAX == UHSUBADDX
5027def : MnemonicAlias<"uhsubaddx", "uhsax">;
5028// UQASX == UQADDSUBX
5029def : MnemonicAlias<"uqaddsubx", "uqasx">;
5030// UQSAX == UQSUBADDX
5031def : MnemonicAlias<"uqsubaddx", "uqsax">;
5032// USAX == USUBADDX
5033def : MnemonicAlias<"usubaddx", "usax">;
5034
5035// "mov Rd, so_imm_not" can be handled via "mvn" in assembly, just like
5036// for isel.
5037def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
5038                   (MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
5039def : ARMInstAlias<"mvn${s}${p} $Rd, $imm",
5040                   (MOVi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
5041// Same for AND <--> BIC
5042def : ARMInstAlias<"bic${s}${p} $Rd, $Rn, $imm",
5043                   (ANDri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm,
5044                          pred:$p, cc_out:$s)>;
5045def : ARMInstAlias<"bic${s}${p} $Rdn, $imm",
5046                   (ANDri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm,
5047                          pred:$p, cc_out:$s)>;
5048def : ARMInstAlias<"and${s}${p} $Rd, $Rn, $imm",
5049                   (BICri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm,
5050                          pred:$p, cc_out:$s)>;
5051def : ARMInstAlias<"and${s}${p} $Rdn, $imm",
5052                   (BICri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm,
5053                          pred:$p, cc_out:$s)>;
5054
5055// Likewise, "add Rd, so_imm_neg" -> sub
5056def : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm",
5057                 (SUBri GPR:$Rd, GPR:$Rn, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
5058def : ARMInstAlias<"add${s}${p} $Rd, $imm",
5059                 (SUBri GPR:$Rd, GPR:$Rd, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
5060// Same for CMP <--> CMN via so_imm_neg
5061def : ARMInstAlias<"cmp${p} $Rd, $imm",
5062                   (CMNri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>;
5063def : ARMInstAlias<"cmn${p} $Rd, $imm",
5064                   (CMPri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>;
5065
5066// The shifter forms of the MOV instruction are aliased to the ASR, LSL,
5067// LSR, ROR, and RRX instructions.
5068// FIXME: We need C++ parser hooks to map the alias to the MOV
5069//        encoding. It seems we should be able to do that sort of thing
5070//        in tblgen, but it could get ugly.
5071let TwoOperandAliasConstraint = "$Rm = $Rd" in {
5072def ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm",
5073                        (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
5074                             cc_out:$s)>;
5075def LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm",
5076                        (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
5077                             cc_out:$s)>;
5078def LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm",
5079                        (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
5080                             cc_out:$s)>;
5081def RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm",
5082                        (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
5083                             cc_out:$s)>;
5084}
5085def RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm",
5086                        (ins GPRnopc:$Rd, GPRnopc:$Rm, pred:$p, cc_out:$s)>;
5087let TwoOperandAliasConstraint = "$Rn = $Rd" in {
5088def ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm",
5089                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5090                             cc_out:$s)>;
5091def LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm",
5092                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5093                             cc_out:$s)>;
5094def LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm",
5095                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5096                             cc_out:$s)>;
5097def RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm",
5098                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5099                             cc_out:$s)>;
5100}
5101
5102// "neg" is and alias for "rsb rd, rn, #0"
5103def : ARMInstAlias<"neg${s}${p} $Rd, $Rm",
5104                   (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>;
5105
5106// Pre-v6, 'mov r0, r0' was used as a NOP encoding.
5107def : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg)>,
5108         Requires<[IsARM, NoV6]>;
5109
5110// UMULL/SMULL are available on all arches, but the instruction definitions
5111// need difference constraints pre-v6. Use these aliases for the assembly
5112// parsing on pre-v6.
5113def : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
5114            (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
5115         Requires<[IsARM, NoV6]>;
5116def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
5117            (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
5118         Requires<[IsARM, NoV6]>;
5119
5120// 'it' blocks in ARM mode just validate the predicates. The IT itself
5121// is discarded.
5122def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>;
5123