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