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