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