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