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