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