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