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