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