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