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