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