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