ARMInstrInfo.td revision 239462
1//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the ARM instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// ARM specific DAG Nodes.
16//
17
18// Type profiles.
19def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, 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, 3,
37                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
38                                   SDTCisVT<2, i32>]>;
39
40def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
41                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
42                                   SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
43
44def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
45                                  [SDTCisVT<0, i32>,
46                                   SDTCisVT<1, i32>, SDTCisVT<2, i32>,
47                                   SDTCisVT<3, i32>, SDTCisVT<4, i32>,
48                                   SDTCisVT<5, OtherVT>]>;
49
50def SDT_ARMAnd     : SDTypeProfile<1, 2,
51                                   [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
52                                    SDTCisVT<2, i32>]>;
53
54def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
55
56def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
57                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
58
59def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
60def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
61                                                 SDTCisInt<2>]>;
62def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
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 SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
75                                            [SDTCisSameAs<0, 2>,
76                                             SDTCisSameAs<0, 3>,
77                                             SDTCisInt<0>, SDTCisVT<1, i32>]>;
78
79// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR
80def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
81                                            [SDTCisSameAs<0, 2>,
82                                             SDTCisSameAs<0, 3>,
83                                             SDTCisInt<0>,
84                                             SDTCisVT<1, i32>,
85                                             SDTCisVT<4, i32>]>;
86// Node definitions.
87def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
88def ARMWrapperDYN    : SDNode<"ARMISD::WrapperDYN",  SDTIntUnaryOp>;
89def ARMWrapperPIC    : SDNode<"ARMISD::WrapperPIC",  SDTIntUnaryOp>;
90def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
91
92def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
93                              [SDNPHasChain, SDNPOutGlue]>;
94def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
95                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
96def ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" ,
97                                SDT_ARMStructByVal,
98                                [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
99                                 SDNPMayStore, SDNPMayLoad]>;
100
101def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
102                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
103                               SDNPVariadic]>;
104def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
105                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
106                               SDNPVariadic]>;
107def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
108                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
109                               SDNPVariadic]>;
110
111def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
112                              [SDNPHasChain, SDNPOptInGlue]>;
113
114def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
115                              [SDNPInGlue]>;
116
117def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
118                              [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
119
120def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
121                              [SDNPHasChain]>;
122def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
123                              [SDNPHasChain]>;
124
125def ARMBcci64        : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
126                              [SDNPHasChain]>;
127
128def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
129                              [SDNPOutGlue]>;
130
131def ARMcmn           : SDNode<"ARMISD::CMN", SDT_ARMCmp,
132                              [SDNPOutGlue]>;
133
134def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
135                              [SDNPOutGlue, SDNPCommutative]>;
136
137def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
138
139def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
140def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
141def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInGlue ]>;
142
143def ARMaddc          : SDNode<"ARMISD::ADDC",  SDTBinaryArithWithFlags,
144                              [SDNPCommutative]>;
145def ARMsubc          : SDNode<"ARMISD::SUBC",  SDTBinaryArithWithFlags>;
146def ARMadde          : SDNode<"ARMISD::ADDE",  SDTBinaryArithWithFlagsInOut>;
147def ARMsube          : SDNode<"ARMISD::SUBE",  SDTBinaryArithWithFlagsInOut>;
148
149def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
150def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
151                               SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
152def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
153                               SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
154
155def ARMMemBarrier     : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
156                               [SDNPHasChain]>;
157def ARMMemBarrierMCR  : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
158                               [SDNPHasChain]>;
159def ARMPreload        : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH,
160                               [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
161
162def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
163
164def ARMtcret         : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
165                        [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
166
167
168def ARMbfi           : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
169
170//===----------------------------------------------------------------------===//
171// ARM Instruction Predicate Definitions.
172//
173def HasV4T           : Predicate<"Subtarget->hasV4TOps()">,
174                                 AssemblerPredicate<"HasV4TOps", "armv4t">;
175def NoV4T            : Predicate<"!Subtarget->hasV4TOps()">;
176def HasV5T           : Predicate<"Subtarget->hasV5TOps()">;
177def HasV5TE          : Predicate<"Subtarget->hasV5TEOps()">,
178                                 AssemblerPredicate<"HasV5TEOps", "armv5te">;
179def HasV6            : Predicate<"Subtarget->hasV6Ops()">,
180                                 AssemblerPredicate<"HasV6Ops", "armv6">;
181def NoV6             : Predicate<"!Subtarget->hasV6Ops()">;
182def HasV6T2          : Predicate<"Subtarget->hasV6T2Ops()">,
183                                 AssemblerPredicate<"HasV6T2Ops", "armv6t2">;
184def NoV6T2           : Predicate<"!Subtarget->hasV6T2Ops()">;
185def HasV7            : Predicate<"Subtarget->hasV7Ops()">,
186                                 AssemblerPredicate<"HasV7Ops", "armv7">;
187def NoVFP            : Predicate<"!Subtarget->hasVFP2()">;
188def HasVFP2          : Predicate<"Subtarget->hasVFP2()">,
189                                 AssemblerPredicate<"FeatureVFP2", "VFP2">;
190def HasVFP3          : Predicate<"Subtarget->hasVFP3()">,
191                                 AssemblerPredicate<"FeatureVFP3", "VFP3">;
192def HasVFP4          : Predicate<"Subtarget->hasVFP4()">,
193                                 AssemblerPredicate<"FeatureVFP4", "VFP4">;
194def HasNEON          : Predicate<"Subtarget->hasNEON()">,
195                                 AssemblerPredicate<"FeatureNEON", "NEON">;
196def HasFP16          : Predicate<"Subtarget->hasFP16()">,
197                                 AssemblerPredicate<"FeatureFP16","half-float">;
198def HasDivide        : Predicate<"Subtarget->hasDivide()">,
199                                 AssemblerPredicate<"FeatureHWDiv", "divide">;
200def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
201                                 AssemblerPredicate<"FeatureT2XtPk",
202                                                     "pack/extract">;
203def HasThumb2DSP     : Predicate<"Subtarget->hasThumb2DSP()">,
204                                 AssemblerPredicate<"FeatureDSPThumb2",
205                                                    "thumb2-dsp">;
206def HasDB            : Predicate<"Subtarget->hasDataBarrier()">,
207                                 AssemblerPredicate<"FeatureDB",
208                                                    "data-barriers">;
209def HasMP            : Predicate<"Subtarget->hasMPExtension()">,
210                                 AssemblerPredicate<"FeatureMP",
211                                                    "mp-extensions">;
212def UseNEONForFP     : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
213def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
214def IsThumb          : Predicate<"Subtarget->isThumb()">,
215                                 AssemblerPredicate<"ModeThumb", "thumb">;
216def IsThumb1Only     : Predicate<"Subtarget->isThumb1Only()">;
217def IsThumb2         : Predicate<"Subtarget->isThumb2()">,
218                                 AssemblerPredicate<"ModeThumb,FeatureThumb2",
219                                                    "thumb2">;
220def IsMClass         : Predicate<"Subtarget->isMClass()">,
221                                 AssemblerPredicate<"FeatureMClass", "armv7m">;
222def IsARClass        : Predicate<"!Subtarget->isMClass()">,
223                                 AssemblerPredicate<"!FeatureMClass",
224                                                    "armv7a/r">;
225def IsARM            : Predicate<"!Subtarget->isThumb()">,
226                                 AssemblerPredicate<"!ModeThumb", "arm-mode">;
227def IsIOS            : Predicate<"Subtarget->isTargetIOS()">;
228def IsNotIOS         : Predicate<"!Subtarget->isTargetIOS()">;
229def IsNaCl           : Predicate<"Subtarget->isTargetNaCl()">;
230
231// FIXME: Eventually this will be just "hasV6T2Ops".
232def UseMovt          : Predicate<"Subtarget->useMovt()">;
233def DontUseMovt      : Predicate<"!Subtarget->useMovt()">;
234def UseFPVMLx        : Predicate<"Subtarget->useFPVMLx()">;
235
236// Prefer fused MAC for fp mul + add over fp VMLA / VMLS if they are available.
237// But only select them if more precision in FP computation is allowed.
238// Do not use them for Darwin platforms.
239def UseFusedMAC      : Predicate<"(TM.Options.AllowFPOpFusion =="
240                                 " FPOpFusion::Fast) && "
241                                 "!Subtarget->isTargetDarwin()">;
242def DontUseFusedMAC  : Predicate<"!Subtarget->hasVFP4() || "
243                                 "Subtarget->isTargetDarwin()">;
244
245def IsLE             : Predicate<"TLI.isLittleEndian()">;
246def IsBE             : Predicate<"TLI.isBigEndian()">;
247
248//===----------------------------------------------------------------------===//
249// ARM Flag Definitions.
250
251class RegConstraint<string C> {
252  string Constraints = C;
253}
254
255//===----------------------------------------------------------------------===//
256//  ARM specific transformation functions and pattern fragments.
257//
258
259// imm_neg_XFORM - Return a imm value packed into the format described for
260// imm_neg defs below.
261def imm_neg_XFORM : SDNodeXForm<imm, [{
262  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
263}]>;
264
265// so_imm_not_XFORM - Return a so_imm value packed into the format described for
266// so_imm_not def below.
267def so_imm_not_XFORM : SDNodeXForm<imm, [{
268  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
269}]>;
270
271/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
272def imm16_31 : ImmLeaf<i32, [{
273  return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
274}]>;
275
276def so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; }
277def so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
278    int64_t Value = -(int)N->getZExtValue();
279    return Value && ARM_AM::getSOImmVal(Value) != -1;
280  }], imm_neg_XFORM> {
281  let ParserMatchClass = so_imm_neg_asmoperand;
282}
283
284// Note: this pattern doesn't require an encoder method and such, as it's
285// only used on aliases (Pat<> and InstAlias<>). The actual encoding
286// is handled by the destination instructions, which use so_imm.
287def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; }
288def so_imm_not : Operand<i32>, PatLeaf<(imm), [{
289    return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
290  }], so_imm_not_XFORM> {
291  let ParserMatchClass = so_imm_not_asmoperand;
292}
293
294// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
295def sext_16_node : PatLeaf<(i32 GPR:$a), [{
296  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
297}]>;
298
299/// Split a 32-bit immediate into two 16 bit parts.
300def hi16 : SDNodeXForm<imm, [{
301  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
302}]>;
303
304def lo16AllZero : PatLeaf<(i32 imm), [{
305  // Returns true if all low 16-bits are 0.
306  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
307}], hi16>;
308
309class BinOpWithFlagFrag<dag res> :
310      PatFrag<(ops node:$LHS, node:$RHS, node:$FLAG), res>;
311class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
312class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
313
314// An 'and' node with a single use.
315def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
316  return N->hasOneUse();
317}]>;
318
319// An 'xor' node with a single use.
320def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
321  return N->hasOneUse();
322}]>;
323
324// An 'fmul' node with a single use.
325def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
326  return N->hasOneUse();
327}]>;
328
329// An 'fadd' node which checks for single non-hazardous use.
330def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
331  return hasNoVMLxHazardUse(N);
332}]>;
333
334// An 'fsub' node which checks for single non-hazardous use.
335def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
336  return hasNoVMLxHazardUse(N);
337}]>;
338
339//===----------------------------------------------------------------------===//
340// Operand Definitions.
341//
342
343// Immediate operands with a shared generic asm render method.
344class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; }
345
346// Branch target.
347// FIXME: rename brtarget to t2_brtarget
348def brtarget : Operand<OtherVT> {
349  let EncoderMethod = "getBranchTargetOpValue";
350  let OperandType = "OPERAND_PCREL";
351  let DecoderMethod = "DecodeT2BROperand";
352}
353
354// FIXME: get rid of this one?
355def uncondbrtarget : Operand<OtherVT> {
356  let EncoderMethod = "getUnconditionalBranchTargetOpValue";
357  let OperandType = "OPERAND_PCREL";
358}
359
360// Branch target for ARM. Handles conditional/unconditional
361def br_target : Operand<OtherVT> {
362  let EncoderMethod = "getARMBranchTargetOpValue";
363  let OperandType = "OPERAND_PCREL";
364}
365
366// Call target.
367// FIXME: rename bltarget to t2_bl_target?
368def bltarget : Operand<i32> {
369  // Encoded the same as branch targets.
370  let EncoderMethod = "getBranchTargetOpValue";
371  let OperandType = "OPERAND_PCREL";
372}
373
374// Call target for ARM. Handles conditional/unconditional
375// FIXME: rename bl_target to t2_bltarget?
376def bl_target : Operand<i32> {
377  let EncoderMethod = "getARMBLTargetOpValue";
378  let OperandType = "OPERAND_PCREL";
379}
380
381def blx_target : Operand<i32> {
382  let EncoderMethod = "getARMBLXTargetOpValue";
383  let OperandType = "OPERAND_PCREL";
384}
385
386// A list of registers separated by comma. Used by load/store multiple.
387def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; }
388def reglist : Operand<i32> {
389  let EncoderMethod = "getRegisterListOpValue";
390  let ParserMatchClass = RegListAsmOperand;
391  let PrintMethod = "printRegisterList";
392  let DecoderMethod = "DecodeRegListOperand";
393}
394
395def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; }
396def dpr_reglist : Operand<i32> {
397  let EncoderMethod = "getRegisterListOpValue";
398  let ParserMatchClass = DPRRegListAsmOperand;
399  let PrintMethod = "printRegisterList";
400  let DecoderMethod = "DecodeDPRRegListOperand";
401}
402
403def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; }
404def spr_reglist : Operand<i32> {
405  let EncoderMethod = "getRegisterListOpValue";
406  let ParserMatchClass = SPRRegListAsmOperand;
407  let PrintMethod = "printRegisterList";
408  let DecoderMethod = "DecodeSPRRegListOperand";
409}
410
411// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
412def cpinst_operand : Operand<i32> {
413  let PrintMethod = "printCPInstOperand";
414}
415
416// Local PC labels.
417def pclabel : Operand<i32> {
418  let PrintMethod = "printPCLabel";
419}
420
421// ADR instruction labels.
422def AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; }
423def adrlabel : Operand<i32> {
424  let EncoderMethod = "getAdrLabelOpValue";
425  let ParserMatchClass = AdrLabelAsmOperand;
426  let PrintMethod = "printAdrLabelOperand";
427}
428
429def neon_vcvt_imm32 : Operand<i32> {
430  let EncoderMethod = "getNEONVcvtImm32OpValue";
431  let DecoderMethod = "DecodeVCVTImmOperand";
432}
433
434// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
435def rot_imm_XFORM: SDNodeXForm<imm, [{
436  switch (N->getZExtValue()){
437  default: assert(0);
438  case 0:  return CurDAG->getTargetConstant(0, MVT::i32);
439  case 8:  return CurDAG->getTargetConstant(1, MVT::i32);
440  case 16: return CurDAG->getTargetConstant(2, MVT::i32);
441  case 24: return CurDAG->getTargetConstant(3, MVT::i32);
442  }
443}]>;
444def RotImmAsmOperand : AsmOperandClass {
445  let Name = "RotImm";
446  let ParserMethod = "parseRotImm";
447}
448def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
449    int32_t v = N->getZExtValue();
450    return v == 8 || v == 16 || v == 24; }],
451    rot_imm_XFORM> {
452  let PrintMethod = "printRotImmOperand";
453  let ParserMatchClass = RotImmAsmOperand;
454}
455
456// shift_imm: An integer that encodes a shift amount and the type of shift
457// (asr or lsl). The 6-bit immediate encodes as:
458//    {5}     0 ==> lsl
459//            1     asr
460//    {4-0}   imm5 shift amount.
461//            asr #32 encoded as imm5 == 0.
462def ShifterImmAsmOperand : AsmOperandClass {
463  let Name = "ShifterImm";
464  let ParserMethod = "parseShifterImm";
465}
466def shift_imm : Operand<i32> {
467  let PrintMethod = "printShiftImmOperand";
468  let ParserMatchClass = ShifterImmAsmOperand;
469}
470
471// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm.
472def ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; }
473def so_reg_reg : Operand<i32>,  // reg reg imm
474                 ComplexPattern<i32, 3, "SelectRegShifterOperand",
475                                [shl, srl, sra, rotr]> {
476  let EncoderMethod = "getSORegRegOpValue";
477  let PrintMethod = "printSORegRegOperand";
478  let DecoderMethod = "DecodeSORegRegOperand";
479  let ParserMatchClass = ShiftedRegAsmOperand;
480  let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm);
481}
482
483def ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; }
484def so_reg_imm : Operand<i32>, // reg imm
485                 ComplexPattern<i32, 2, "SelectImmShifterOperand",
486                                [shl, srl, sra, rotr]> {
487  let EncoderMethod = "getSORegImmOpValue";
488  let PrintMethod = "printSORegImmOperand";
489  let DecoderMethod = "DecodeSORegImmOperand";
490  let ParserMatchClass = ShiftedImmAsmOperand;
491  let MIOperandInfo = (ops GPR, i32imm);
492}
493
494// FIXME: Does this need to be distinct from so_reg?
495def shift_so_reg_reg : Operand<i32>,    // reg reg imm
496                   ComplexPattern<i32, 3, "SelectShiftRegShifterOperand",
497                                  [shl,srl,sra,rotr]> {
498  let EncoderMethod = "getSORegRegOpValue";
499  let PrintMethod = "printSORegRegOperand";
500  let DecoderMethod = "DecodeSORegRegOperand";
501  let ParserMatchClass = ShiftedRegAsmOperand;
502  let MIOperandInfo = (ops GPR, GPR, i32imm);
503}
504
505// FIXME: Does this need to be distinct from so_reg?
506def shift_so_reg_imm : Operand<i32>,    // reg reg imm
507                   ComplexPattern<i32, 2, "SelectShiftImmShifterOperand",
508                                  [shl,srl,sra,rotr]> {
509  let EncoderMethod = "getSORegImmOpValue";
510  let PrintMethod = "printSORegImmOperand";
511  let DecoderMethod = "DecodeSORegImmOperand";
512  let ParserMatchClass = ShiftedImmAsmOperand;
513  let MIOperandInfo = (ops GPR, i32imm);
514}
515
516
517// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
518// 8-bit immediate rotated by an arbitrary number of bits.
519def SOImmAsmOperand: ImmAsmOperand { let Name = "ARMSOImm"; }
520def so_imm : Operand<i32>, ImmLeaf<i32, [{
521    return ARM_AM::getSOImmVal(Imm) != -1;
522  }]> {
523  let EncoderMethod = "getSOImmOpValue";
524  let ParserMatchClass = SOImmAsmOperand;
525  let DecoderMethod = "DecodeSOImmOperand";
526}
527
528// Break so_imm's up into two pieces.  This handles immediates with up to 16
529// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
530// get the first/second pieces.
531def so_imm2part : PatLeaf<(imm), [{
532      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
533}]>;
534
535/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
536///
537def arm_i32imm : PatLeaf<(imm), [{
538  if (Subtarget->hasV6T2Ops())
539    return true;
540  return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
541}]>;
542
543/// imm0_1 predicate - Immediate in the range [0,1].
544def Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; }
545def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
546
547/// imm0_3 predicate - Immediate in the range [0,3].
548def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; }
549def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; }
550
551/// imm0_7 predicate - Immediate in the range [0,7].
552def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; }
553def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
554  return Imm >= 0 && Imm < 8;
555}]> {
556  let ParserMatchClass = Imm0_7AsmOperand;
557}
558
559/// imm8 predicate - Immediate is exactly 8.
560def Imm8AsmOperand: ImmAsmOperand { let Name = "Imm8"; }
561def imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> {
562  let ParserMatchClass = Imm8AsmOperand;
563}
564
565/// imm16 predicate - Immediate is exactly 16.
566def Imm16AsmOperand: ImmAsmOperand { let Name = "Imm16"; }
567def imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> {
568  let ParserMatchClass = Imm16AsmOperand;
569}
570
571/// imm32 predicate - Immediate is exactly 32.
572def Imm32AsmOperand: ImmAsmOperand { let Name = "Imm32"; }
573def imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> {
574  let ParserMatchClass = Imm32AsmOperand;
575}
576
577/// imm1_7 predicate - Immediate in the range [1,7].
578def Imm1_7AsmOperand: ImmAsmOperand { let Name = "Imm1_7"; }
579def imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> {
580  let ParserMatchClass = Imm1_7AsmOperand;
581}
582
583/// imm1_15 predicate - Immediate in the range [1,15].
584def Imm1_15AsmOperand: ImmAsmOperand { let Name = "Imm1_15"; }
585def imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> {
586  let ParserMatchClass = Imm1_15AsmOperand;
587}
588
589/// imm1_31 predicate - Immediate in the range [1,31].
590def Imm1_31AsmOperand: ImmAsmOperand { let Name = "Imm1_31"; }
591def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> {
592  let ParserMatchClass = Imm1_31AsmOperand;
593}
594
595/// imm0_15 predicate - Immediate in the range [0,15].
596def Imm0_15AsmOperand: ImmAsmOperand {
597  let Name = "Imm0_15";
598  let DiagnosticType = "ImmRange0_15";
599}
600def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
601  return Imm >= 0 && Imm < 16;
602}]> {
603  let ParserMatchClass = Imm0_15AsmOperand;
604}
605
606/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
607def Imm0_31AsmOperand: ImmAsmOperand { let Name = "Imm0_31"; }
608def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
609  return Imm >= 0 && Imm < 32;
610}]> {
611  let ParserMatchClass = Imm0_31AsmOperand;
612}
613
614/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32].
615def Imm0_32AsmOperand: ImmAsmOperand { let Name = "Imm0_32"; }
616def imm0_32 : Operand<i32>, ImmLeaf<i32, [{
617  return Imm >= 0 && Imm < 32;
618}]> {
619  let ParserMatchClass = Imm0_32AsmOperand;
620}
621
622/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63].
623def Imm0_63AsmOperand: ImmAsmOperand { let Name = "Imm0_63"; }
624def imm0_63 : Operand<i32>, ImmLeaf<i32, [{
625  return Imm >= 0 && Imm < 64;
626}]> {
627  let ParserMatchClass = Imm0_63AsmOperand;
628}
629
630/// imm0_255 predicate - Immediate in the range [0,255].
631def Imm0_255AsmOperand : ImmAsmOperand { let Name = "Imm0_255"; }
632def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
633  let ParserMatchClass = Imm0_255AsmOperand;
634}
635
636/// imm0_65535 - An immediate is in the range [0.65535].
637def Imm0_65535AsmOperand: ImmAsmOperand { let Name = "Imm0_65535"; }
638def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
639  return Imm >= 0 && Imm < 65536;
640}]> {
641  let ParserMatchClass = Imm0_65535AsmOperand;
642}
643
644// imm0_65535_neg - An immediate whose negative value is in the range [0.65535].
645def imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{
646  return -Imm >= 0 && -Imm < 65536;
647}]>;
648
649// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference
650// a relocatable expression.
651//
652// FIXME: This really needs a Thumb version separate from the ARM version.
653// While the range is the same, and can thus use the same match class,
654// the encoding is different so it should have a different encoder method.
655def Imm0_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm0_65535Expr"; }
656def imm0_65535_expr : Operand<i32> {
657  let EncoderMethod = "getHiLo16ImmOpValue";
658  let ParserMatchClass = Imm0_65535ExprAsmOperand;
659}
660
661/// imm24b - True if the 32-bit immediate is encodable in 24 bits.
662def Imm24bitAsmOperand: ImmAsmOperand { let Name = "Imm24bit"; }
663def imm24b : Operand<i32>, ImmLeaf<i32, [{
664  return Imm >= 0 && Imm <= 0xffffff;
665}]> {
666  let ParserMatchClass = Imm24bitAsmOperand;
667}
668
669
670/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
671/// e.g., 0xf000ffff
672def BitfieldAsmOperand : AsmOperandClass {
673  let Name = "Bitfield";
674  let ParserMethod = "parseBitfield";
675}
676
677def bf_inv_mask_imm : Operand<i32>,
678                      PatLeaf<(imm), [{
679  return ARM::isBitFieldInvertedMask(N->getZExtValue());
680}] > {
681  let EncoderMethod = "getBitfieldInvertedMaskOpValue";
682  let PrintMethod = "printBitfieldInvMaskImmOperand";
683  let DecoderMethod = "DecodeBitfieldMaskOperand";
684  let ParserMatchClass = BitfieldAsmOperand;
685}
686
687def imm1_32_XFORM: SDNodeXForm<imm, [{
688  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
689}]>;
690def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
691def imm1_32 : Operand<i32>, PatLeaf<(imm), [{
692   uint64_t Imm = N->getZExtValue();
693   return Imm > 0 && Imm <= 32;
694 }],
695    imm1_32_XFORM> {
696  let PrintMethod = "printImmPlusOneOperand";
697  let ParserMatchClass = Imm1_32AsmOperand;
698}
699
700def imm1_16_XFORM: SDNodeXForm<imm, [{
701  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
702}]>;
703def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; }
704def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }],
705    imm1_16_XFORM> {
706  let PrintMethod = "printImmPlusOneOperand";
707  let ParserMatchClass = Imm1_16AsmOperand;
708}
709
710// Define ARM specific addressing modes.
711// addrmode_imm12 := reg +/- imm12
712//
713def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; }
714def addrmode_imm12 : Operand<i32>,
715                     ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
716  // 12-bit immediate operand. Note that instructions using this encode
717  // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
718  // immediate values are as normal.
719
720  let EncoderMethod = "getAddrModeImm12OpValue";
721  let PrintMethod = "printAddrModeImm12Operand";
722  let DecoderMethod = "DecodeAddrModeImm12Operand";
723  let ParserMatchClass = MemImm12OffsetAsmOperand;
724  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
725}
726// ldst_so_reg := reg +/- reg shop imm
727//
728def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; }
729def ldst_so_reg : Operand<i32>,
730                  ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
731  let EncoderMethod = "getLdStSORegOpValue";
732  // FIXME: Simplify the printer
733  let PrintMethod = "printAddrMode2Operand";
734  let DecoderMethod = "DecodeSORegMemOperand";
735  let ParserMatchClass = MemRegOffsetAsmOperand;
736  let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift);
737}
738
739// postidx_imm8 := +/- [0,255]
740//
741// 9 bit value:
742//  {8}       1 is imm8 is non-negative. 0 otherwise.
743//  {7-0}     [0,255] imm8 value.
744def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; }
745def postidx_imm8 : Operand<i32> {
746  let PrintMethod = "printPostIdxImm8Operand";
747  let ParserMatchClass = PostIdxImm8AsmOperand;
748  let MIOperandInfo = (ops i32imm);
749}
750
751// postidx_imm8s4 := +/- [0,1020]
752//
753// 9 bit value:
754//  {8}       1 is imm8 is non-negative. 0 otherwise.
755//  {7-0}     [0,255] imm8 value, scaled by 4.
756def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; }
757def postidx_imm8s4 : Operand<i32> {
758  let PrintMethod = "printPostIdxImm8s4Operand";
759  let ParserMatchClass = PostIdxImm8s4AsmOperand;
760  let MIOperandInfo = (ops i32imm);
761}
762
763
764// postidx_reg := +/- reg
765//
766def PostIdxRegAsmOperand : AsmOperandClass {
767  let Name = "PostIdxReg";
768  let ParserMethod = "parsePostIdxReg";
769}
770def postidx_reg : Operand<i32> {
771  let EncoderMethod = "getPostIdxRegOpValue";
772  let DecoderMethod = "DecodePostIdxReg";
773  let PrintMethod = "printPostIdxRegOperand";
774  let ParserMatchClass = PostIdxRegAsmOperand;
775  let MIOperandInfo = (ops GPRnopc, i32imm);
776}
777
778
779// addrmode2 := reg +/- imm12
780//           := reg +/- reg shop imm
781//
782// FIXME: addrmode2 should be refactored the rest of the way to always
783// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg).
784def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; }
785def addrmode2 : Operand<i32>,
786                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
787  let EncoderMethod = "getAddrMode2OpValue";
788  let PrintMethod = "printAddrMode2Operand";
789  let ParserMatchClass = AddrMode2AsmOperand;
790  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
791}
792
793def PostIdxRegShiftedAsmOperand : AsmOperandClass {
794  let Name = "PostIdxRegShifted";
795  let ParserMethod = "parsePostIdxReg";
796}
797def am2offset_reg : Operand<i32>,
798                ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
799                [], [SDNPWantRoot]> {
800  let EncoderMethod = "getAddrMode2OffsetOpValue";
801  let PrintMethod = "printAddrMode2OffsetOperand";
802  // When using this for assembly, it's always as a post-index offset.
803  let ParserMatchClass = PostIdxRegShiftedAsmOperand;
804  let MIOperandInfo = (ops GPRnopc, i32imm);
805}
806
807// FIXME: am2offset_imm should only need the immediate, not the GPR. Having
808// the GPR is purely vestigal at this point.
809def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; }
810def am2offset_imm : Operand<i32>,
811                ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm",
812                [], [SDNPWantRoot]> {
813  let EncoderMethod = "getAddrMode2OffsetOpValue";
814  let PrintMethod = "printAddrMode2OffsetOperand";
815  let ParserMatchClass = AM2OffsetImmAsmOperand;
816  let MIOperandInfo = (ops GPRnopc, i32imm);
817}
818
819
820// addrmode3 := reg +/- reg
821// addrmode3 := reg +/- imm8
822//
823// FIXME: split into imm vs. reg versions.
824def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; }
825def addrmode3 : Operand<i32>,
826                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
827  let EncoderMethod = "getAddrMode3OpValue";
828  let PrintMethod = "printAddrMode3Operand";
829  let ParserMatchClass = AddrMode3AsmOperand;
830  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
831}
832
833// FIXME: split into imm vs. reg versions.
834// FIXME: parser method to handle +/- register.
835def AM3OffsetAsmOperand : AsmOperandClass {
836  let Name = "AM3Offset";
837  let ParserMethod = "parseAM3Offset";
838}
839def am3offset : Operand<i32>,
840                ComplexPattern<i32, 2, "SelectAddrMode3Offset",
841                               [], [SDNPWantRoot]> {
842  let EncoderMethod = "getAddrMode3OffsetOpValue";
843  let PrintMethod = "printAddrMode3OffsetOperand";
844  let ParserMatchClass = AM3OffsetAsmOperand;
845  let MIOperandInfo = (ops GPR, i32imm);
846}
847
848// ldstm_mode := {ia, ib, da, db}
849//
850def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
851  let EncoderMethod = "getLdStmModeOpValue";
852  let PrintMethod = "printLdStmModeOperand";
853}
854
855// addrmode5 := reg +/- imm8*4
856//
857def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; }
858def addrmode5 : Operand<i32>,
859                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
860  let PrintMethod = "printAddrMode5Operand";
861  let EncoderMethod = "getAddrMode5OpValue";
862  let DecoderMethod = "DecodeAddrMode5Operand";
863  let ParserMatchClass = AddrMode5AsmOperand;
864  let MIOperandInfo = (ops GPR:$base, i32imm);
865}
866
867// addrmode6 := reg with optional alignment
868//
869def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; }
870def addrmode6 : Operand<i32>,
871                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
872  let PrintMethod = "printAddrMode6Operand";
873  let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
874  let EncoderMethod = "getAddrMode6AddressOpValue";
875  let DecoderMethod = "DecodeAddrMode6Operand";
876  let ParserMatchClass = AddrMode6AsmOperand;
877}
878
879def am6offset : Operand<i32>,
880                ComplexPattern<i32, 1, "SelectAddrMode6Offset",
881                               [], [SDNPWantRoot]> {
882  let PrintMethod = "printAddrMode6OffsetOperand";
883  let MIOperandInfo = (ops GPR);
884  let EncoderMethod = "getAddrMode6OffsetOpValue";
885  let DecoderMethod = "DecodeGPRRegisterClass";
886}
887
888// Special version of addrmode6 to handle alignment encoding for VST1/VLD1
889// (single element from one lane) for size 32.
890def addrmode6oneL32 : Operand<i32>,
891                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
892  let PrintMethod = "printAddrMode6Operand";
893  let MIOperandInfo = (ops GPR:$addr, i32imm);
894  let EncoderMethod = "getAddrMode6OneLane32AddressOpValue";
895}
896
897// Special version of addrmode6 to handle alignment encoding for VLD-dup
898// instructions, specifically VLD4-dup.
899def addrmode6dup : Operand<i32>,
900                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
901  let PrintMethod = "printAddrMode6Operand";
902  let MIOperandInfo = (ops GPR:$addr, i32imm);
903  let EncoderMethod = "getAddrMode6DupAddressOpValue";
904  // FIXME: This is close, but not quite right. The alignment specifier is
905  // different.
906  let ParserMatchClass = AddrMode6AsmOperand;
907}
908
909// addrmodepc := pc + reg
910//
911def addrmodepc : Operand<i32>,
912                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
913  let PrintMethod = "printAddrModePCOperand";
914  let MIOperandInfo = (ops GPR, i32imm);
915}
916
917// addr_offset_none := reg
918//
919def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; }
920def addr_offset_none : Operand<i32>,
921                       ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> {
922  let PrintMethod = "printAddrMode7Operand";
923  let DecoderMethod = "DecodeAddrMode7Operand";
924  let ParserMatchClass = MemNoOffsetAsmOperand;
925  let MIOperandInfo = (ops GPR:$base);
926}
927
928def nohash_imm : Operand<i32> {
929  let PrintMethod = "printNoHashImmediate";
930}
931
932def CoprocNumAsmOperand : AsmOperandClass {
933  let Name = "CoprocNum";
934  let ParserMethod = "parseCoprocNumOperand";
935}
936def p_imm : Operand<i32> {
937  let PrintMethod = "printPImmediate";
938  let ParserMatchClass = CoprocNumAsmOperand;
939  let DecoderMethod = "DecodeCoprocessor";
940}
941
942def pf_imm : Operand<i32> {
943  let PrintMethod = "printPImmediate";
944  let ParserMatchClass = CoprocNumAsmOperand;
945}
946
947def CoprocRegAsmOperand : AsmOperandClass {
948  let Name = "CoprocReg";
949  let ParserMethod = "parseCoprocRegOperand";
950}
951def c_imm : Operand<i32> {
952  let PrintMethod = "printCImmediate";
953  let ParserMatchClass = CoprocRegAsmOperand;
954}
955def CoprocOptionAsmOperand : AsmOperandClass {
956  let Name = "CoprocOption";
957  let ParserMethod = "parseCoprocOptionOperand";
958}
959def coproc_option_imm : Operand<i32> {
960  let PrintMethod = "printCoprocOptionImm";
961  let ParserMatchClass = CoprocOptionAsmOperand;
962}
963
964//===----------------------------------------------------------------------===//
965
966include "ARMInstrFormats.td"
967
968//===----------------------------------------------------------------------===//
969// Multiclass helpers...
970//
971
972/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
973/// binop that produces a value.
974let TwoOperandAliasConstraint = "$Rn = $Rd" in
975multiclass AsI1_bin_irs<bits<4> opcod, string opc,
976                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
977                        PatFrag opnode, bit Commutable = 0> {
978  // The register-immediate version is re-materializable. This is useful
979  // in particular for taking the address of a local.
980  let isReMaterializable = 1 in {
981  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
982               iii, opc, "\t$Rd, $Rn, $imm",
983               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
984    bits<4> Rd;
985    bits<4> Rn;
986    bits<12> imm;
987    let Inst{25} = 1;
988    let Inst{19-16} = Rn;
989    let Inst{15-12} = Rd;
990    let Inst{11-0} = imm;
991  }
992  }
993  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
994               iir, opc, "\t$Rd, $Rn, $Rm",
995               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
996    bits<4> Rd;
997    bits<4> Rn;
998    bits<4> Rm;
999    let Inst{25} = 0;
1000    let isCommutable = Commutable;
1001    let Inst{19-16} = Rn;
1002    let Inst{15-12} = Rd;
1003    let Inst{11-4} = 0b00000000;
1004    let Inst{3-0} = Rm;
1005  }
1006
1007  def rsi : AsI1<opcod, (outs GPR:$Rd),
1008               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
1009               iis, opc, "\t$Rd, $Rn, $shift",
1010               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
1011    bits<4> Rd;
1012    bits<4> Rn;
1013    bits<12> shift;
1014    let Inst{25} = 0;
1015    let Inst{19-16} = Rn;
1016    let Inst{15-12} = Rd;
1017    let Inst{11-5} = shift{11-5};
1018    let Inst{4} = 0;
1019    let Inst{3-0} = shift{3-0};
1020  }
1021
1022  def rsr : AsI1<opcod, (outs GPR:$Rd),
1023               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
1024               iis, opc, "\t$Rd, $Rn, $shift",
1025               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
1026    bits<4> Rd;
1027    bits<4> Rn;
1028    bits<12> shift;
1029    let Inst{25} = 0;
1030    let Inst{19-16} = Rn;
1031    let Inst{15-12} = Rd;
1032    let Inst{11-8} = shift{11-8};
1033    let Inst{7} = 0;
1034    let Inst{6-5} = shift{6-5};
1035    let Inst{4} = 1;
1036    let Inst{3-0} = shift{3-0};
1037  }
1038}
1039
1040/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are
1041/// reversed.  The 'rr' form is only defined for the disassembler; for codegen
1042/// it is equivalent to the AsI1_bin_irs counterpart.
1043let TwoOperandAliasConstraint = "$Rn = $Rd" in
1044multiclass AsI1_rbin_irs<bits<4> opcod, string opc,
1045                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
1046                        PatFrag opnode, bit Commutable = 0> {
1047  // The register-immediate version is re-materializable. This is useful
1048  // in particular for taking the address of a local.
1049  let isReMaterializable = 1 in {
1050  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1051               iii, opc, "\t$Rd, $Rn, $imm",
1052               [(set GPR:$Rd, (opnode so_imm:$imm, GPR:$Rn))]> {
1053    bits<4> Rd;
1054    bits<4> Rn;
1055    bits<12> imm;
1056    let Inst{25} = 1;
1057    let Inst{19-16} = Rn;
1058    let Inst{15-12} = Rd;
1059    let Inst{11-0} = imm;
1060  }
1061  }
1062  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1063               iir, opc, "\t$Rd, $Rn, $Rm",
1064               [/* pattern left blank */]> {
1065    bits<4> Rd;
1066    bits<4> Rn;
1067    bits<4> Rm;
1068    let Inst{11-4} = 0b00000000;
1069    let Inst{25} = 0;
1070    let Inst{3-0} = Rm;
1071    let Inst{15-12} = Rd;
1072    let Inst{19-16} = Rn;
1073  }
1074
1075  def rsi : AsI1<opcod, (outs GPR:$Rd),
1076               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
1077               iis, opc, "\t$Rd, $Rn, $shift",
1078               [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]> {
1079    bits<4> Rd;
1080    bits<4> Rn;
1081    bits<12> shift;
1082    let Inst{25} = 0;
1083    let Inst{19-16} = Rn;
1084    let Inst{15-12} = Rd;
1085    let Inst{11-5} = shift{11-5};
1086    let Inst{4} = 0;
1087    let Inst{3-0} = shift{3-0};
1088  }
1089
1090  def rsr : AsI1<opcod, (outs GPR:$Rd),
1091               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
1092               iis, opc, "\t$Rd, $Rn, $shift",
1093               [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]> {
1094    bits<4> Rd;
1095    bits<4> Rn;
1096    bits<12> shift;
1097    let Inst{25} = 0;
1098    let Inst{19-16} = Rn;
1099    let Inst{15-12} = Rd;
1100    let Inst{11-8} = shift{11-8};
1101    let Inst{7} = 0;
1102    let Inst{6-5} = shift{6-5};
1103    let Inst{4} = 1;
1104    let Inst{3-0} = shift{3-0};
1105  }
1106}
1107
1108/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
1109///
1110/// These opcodes will be converted to the real non-S opcodes by
1111/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand.
1112let hasPostISelHook = 1, Defs = [CPSR] in {
1113multiclass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
1114                          InstrItinClass iis, PatFrag opnode,
1115                          bit Commutable = 0> {
1116  def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
1117                         4, iii,
1118                         [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>;
1119
1120  def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p),
1121                         4, iir,
1122                         [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]> {
1123    let isCommutable = Commutable;
1124  }
1125  def rsi : ARMPseudoInst<(outs GPR:$Rd),
1126                          (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
1127                          4, iis,
1128                          [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
1129                                                so_reg_imm:$shift))]>;
1130
1131  def rsr : ARMPseudoInst<(outs GPR:$Rd),
1132                          (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
1133                          4, iis,
1134                          [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
1135                                                so_reg_reg:$shift))]>;
1136}
1137}
1138
1139/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG
1140/// operands are reversed.
1141let hasPostISelHook = 1, Defs = [CPSR] in {
1142multiclass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir,
1143                          InstrItinClass iis, PatFrag opnode,
1144                          bit Commutable = 0> {
1145  def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
1146                         4, iii,
1147                         [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>;
1148
1149  def rsi : ARMPseudoInst<(outs GPR:$Rd),
1150                          (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
1151                          4, iis,
1152                          [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift,
1153                                             GPR:$Rn))]>;
1154
1155  def rsr : ARMPseudoInst<(outs GPR:$Rd),
1156                          (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
1157                          4, iis,
1158                          [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift,
1159                                             GPR:$Rn))]>;
1160}
1161}
1162
1163/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
1164/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
1165/// a explicit result, only implicitly set CPSR.
1166let isCompare = 1, Defs = [CPSR] in {
1167multiclass AI1_cmp_irs<bits<4> opcod, string opc,
1168                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
1169                       PatFrag opnode, bit Commutable = 0> {
1170  def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
1171               opc, "\t$Rn, $imm",
1172               [(opnode GPR:$Rn, so_imm:$imm)]> {
1173    bits<4> Rn;
1174    bits<12> imm;
1175    let Inst{25} = 1;
1176    let Inst{20} = 1;
1177    let Inst{19-16} = Rn;
1178    let Inst{15-12} = 0b0000;
1179    let Inst{11-0} = imm;
1180
1181    let Unpredictable{15-12} = 0b1111;
1182  }
1183  def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
1184               opc, "\t$Rn, $Rm",
1185               [(opnode GPR:$Rn, GPR:$Rm)]> {
1186    bits<4> Rn;
1187    bits<4> Rm;
1188    let isCommutable = Commutable;
1189    let Inst{25} = 0;
1190    let Inst{20} = 1;
1191    let Inst{19-16} = Rn;
1192    let Inst{15-12} = 0b0000;
1193    let Inst{11-4} = 0b00000000;
1194    let Inst{3-0} = Rm;
1195
1196    let Unpredictable{15-12} = 0b1111;
1197  }
1198  def rsi : AI1<opcod, (outs),
1199               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis,
1200               opc, "\t$Rn, $shift",
1201               [(opnode GPR:$Rn, so_reg_imm:$shift)]> {
1202    bits<4> Rn;
1203    bits<12> shift;
1204    let Inst{25} = 0;
1205    let Inst{20} = 1;
1206    let Inst{19-16} = Rn;
1207    let Inst{15-12} = 0b0000;
1208    let Inst{11-5} = shift{11-5};
1209    let Inst{4} = 0;
1210    let Inst{3-0} = shift{3-0};
1211
1212    let Unpredictable{15-12} = 0b1111;
1213  }
1214  def rsr : AI1<opcod, (outs),
1215               (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis,
1216               opc, "\t$Rn, $shift",
1217               [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]> {
1218    bits<4> Rn;
1219    bits<12> shift;
1220    let Inst{25} = 0;
1221    let Inst{20} = 1;
1222    let Inst{19-16} = Rn;
1223    let Inst{15-12} = 0b0000;
1224    let Inst{11-8} = shift{11-8};
1225    let Inst{7} = 0;
1226    let Inst{6-5} = shift{6-5};
1227    let Inst{4} = 1;
1228    let Inst{3-0} = shift{3-0};
1229
1230    let Unpredictable{15-12} = 0b1111;
1231  }
1232
1233}
1234}
1235
1236/// AI_ext_rrot - A unary operation with two forms: one whose operand is a
1237/// register and one whose operand is a register rotated by 8/16/24.
1238/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
1239class AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode>
1240  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
1241          IIC_iEXTr, opc, "\t$Rd, $Rm$rot",
1242          [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
1243       Requires<[IsARM, HasV6]> {
1244  bits<4> Rd;
1245  bits<4> Rm;
1246  bits<2> rot;
1247  let Inst{19-16} = 0b1111;
1248  let Inst{15-12} = Rd;
1249  let Inst{11-10} = rot;
1250  let Inst{3-0}   = Rm;
1251}
1252
1253class AI_ext_rrot_np<bits<8> opcod, string opc>
1254  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
1255          IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>,
1256       Requires<[IsARM, HasV6]> {
1257  bits<2> rot;
1258  let Inst{19-16} = 0b1111;
1259  let Inst{11-10} = rot;
1260}
1261
1262/// AI_exta_rrot - A binary operation with two forms: one whose operand is a
1263/// register and one whose operand is a register rotated by 8/16/24.
1264class AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode>
1265  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
1266          IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot",
1267          [(set GPRnopc:$Rd, (opnode GPR:$Rn,
1268                                     (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
1269        Requires<[IsARM, HasV6]> {
1270  bits<4> Rd;
1271  bits<4> Rm;
1272  bits<4> Rn;
1273  bits<2> rot;
1274  let Inst{19-16} = Rn;
1275  let Inst{15-12} = Rd;
1276  let Inst{11-10} = rot;
1277  let Inst{9-4}   = 0b000111;
1278  let Inst{3-0}   = Rm;
1279}
1280
1281class AI_exta_rrot_np<bits<8> opcod, string opc>
1282  : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
1283          IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>,
1284       Requires<[IsARM, HasV6]> {
1285  bits<4> Rn;
1286  bits<2> rot;
1287  let Inst{19-16} = Rn;
1288  let Inst{11-10} = rot;
1289}
1290
1291/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
1292let TwoOperandAliasConstraint = "$Rn = $Rd" in
1293multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
1294                             bit Commutable = 0> {
1295  let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
1296  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1297                DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
1298               [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>,
1299               Requires<[IsARM]> {
1300    bits<4> Rd;
1301    bits<4> Rn;
1302    bits<12> imm;
1303    let Inst{25} = 1;
1304    let Inst{15-12} = Rd;
1305    let Inst{19-16} = Rn;
1306    let Inst{11-0} = imm;
1307  }
1308  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1309                DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
1310               [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>,
1311               Requires<[IsARM]> {
1312    bits<4> Rd;
1313    bits<4> Rn;
1314    bits<4> Rm;
1315    let Inst{11-4} = 0b00000000;
1316    let Inst{25} = 0;
1317    let isCommutable = Commutable;
1318    let Inst{3-0} = Rm;
1319    let Inst{15-12} = Rd;
1320    let Inst{19-16} = Rn;
1321  }
1322  def rsi : AsI1<opcod, (outs GPR:$Rd),
1323                (ins GPR:$Rn, so_reg_imm:$shift),
1324                DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1325              [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>,
1326               Requires<[IsARM]> {
1327    bits<4> Rd;
1328    bits<4> Rn;
1329    bits<12> shift;
1330    let Inst{25} = 0;
1331    let Inst{19-16} = Rn;
1332    let Inst{15-12} = Rd;
1333    let Inst{11-5} = shift{11-5};
1334    let Inst{4} = 0;
1335    let Inst{3-0} = shift{3-0};
1336  }
1337  def rsr : AsI1<opcod, (outs GPRnopc:$Rd),
1338                (ins GPRnopc:$Rn, so_reg_reg:$shift),
1339                DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1340              [(set GPRnopc:$Rd, CPSR,
1341                    (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>,
1342               Requires<[IsARM]> {
1343    bits<4> Rd;
1344    bits<4> Rn;
1345    bits<12> shift;
1346    let Inst{25} = 0;
1347    let Inst{19-16} = Rn;
1348    let Inst{15-12} = Rd;
1349    let Inst{11-8} = shift{11-8};
1350    let Inst{7} = 0;
1351    let Inst{6-5} = shift{6-5};
1352    let Inst{4} = 1;
1353    let Inst{3-0} = shift{3-0};
1354  }
1355  }
1356}
1357
1358/// AI1_rsc_irs - Define instructions and patterns for rsc
1359let TwoOperandAliasConstraint = "$Rn = $Rd" in
1360multiclass AI1_rsc_irs<bits<4> opcod, string opc, PatFrag opnode> {
1361  let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
1362  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1363                DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
1364               [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn, CPSR))]>,
1365               Requires<[IsARM]> {
1366    bits<4> Rd;
1367    bits<4> Rn;
1368    bits<12> imm;
1369    let Inst{25} = 1;
1370    let Inst{15-12} = Rd;
1371    let Inst{19-16} = Rn;
1372    let Inst{11-0} = imm;
1373  }
1374  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1375                DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
1376               [/* pattern left blank */]> {
1377    bits<4> Rd;
1378    bits<4> Rn;
1379    bits<4> Rm;
1380    let Inst{11-4} = 0b00000000;
1381    let Inst{25} = 0;
1382    let Inst{3-0} = Rm;
1383    let Inst{15-12} = Rd;
1384    let Inst{19-16} = Rn;
1385  }
1386  def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
1387                DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1388              [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>,
1389               Requires<[IsARM]> {
1390    bits<4> Rd;
1391    bits<4> Rn;
1392    bits<12> shift;
1393    let Inst{25} = 0;
1394    let Inst{19-16} = Rn;
1395    let Inst{15-12} = Rd;
1396    let Inst{11-5} = shift{11-5};
1397    let Inst{4} = 0;
1398    let Inst{3-0} = shift{3-0};
1399  }
1400  def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
1401                DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
1402              [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>,
1403               Requires<[IsARM]> {
1404    bits<4> Rd;
1405    bits<4> Rn;
1406    bits<12> shift;
1407    let Inst{25} = 0;
1408    let Inst{19-16} = Rn;
1409    let Inst{15-12} = Rd;
1410    let Inst{11-8} = shift{11-8};
1411    let Inst{7} = 0;
1412    let Inst{6-5} = shift{6-5};
1413    let Inst{4} = 1;
1414    let Inst{3-0} = shift{3-0};
1415  }
1416  }
1417}
1418
1419let canFoldAsLoad = 1, isReMaterializable = 1 in {
1420multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
1421           InstrItinClass iir, PatFrag opnode> {
1422  // Note: We use the complex addrmode_imm12 rather than just an input
1423  // GPR and a constrained immediate so that we can use this to match
1424  // frame index references and avoid matching constant pool references.
1425  def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1426                   AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
1427                  [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
1428    bits<4>  Rt;
1429    bits<17> addr;
1430    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1431    let Inst{19-16} = addr{16-13};  // Rn
1432    let Inst{15-12} = Rt;
1433    let Inst{11-0}  = addr{11-0};   // imm12
1434  }
1435  def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
1436                  AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
1437                 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
1438    bits<4>  Rt;
1439    bits<17> shift;
1440    let shift{4}    = 0;            // Inst{4} = 0
1441    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1442    let Inst{19-16} = shift{16-13}; // Rn
1443    let Inst{15-12} = Rt;
1444    let Inst{11-0}  = shift{11-0};
1445  }
1446}
1447}
1448
1449let canFoldAsLoad = 1, isReMaterializable = 1 in {
1450multiclass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii,
1451           InstrItinClass iir, PatFrag opnode> {
1452  // Note: We use the complex addrmode_imm12 rather than just an input
1453  // GPR and a constrained immediate so that we can use this to match
1454  // frame index references and avoid matching constant pool references.
1455  def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt),
1456                   (ins addrmode_imm12:$addr),
1457                   AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
1458                   [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> {
1459    bits<4>  Rt;
1460    bits<17> addr;
1461    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1462    let Inst{19-16} = addr{16-13};  // Rn
1463    let Inst{15-12} = Rt;
1464    let Inst{11-0}  = addr{11-0};   // imm12
1465  }
1466  def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt),
1467                   (ins ldst_so_reg:$shift),
1468                   AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
1469                   [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> {
1470    bits<4>  Rt;
1471    bits<17> shift;
1472    let shift{4}    = 0;            // Inst{4} = 0
1473    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1474    let Inst{19-16} = shift{16-13}; // Rn
1475    let Inst{15-12} = Rt;
1476    let Inst{11-0}  = shift{11-0};
1477  }
1478}
1479}
1480
1481
1482multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
1483           InstrItinClass iir, PatFrag opnode> {
1484  // Note: We use the complex addrmode_imm12 rather than just an input
1485  // GPR and a constrained immediate so that we can use this to match
1486  // frame index references and avoid matching constant pool references.
1487  def i12 : AI2ldst<0b010, 0, isByte, (outs),
1488                   (ins GPR:$Rt, addrmode_imm12:$addr),
1489                   AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
1490                  [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
1491    bits<4> Rt;
1492    bits<17> addr;
1493    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1494    let Inst{19-16} = addr{16-13};  // Rn
1495    let Inst{15-12} = Rt;
1496    let Inst{11-0}  = addr{11-0};   // imm12
1497  }
1498  def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
1499                  AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
1500                 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1501    bits<4> Rt;
1502    bits<17> shift;
1503    let shift{4}    = 0;            // Inst{4} = 0
1504    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1505    let Inst{19-16} = shift{16-13}; // Rn
1506    let Inst{15-12} = Rt;
1507    let Inst{11-0}  = shift{11-0};
1508  }
1509}
1510
1511multiclass AI_str1nopc<bit isByte, string opc, InstrItinClass iii,
1512           InstrItinClass iir, PatFrag opnode> {
1513  // Note: We use the complex addrmode_imm12 rather than just an input
1514  // GPR and a constrained immediate so that we can use this to match
1515  // frame index references and avoid matching constant pool references.
1516  def i12 : AI2ldst<0b010, 0, isByte, (outs),
1517                   (ins GPRnopc:$Rt, addrmode_imm12:$addr),
1518                   AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
1519                  [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> {
1520    bits<4> Rt;
1521    bits<17> addr;
1522    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1523    let Inst{19-16} = addr{16-13};  // Rn
1524    let Inst{15-12} = Rt;
1525    let Inst{11-0}  = addr{11-0};   // imm12
1526  }
1527  def rs : AI2ldst<0b011, 0, isByte, (outs),
1528                   (ins GPRnopc:$Rt, ldst_so_reg:$shift),
1529                   AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
1530                   [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> {
1531    bits<4> Rt;
1532    bits<17> shift;
1533    let shift{4}    = 0;            // Inst{4} = 0
1534    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
1535    let Inst{19-16} = shift{16-13}; // Rn
1536    let Inst{15-12} = Rt;
1537    let Inst{11-0}  = shift{11-0};
1538  }
1539}
1540
1541
1542//===----------------------------------------------------------------------===//
1543// Instructions
1544//===----------------------------------------------------------------------===//
1545
1546//===----------------------------------------------------------------------===//
1547//  Miscellaneous Instructions.
1548//
1549
1550/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1551/// the function.  The first operand is the ID# for this instruction, the second
1552/// is the index into the MachineConstantPool that this is, the third is the
1553/// size in bytes of this constant pool entry.
1554let neverHasSideEffects = 1, isNotDuplicable = 1 in
1555def CONSTPOOL_ENTRY :
1556PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1557                    i32imm:$size), NoItinerary, []>;
1558
1559// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1560// from removing one half of the matched pairs. That breaks PEI, which assumes
1561// these will always be in pairs, and asserts if it finds otherwise. Better way?
1562let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1563def ADJCALLSTACKUP :
1564PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1565           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1566
1567def ADJCALLSTACKDOWN :
1568PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1569           [(ARMcallseq_start timm:$amt)]>;
1570}
1571
1572// Atomic pseudo-insts which will be lowered to ldrexd/strexd loops.
1573// (These pseudos use a hand-written selection code).
1574let usesCustomInserter = 1, Defs = [CPSR], mayLoad = 1, mayStore = 1 in {
1575def ATOMOR6432   : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1576                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1577                              NoItinerary, []>;
1578def ATOMXOR6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1579                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1580                              NoItinerary, []>;
1581def ATOMADD6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1582                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1583                              NoItinerary, []>;
1584def ATOMSUB6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1585                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1586                              NoItinerary, []>;
1587def ATOMNAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1588                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1589                              NoItinerary, []>;
1590def ATOMAND6432  : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1591                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1592                              NoItinerary, []>;
1593def ATOMSWAP6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1594                              (ins GPR:$addr, GPR:$src1, GPR:$src2),
1595                              NoItinerary, []>;
1596def ATOMCMPXCHG6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2),
1597                                 (ins GPR:$addr, GPR:$cmp1, GPR:$cmp2,
1598                                      GPR:$set1, GPR:$set2),
1599                                 NoItinerary, []>;
1600}
1601
1602def HINT : AI<(outs), (ins imm0_255:$imm), MiscFrm, NoItinerary,
1603              "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> {
1604  bits<8> imm;
1605  let Inst{27-8} = 0b00110010000011110000;
1606  let Inst{7-0} = imm;
1607}
1608
1609def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1610def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1611def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1612def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1613def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>;
1614
1615def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
1616             "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> {
1617  bits<4> Rd;
1618  bits<4> Rn;
1619  bits<4> Rm;
1620  let Inst{3-0} = Rm;
1621  let Inst{15-12} = Rd;
1622  let Inst{19-16} = Rn;
1623  let Inst{27-20} = 0b01101000;
1624  let Inst{7-4} = 0b1011;
1625  let Inst{11-8} = 0b1111;
1626  let Unpredictable{11-8} = 0b1111;
1627}
1628
1629// The 16-bit operand $val can be used by a debugger to store more information
1630// about the breakpoint.
1631def BKPT : AI<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
1632              "bkpt", "\t$val", []>, Requires<[IsARM]> {
1633  bits<16> val;
1634  let Inst{3-0} = val{3-0};
1635  let Inst{19-8} = val{15-4};
1636  let Inst{27-20} = 0b00010010;
1637  let Inst{7-4} = 0b0111;
1638}
1639
1640// Change Processor State
1641// FIXME: We should use InstAlias to handle the optional operands.
1642class CPS<dag iops, string asm_ops>
1643  : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
1644        []>, Requires<[IsARM]> {
1645  bits<2> imod;
1646  bits<3> iflags;
1647  bits<5> mode;
1648  bit M;
1649
1650  let Inst{31-28} = 0b1111;
1651  let Inst{27-20} = 0b00010000;
1652  let Inst{19-18} = imod;
1653  let Inst{17}    = M; // Enabled if mode is set;
1654  let Inst{16-9}  = 0b00000000;
1655  let Inst{8-6}   = iflags;
1656  let Inst{5}     = 0;
1657  let Inst{4-0}   = mode;
1658}
1659
1660let DecoderMethod = "DecodeCPSInstruction" in {
1661let M = 1 in
1662  def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode),
1663                  "$imod\t$iflags, $mode">;
1664let mode = 0, M = 0 in
1665  def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
1666
1667let imod = 0, iflags = 0, M = 1 in
1668  def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">;
1669}
1670
1671// Preload signals the memory system of possible future data/instruction access.
1672multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1673
1674  def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1675                !strconcat(opc, "\t$addr"),
1676                [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1677    bits<4> Rt;
1678    bits<17> addr;
1679    let Inst{31-26} = 0b111101;
1680    let Inst{25} = 0; // 0 for immediate form
1681    let Inst{24} = data;
1682    let Inst{23} = addr{12};        // U (add = ('U' == 1))
1683    let Inst{22} = read;
1684    let Inst{21-20} = 0b01;
1685    let Inst{19-16} = addr{16-13};  // Rn
1686    let Inst{15-12} = 0b1111;
1687    let Inst{11-0}  = addr{11-0};   // imm12
1688  }
1689
1690  def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1691               !strconcat(opc, "\t$shift"),
1692               [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1693    bits<17> shift;
1694    let Inst{31-26} = 0b111101;
1695    let Inst{25} = 1; // 1 for register form
1696    let Inst{24} = data;
1697    let Inst{23} = shift{12};    // U (add = ('U' == 1))
1698    let Inst{22} = read;
1699    let Inst{21-20} = 0b01;
1700    let Inst{19-16} = shift{16-13}; // Rn
1701    let Inst{15-12} = 0b1111;
1702    let Inst{11-0}  = shift{11-0};
1703    let Inst{4} = 0;
1704  }
1705}
1706
1707defm PLD  : APreLoad<1, 1, "pld">,  Requires<[IsARM]>;
1708defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1709defm PLI  : APreLoad<1, 0, "pli">,  Requires<[IsARM,HasV7]>;
1710
1711def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary,
1712                 "setend\t$end", []>, Requires<[IsARM]> {
1713  bits<1> end;
1714  let Inst{31-10} = 0b1111000100000001000000;
1715  let Inst{9} = end;
1716  let Inst{8-0} = 0;
1717}
1718
1719def DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1720             []>, Requires<[IsARM, HasV7]> {
1721  bits<4> opt;
1722  let Inst{27-4} = 0b001100100000111100001111;
1723  let Inst{3-0} = opt;
1724}
1725
1726// A5.4 Permanently UNDEFINED instructions.
1727let isBarrier = 1, isTerminator = 1 in
1728def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1729               "trap", [(trap)]>,
1730           Requires<[IsARM]> {
1731  let Inst = 0xe7ffdefe;
1732}
1733
1734// Address computation and loads and stores in PIC mode.
1735let isNotDuplicable = 1 in {
1736def PICADD  : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1737                            4, IIC_iALUr,
1738                            [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1739
1740let AddedComplexity = 10 in {
1741def PICLDR  : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1742                            4, IIC_iLoad_r,
1743                            [(set GPR:$dst, (load addrmodepc:$addr))]>;
1744
1745def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1746                            4, IIC_iLoad_bh_r,
1747                            [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1748
1749def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1750                            4, IIC_iLoad_bh_r,
1751                            [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1752
1753def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1754                            4, IIC_iLoad_bh_r,
1755                            [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1756
1757def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1758                            4, IIC_iLoad_bh_r,
1759                            [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1760}
1761let AddedComplexity = 10 in {
1762def PICSTR  : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1763      4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1764
1765def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1766      4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1767                                                   addrmodepc:$addr)]>;
1768
1769def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1770      4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1771}
1772} // isNotDuplicable = 1
1773
1774
1775// LEApcrel - Load a pc-relative address into a register without offending the
1776// assembler.
1777let neverHasSideEffects = 1, isReMaterializable = 1 in
1778// The 'adr' mnemonic encodes differently if the label is before or after
1779// the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1780// know until then which form of the instruction will be used.
1781def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
1782                 MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []> {
1783  bits<4> Rd;
1784  bits<14> label;
1785  let Inst{27-25} = 0b001;
1786  let Inst{24} = 0;
1787  let Inst{23-22} = label{13-12};
1788  let Inst{21} = 0;
1789  let Inst{20} = 0;
1790  let Inst{19-16} = 0b1111;
1791  let Inst{15-12} = Rd;
1792  let Inst{11-0} = label{11-0};
1793}
1794def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1795                    4, IIC_iALUi, []>;
1796
1797def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1798                      (ins i32imm:$label, nohash_imm:$id, pred:$p),
1799                      4, IIC_iALUi, []>;
1800
1801//===----------------------------------------------------------------------===//
1802//  Control Flow Instructions.
1803//
1804
1805let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1806  // ARMV4T and above
1807  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1808                  "bx", "\tlr", [(ARMretflag)]>,
1809               Requires<[IsARM, HasV4T]> {
1810    let Inst{27-0}  = 0b0001001011111111111100011110;
1811  }
1812
1813  // ARMV4 only
1814  def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1815                  "mov", "\tpc, lr", [(ARMretflag)]>,
1816               Requires<[IsARM, NoV4T]> {
1817    let Inst{27-0} = 0b0001101000001111000000001110;
1818  }
1819}
1820
1821// Indirect branches
1822let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1823  // ARMV4T and above
1824  def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1825                  [(brind GPR:$dst)]>,
1826              Requires<[IsARM, HasV4T]> {
1827    bits<4> dst;
1828    let Inst{31-4} = 0b1110000100101111111111110001;
1829    let Inst{3-0}  = dst;
1830  }
1831
1832  def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br,
1833                  "bx", "\t$dst", [/* pattern left blank */]>,
1834              Requires<[IsARM, HasV4T]> {
1835    bits<4> dst;
1836    let Inst{27-4} = 0b000100101111111111110001;
1837    let Inst{3-0}  = dst;
1838  }
1839}
1840
1841// SP is marked as a use to prevent stack-pointer assignments that appear
1842// immediately before calls from potentially appearing dead.
1843let isCall = 1,
1844  // FIXME:  Do we really need a non-predicated version? If so, it should
1845  // at least be a pseudo instruction expanding to the predicated version
1846  // at MC lowering time.
1847  Defs = [LR], Uses = [SP] in {
1848  def BL  : ABXI<0b1011, (outs), (ins bl_target:$func),
1849                IIC_Br, "bl\t$func",
1850                [(ARMcall tglobaladdr:$func)]>,
1851            Requires<[IsARM]> {
1852    let Inst{31-28} = 0b1110;
1853    bits<24> func;
1854    let Inst{23-0} = func;
1855    let DecoderMethod = "DecodeBranchImmInstruction";
1856  }
1857
1858  def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func),
1859                   IIC_Br, "bl", "\t$func",
1860                   [(ARMcall_pred tglobaladdr:$func)]>,
1861                Requires<[IsARM]> {
1862    bits<24> func;
1863    let Inst{23-0} = func;
1864    let DecoderMethod = "DecodeBranchImmInstruction";
1865  }
1866
1867  // ARMv5T and above
1868  def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm,
1869                IIC_Br, "blx\t$func",
1870                [(ARMcall GPR:$func)]>,
1871            Requires<[IsARM, HasV5T]> {
1872    bits<4> func;
1873    let Inst{31-4} = 0b1110000100101111111111110011;
1874    let Inst{3-0}  = func;
1875  }
1876
1877  def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm,
1878                    IIC_Br, "blx", "\t$func",
1879                    [(ARMcall_pred GPR:$func)]>,
1880                 Requires<[IsARM, HasV5T]> {
1881    bits<4> func;
1882    let Inst{27-4} = 0b000100101111111111110011;
1883    let Inst{3-0}  = func;
1884  }
1885
1886  // ARMv4T
1887  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1888  def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func),
1889                   8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1890                   Requires<[IsARM, HasV4T]>;
1891
1892  // ARMv4
1893  def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func),
1894                   8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1895                   Requires<[IsARM, NoV4T]>;
1896
1897  // mov lr, pc; b if callee is marked noreturn to avoid confusing the
1898  // return stack predictor.
1899  def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins bl_target:$func),
1900                               8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>,
1901                      Requires<[IsARM]>;
1902}
1903
1904let isBranch = 1, isTerminator = 1 in {
1905  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1906  // a two-value operand where a dag node expects two operands. :(
1907  def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1908               IIC_Br, "b", "\t$target",
1909               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1910    bits<24> target;
1911    let Inst{23-0} = target;
1912    let DecoderMethod = "DecodeBranchImmInstruction";
1913  }
1914
1915  let isBarrier = 1 in {
1916    // B is "predicable" since it's just a Bcc with an 'always' condition.
1917    let isPredicable = 1 in
1918    // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
1919    // should be sufficient.
1920    // FIXME: Is B really a Barrier? That doesn't seem right.
1921    def B : ARMPseudoExpand<(outs), (ins br_target:$target), 4, IIC_Br,
1922                [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>;
1923
1924    let isNotDuplicable = 1, isIndirectBranch = 1 in {
1925    def BR_JTr : ARMPseudoInst<(outs),
1926                      (ins GPR:$target, i32imm:$jt, i32imm:$id),
1927                      0, IIC_Br,
1928                      [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1929    // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1930    // into i12 and rs suffixed versions.
1931    def BR_JTm : ARMPseudoInst<(outs),
1932                     (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1933                     0, IIC_Br,
1934                     [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1935                       imm:$id)]>;
1936    def BR_JTadd : ARMPseudoInst<(outs),
1937                   (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1938                   0, IIC_Br,
1939                   [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1940                     imm:$id)]>;
1941    } // isNotDuplicable = 1, isIndirectBranch = 1
1942  } // isBarrier = 1
1943
1944}
1945
1946// BLX (immediate)
1947def BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary,
1948               "blx\t$target", []>,
1949           Requires<[IsARM, HasV5T]> {
1950  let Inst{31-25} = 0b1111101;
1951  bits<25> target;
1952  let Inst{23-0} = target{24-1};
1953  let Inst{24} = target{0};
1954}
1955
1956// Branch and Exchange Jazelle
1957def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1958              [/* pattern left blank */]> {
1959  bits<4> func;
1960  let Inst{23-20} = 0b0010;
1961  let Inst{19-8} = 0xfff;
1962  let Inst{7-4} = 0b0010;
1963  let Inst{3-0} = func;
1964}
1965
1966// Tail calls.
1967
1968let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
1969  def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst), IIC_Br, []>;
1970
1971  def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst), IIC_Br, []>;
1972
1973  def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst),
1974                                 4, IIC_Br, [],
1975                                 (Bcc br_target:$dst, (ops 14, zero_reg))>,
1976                                 Requires<[IsARM]>;
1977
1978  def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst),
1979                                 4, IIC_Br, [],
1980                                 (BX GPR:$dst)>,
1981                                 Requires<[IsARM]>;
1982}
1983
1984// Secure Monitor Call is a system instruction.
1985def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt",
1986              []> {
1987  bits<4> opt;
1988  let Inst{23-4} = 0b01100000000000000111;
1989  let Inst{3-0} = opt;
1990}
1991
1992// Supervisor Call (Software Interrupt)
1993let isCall = 1, Uses = [SP] in {
1994def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> {
1995  bits<24> svc;
1996  let Inst{23-0} = svc;
1997}
1998}
1999
2000// Store Return State
2001class SRSI<bit wb, string asm>
2002  : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm,
2003       NoItinerary, asm, "", []> {
2004  bits<5> mode;
2005  let Inst{31-28} = 0b1111;
2006  let Inst{27-25} = 0b100;
2007  let Inst{22} = 1;
2008  let Inst{21} = wb;
2009  let Inst{20} = 0;
2010  let Inst{19-16} = 0b1101;  // SP
2011  let Inst{15-5} = 0b00000101000;
2012  let Inst{4-0} = mode;
2013}
2014
2015def SRSDA : SRSI<0, "srsda\tsp, $mode"> {
2016  let Inst{24-23} = 0;
2017}
2018def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> {
2019  let Inst{24-23} = 0;
2020}
2021def SRSDB : SRSI<0, "srsdb\tsp, $mode"> {
2022  let Inst{24-23} = 0b10;
2023}
2024def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> {
2025  let Inst{24-23} = 0b10;
2026}
2027def SRSIA : SRSI<0, "srsia\tsp, $mode"> {
2028  let Inst{24-23} = 0b01;
2029}
2030def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> {
2031  let Inst{24-23} = 0b01;
2032}
2033def SRSIB : SRSI<0, "srsib\tsp, $mode"> {
2034  let Inst{24-23} = 0b11;
2035}
2036def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> {
2037  let Inst{24-23} = 0b11;
2038}
2039
2040// Return From Exception
2041class RFEI<bit wb, string asm>
2042  : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm,
2043       NoItinerary, asm, "", []> {
2044  bits<4> Rn;
2045  let Inst{31-28} = 0b1111;
2046  let Inst{27-25} = 0b100;
2047  let Inst{22} = 0;
2048  let Inst{21} = wb;
2049  let Inst{20} = 1;
2050  let Inst{19-16} = Rn;
2051  let Inst{15-0} = 0xa00;
2052}
2053
2054def RFEDA : RFEI<0, "rfeda\t$Rn"> {
2055  let Inst{24-23} = 0;
2056}
2057def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> {
2058  let Inst{24-23} = 0;
2059}
2060def RFEDB : RFEI<0, "rfedb\t$Rn"> {
2061  let Inst{24-23} = 0b10;
2062}
2063def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> {
2064  let Inst{24-23} = 0b10;
2065}
2066def RFEIA : RFEI<0, "rfeia\t$Rn"> {
2067  let Inst{24-23} = 0b01;
2068}
2069def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> {
2070  let Inst{24-23} = 0b01;
2071}
2072def RFEIB : RFEI<0, "rfeib\t$Rn"> {
2073  let Inst{24-23} = 0b11;
2074}
2075def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
2076  let Inst{24-23} = 0b11;
2077}
2078
2079//===----------------------------------------------------------------------===//
2080//  Load / Store Instructions.
2081//
2082
2083// Load
2084
2085
2086defm LDR  : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
2087                    UnOpFrag<(load node:$Src)>>;
2088defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
2089                    UnOpFrag<(zextloadi8 node:$Src)>>;
2090defm STR  : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
2091                   BinOpFrag<(store node:$LHS, node:$RHS)>>;
2092defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
2093                   BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
2094
2095// Special LDR for loads from non-pc-relative constpools.
2096let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
2097    isReMaterializable = 1, isCodeGenOnly = 1 in
2098def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
2099                 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
2100                 []> {
2101  bits<4> Rt;
2102  bits<17> addr;
2103  let Inst{23}    = addr{12};     // U (add = ('U' == 1))
2104  let Inst{19-16} = 0b1111;
2105  let Inst{15-12} = Rt;
2106  let Inst{11-0}  = addr{11-0};   // imm12
2107}
2108
2109// Loads with zero extension
2110def LDRH  : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2111                  IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
2112                  [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
2113
2114// Loads with sign extension
2115def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2116                   IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
2117                   [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
2118
2119def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
2120                   IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
2121                   [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
2122
2123let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
2124// Load doubleword
2125def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
2126                 (ins addrmode3:$addr), LdMiscFrm,
2127                 IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr",
2128                 []>, Requires<[IsARM, HasV5TE]>;
2129}
2130
2131// Indexed loads
2132multiclass AI2_ldridx<bit isByte, string opc,
2133                      InstrItinClass iii, InstrItinClass iir> {
2134  def _PRE_IMM  : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2135                      (ins addrmode_imm12:$addr), IndexModePre, LdFrm, iii,
2136                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2137    bits<17> addr;
2138    let Inst{25} = 0;
2139    let Inst{23} = addr{12};
2140    let Inst{19-16} = addr{16-13};
2141    let Inst{11-0} = addr{11-0};
2142    let DecoderMethod = "DecodeLDRPreImm";
2143    let AsmMatchConverter = "cvtLdWriteBackRegAddrModeImm12";
2144  }
2145
2146  def _PRE_REG  : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2147                      (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir,
2148                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2149    bits<17> addr;
2150    let Inst{25} = 1;
2151    let Inst{23} = addr{12};
2152    let Inst{19-16} = addr{16-13};
2153    let Inst{11-0} = addr{11-0};
2154    let Inst{4} = 0;
2155    let DecoderMethod = "DecodeLDRPreReg";
2156    let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
2157  }
2158
2159  def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2160                       (ins addr_offset_none:$addr, am2offset_reg:$offset),
2161                       IndexModePost, LdFrm, iir,
2162                       opc, "\t$Rt, $addr, $offset",
2163                       "$addr.base = $Rn_wb", []> {
2164     // {12}     isAdd
2165     // {11-0}   imm12/Rm
2166     bits<14> offset;
2167     bits<4> addr;
2168     let Inst{25} = 1;
2169     let Inst{23} = offset{12};
2170     let Inst{19-16} = addr;
2171     let Inst{11-0} = offset{11-0};
2172
2173    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2174   }
2175
2176   def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2177                       (ins addr_offset_none:$addr, am2offset_imm:$offset),
2178                      IndexModePost, LdFrm, iii,
2179                      opc, "\t$Rt, $addr, $offset",
2180                      "$addr.base = $Rn_wb", []> {
2181    // {12}     isAdd
2182    // {11-0}   imm12/Rm
2183    bits<14> offset;
2184    bits<4> addr;
2185    let Inst{25} = 0;
2186    let Inst{23} = offset{12};
2187    let Inst{19-16} = addr;
2188    let Inst{11-0} = offset{11-0};
2189
2190    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2191  }
2192
2193}
2194
2195let mayLoad = 1, neverHasSideEffects = 1 in {
2196// FIXME: for LDR_PRE_REG etc. the itineray should be either IIC_iLoad_ru or
2197// IIC_iLoad_siu depending on whether it the offset register is shifted.
2198defm LDR  : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>;
2199defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>;
2200}
2201
2202multiclass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> {
2203  def _PRE  : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
2204                        (ins addrmode3:$addr), IndexModePre,
2205                        LdMiscFrm, itin,
2206                        opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2207    bits<14> addr;
2208    let Inst{23}    = addr{8};      // U bit
2209    let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2210    let Inst{19-16} = addr{12-9};   // Rn
2211    let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2212    let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2213    let AsmMatchConverter = "cvtLdWriteBackRegAddrMode3";
2214    let DecoderMethod = "DecodeAddrMode3Instruction";
2215  }
2216  def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2217                        (ins addr_offset_none:$addr, am3offset:$offset),
2218                        IndexModePost, LdMiscFrm, itin,
2219                        opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb",
2220                        []> {
2221    bits<10> offset;
2222    bits<4> addr;
2223    let Inst{23}    = offset{8};      // U bit
2224    let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2225    let Inst{19-16} = addr;
2226    let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2227    let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2228    let DecoderMethod = "DecodeAddrMode3Instruction";
2229  }
2230}
2231
2232let mayLoad = 1, neverHasSideEffects = 1 in {
2233defm LDRH  : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>;
2234defm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>;
2235defm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>;
2236let hasExtraDefRegAllocReq = 1 in {
2237def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
2238                          (ins addrmode3:$addr), IndexModePre,
2239                          LdMiscFrm, IIC_iLoad_d_ru,
2240                          "ldrd", "\t$Rt, $Rt2, $addr!",
2241                          "$addr.base = $Rn_wb", []> {
2242  bits<14> addr;
2243  let Inst{23}    = addr{8};      // U bit
2244  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2245  let Inst{19-16} = addr{12-9};   // Rn
2246  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2247  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2248  let DecoderMethod = "DecodeAddrMode3Instruction";
2249  let AsmMatchConverter = "cvtLdrdPre";
2250}
2251def LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
2252                          (ins addr_offset_none:$addr, am3offset:$offset),
2253                          IndexModePost, LdMiscFrm, IIC_iLoad_d_ru,
2254                          "ldrd", "\t$Rt, $Rt2, $addr, $offset",
2255                          "$addr.base = $Rn_wb", []> {
2256  bits<10> offset;
2257  bits<4> addr;
2258  let Inst{23}    = offset{8};      // U bit
2259  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2260  let Inst{19-16} = addr;
2261  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2262  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2263  let DecoderMethod = "DecodeAddrMode3Instruction";
2264}
2265} // hasExtraDefRegAllocReq = 1
2266} // mayLoad = 1, neverHasSideEffects = 1
2267
2268// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT.
2269let mayLoad = 1, neverHasSideEffects = 1 in {
2270def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2271                    (ins addr_offset_none:$addr, am2offset_reg:$offset),
2272                    IndexModePost, LdFrm, IIC_iLoad_ru,
2273                    "ldrt", "\t$Rt, $addr, $offset",
2274                    "$addr.base = $Rn_wb", []> {
2275  // {12}     isAdd
2276  // {11-0}   imm12/Rm
2277  bits<14> offset;
2278  bits<4> addr;
2279  let Inst{25} = 1;
2280  let Inst{23} = offset{12};
2281  let Inst{21} = 1; // overwrite
2282  let Inst{19-16} = addr;
2283  let Inst{11-5} = offset{11-5};
2284  let Inst{4} = 0;
2285  let Inst{3-0} = offset{3-0};
2286  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2287}
2288
2289def LDRT_POST_IMM : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2290                    (ins addr_offset_none:$addr, am2offset_imm:$offset),
2291                   IndexModePost, LdFrm, IIC_iLoad_ru,
2292                   "ldrt", "\t$Rt, $addr, $offset",
2293                   "$addr.base = $Rn_wb", []> {
2294  // {12}     isAdd
2295  // {11-0}   imm12/Rm
2296  bits<14> offset;
2297  bits<4> addr;
2298  let Inst{25} = 0;
2299  let Inst{23} = offset{12};
2300  let Inst{21} = 1; // overwrite
2301  let Inst{19-16} = addr;
2302  let Inst{11-0} = offset{11-0};
2303  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2304}
2305
2306def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2307                     (ins addr_offset_none:$addr, am2offset_reg:$offset),
2308                     IndexModePost, LdFrm, IIC_iLoad_bh_ru,
2309                     "ldrbt", "\t$Rt, $addr, $offset",
2310                     "$addr.base = $Rn_wb", []> {
2311  // {12}     isAdd
2312  // {11-0}   imm12/Rm
2313  bits<14> offset;
2314  bits<4> addr;
2315  let Inst{25} = 1;
2316  let Inst{23} = offset{12};
2317  let Inst{21} = 1; // overwrite
2318  let Inst{19-16} = addr;
2319  let Inst{11-5} = offset{11-5};
2320  let Inst{4} = 0;
2321  let Inst{3-0} = offset{3-0};
2322  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2323}
2324
2325def LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
2326                     (ins addr_offset_none:$addr, am2offset_imm:$offset),
2327                    IndexModePost, LdFrm, IIC_iLoad_bh_ru,
2328                    "ldrbt", "\t$Rt, $addr, $offset",
2329                    "$addr.base = $Rn_wb", []> {
2330  // {12}     isAdd
2331  // {11-0}   imm12/Rm
2332  bits<14> offset;
2333  bits<4> addr;
2334  let Inst{25} = 0;
2335  let Inst{23} = offset{12};
2336  let Inst{21} = 1; // overwrite
2337  let Inst{19-16} = addr;
2338  let Inst{11-0} = offset{11-0};
2339  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2340}
2341
2342multiclass AI3ldrT<bits<4> op, string opc> {
2343  def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb),
2344                      (ins addr_offset_none:$addr, postidx_imm8:$offset),
2345                      IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
2346                      "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
2347    bits<9> offset;
2348    let Inst{23} = offset{8};
2349    let Inst{22} = 1;
2350    let Inst{11-8} = offset{7-4};
2351    let Inst{3-0} = offset{3-0};
2352    let AsmMatchConverter = "cvtLdExtTWriteBackImm";
2353  }
2354  def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb),
2355                      (ins addr_offset_none:$addr, postidx_reg:$Rm),
2356                      IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
2357                      "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
2358    bits<5> Rm;
2359    let Inst{23} = Rm{4};
2360    let Inst{22} = 0;
2361    let Inst{11-8} = 0;
2362    let Unpredictable{11-8} = 0b1111;
2363    let Inst{3-0} = Rm{3-0};
2364    let AsmMatchConverter = "cvtLdExtTWriteBackReg";
2365    let DecoderMethod = "DecodeLDR";
2366  }
2367}
2368
2369defm LDRSBT : AI3ldrT<0b1101, "ldrsbt">;
2370defm LDRHT  : AI3ldrT<0b1011, "ldrht">;
2371defm LDRSHT : AI3ldrT<0b1111, "ldrsht">;
2372}
2373
2374// Store
2375
2376// Stores with truncate
2377def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
2378               IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
2379               [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
2380
2381// Store doubleword
2382let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
2383def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr),
2384               StMiscFrm, IIC_iStore_d_r,
2385               "strd", "\t$Rt, $src2, $addr", []>,
2386           Requires<[IsARM, HasV5TE]> {
2387  let Inst{21} = 0;
2388}
2389
2390// Indexed stores
2391multiclass AI2_stridx<bit isByte, string opc,
2392                      InstrItinClass iii, InstrItinClass iir> {
2393  def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
2394                            (ins GPR:$Rt, addrmode_imm12:$addr), IndexModePre,
2395                            StFrm, iii,
2396                            opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2397    bits<17> addr;
2398    let Inst{25} = 0;
2399    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
2400    let Inst{19-16} = addr{16-13};  // Rn
2401    let Inst{11-0}  = addr{11-0};   // imm12
2402    let AsmMatchConverter = "cvtStWriteBackRegAddrModeImm12";
2403    let DecoderMethod = "DecodeSTRPreImm";
2404  }
2405
2406  def _PRE_REG  : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
2407                      (ins GPR:$Rt, ldst_so_reg:$addr),
2408                      IndexModePre, StFrm, iir,
2409                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2410    bits<17> addr;
2411    let Inst{25} = 1;
2412    let Inst{23}    = addr{12};    // U (add = ('U' == 1))
2413    let Inst{19-16} = addr{16-13}; // Rn
2414    let Inst{11-0}  = addr{11-0};
2415    let Inst{4}     = 0;           // Inst{4} = 0
2416    let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
2417    let DecoderMethod = "DecodeSTRPreReg";
2418  }
2419  def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
2420                (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2421                IndexModePost, StFrm, iir,
2422                opc, "\t$Rt, $addr, $offset",
2423                "$addr.base = $Rn_wb", []> {
2424     // {12}     isAdd
2425     // {11-0}   imm12/Rm
2426     bits<14> offset;
2427     bits<4> addr;
2428     let Inst{25} = 1;
2429     let Inst{23} = offset{12};
2430     let Inst{19-16} = addr;
2431     let Inst{11-0} = offset{11-0};
2432     let Inst{4} = 0;
2433
2434    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2435   }
2436
2437   def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
2438                (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2439                IndexModePost, StFrm, iii,
2440                opc, "\t$Rt, $addr, $offset",
2441                "$addr.base = $Rn_wb", []> {
2442    // {12}     isAdd
2443    // {11-0}   imm12/Rm
2444    bits<14> offset;
2445    bits<4> addr;
2446    let Inst{25} = 0;
2447    let Inst{23} = offset{12};
2448    let Inst{19-16} = addr;
2449    let Inst{11-0} = offset{11-0};
2450
2451    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2452  }
2453}
2454
2455let mayStore = 1, neverHasSideEffects = 1 in {
2456// FIXME: for STR_PRE_REG etc. the itineray should be either IIC_iStore_ru or
2457// IIC_iStore_siu depending on whether it the offset register is shifted.
2458defm STR  : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>;
2459defm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>;
2460}
2461
2462def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
2463                         am2offset_reg:$offset),
2464             (STR_POST_REG GPR:$Rt, addr_offset_none:$addr,
2465                           am2offset_reg:$offset)>;
2466def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
2467                         am2offset_imm:$offset),
2468             (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr,
2469                           am2offset_imm:$offset)>;
2470def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
2471                             am2offset_reg:$offset),
2472             (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr,
2473                            am2offset_reg:$offset)>;
2474def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
2475                             am2offset_imm:$offset),
2476             (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr,
2477                            am2offset_imm:$offset)>;
2478
2479// Pseudo-instructions for pattern matching the pre-indexed stores. We can't
2480// put the patterns on the instruction definitions directly as ISel wants
2481// the address base and offset to be separate operands, not a single
2482// complex operand like we represent the instructions themselves. The
2483// pseudos map between the two.
2484let usesCustomInserter = 1,
2485    Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in {
2486def STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2487               (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
2488               4, IIC_iStore_ru,
2489            [(set GPR:$Rn_wb,
2490                  (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
2491def STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2492               (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
2493               4, IIC_iStore_ru,
2494            [(set GPR:$Rn_wb,
2495                  (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
2496def STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2497               (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
2498               4, IIC_iStore_ru,
2499            [(set GPR:$Rn_wb,
2500                  (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
2501def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2502               (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
2503               4, IIC_iStore_ru,
2504            [(set GPR:$Rn_wb,
2505                  (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
2506def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
2507               (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p),
2508               4, IIC_iStore_ru,
2509            [(set GPR:$Rn_wb,
2510                  (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
2511}
2512
2513
2514
2515def STRH_PRE  : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb),
2516                           (ins GPR:$Rt, addrmode3:$addr), IndexModePre,
2517                           StMiscFrm, IIC_iStore_bh_ru,
2518                           "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
2519  bits<14> addr;
2520  let Inst{23}    = addr{8};      // U bit
2521  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2522  let Inst{19-16} = addr{12-9};   // Rn
2523  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2524  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2525  let AsmMatchConverter = "cvtStWriteBackRegAddrMode3";
2526  let DecoderMethod = "DecodeAddrMode3Instruction";
2527}
2528
2529def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb),
2530                       (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset),
2531                       IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
2532                       "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb",
2533                   [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
2534                                                      addr_offset_none:$addr,
2535                                                      am3offset:$offset))]> {
2536  bits<10> offset;
2537  bits<4> addr;
2538  let Inst{23}    = offset{8};      // U bit
2539  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2540  let Inst{19-16} = addr;
2541  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2542  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2543  let DecoderMethod = "DecodeAddrMode3Instruction";
2544}
2545
2546let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
2547def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb),
2548                          (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
2549                          IndexModePre, StMiscFrm, IIC_iStore_d_ru,
2550                          "strd", "\t$Rt, $Rt2, $addr!",
2551                          "$addr.base = $Rn_wb", []> {
2552  bits<14> addr;
2553  let Inst{23}    = addr{8};      // U bit
2554  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
2555  let Inst{19-16} = addr{12-9};   // Rn
2556  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
2557  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
2558  let DecoderMethod = "DecodeAddrMode3Instruction";
2559  let AsmMatchConverter = "cvtStrdPre";
2560}
2561
2562def STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb),
2563                          (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr,
2564                               am3offset:$offset),
2565                          IndexModePost, StMiscFrm, IIC_iStore_d_ru,
2566                          "strd", "\t$Rt, $Rt2, $addr, $offset",
2567                          "$addr.base = $Rn_wb", []> {
2568  bits<10> offset;
2569  bits<4> addr;
2570  let Inst{23}    = offset{8};      // U bit
2571  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
2572  let Inst{19-16} = addr;
2573  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
2574  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
2575  let DecoderMethod = "DecodeAddrMode3Instruction";
2576}
2577} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
2578
2579// STRT, STRBT, and STRHT
2580
2581def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
2582                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2583                   IndexModePost, StFrm, IIC_iStore_bh_ru,
2584                   "strbt", "\t$Rt, $addr, $offset",
2585                   "$addr.base = $Rn_wb", []> {
2586  // {12}     isAdd
2587  // {11-0}   imm12/Rm
2588  bits<14> offset;
2589  bits<4> addr;
2590  let Inst{25} = 1;
2591  let Inst{23} = offset{12};
2592  let Inst{21} = 1; // overwrite
2593  let Inst{19-16} = addr;
2594  let Inst{11-5} = offset{11-5};
2595  let Inst{4} = 0;
2596  let Inst{3-0} = offset{3-0};
2597  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2598}
2599
2600def STRBT_POST_IMM : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
2601                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2602                   IndexModePost, StFrm, IIC_iStore_bh_ru,
2603                   "strbt", "\t$Rt, $addr, $offset",
2604                   "$addr.base = $Rn_wb", []> {
2605  // {12}     isAdd
2606  // {11-0}   imm12/Rm
2607  bits<14> offset;
2608  bits<4> addr;
2609  let Inst{25} = 0;
2610  let Inst{23} = offset{12};
2611  let Inst{21} = 1; // overwrite
2612  let Inst{19-16} = addr;
2613  let Inst{11-0} = offset{11-0};
2614  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2615}
2616
2617let mayStore = 1, neverHasSideEffects = 1 in {
2618def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
2619                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
2620                   IndexModePost, StFrm, IIC_iStore_ru,
2621                   "strt", "\t$Rt, $addr, $offset",
2622                   "$addr.base = $Rn_wb", []> {
2623  // {12}     isAdd
2624  // {11-0}   imm12/Rm
2625  bits<14> offset;
2626  bits<4> addr;
2627  let Inst{25} = 1;
2628  let Inst{23} = offset{12};
2629  let Inst{21} = 1; // overwrite
2630  let Inst{19-16} = addr;
2631  let Inst{11-5} = offset{11-5};
2632  let Inst{4} = 0;
2633  let Inst{3-0} = offset{3-0};
2634  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2635}
2636
2637def STRT_POST_IMM : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
2638                   (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
2639                   IndexModePost, StFrm, IIC_iStore_ru,
2640                   "strt", "\t$Rt, $addr, $offset",
2641                   "$addr.base = $Rn_wb", []> {
2642  // {12}     isAdd
2643  // {11-0}   imm12/Rm
2644  bits<14> offset;
2645  bits<4> addr;
2646  let Inst{25} = 0;
2647  let Inst{23} = offset{12};
2648  let Inst{21} = 1; // overwrite
2649  let Inst{19-16} = addr;
2650  let Inst{11-0} = offset{11-0};
2651  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
2652}
2653}
2654
2655
2656multiclass AI3strT<bits<4> op, string opc> {
2657  def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
2658                    (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset),
2659                    IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
2660                    "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
2661    bits<9> offset;
2662    let Inst{23} = offset{8};
2663    let Inst{22} = 1;
2664    let Inst{11-8} = offset{7-4};
2665    let Inst{3-0} = offset{3-0};
2666    let AsmMatchConverter = "cvtStExtTWriteBackImm";
2667  }
2668  def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
2669                      (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm),
2670                      IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
2671                      "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
2672    bits<5> Rm;
2673    let Inst{23} = Rm{4};
2674    let Inst{22} = 0;
2675    let Inst{11-8} = 0;
2676    let Inst{3-0} = Rm{3-0};
2677    let AsmMatchConverter = "cvtStExtTWriteBackReg";
2678  }
2679}
2680
2681
2682defm STRHT : AI3strT<0b1011, "strht">;
2683
2684
2685//===----------------------------------------------------------------------===//
2686//  Load / store multiple Instructions.
2687//
2688
2689multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f,
2690                         InstrItinClass itin, InstrItinClass itin_upd> {
2691  // IA is the default, so no need for an explicit suffix on the
2692  // mnemonic here. Without it is the canonical spelling.
2693  def IA :
2694    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2695         IndexModeNone, f, itin,
2696         !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> {
2697    let Inst{24-23} = 0b01;       // Increment After
2698    let Inst{22}    = P_bit;
2699    let Inst{21}    = 0;          // No writeback
2700    let Inst{20}    = L_bit;
2701  }
2702  def IA_UPD :
2703    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2704         IndexModeUpd, f, itin_upd,
2705         !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2706    let Inst{24-23} = 0b01;       // Increment After
2707    let Inst{22}    = P_bit;
2708    let Inst{21}    = 1;          // Writeback
2709    let Inst{20}    = L_bit;
2710
2711    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2712  }
2713  def DA :
2714    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2715         IndexModeNone, f, itin,
2716         !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> {
2717    let Inst{24-23} = 0b00;       // Decrement After
2718    let Inst{22}    = P_bit;
2719    let Inst{21}    = 0;          // No writeback
2720    let Inst{20}    = L_bit;
2721  }
2722  def DA_UPD :
2723    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2724         IndexModeUpd, f, itin_upd,
2725         !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2726    let Inst{24-23} = 0b00;       // Decrement After
2727    let Inst{22}    = P_bit;
2728    let Inst{21}    = 1;          // Writeback
2729    let Inst{20}    = L_bit;
2730
2731    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2732  }
2733  def DB :
2734    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2735         IndexModeNone, f, itin,
2736         !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> {
2737    let Inst{24-23} = 0b10;       // Decrement Before
2738    let Inst{22}    = P_bit;
2739    let Inst{21}    = 0;          // No writeback
2740    let Inst{20}    = L_bit;
2741  }
2742  def DB_UPD :
2743    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2744         IndexModeUpd, f, itin_upd,
2745         !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2746    let Inst{24-23} = 0b10;       // Decrement Before
2747    let Inst{22}    = P_bit;
2748    let Inst{21}    = 1;          // Writeback
2749    let Inst{20}    = L_bit;
2750
2751    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2752  }
2753  def IB :
2754    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2755         IndexModeNone, f, itin,
2756         !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> {
2757    let Inst{24-23} = 0b11;       // Increment Before
2758    let Inst{22}    = P_bit;
2759    let Inst{21}    = 0;          // No writeback
2760    let Inst{20}    = L_bit;
2761  }
2762  def IB_UPD :
2763    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
2764         IndexModeUpd, f, itin_upd,
2765         !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
2766    let Inst{24-23} = 0b11;       // Increment Before
2767    let Inst{22}    = P_bit;
2768    let Inst{21}    = 1;          // Writeback
2769    let Inst{20}    = L_bit;
2770
2771    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
2772  }
2773}
2774
2775let neverHasSideEffects = 1 in {
2776
2777let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
2778defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
2779                         IIC_iLoad_mu>;
2780
2781let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
2782defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m,
2783                         IIC_iStore_mu>;
2784
2785} // neverHasSideEffects
2786
2787// FIXME: remove when we have a way to marking a MI with these properties.
2788// FIXME: Should pc be an implicit operand like PICADD, etc?
2789let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2790    hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2791def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2792                                                 reglist:$regs, variable_ops),
2793                     4, IIC_iLoad_mBr, [],
2794                     (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
2795      RegConstraint<"$Rn = $wb">;
2796
2797let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
2798defm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m,
2799                               IIC_iLoad_mu>;
2800
2801let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
2802defm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m,
2803                               IIC_iStore_mu>;
2804
2805
2806
2807//===----------------------------------------------------------------------===//
2808//  Move Instructions.
2809//
2810
2811let neverHasSideEffects = 1 in
2812def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
2813                "mov", "\t$Rd, $Rm", []>, UnaryDP {
2814  bits<4> Rd;
2815  bits<4> Rm;
2816
2817  let Inst{19-16} = 0b0000;
2818  let Inst{11-4} = 0b00000000;
2819  let Inst{25} = 0;
2820  let Inst{3-0} = Rm;
2821  let Inst{15-12} = Rd;
2822}
2823
2824// A version for the smaller set of tail call registers.
2825let neverHasSideEffects = 1 in
2826def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
2827                IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
2828  bits<4> Rd;
2829  bits<4> Rm;
2830
2831  let Inst{11-4} = 0b00000000;
2832  let Inst{25} = 0;
2833  let Inst{3-0} = Rm;
2834  let Inst{15-12} = Rd;
2835}
2836
2837def MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src),
2838                DPSoRegRegFrm, IIC_iMOVsr,
2839                "mov", "\t$Rd, $src",
2840                [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP {
2841  bits<4> Rd;
2842  bits<12> src;
2843  let Inst{15-12} = Rd;
2844  let Inst{19-16} = 0b0000;
2845  let Inst{11-8} = src{11-8};
2846  let Inst{7} = 0;
2847  let Inst{6-5} = src{6-5};
2848  let Inst{4} = 1;
2849  let Inst{3-0} = src{3-0};
2850  let Inst{25} = 0;
2851}
2852
2853def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src),
2854                DPSoRegImmFrm, IIC_iMOVsr,
2855                "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>,
2856                UnaryDP {
2857  bits<4> Rd;
2858  bits<12> src;
2859  let Inst{15-12} = Rd;
2860  let Inst{19-16} = 0b0000;
2861  let Inst{11-5} = src{11-5};
2862  let Inst{4} = 0;
2863  let Inst{3-0} = src{3-0};
2864  let Inst{25} = 0;
2865}
2866
2867let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2868def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
2869                "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
2870  bits<4> Rd;
2871  bits<12> imm;
2872  let Inst{25} = 1;
2873  let Inst{15-12} = Rd;
2874  let Inst{19-16} = 0b0000;
2875  let Inst{11-0} = imm;
2876}
2877
2878let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2879def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm),
2880                 DPFrm, IIC_iMOVi,
2881                 "movw", "\t$Rd, $imm",
2882                 [(set GPR:$Rd, imm0_65535:$imm)]>,
2883                 Requires<[IsARM, HasV6T2]>, UnaryDP {
2884  bits<4> Rd;
2885  bits<16> imm;
2886  let Inst{15-12} = Rd;
2887  let Inst{11-0}  = imm{11-0};
2888  let Inst{19-16} = imm{15-12};
2889  let Inst{20} = 0;
2890  let Inst{25} = 1;
2891  let DecoderMethod = "DecodeArmMOVTWInstruction";
2892}
2893
2894def : InstAlias<"mov${p} $Rd, $imm",
2895                (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p)>,
2896        Requires<[IsARM]>;
2897
2898def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2899                                (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2900
2901let Constraints = "$src = $Rd" in {
2902def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd),
2903                  (ins GPR:$src, imm0_65535_expr:$imm),
2904                  DPFrm, IIC_iMOVi,
2905                  "movt", "\t$Rd, $imm",
2906                  [(set GPRnopc:$Rd,
2907                        (or (and GPR:$src, 0xffff),
2908                            lo16AllZero:$imm))]>, UnaryDP,
2909                  Requires<[IsARM, HasV6T2]> {
2910  bits<4> Rd;
2911  bits<16> imm;
2912  let Inst{15-12} = Rd;
2913  let Inst{11-0}  = imm{11-0};
2914  let Inst{19-16} = imm{15-12};
2915  let Inst{20} = 0;
2916  let Inst{25} = 1;
2917  let DecoderMethod = "DecodeArmMOVTWInstruction";
2918}
2919
2920def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2921                      (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2922
2923} // Constraints
2924
2925def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2926      Requires<[IsARM, HasV6T2]>;
2927
2928let Uses = [CPSR] in
2929def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2930                    [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2931                    Requires<[IsARM]>;
2932
2933// These aren't really mov instructions, but we have to define them this way
2934// due to flag operands.
2935
2936let Defs = [CPSR] in {
2937def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2938                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2939                      Requires<[IsARM]>;
2940def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2941                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2942                      Requires<[IsARM]>;
2943}
2944
2945//===----------------------------------------------------------------------===//
2946//  Extend Instructions.
2947//
2948
2949// Sign extenders
2950
2951def SXTB  : AI_ext_rrot<0b01101010,
2952                         "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2953def SXTH  : AI_ext_rrot<0b01101011,
2954                         "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2955
2956def SXTAB : AI_exta_rrot<0b01101010,
2957               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2958def SXTAH : AI_exta_rrot<0b01101011,
2959               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2960
2961def SXTB16  : AI_ext_rrot_np<0b01101000, "sxtb16">;
2962
2963def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2964
2965// Zero extenders
2966
2967let AddedComplexity = 16 in {
2968def UXTB   : AI_ext_rrot<0b01101110,
2969                          "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2970def UXTH   : AI_ext_rrot<0b01101111,
2971                          "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2972def UXTB16 : AI_ext_rrot<0b01101100,
2973                          "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2974
2975// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2976//        The transformation should probably be done as a combiner action
2977//        instead so we can include a check for masking back in the upper
2978//        eight bits of the source into the lower eight bits of the result.
2979//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2980//               (UXTB16r_rot GPR:$Src, 3)>;
2981def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2982               (UXTB16 GPR:$Src, 1)>;
2983
2984def UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2985                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2986def UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2987                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2988}
2989
2990// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2991def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2992
2993
2994def SBFX  : I<(outs GPRnopc:$Rd),
2995              (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width),
2996               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
2997               "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2998               Requires<[IsARM, HasV6T2]> {
2999  bits<4> Rd;
3000  bits<4> Rn;
3001  bits<5> lsb;
3002  bits<5> width;
3003  let Inst{27-21} = 0b0111101;
3004  let Inst{6-4}   = 0b101;
3005  let Inst{20-16} = width;
3006  let Inst{15-12} = Rd;
3007  let Inst{11-7}  = lsb;
3008  let Inst{3-0}   = Rn;
3009}
3010
3011def UBFX  : I<(outs GPR:$Rd),
3012              (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
3013               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3014               "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
3015               Requires<[IsARM, HasV6T2]> {
3016  bits<4> Rd;
3017  bits<4> Rn;
3018  bits<5> lsb;
3019  bits<5> width;
3020  let Inst{27-21} = 0b0111111;
3021  let Inst{6-4}   = 0b101;
3022  let Inst{20-16} = width;
3023  let Inst{15-12} = Rd;
3024  let Inst{11-7}  = lsb;
3025  let Inst{3-0}   = Rn;
3026}
3027
3028//===----------------------------------------------------------------------===//
3029//  Arithmetic Instructions.
3030//
3031
3032defm ADD  : AsI1_bin_irs<0b0100, "add",
3033                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3034                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
3035defm SUB  : AsI1_bin_irs<0b0010, "sub",
3036                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3037                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
3038
3039// ADD and SUB with 's' bit set.
3040//
3041// Currently, ADDS/SUBS are pseudo opcodes that exist only in the
3042// selection DAG. They are "lowered" to real ADD/SUB opcodes by
3043// AdjustInstrPostInstrSelection where we determine whether or not to
3044// set the "s" bit based on CPSR liveness.
3045//
3046// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
3047// support for an optional CPSR definition that corresponds to the DAG
3048// node's second value. We can then eliminate the implicit def of CPSR.
3049defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3050                           BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
3051defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3052                           BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
3053
3054defm ADC : AI1_adde_sube_irs<0b0101, "adc",
3055              BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>;
3056defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
3057              BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>;
3058
3059defm RSB  : AsI1_rbin_irs<0b0011, "rsb",
3060                          IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3061                          BinOpFrag<(sub node:$LHS, node:$RHS)>>;
3062
3063// FIXME: Eliminate them if we can write def : Pat patterns which defines
3064// CPSR and the implicit def of CPSR is not needed.
3065defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
3066                           BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
3067
3068defm RSC : AI1_rsc_irs<0b0111, "rsc",
3069                BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>;
3070
3071// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
3072// The assume-no-carry-in form uses the negation of the input since add/sub
3073// assume opposite meanings of the carry flag (i.e., carry == !borrow).
3074// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
3075// details.
3076def : ARMPat<(add     GPR:$src, so_imm_neg:$imm),
3077             (SUBri   GPR:$src, so_imm_neg:$imm)>;
3078def : ARMPat<(ARMaddc GPR:$src, so_imm_neg:$imm),
3079             (SUBSri  GPR:$src, so_imm_neg:$imm)>;
3080
3081def : ARMPat<(add     GPR:$src, imm0_65535_neg:$imm),
3082             (SUBrr   GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>;
3083def : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm),
3084             (SUBSrr  GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>;
3085
3086// The with-carry-in form matches bitwise not instead of the negation.
3087// Effectively, the inverse interpretation of the carry flag already accounts
3088// for part of the negation.
3089def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR),
3090             (SBCri   GPR:$src, so_imm_not:$imm)>;
3091
3092// Note: These are implemented in C++ code, because they have to generate
3093// ADD/SUBrs instructions, which use a complex pattern that a xform function
3094// cannot produce.
3095// (mul X, 2^n+1) -> (add (X << n), X)
3096// (mul X, 2^n-1) -> (rsb X, (X << n))
3097
3098// ARM Arithmetic Instruction
3099// GPR:$dst = GPR:$a op GPR:$b
3100class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
3101          list<dag> pattern = [],
3102          dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm),
3103          string asm = "\t$Rd, $Rn, $Rm">
3104  : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
3105  bits<4> Rn;
3106  bits<4> Rd;
3107  bits<4> Rm;
3108  let Inst{27-20} = op27_20;
3109  let Inst{11-4} = op11_4;
3110  let Inst{19-16} = Rn;
3111  let Inst{15-12} = Rd;
3112  let Inst{3-0}   = Rm;
3113
3114  let Unpredictable{11-8} = 0b1111;
3115}
3116
3117// Saturating add/subtract
3118
3119def QADD    : AAI<0b00010000, 0b00000101, "qadd",
3120                  [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))],
3121                  (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
3122def QSUB    : AAI<0b00010010, 0b00000101, "qsub",
3123                  [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))],
3124                  (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
3125def QDADD   : AAI<0b00010100, 0b00000101, "qdadd", [],
3126                  (ins GPRnopc:$Rm, GPRnopc:$Rn),
3127                  "\t$Rd, $Rm, $Rn">;
3128def QDSUB   : AAI<0b00010110, 0b00000101, "qdsub", [],
3129                  (ins GPRnopc:$Rm, GPRnopc:$Rn),
3130                  "\t$Rd, $Rm, $Rn">;
3131
3132def QADD16  : AAI<0b01100010, 0b11110001, "qadd16">;
3133def QADD8   : AAI<0b01100010, 0b11111001, "qadd8">;
3134def QASX    : AAI<0b01100010, 0b11110011, "qasx">;
3135def QSAX    : AAI<0b01100010, 0b11110101, "qsax">;
3136def QSUB16  : AAI<0b01100010, 0b11110111, "qsub16">;
3137def QSUB8   : AAI<0b01100010, 0b11111111, "qsub8">;
3138def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
3139def UQADD8  : AAI<0b01100110, 0b11111001, "uqadd8">;
3140def UQASX   : AAI<0b01100110, 0b11110011, "uqasx">;
3141def UQSAX   : AAI<0b01100110, 0b11110101, "uqsax">;
3142def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
3143def UQSUB8  : AAI<0b01100110, 0b11111111, "uqsub8">;
3144
3145// Signed/Unsigned add/subtract
3146
3147def SASX   : AAI<0b01100001, 0b11110011, "sasx">;
3148def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
3149def SADD8  : AAI<0b01100001, 0b11111001, "sadd8">;
3150def SSAX   : AAI<0b01100001, 0b11110101, "ssax">;
3151def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
3152def SSUB8  : AAI<0b01100001, 0b11111111, "ssub8">;
3153def UASX   : AAI<0b01100101, 0b11110011, "uasx">;
3154def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
3155def UADD8  : AAI<0b01100101, 0b11111001, "uadd8">;
3156def USAX   : AAI<0b01100101, 0b11110101, "usax">;
3157def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
3158def USUB8  : AAI<0b01100101, 0b11111111, "usub8">;
3159
3160// Signed/Unsigned halving add/subtract
3161
3162def SHASX   : AAI<0b01100011, 0b11110011, "shasx">;
3163def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
3164def SHADD8  : AAI<0b01100011, 0b11111001, "shadd8">;
3165def SHSAX   : AAI<0b01100011, 0b11110101, "shsax">;
3166def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
3167def SHSUB8  : AAI<0b01100011, 0b11111111, "shsub8">;
3168def UHASX   : AAI<0b01100111, 0b11110011, "uhasx">;
3169def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
3170def UHADD8  : AAI<0b01100111, 0b11111001, "uhadd8">;
3171def UHSAX   : AAI<0b01100111, 0b11110101, "uhsax">;
3172def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
3173def UHSUB8  : AAI<0b01100111, 0b11111111, "uhsub8">;
3174
3175// Unsigned Sum of Absolute Differences [and Accumulate].
3176
3177def USAD8  : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3178                MulFrm /* for convenience */, NoItinerary, "usad8",
3179                "\t$Rd, $Rn, $Rm", []>,
3180             Requires<[IsARM, HasV6]> {
3181  bits<4> Rd;
3182  bits<4> Rn;
3183  bits<4> Rm;
3184  let Inst{27-20} = 0b01111000;
3185  let Inst{15-12} = 0b1111;
3186  let Inst{7-4} = 0b0001;
3187  let Inst{19-16} = Rd;
3188  let Inst{11-8} = Rm;
3189  let Inst{3-0} = Rn;
3190}
3191def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3192                MulFrm /* for convenience */, NoItinerary, "usada8",
3193                "\t$Rd, $Rn, $Rm, $Ra", []>,
3194             Requires<[IsARM, HasV6]> {
3195  bits<4> Rd;
3196  bits<4> Rn;
3197  bits<4> Rm;
3198  bits<4> Ra;
3199  let Inst{27-20} = 0b01111000;
3200  let Inst{7-4} = 0b0001;
3201  let Inst{19-16} = Rd;
3202  let Inst{15-12} = Ra;
3203  let Inst{11-8} = Rm;
3204  let Inst{3-0} = Rn;
3205}
3206
3207// Signed/Unsigned saturate
3208
3209def SSAT : AI<(outs GPRnopc:$Rd),
3210              (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
3211              SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
3212  bits<4> Rd;
3213  bits<5> sat_imm;
3214  bits<4> Rn;
3215  bits<8> sh;
3216  let Inst{27-21} = 0b0110101;
3217  let Inst{5-4} = 0b01;
3218  let Inst{20-16} = sat_imm;
3219  let Inst{15-12} = Rd;
3220  let Inst{11-7} = sh{4-0};
3221  let Inst{6} = sh{5};
3222  let Inst{3-0} = Rn;
3223}
3224
3225def SSAT16 : AI<(outs GPRnopc:$Rd),
3226                (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm,
3227                NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
3228  bits<4> Rd;
3229  bits<4> sat_imm;
3230  bits<4> Rn;
3231  let Inst{27-20} = 0b01101010;
3232  let Inst{11-4} = 0b11110011;
3233  let Inst{15-12} = Rd;
3234  let Inst{19-16} = sat_imm;
3235  let Inst{3-0} = Rn;
3236}
3237
3238def USAT : AI<(outs GPRnopc:$Rd),
3239              (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
3240              SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
3241  bits<4> Rd;
3242  bits<5> sat_imm;
3243  bits<4> Rn;
3244  bits<8> sh;
3245  let Inst{27-21} = 0b0110111;
3246  let Inst{5-4} = 0b01;
3247  let Inst{15-12} = Rd;
3248  let Inst{11-7} = sh{4-0};
3249  let Inst{6} = sh{5};
3250  let Inst{20-16} = sat_imm;
3251  let Inst{3-0} = Rn;
3252}
3253
3254def USAT16 : AI<(outs GPRnopc:$Rd),
3255                (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm,
3256                NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> {
3257  bits<4> Rd;
3258  bits<4> sat_imm;
3259  bits<4> Rn;
3260  let Inst{27-20} = 0b01101110;
3261  let Inst{11-4} = 0b11110011;
3262  let Inst{15-12} = Rd;
3263  let Inst{19-16} = sat_imm;
3264  let Inst{3-0} = Rn;
3265}
3266
3267def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm:$pos),
3268               (SSAT imm:$pos, GPRnopc:$a, 0)>;
3269def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm:$pos),
3270               (USAT imm:$pos, GPRnopc:$a, 0)>;
3271
3272//===----------------------------------------------------------------------===//
3273//  Bitwise Instructions.
3274//
3275
3276defm AND   : AsI1_bin_irs<0b0000, "and",
3277                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3278                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
3279defm ORR   : AsI1_bin_irs<0b1100, "orr",
3280                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3281                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
3282defm EOR   : AsI1_bin_irs<0b0001, "eor",
3283                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3284                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
3285defm BIC   : AsI1_bin_irs<0b1110, "bic",
3286                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
3287                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
3288
3289// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just
3290// like in the actual instruction encoding. The complexity of mapping the mask
3291// to the lsb/msb pair should be handled by ISel, not encapsulated in the
3292// instruction description.
3293def BFC    : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
3294               AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3295               "bfc", "\t$Rd, $imm", "$src = $Rd",
3296               [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
3297               Requires<[IsARM, HasV6T2]> {
3298  bits<4> Rd;
3299  bits<10> imm;
3300  let Inst{27-21} = 0b0111110;
3301  let Inst{6-0}   = 0b0011111;
3302  let Inst{15-12} = Rd;
3303  let Inst{11-7}  = imm{4-0}; // lsb
3304  let Inst{20-16} = imm{9-5}; // msb
3305}
3306
3307// A8.6.18  BFI - Bitfield insert (Encoding A1)
3308def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
3309          AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
3310          "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
3311          [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn,
3312                           bf_inv_mask_imm:$imm))]>,
3313          Requires<[IsARM, HasV6T2]> {
3314  bits<4> Rd;
3315  bits<4> Rn;
3316  bits<10> imm;
3317  let Inst{27-21} = 0b0111110;
3318  let Inst{6-4}   = 0b001; // Rn: Inst{3-0} != 15
3319  let Inst{15-12} = Rd;
3320  let Inst{11-7}  = imm{4-0}; // lsb
3321  let Inst{20-16} = imm{9-5}; // width
3322  let Inst{3-0}   = Rn;
3323}
3324
3325def  MVNr  : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
3326                  "mvn", "\t$Rd, $Rm",
3327                  [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
3328  bits<4> Rd;
3329  bits<4> Rm;
3330  let Inst{25} = 0;
3331  let Inst{19-16} = 0b0000;
3332  let Inst{11-4} = 0b00000000;
3333  let Inst{15-12} = Rd;
3334  let Inst{3-0} = Rm;
3335}
3336def  MVNsi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift),
3337                  DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
3338                  [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP {
3339  bits<4> Rd;
3340  bits<12> shift;
3341  let Inst{25} = 0;
3342  let Inst{19-16} = 0b0000;
3343  let Inst{15-12} = Rd;
3344  let Inst{11-5} = shift{11-5};
3345  let Inst{4} = 0;
3346  let Inst{3-0} = shift{3-0};
3347}
3348def  MVNsr  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift),
3349                  DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
3350                  [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP {
3351  bits<4> Rd;
3352  bits<12> shift;
3353  let Inst{25} = 0;
3354  let Inst{19-16} = 0b0000;
3355  let Inst{15-12} = Rd;
3356  let Inst{11-8} = shift{11-8};
3357  let Inst{7} = 0;
3358  let Inst{6-5} = shift{6-5};
3359  let Inst{4} = 1;
3360  let Inst{3-0} = shift{3-0};
3361}
3362let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
3363def  MVNi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
3364                  IIC_iMVNi, "mvn", "\t$Rd, $imm",
3365                  [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
3366  bits<4> Rd;
3367  bits<12> imm;
3368  let Inst{25} = 1;
3369  let Inst{19-16} = 0b0000;
3370  let Inst{15-12} = Rd;
3371  let Inst{11-0} = imm;
3372}
3373
3374def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
3375             (BICri GPR:$src, so_imm_not:$imm)>;
3376
3377//===----------------------------------------------------------------------===//
3378//  Multiply Instructions.
3379//
3380class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
3381             string opc, string asm, list<dag> pattern>
3382  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
3383  bits<4> Rd;
3384  bits<4> Rm;
3385  bits<4> Rn;
3386  let Inst{19-16} = Rd;
3387  let Inst{11-8}  = Rm;
3388  let Inst{3-0}   = Rn;
3389}
3390class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
3391             string opc, string asm, list<dag> pattern>
3392  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
3393  bits<4> RdLo;
3394  bits<4> RdHi;
3395  bits<4> Rm;
3396  bits<4> Rn;
3397  let Inst{19-16} = RdHi;
3398  let Inst{15-12} = RdLo;
3399  let Inst{11-8}  = Rm;
3400  let Inst{3-0}   = Rn;
3401}
3402
3403// FIXME: The v5 pseudos are only necessary for the additional Constraint
3404//        property. Remove them when it's possible to add those properties
3405//        on an individual MachineInstr, not just an instruction description.
3406let isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in {
3407def MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd),
3408                    (ins GPRnopc:$Rn, GPRnopc:$Rm),
3409                    IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
3410                  [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>,
3411                  Requires<[IsARM, HasV6]> {
3412  let Inst{15-12} = 0b0000;
3413  let Unpredictable{15-12} = 0b1111;
3414}
3415
3416let Constraints = "@earlyclobber $Rd" in
3417def MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm,
3418                                                    pred:$p, cc_out:$s),
3419                           4, IIC_iMUL32,
3420               [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))],
3421               (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>,
3422               Requires<[IsARM, NoV6]>;
3423}
3424
3425def MLA  : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3426                     IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
3427                   [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
3428                   Requires<[IsARM, HasV6]> {
3429  bits<4> Ra;
3430  let Inst{15-12} = Ra;
3431}
3432
3433let Constraints = "@earlyclobber $Rd" in
3434def MLAv5: ARMPseudoExpand<(outs GPR:$Rd),
3435                           (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
3436                           4, IIC_iMAC32,
3437                        [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))],
3438                  (MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>,
3439                        Requires<[IsARM, NoV6]>;
3440
3441def MLS  : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3442                   IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
3443                   [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
3444                   Requires<[IsARM, HasV6T2]> {
3445  bits<4> Rd;
3446  bits<4> Rm;
3447  bits<4> Rn;
3448  bits<4> Ra;
3449  let Inst{19-16} = Rd;
3450  let Inst{15-12} = Ra;
3451  let Inst{11-8}  = Rm;
3452  let Inst{3-0}   = Rn;
3453}
3454
3455// Extra precision multiplies with low / high results
3456let neverHasSideEffects = 1 in {
3457let isCommutable = 1 in {
3458def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
3459                                 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
3460                    "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3461                    Requires<[IsARM, HasV6]>;
3462
3463def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
3464                                 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
3465                    "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3466                    Requires<[IsARM, HasV6]>;
3467
3468let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
3469def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3470                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3471                            4, IIC_iMUL64, [],
3472          (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3473                           Requires<[IsARM, NoV6]>;
3474
3475def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3476                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3477                            4, IIC_iMUL64, [],
3478          (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3479                           Requires<[IsARM, NoV6]>;
3480}
3481}
3482
3483// Multiply + accumulate
3484def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
3485                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3486                    "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3487                    Requires<[IsARM, HasV6]>;
3488def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
3489                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3490                    "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3491                    Requires<[IsARM, HasV6]>;
3492
3493def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
3494                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
3495                    "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3496                    Requires<[IsARM, HasV6]> {
3497  bits<4> RdLo;
3498  bits<4> RdHi;
3499  bits<4> Rm;
3500  bits<4> Rn;
3501  let Inst{19-16} = RdHi;
3502  let Inst{15-12} = RdLo;
3503  let Inst{11-8}  = Rm;
3504  let Inst{3-0}   = Rn;
3505}
3506
3507let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
3508def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3509                              (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3510                              4, IIC_iMAC64, [],
3511          (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3512                           Requires<[IsARM, NoV6]>;
3513def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3514                              (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
3515                              4, IIC_iMAC64, [],
3516          (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
3517                           Requires<[IsARM, NoV6]>;
3518def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
3519                              (ins GPR:$Rn, GPR:$Rm, pred:$p),
3520                              4, IIC_iMAC64, [],
3521          (UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>,
3522                           Requires<[IsARM, NoV6]>;
3523}
3524
3525} // neverHasSideEffects
3526
3527// Most significant word multiply
3528def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3529               IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
3530               [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
3531            Requires<[IsARM, HasV6]> {
3532  let Inst{15-12} = 0b1111;
3533}
3534
3535def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3536               IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", []>,
3537            Requires<[IsARM, HasV6]> {
3538  let Inst{15-12} = 0b1111;
3539}
3540
3541def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
3542               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3543               IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
3544               [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
3545            Requires<[IsARM, HasV6]>;
3546
3547def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
3548               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3549               IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>,
3550            Requires<[IsARM, HasV6]>;
3551
3552def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
3553               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3554               IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>,
3555            Requires<[IsARM, HasV6]>;
3556
3557def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
3558               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
3559               IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>,
3560            Requires<[IsARM, HasV6]>;
3561
3562multiclass AI_smul<string opc, PatFrag opnode> {
3563  def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3564              IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
3565              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
3566                                      (sext_inreg GPR:$Rm, i16)))]>,
3567           Requires<[IsARM, HasV5TE]>;
3568
3569  def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3570              IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
3571              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
3572                                      (sra GPR:$Rm, (i32 16))))]>,
3573           Requires<[IsARM, HasV5TE]>;
3574
3575  def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3576              IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
3577              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
3578                                      (sext_inreg GPR:$Rm, i16)))]>,
3579           Requires<[IsARM, HasV5TE]>;
3580
3581  def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3582              IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
3583              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
3584                                      (sra GPR:$Rm, (i32 16))))]>,
3585            Requires<[IsARM, HasV5TE]>;
3586
3587  def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3588              IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
3589              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
3590                                    (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
3591           Requires<[IsARM, HasV5TE]>;
3592
3593  def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
3594              IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
3595              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
3596                                    (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
3597            Requires<[IsARM, HasV5TE]>;
3598}
3599
3600
3601multiclass AI_smla<string opc, PatFrag opnode> {
3602  let DecoderMethod = "DecodeSMLAInstruction" in {
3603  def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd),
3604              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3605              IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
3606              [(set GPRnopc:$Rd, (add GPR:$Ra,
3607                               (opnode (sext_inreg GPRnopc:$Rn, i16),
3608                                       (sext_inreg GPRnopc:$Rm, i16))))]>,
3609           Requires<[IsARM, HasV5TE]>;
3610
3611  def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd),
3612              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3613              IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
3614              [(set GPRnopc:$Rd,
3615                    (add GPR:$Ra, (opnode (sext_inreg GPRnopc:$Rn, i16),
3616                                          (sra GPRnopc:$Rm, (i32 16)))))]>,
3617           Requires<[IsARM, HasV5TE]>;
3618
3619  def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd),
3620              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3621              IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
3622              [(set GPRnopc:$Rd,
3623                    (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)),
3624                                          (sext_inreg GPRnopc:$Rm, i16))))]>,
3625           Requires<[IsARM, HasV5TE]>;
3626
3627  def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd),
3628              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3629              IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
3630             [(set GPRnopc:$Rd,
3631                   (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)),
3632                                         (sra GPRnopc:$Rm, (i32 16)))))]>,
3633            Requires<[IsARM, HasV5TE]>;
3634
3635  def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd),
3636              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3637              IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
3638              [(set GPRnopc:$Rd,
3639                    (add GPR:$Ra, (sra (opnode GPRnopc:$Rn,
3640                                  (sext_inreg GPRnopc:$Rm, i16)), (i32 16))))]>,
3641           Requires<[IsARM, HasV5TE]>;
3642
3643  def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd),
3644              (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3645              IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
3646              [(set GPRnopc:$Rd,
3647                 (add GPR:$Ra, (sra (opnode GPRnopc:$Rn,
3648                                    (sra GPRnopc:$Rm, (i32 16))), (i32 16))))]>,
3649            Requires<[IsARM, HasV5TE]>;
3650  }
3651}
3652
3653defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
3654defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
3655
3656// Halfword multiply accumulate long: SMLAL<x><y>.
3657def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3658                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3659                      IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3660              Requires<[IsARM, HasV5TE]>;
3661
3662def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3663                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3664                      IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3665              Requires<[IsARM, HasV5TE]>;
3666
3667def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3668                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3669                      IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3670              Requires<[IsARM, HasV5TE]>;
3671
3672def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3673                      (ins GPRnopc:$Rn, GPRnopc:$Rm),
3674                      IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
3675              Requires<[IsARM, HasV5TE]>;
3676
3677// Helper class for AI_smld.
3678class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
3679                    InstrItinClass itin, string opc, string asm>
3680  : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
3681  bits<4> Rn;
3682  bits<4> Rm;
3683  let Inst{27-23} = 0b01110;
3684  let Inst{22}    = long;
3685  let Inst{21-20} = 0b00;
3686  let Inst{11-8}  = Rm;
3687  let Inst{7}     = 0;
3688  let Inst{6}     = sub;
3689  let Inst{5}     = swap;
3690  let Inst{4}     = 1;
3691  let Inst{3-0}   = Rn;
3692}
3693class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
3694                InstrItinClass itin, string opc, string asm>
3695  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3696  bits<4> Rd;
3697  let Inst{15-12} = 0b1111;
3698  let Inst{19-16} = Rd;
3699}
3700class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
3701                InstrItinClass itin, string opc, string asm>
3702  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3703  bits<4> Ra;
3704  bits<4> Rd;
3705  let Inst{19-16} = Rd;
3706  let Inst{15-12} = Ra;
3707}
3708class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
3709                  InstrItinClass itin, string opc, string asm>
3710  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
3711  bits<4> RdLo;
3712  bits<4> RdHi;
3713  let Inst{19-16} = RdHi;
3714  let Inst{15-12} = RdLo;
3715}
3716
3717multiclass AI_smld<bit sub, string opc> {
3718
3719  def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd),
3720                  (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3721                  NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
3722
3723  def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd),
3724                  (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
3725                  NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
3726
3727  def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3728                  (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary,
3729                  !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
3730
3731  def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
3732                  (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary,
3733                  !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
3734
3735}
3736
3737defm SMLA : AI_smld<0, "smla">;
3738defm SMLS : AI_smld<1, "smls">;
3739
3740multiclass AI_sdml<bit sub, string opc> {
3741
3742  def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm),
3743                  NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
3744  def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm),
3745                  NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
3746}
3747
3748defm SMUA : AI_sdml<0, "smua">;
3749defm SMUS : AI_sdml<1, "smus">;
3750
3751//===----------------------------------------------------------------------===//
3752//  Misc. Arithmetic Instructions.
3753//
3754
3755def CLZ  : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
3756              IIC_iUNAr, "clz", "\t$Rd, $Rm",
3757              [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
3758
3759def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
3760              IIC_iUNAr, "rbit", "\t$Rd, $Rm",
3761              [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
3762           Requires<[IsARM, HasV6T2]>;
3763
3764def REV  : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
3765              IIC_iUNAr, "rev", "\t$Rd, $Rm",
3766              [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
3767
3768let AddedComplexity = 5 in
3769def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
3770               IIC_iUNAr, "rev16", "\t$Rd, $Rm",
3771               [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>,
3772               Requires<[IsARM, HasV6]>;
3773
3774let AddedComplexity = 5 in
3775def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
3776               IIC_iUNAr, "revsh", "\t$Rd, $Rm",
3777               [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>,
3778               Requires<[IsARM, HasV6]>;
3779
3780def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)),
3781                   (and (srl GPR:$Rm, (i32 8)), 0xFF)),
3782               (REVSH GPR:$Rm)>;
3783
3784def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd),
3785                              (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh),
3786               IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
3787               [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF),
3788                                      (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh),
3789                                           0xFFFF0000)))]>,
3790               Requires<[IsARM, HasV6]>;
3791
3792// Alternate cases for PKHBT where identities eliminate some nodes.
3793def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)),
3794               (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>;
3795def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)),
3796               (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>;
3797
3798// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3799// will match the pattern below.
3800def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd),
3801                              (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh),
3802               IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3803               [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000),
3804                                      (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh),
3805                                           0xFFFF)))]>,
3806               Requires<[IsARM, HasV6]>;
3807
3808// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
3809// a shift amount of 0 is *not legal* here, it is PKHBT instead.
3810def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
3811                   (srl GPRnopc:$src2, imm16_31:$sh)),
3812               (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>;
3813def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
3814                   (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)),
3815               (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>;
3816
3817//===----------------------------------------------------------------------===//
3818//  Comparison Instructions...
3819//
3820
3821defm CMP  : AI1_cmp_irs<0b1010, "cmp",
3822                        IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3823                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3824
3825// ARMcmpZ can re-use the above instruction definitions.
3826def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3827             (CMPri   GPR:$src, so_imm:$imm)>;
3828def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3829             (CMPrr   GPR:$src, GPR:$rhs)>;
3830def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs),
3831             (CMPrsi   GPR:$src, so_reg_imm:$rhs)>;
3832def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs),
3833             (CMPrsr   GPR:$src, so_reg_reg:$rhs)>;
3834
3835// CMN register-integer
3836let isCompare = 1, Defs = [CPSR] in {
3837def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iCMPi,
3838                "cmn", "\t$Rn, $imm",
3839                [(ARMcmn GPR:$Rn, so_imm:$imm)]> {
3840  bits<4> Rn;
3841  bits<12> imm;
3842  let Inst{25} = 1;
3843  let Inst{20} = 1;
3844  let Inst{19-16} = Rn;
3845  let Inst{15-12} = 0b0000;
3846  let Inst{11-0} = imm;
3847
3848  let Unpredictable{15-12} = 0b1111;
3849}
3850
3851// CMN register-register/shift
3852def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
3853                 "cmn", "\t$Rn, $Rm",
3854                 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3855                   GPR:$Rn, GPR:$Rm)]> {
3856  bits<4> Rn;
3857  bits<4> Rm;
3858  let isCommutable = 1;
3859  let Inst{25} = 0;
3860  let Inst{20} = 1;
3861  let Inst{19-16} = Rn;
3862  let Inst{15-12} = 0b0000;
3863  let Inst{11-4} = 0b00000000;
3864  let Inst{3-0} = Rm;
3865
3866  let Unpredictable{15-12} = 0b1111;
3867}
3868
3869def CMNzrsi : AI1<0b1011, (outs),
3870                  (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr,
3871                  "cmn", "\t$Rn, $shift",
3872                  [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3873                    GPR:$Rn, so_reg_imm:$shift)]> {
3874  bits<4> Rn;
3875  bits<12> shift;
3876  let Inst{25} = 0;
3877  let Inst{20} = 1;
3878  let Inst{19-16} = Rn;
3879  let Inst{15-12} = 0b0000;
3880  let Inst{11-5} = shift{11-5};
3881  let Inst{4} = 0;
3882  let Inst{3-0} = shift{3-0};
3883
3884  let Unpredictable{15-12} = 0b1111;
3885}
3886
3887def CMNzrsr : AI1<0b1011, (outs),
3888                  (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr,
3889                  "cmn", "\t$Rn, $shift",
3890                  [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3891                    GPRnopc:$Rn, so_reg_reg:$shift)]> {
3892  bits<4> Rn;
3893  bits<12> shift;
3894  let Inst{25} = 0;
3895  let Inst{20} = 1;
3896  let Inst{19-16} = Rn;
3897  let Inst{15-12} = 0b0000;
3898  let Inst{11-8} = shift{11-8};
3899  let Inst{7} = 0;
3900  let Inst{6-5} = shift{6-5};
3901  let Inst{4} = 1;
3902  let Inst{3-0} = shift{3-0};
3903
3904  let Unpredictable{15-12} = 0b1111;
3905}
3906
3907}
3908
3909def : ARMPat<(ARMcmp  GPR:$src, so_imm_neg:$imm),
3910             (CMNri   GPR:$src, so_imm_neg:$imm)>;
3911
3912def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3913             (CMNri   GPR:$src, so_imm_neg:$imm)>;
3914
3915// Note that TST/TEQ don't set all the same flags that CMP does!
3916defm TST  : AI1_cmp_irs<0b1000, "tst",
3917                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3918                      BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3919defm TEQ  : AI1_cmp_irs<0b1001, "teq",
3920                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3921                      BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3922
3923// Pseudo i64 compares for some floating point compares.
3924let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3925    Defs = [CPSR] in {
3926def BCCi64 : PseudoInst<(outs),
3927    (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3928     IIC_Br,
3929    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3930
3931def BCCZi64 : PseudoInst<(outs),
3932     (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3933    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3934} // usesCustomInserter
3935
3936
3937// Conditional moves
3938// FIXME: should be able to write a pattern for ARMcmov, but can't use
3939// a two-value operand where a dag node expects two operands. :(
3940let neverHasSideEffects = 1 in {
3941
3942let isCommutable = 1, isSelect = 1 in
3943def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p),
3944                           4, IIC_iCMOVr,
3945  [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3946      RegConstraint<"$false = $Rd">;
3947
3948def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd),
3949                           (ins GPR:$false, so_reg_imm:$shift, pred:$p),
3950                           4, IIC_iCMOVsr,
3951  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_imm:$shift,
3952                            imm:$cc, CCR:$ccr))*/]>,
3953      RegConstraint<"$false = $Rd">;
3954def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd),
3955                           (ins GPR:$false, so_reg_reg:$shift, pred:$p),
3956                           4, IIC_iCMOVsr,
3957  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift,
3958                            imm:$cc, CCR:$ccr))*/]>,
3959      RegConstraint<"$false = $Rd">;
3960
3961
3962let isMoveImm = 1 in
3963def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd),
3964                             (ins GPR:$false, imm0_65535_expr:$imm, pred:$p),
3965                             4, IIC_iMOVi,
3966                             []>,
3967      RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>;
3968
3969let isMoveImm = 1 in
3970def MOVCCi : ARMPseudoInst<(outs GPR:$Rd),
3971                           (ins GPR:$false, so_imm:$imm, pred:$p),
3972                           4, IIC_iCMOVi,
3973   [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3974      RegConstraint<"$false = $Rd">;
3975
3976// Two instruction predicate mov immediate.
3977let isMoveImm = 1 in
3978def MOVCCi32imm : ARMPseudoInst<(outs GPR:$Rd),
3979                                (ins GPR:$false, i32imm:$src, pred:$p),
3980                  8, IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3981
3982let isMoveImm = 1 in
3983def MVNCCi : ARMPseudoInst<(outs GPR:$Rd),
3984                           (ins GPR:$false, so_imm:$imm, pred:$p),
3985                           4, IIC_iCMOVi,
3986 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3987                RegConstraint<"$false = $Rd">;
3988
3989// Conditional instructions
3990multiclass AsI1_bincc_irs<Instruction iri, Instruction irr, Instruction irsi,
3991                          Instruction irsr,
3992                          InstrItinClass iii, InstrItinClass iir,
3993                          InstrItinClass iis> {
3994  def ri  : ARMPseudoExpand<(outs GPR:$Rd),
3995                            (ins GPR:$Rfalse, GPR:$Rn, so_imm:$imm,
3996                                 pred:$p, cc_out:$s),
3997                            4, iii, [],
3998                       (iri GPR:$Rd, GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s)>,
3999                            RegConstraint<"$Rfalse = $Rd">;
4000  def rr  : ARMPseudoExpand<(outs GPR:$Rd),
4001                            (ins GPR:$Rfalse, GPR:$Rn, GPR:$Rm,
4002                                 pred:$p, cc_out:$s),
4003                            4, iir, [],
4004                           (irr GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
4005                            RegConstraint<"$Rfalse = $Rd">;
4006  def rsi : ARMPseudoExpand<(outs GPR:$Rd),
4007                            (ins GPR:$Rfalse, GPR:$Rn, so_reg_imm:$shift,
4008                                 pred:$p, cc_out:$s),
4009                            4, iis, [],
4010                (irsi GPR:$Rd, GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s)>,
4011                            RegConstraint<"$Rfalse = $Rd">;
4012  def rsr : ARMPseudoExpand<(outs GPRnopc:$Rd),
4013                           (ins GPRnopc:$Rfalse, GPRnopc:$Rn, so_reg_reg:$shift,
4014                                pred:$p, cc_out:$s),
4015                            4, iis, [],
4016                (irsr GPR:$Rd, GPR:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s)>,
4017                            RegConstraint<"$Rfalse = $Rd">;
4018}
4019
4020defm ANDCC : AsI1_bincc_irs<ANDri, ANDrr, ANDrsi, ANDrsr,
4021                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4022defm ORRCC : AsI1_bincc_irs<ORRri, ORRrr, ORRrsi, ORRrsr,
4023                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4024defm EORCC : AsI1_bincc_irs<EORri, EORrr, EORrsi, EORrsr,
4025                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4026defm ADDCC : AsI1_bincc_irs<ADDri, ADDrr, ADDrsi, ADDrsr,
4027                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4028defm SUBCC : AsI1_bincc_irs<SUBri, SUBrr, SUBrsi, SUBrsr,
4029                            IIC_iBITi, IIC_iBITr, IIC_iBITsr>;
4030
4031} // neverHasSideEffects
4032
4033
4034//===----------------------------------------------------------------------===//
4035// Atomic operations intrinsics
4036//
4037
4038def MemBarrierOptOperand : AsmOperandClass {
4039  let Name = "MemBarrierOpt";
4040  let ParserMethod = "parseMemBarrierOptOperand";
4041}
4042def memb_opt : Operand<i32> {
4043  let PrintMethod = "printMemBOption";
4044  let ParserMatchClass = MemBarrierOptOperand;
4045  let DecoderMethod = "DecodeMemBarrierOption";
4046}
4047
4048// memory barriers protect the atomic sequences
4049let hasSideEffects = 1 in {
4050def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4051                "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
4052                Requires<[IsARM, HasDB]> {
4053  bits<4> opt;
4054  let Inst{31-4} = 0xf57ff05;
4055  let Inst{3-0} = opt;
4056}
4057}
4058
4059def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4060                "dsb", "\t$opt", []>,
4061                Requires<[IsARM, HasDB]> {
4062  bits<4> opt;
4063  let Inst{31-4} = 0xf57ff04;
4064  let Inst{3-0} = opt;
4065}
4066
4067// ISB has only full system option
4068def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4069                "isb", "\t$opt", []>,
4070                Requires<[IsARM, HasDB]> {
4071  bits<4> opt;
4072  let Inst{31-4} = 0xf57ff06;
4073  let Inst{3-0} = opt;
4074}
4075
4076// Pseudo instruction that combines movs + predicated rsbmi
4077// to implement integer ABS
4078let usesCustomInserter = 1, Defs = [CPSR] in
4079def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>;
4080
4081let usesCustomInserter = 1 in {
4082  let Defs = [CPSR] in {
4083    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
4084      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4085      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
4086    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
4087      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4088      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
4089    def ATOMIC_LOAD_AND_I8 : PseudoInst<
4090      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4091      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
4092    def ATOMIC_LOAD_OR_I8 : PseudoInst<
4093      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4094      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
4095    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
4096      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4097      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
4098    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
4099      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4100      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
4101    def ATOMIC_LOAD_MIN_I8 : PseudoInst<
4102      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4103      [(set GPR:$dst, (atomic_load_min_8 GPR:$ptr, GPR:$val))]>;
4104    def ATOMIC_LOAD_MAX_I8 : PseudoInst<
4105      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4106      [(set GPR:$dst, (atomic_load_max_8 GPR:$ptr, GPR:$val))]>;
4107    def ATOMIC_LOAD_UMIN_I8 : PseudoInst<
4108      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4109      [(set GPR:$dst, (atomic_load_umin_8 GPR:$ptr, GPR:$val))]>;
4110    def ATOMIC_LOAD_UMAX_I8 : PseudoInst<
4111      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4112      [(set GPR:$dst, (atomic_load_umax_8 GPR:$ptr, GPR:$val))]>;
4113    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
4114      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4115      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
4116    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
4117      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4118      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
4119    def ATOMIC_LOAD_AND_I16 : PseudoInst<
4120      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4121      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
4122    def ATOMIC_LOAD_OR_I16 : PseudoInst<
4123      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4124      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
4125    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
4126      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4127      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
4128    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
4129      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4130      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
4131    def ATOMIC_LOAD_MIN_I16 : PseudoInst<
4132      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4133      [(set GPR:$dst, (atomic_load_min_16 GPR:$ptr, GPR:$val))]>;
4134    def ATOMIC_LOAD_MAX_I16 : PseudoInst<
4135      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4136      [(set GPR:$dst, (atomic_load_max_16 GPR:$ptr, GPR:$val))]>;
4137    def ATOMIC_LOAD_UMIN_I16 : PseudoInst<
4138      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4139      [(set GPR:$dst, (atomic_load_umin_16 GPR:$ptr, GPR:$val))]>;
4140    def ATOMIC_LOAD_UMAX_I16 : PseudoInst<
4141      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4142      [(set GPR:$dst, (atomic_load_umax_16 GPR:$ptr, GPR:$val))]>;
4143    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
4144      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4145      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
4146    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
4147      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4148      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
4149    def ATOMIC_LOAD_AND_I32 : PseudoInst<
4150      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4151      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
4152    def ATOMIC_LOAD_OR_I32 : PseudoInst<
4153      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4154      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
4155    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
4156      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4157      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
4158    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
4159      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
4160      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
4161    def ATOMIC_LOAD_MIN_I32 : PseudoInst<
4162      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4163      [(set GPR:$dst, (atomic_load_min_32 GPR:$ptr, GPR:$val))]>;
4164    def ATOMIC_LOAD_MAX_I32 : PseudoInst<
4165      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4166      [(set GPR:$dst, (atomic_load_max_32 GPR:$ptr, GPR:$val))]>;
4167    def ATOMIC_LOAD_UMIN_I32 : PseudoInst<
4168      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4169      [(set GPR:$dst, (atomic_load_umin_32 GPR:$ptr, GPR:$val))]>;
4170    def ATOMIC_LOAD_UMAX_I32 : PseudoInst<
4171      (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary,
4172      [(set GPR:$dst, (atomic_load_umax_32 GPR:$ptr, GPR:$val))]>;
4173
4174    def ATOMIC_SWAP_I8 : PseudoInst<
4175      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4176      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
4177    def ATOMIC_SWAP_I16 : PseudoInst<
4178      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4179      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
4180    def ATOMIC_SWAP_I32 : PseudoInst<
4181      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
4182      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
4183
4184    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
4185      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4186      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
4187    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
4188      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4189      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
4190    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
4191      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
4192      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
4193}
4194}
4195
4196let usesCustomInserter = 1 in {
4197    def COPY_STRUCT_BYVAL_I32 : PseudoInst<
4198      (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment),
4199      NoItinerary,
4200      [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>;
4201}
4202
4203let mayLoad = 1 in {
4204def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4205                     NoItinerary,
4206                    "ldrexb", "\t$Rt, $addr", []>;
4207def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4208                     NoItinerary, "ldrexh", "\t$Rt, $addr", []>;
4209def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
4210                     NoItinerary, "ldrex", "\t$Rt, $addr", []>;
4211let hasExtraDefRegAllocReq = 1 in
4212def LDREXD: AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2),(ins addr_offset_none:$addr),
4213                      NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []> {
4214  let DecoderMethod = "DecodeDoubleRegLoad";
4215}
4216}
4217
4218let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
4219def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4220                    NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>;
4221def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4222                    NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>;
4223def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
4224                    NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>;
4225let hasExtraSrcRegAllocReq = 1 in
4226def STREXD : AIstrex<0b01, (outs GPR:$Rd),
4227                    (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr),
4228                    NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []> {
4229  let DecoderMethod = "DecodeDoubleRegStore";
4230}
4231}
4232
4233
4234def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", []>,
4235            Requires<[IsARM, HasV7]>  {
4236  let Inst{31-0} = 0b11110101011111111111000000011111;
4237}
4238
4239// SWP/SWPB are deprecated in V6/V7.
4240let mayLoad = 1, mayStore = 1 in {
4241def SWP : AIswp<0, (outs GPRnopc:$Rt),
4242                (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>;
4243def SWPB: AIswp<1, (outs GPRnopc:$Rt),
4244                (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>;
4245}
4246
4247//===----------------------------------------------------------------------===//
4248// Coprocessor Instructions.
4249//
4250
4251def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4252            c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4253            NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4254            [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4255                          imm:$CRm, imm:$opc2)]> {
4256  bits<4> opc1;
4257  bits<4> CRn;
4258  bits<4> CRd;
4259  bits<4> cop;
4260  bits<3> opc2;
4261  bits<4> CRm;
4262
4263  let Inst{3-0}   = CRm;
4264  let Inst{4}     = 0;
4265  let Inst{7-5}   = opc2;
4266  let Inst{11-8}  = cop;
4267  let Inst{15-12} = CRd;
4268  let Inst{19-16} = CRn;
4269  let Inst{23-20} = opc1;
4270}
4271
4272def CDP2 : ABXI<0b1110, (outs), (ins pf_imm:$cop, imm0_15:$opc1,
4273               c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4274               NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4275               [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4276                              imm:$CRm, imm:$opc2)]> {
4277  let Inst{31-28} = 0b1111;
4278  bits<4> opc1;
4279  bits<4> CRn;
4280  bits<4> CRd;
4281  bits<4> cop;
4282  bits<3> opc2;
4283  bits<4> CRm;
4284
4285  let Inst{3-0}   = CRm;
4286  let Inst{4}     = 0;
4287  let Inst{7-5}   = opc2;
4288  let Inst{11-8}  = cop;
4289  let Inst{15-12} = CRd;
4290  let Inst{19-16} = CRn;
4291  let Inst{23-20} = opc1;
4292}
4293
4294class ACI<dag oops, dag iops, string opc, string asm,
4295          IndexMode im = IndexModeNone>
4296  : I<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
4297      opc, asm, "", []> {
4298  let Inst{27-25} = 0b110;
4299}
4300class ACInoP<dag oops, dag iops, string opc, string asm,
4301          IndexMode im = IndexModeNone>
4302  : InoP<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
4303         opc, asm, "", []> {
4304  let Inst{31-28} = 0b1111;
4305  let Inst{27-25} = 0b110;
4306}
4307multiclass LdStCop<bit load, bit Dbit, string asm> {
4308  def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4309                    asm, "\t$cop, $CRd, $addr"> {
4310    bits<13> addr;
4311    bits<4> cop;
4312    bits<4> CRd;
4313    let Inst{24} = 1; // P = 1
4314    let Inst{23} = addr{8};
4315    let Inst{22} = Dbit;
4316    let Inst{21} = 0; // W = 0
4317    let Inst{20} = load;
4318    let Inst{19-16} = addr{12-9};
4319    let Inst{15-12} = CRd;
4320    let Inst{11-8} = cop;
4321    let Inst{7-0} = addr{7-0};
4322    let DecoderMethod = "DecodeCopMemInstruction";
4323  }
4324  def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4325                 asm, "\t$cop, $CRd, $addr!", IndexModePre> {
4326    bits<13> addr;
4327    bits<4> cop;
4328    bits<4> CRd;
4329    let Inst{24} = 1; // P = 1
4330    let Inst{23} = addr{8};
4331    let Inst{22} = Dbit;
4332    let Inst{21} = 1; // W = 1
4333    let Inst{20} = load;
4334    let Inst{19-16} = addr{12-9};
4335    let Inst{15-12} = CRd;
4336    let Inst{11-8} = cop;
4337    let Inst{7-0} = addr{7-0};
4338    let DecoderMethod = "DecodeCopMemInstruction";
4339  }
4340  def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4341                              postidx_imm8s4:$offset),
4342                 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> {
4343    bits<9> offset;
4344    bits<4> addr;
4345    bits<4> cop;
4346    bits<4> CRd;
4347    let Inst{24} = 0; // P = 0
4348    let Inst{23} = offset{8};
4349    let Inst{22} = Dbit;
4350    let Inst{21} = 1; // W = 1
4351    let Inst{20} = load;
4352    let Inst{19-16} = addr;
4353    let Inst{15-12} = CRd;
4354    let Inst{11-8} = cop;
4355    let Inst{7-0} = offset{7-0};
4356    let DecoderMethod = "DecodeCopMemInstruction";
4357  }
4358  def _OPTION : ACI<(outs),
4359                    (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4360                         coproc_option_imm:$option),
4361      asm, "\t$cop, $CRd, $addr, $option"> {
4362    bits<8> option;
4363    bits<4> addr;
4364    bits<4> cop;
4365    bits<4> CRd;
4366    let Inst{24} = 0; // P = 0
4367    let Inst{23} = 1; // U = 1
4368    let Inst{22} = Dbit;
4369    let Inst{21} = 0; // W = 0
4370    let Inst{20} = load;
4371    let Inst{19-16} = addr;
4372    let Inst{15-12} = CRd;
4373    let Inst{11-8} = cop;
4374    let Inst{7-0} = option;
4375    let DecoderMethod = "DecodeCopMemInstruction";
4376  }
4377}
4378multiclass LdSt2Cop<bit load, bit Dbit, string asm> {
4379  def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4380                       asm, "\t$cop, $CRd, $addr"> {
4381    bits<13> addr;
4382    bits<4> cop;
4383    bits<4> CRd;
4384    let Inst{24} = 1; // P = 1
4385    let Inst{23} = addr{8};
4386    let Inst{22} = Dbit;
4387    let Inst{21} = 0; // W = 0
4388    let Inst{20} = load;
4389    let Inst{19-16} = addr{12-9};
4390    let Inst{15-12} = CRd;
4391    let Inst{11-8} = cop;
4392    let Inst{7-0} = addr{7-0};
4393    let DecoderMethod = "DecodeCopMemInstruction";
4394  }
4395  def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
4396                    asm, "\t$cop, $CRd, $addr!", IndexModePre> {
4397    bits<13> addr;
4398    bits<4> cop;
4399    bits<4> CRd;
4400    let Inst{24} = 1; // P = 1
4401    let Inst{23} = addr{8};
4402    let Inst{22} = Dbit;
4403    let Inst{21} = 1; // W = 1
4404    let Inst{20} = load;
4405    let Inst{19-16} = addr{12-9};
4406    let Inst{15-12} = CRd;
4407    let Inst{11-8} = cop;
4408    let Inst{7-0} = addr{7-0};
4409    let DecoderMethod = "DecodeCopMemInstruction";
4410  }
4411  def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4412                                 postidx_imm8s4:$offset),
4413                 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> {
4414    bits<9> offset;
4415    bits<4> addr;
4416    bits<4> cop;
4417    bits<4> CRd;
4418    let Inst{24} = 0; // P = 0
4419    let Inst{23} = offset{8};
4420    let Inst{22} = Dbit;
4421    let Inst{21} = 1; // W = 1
4422    let Inst{20} = load;
4423    let Inst{19-16} = addr;
4424    let Inst{15-12} = CRd;
4425    let Inst{11-8} = cop;
4426    let Inst{7-0} = offset{7-0};
4427    let DecoderMethod = "DecodeCopMemInstruction";
4428  }
4429  def _OPTION : ACInoP<(outs),
4430                       (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
4431                            coproc_option_imm:$option),
4432      asm, "\t$cop, $CRd, $addr, $option"> {
4433    bits<8> option;
4434    bits<4> addr;
4435    bits<4> cop;
4436    bits<4> CRd;
4437    let Inst{24} = 0; // P = 0
4438    let Inst{23} = 1; // U = 1
4439    let Inst{22} = Dbit;
4440    let Inst{21} = 0; // W = 0
4441    let Inst{20} = load;
4442    let Inst{19-16} = addr;
4443    let Inst{15-12} = CRd;
4444    let Inst{11-8} = cop;
4445    let Inst{7-0} = option;
4446    let DecoderMethod = "DecodeCopMemInstruction";
4447  }
4448}
4449
4450defm LDC   : LdStCop <1, 0, "ldc">;
4451defm LDCL  : LdStCop <1, 1, "ldcl">;
4452defm STC   : LdStCop <0, 0, "stc">;
4453defm STCL  : LdStCop <0, 1, "stcl">;
4454defm LDC2  : LdSt2Cop<1, 0, "ldc2">;
4455defm LDC2L : LdSt2Cop<1, 1, "ldc2l">;
4456defm STC2  : LdSt2Cop<0, 0, "stc2">;
4457defm STC2L : LdSt2Cop<0, 1, "stc2l">;
4458
4459//===----------------------------------------------------------------------===//
4460// Move between coprocessor and ARM core register.
4461//
4462
4463class MovRCopro<string opc, bit direction, dag oops, dag iops,
4464                list<dag> pattern>
4465  : ABI<0b1110, oops, iops, NoItinerary, opc,
4466        "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> {
4467  let Inst{20} = direction;
4468  let Inst{4} = 1;
4469
4470  bits<4> Rt;
4471  bits<4> cop;
4472  bits<3> opc1;
4473  bits<3> opc2;
4474  bits<4> CRm;
4475  bits<4> CRn;
4476
4477  let Inst{15-12} = Rt;
4478  let Inst{11-8}  = cop;
4479  let Inst{23-21} = opc1;
4480  let Inst{7-5}   = opc2;
4481  let Inst{3-0}   = CRm;
4482  let Inst{19-16} = CRn;
4483}
4484
4485def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */,
4486                    (outs),
4487                    (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4488                         c_imm:$CRm, imm0_7:$opc2),
4489                    [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4490                                  imm:$CRm, imm:$opc2)]>;
4491def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
4492                   (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4493                        c_imm:$CRm, 0, pred:$p)>;
4494def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */,
4495                    (outs GPR:$Rt),
4496                    (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
4497                         imm0_7:$opc2), []>;
4498def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm",
4499                   (MRC GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4500                        c_imm:$CRm, 0, pred:$p)>;
4501
4502def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
4503             (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4504
4505class MovRCopro2<string opc, bit direction, dag oops, dag iops,
4506                 list<dag> pattern>
4507  : ABXI<0b1110, oops, iops, NoItinerary,
4508         !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> {
4509  let Inst{31-28} = 0b1111;
4510  let Inst{20} = direction;
4511  let Inst{4} = 1;
4512
4513  bits<4> Rt;
4514  bits<4> cop;
4515  bits<3> opc1;
4516  bits<3> opc2;
4517  bits<4> CRm;
4518  bits<4> CRn;
4519
4520  let Inst{15-12} = Rt;
4521  let Inst{11-8}  = cop;
4522  let Inst{23-21} = opc1;
4523  let Inst{7-5}   = opc2;
4524  let Inst{3-0}   = CRm;
4525  let Inst{19-16} = CRn;
4526}
4527
4528def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */,
4529                      (outs),
4530                      (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4531                           c_imm:$CRm, imm0_7:$opc2),
4532                      [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4533                                     imm:$CRm, imm:$opc2)]>;
4534def : ARMInstAlias<"mcr2$ $cop, $opc1, $Rt, $CRn, $CRm",
4535                   (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4536                         c_imm:$CRm, 0)>;
4537def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */,
4538                      (outs GPR:$Rt),
4539                      (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
4540                           imm0_7:$opc2), []>;
4541def : ARMInstAlias<"mrc2$ $cop, $opc1, $Rt, $CRn, $CRm",
4542                   (MRC2 GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4543                         c_imm:$CRm, 0)>;
4544
4545def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn,
4546                              imm:$CRm, imm:$opc2),
4547                (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4548
4549class MovRRCopro<string opc, bit direction, list<dag> pattern = []>
4550  : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4551        GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm),
4552        NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> {
4553  let Inst{23-21} = 0b010;
4554  let Inst{20} = direction;
4555
4556  bits<4> Rt;
4557  bits<4> Rt2;
4558  bits<4> cop;
4559  bits<4> opc1;
4560  bits<4> CRm;
4561
4562  let Inst{15-12} = Rt;
4563  let Inst{19-16} = Rt2;
4564  let Inst{11-8}  = cop;
4565  let Inst{7-4}   = opc1;
4566  let Inst{3-0}   = CRm;
4567}
4568
4569def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */,
4570                      [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt,
4571                                     GPRnopc:$Rt2, imm:$CRm)]>;
4572def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
4573
4574class MovRRCopro2<string opc, bit direction, list<dag> pattern = []>
4575  : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4576         GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary,
4577         !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> {
4578  let Inst{31-28} = 0b1111;
4579  let Inst{23-21} = 0b010;
4580  let Inst{20} = direction;
4581
4582  bits<4> Rt;
4583  bits<4> Rt2;
4584  bits<4> cop;
4585  bits<4> opc1;
4586  bits<4> CRm;
4587
4588  let Inst{15-12} = Rt;
4589  let Inst{19-16} = Rt2;
4590  let Inst{11-8}  = cop;
4591  let Inst{7-4}   = opc1;
4592  let Inst{3-0}   = CRm;
4593
4594  let DecoderMethod = "DecodeMRRC2";
4595}
4596
4597def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */,
4598                        [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt,
4599                                        GPRnopc:$Rt2, imm:$CRm)]>;
4600def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
4601
4602//===----------------------------------------------------------------------===//
4603// Move between special register and ARM core register
4604//
4605
4606// Move to ARM core register from Special Register
4607def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
4608              "mrs", "\t$Rd, apsr", []> {
4609  bits<4> Rd;
4610  let Inst{23-16} = 0b00001111;
4611  let Unpredictable{19-17} = 0b111;
4612
4613  let Inst{15-12} = Rd;
4614
4615  let Inst{11-0} = 0b000000000000;
4616  let Unpredictable{11-0} = 0b110100001111;
4617}
4618
4619def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p)>,
4620         Requires<[IsARM]>;
4621
4622// The MRSsys instruction is the MRS instruction from the ARM ARM,
4623// section B9.3.9, with the R bit set to 1.
4624def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
4625                 "mrs", "\t$Rd, spsr", []> {
4626  bits<4> Rd;
4627  let Inst{23-16} = 0b01001111;
4628  let Unpredictable{19-16} = 0b1111;
4629
4630  let Inst{15-12} = Rd;
4631
4632  let Inst{11-0} = 0b000000000000;
4633  let Unpredictable{11-0} = 0b110100001111;
4634}
4635
4636// Move from ARM core register to Special Register
4637//
4638// No need to have both system and application versions, the encodings are the
4639// same and the assembly parser has no way to distinguish between them. The mask
4640// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
4641// the mask with the fields to be accessed in the special register.
4642def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
4643              "msr", "\t$mask, $Rn", []> {
4644  bits<5> mask;
4645  bits<4> Rn;
4646
4647  let Inst{23} = 0;
4648  let Inst{22} = mask{4}; // R bit
4649  let Inst{21-20} = 0b10;
4650  let Inst{19-16} = mask{3-0};
4651  let Inst{15-12} = 0b1111;
4652  let Inst{11-4} = 0b00000000;
4653  let Inst{3-0} = Rn;
4654}
4655
4656def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask,  so_imm:$a), NoItinerary,
4657               "msr", "\t$mask, $a", []> {
4658  bits<5> mask;
4659  bits<12> a;
4660
4661  let Inst{23} = 0;
4662  let Inst{22} = mask{4}; // R bit
4663  let Inst{21-20} = 0b10;
4664  let Inst{19-16} = mask{3-0};
4665  let Inst{15-12} = 0b1111;
4666  let Inst{11-0} = a;
4667}
4668
4669//===----------------------------------------------------------------------===//
4670// TLS Instructions
4671//
4672
4673// __aeabi_read_tp preserves the registers r1-r3.
4674// This is a pseudo inst so that we can get the encoding right,
4675// complete with fixup for the aeabi_read_tp function.
4676let isCall = 1,
4677  Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
4678  def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
4679               [(set R0, ARMthread_pointer)]>;
4680}
4681
4682//===----------------------------------------------------------------------===//
4683// SJLJ Exception handling intrinsics
4684//   eh_sjlj_setjmp() is an instruction sequence to store the return
4685//   address and save #0 in R0 for the non-longjmp case.
4686//   Since by its nature we may be coming from some other function to get
4687//   here, and we're using the stack frame for the containing function to
4688//   save/restore registers, we can't keep anything live in regs across
4689//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
4690//   when we get here from a longjmp(). We force everything out of registers
4691//   except for our own input by listing the relevant registers in Defs. By
4692//   doing so, we also cause the prologue/epilogue code to actively preserve
4693//   all of the callee-saved resgisters, which is exactly what we want.
4694//   A constant value is passed in $val, and we use the location as a scratch.
4695//
4696// These are pseudo-instructions and are lowered to individual MC-insts, so
4697// no encoding information is necessary.
4698let Defs =
4699  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR,
4700    Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
4701  hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
4702  def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
4703                               NoItinerary,
4704                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
4705                           Requires<[IsARM, HasVFP2]>;
4706}
4707
4708let Defs =
4709  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR ],
4710  hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
4711  def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
4712                                   NoItinerary,
4713                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
4714                                Requires<[IsARM, NoVFP]>;
4715}
4716
4717// FIXME: Non-IOS version(s)
4718let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
4719    Defs = [ R7, LR, SP ] in {
4720def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
4721                             NoItinerary,
4722                         [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
4723                                Requires<[IsARM, IsIOS]>;
4724}
4725
4726// eh.sjlj.dispatchsetup pseudo-instructions.
4727// These pseudos are used for both ARM and Thumb2. Any differences are
4728// handled when the pseudo is expanded (which happens before any passes
4729// that need the instruction size).
4730let Defs =
4731  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR,
4732    Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
4733  isBarrier = 1 in
4734def Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>;
4735
4736let Defs =
4737  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR ],
4738  isBarrier = 1 in
4739def Int_eh_sjlj_dispatchsetup_nofp : PseudoInst<(outs), (ins), NoItinerary, []>;
4740
4741
4742//===----------------------------------------------------------------------===//
4743// Non-Instruction Patterns
4744//
4745
4746// ARMv4 indirect branch using (MOVr PC, dst)
4747let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
4748  def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst),
4749                    4, IIC_Br, [(brind GPR:$dst)],
4750                    (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
4751                  Requires<[IsARM, NoV4T]>;
4752
4753// Large immediate handling.
4754
4755// 32-bit immediate using two piece so_imms or movw + movt.
4756// This is a single pseudo instruction, the benefit is that it can be remat'd
4757// as a single unit instead of having to handle reg inputs.
4758// FIXME: Remove this when we can do generalized remat.
4759let isReMaterializable = 1, isMoveImm = 1 in
4760def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
4761                           [(set GPR:$dst, (arm_i32imm:$src))]>,
4762                           Requires<[IsARM]>;
4763
4764// Pseudo instruction that combines movw + movt + add pc (if PIC).
4765// It also makes it possible to rematerialize the instructions.
4766// FIXME: Remove this when we can do generalized remat and when machine licm
4767// can properly the instructions.
4768let isReMaterializable = 1 in {
4769def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4770                              IIC_iMOVix2addpc,
4771                        [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
4772                        Requires<[IsARM, UseMovt]>;
4773
4774def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4775                             IIC_iMOVix2,
4776                        [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
4777                        Requires<[IsARM, UseMovt]>;
4778
4779let AddedComplexity = 10 in
4780def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
4781                                IIC_iMOVix2ld,
4782                    [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
4783                    Requires<[IsARM, UseMovt]>;
4784} // isReMaterializable
4785
4786// ConstantPool, GlobalAddress, and JumpTable
4787def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
4788            Requires<[IsARM, DontUseMovt]>;
4789def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
4790def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
4791            Requires<[IsARM, UseMovt]>;
4792def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
4793             (LEApcrelJT tjumptable:$dst, imm:$id)>;
4794
4795// TODO: add,sub,and, 3-instr forms?
4796
4797// Tail calls. These patterns also apply to Thumb mode.
4798def : Pat<(ARMtcret tcGPR:$dst), (TCRETURNri tcGPR:$dst)>;
4799def : Pat<(ARMtcret (i32 tglobaladdr:$dst)), (TCRETURNdi texternalsym:$dst)>;
4800def : Pat<(ARMtcret (i32 texternalsym:$dst)), (TCRETURNdi texternalsym:$dst)>;
4801
4802// Direct calls
4803def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
4804def : ARMPat<(ARMcall_nolink texternalsym:$func),
4805             (BMOVPCB_CALL texternalsym:$func)>;
4806
4807// zextload i1 -> zextload i8
4808def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
4809def : ARMPat<(zextloadi1 ldst_so_reg:$addr),    (LDRBrs ldst_so_reg:$addr)>;
4810
4811// extload -> zextload
4812def : ARMPat<(extloadi1 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
4813def : ARMPat<(extloadi1 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
4814def : ARMPat<(extloadi8 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
4815def : ARMPat<(extloadi8 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
4816
4817def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
4818
4819def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
4820def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
4821
4822// smul* and smla*
4823def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4824                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
4825                 (SMULBB GPR:$a, GPR:$b)>;
4826def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
4827                 (SMULBB GPR:$a, GPR:$b)>;
4828def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4829                      (sra GPR:$b, (i32 16))),
4830                 (SMULBT GPR:$a, GPR:$b)>;
4831def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
4832                 (SMULBT GPR:$a, GPR:$b)>;
4833def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
4834                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
4835                 (SMULTB GPR:$a, GPR:$b)>;
4836def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
4837                (SMULTB GPR:$a, GPR:$b)>;
4838def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
4839                      (i32 16)),
4840                 (SMULWB GPR:$a, GPR:$b)>;
4841def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
4842                 (SMULWB GPR:$a, GPR:$b)>;
4843
4844def : ARMV5TEPat<(add GPR:$acc,
4845                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4846                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
4847                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
4848def : ARMV5TEPat<(add GPR:$acc,
4849                      (mul sext_16_node:$a, sext_16_node:$b)),
4850                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
4851def : ARMV5TEPat<(add GPR:$acc,
4852                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
4853                           (sra GPR:$b, (i32 16)))),
4854                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
4855def : ARMV5TEPat<(add GPR:$acc,
4856                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
4857                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
4858def : ARMV5TEPat<(add GPR:$acc,
4859                      (mul (sra GPR:$a, (i32 16)),
4860                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
4861                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
4862def : ARMV5TEPat<(add GPR:$acc,
4863                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
4864                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
4865def : ARMV5TEPat<(add GPR:$acc,
4866                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
4867                           (i32 16))),
4868                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
4869def : ARMV5TEPat<(add GPR:$acc,
4870                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
4871                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
4872
4873
4874// Pre-v7 uses MCR for synchronization barriers.
4875def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>,
4876         Requires<[IsARM, HasV6]>;
4877
4878// SXT/UXT with no rotate
4879let AddedComplexity = 16 in {
4880def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>;
4881def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>;
4882def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>;
4883def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)),
4884               (UXTAB GPR:$Rn, GPR:$Rm, 0)>;
4885def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)),
4886               (UXTAH GPR:$Rn, GPR:$Rm, 0)>;
4887}
4888
4889def : ARMV6Pat<(sext_inreg GPR:$Src, i8),  (SXTB GPR:$Src, 0)>;
4890def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>;
4891
4892def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)),
4893               (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>;
4894def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)),
4895               (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>;
4896
4897// Atomic load/store patterns
4898def : ARMPat<(atomic_load_8 ldst_so_reg:$src),
4899             (LDRBrs ldst_so_reg:$src)>;
4900def : ARMPat<(atomic_load_8 addrmode_imm12:$src),
4901             (LDRBi12 addrmode_imm12:$src)>;
4902def : ARMPat<(atomic_load_16 addrmode3:$src),
4903             (LDRH addrmode3:$src)>;
4904def : ARMPat<(atomic_load_32 ldst_so_reg:$src),
4905             (LDRrs ldst_so_reg:$src)>;
4906def : ARMPat<(atomic_load_32 addrmode_imm12:$src),
4907             (LDRi12 addrmode_imm12:$src)>;
4908def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val),
4909             (STRBrs GPR:$val, ldst_so_reg:$ptr)>;
4910def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val),
4911             (STRBi12 GPR:$val, addrmode_imm12:$ptr)>;
4912def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val),
4913             (STRH GPR:$val, addrmode3:$ptr)>;
4914def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val),
4915             (STRrs GPR:$val, ldst_so_reg:$ptr)>;
4916def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val),
4917             (STRi12 GPR:$val, addrmode_imm12:$ptr)>;
4918
4919
4920//===----------------------------------------------------------------------===//
4921// Thumb Support
4922//
4923
4924include "ARMInstrThumb.td"
4925
4926//===----------------------------------------------------------------------===//
4927// Thumb2 Support
4928//
4929
4930include "ARMInstrThumb2.td"
4931
4932//===----------------------------------------------------------------------===//
4933// Floating Point Support
4934//
4935
4936include "ARMInstrVFP.td"
4937
4938//===----------------------------------------------------------------------===//
4939// Advanced SIMD (NEON) Support
4940//
4941
4942include "ARMInstrNEON.td"
4943
4944//===----------------------------------------------------------------------===//
4945// Assembler aliases
4946//
4947
4948// Memory barriers
4949def : InstAlias<"dmb", (DMB 0xf)>, Requires<[IsARM, HasDB]>;
4950def : InstAlias<"dsb", (DSB 0xf)>, Requires<[IsARM, HasDB]>;
4951def : InstAlias<"isb", (ISB 0xf)>, Requires<[IsARM, HasDB]>;
4952
4953// System instructions
4954def : MnemonicAlias<"swi", "svc">;
4955
4956// Load / Store Multiple
4957def : MnemonicAlias<"ldmfd", "ldm">;
4958def : MnemonicAlias<"ldmia", "ldm">;
4959def : MnemonicAlias<"ldmea", "ldmdb">;
4960def : MnemonicAlias<"stmfd", "stmdb">;
4961def : MnemonicAlias<"stmia", "stm">;
4962def : MnemonicAlias<"stmea", "stm">;
4963
4964// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the
4965// shift amount is zero (i.e., unspecified).
4966def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm",
4967                (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>,
4968        Requires<[IsARM, HasV6]>;
4969def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm",
4970                (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>,
4971        Requires<[IsARM, HasV6]>;
4972
4973// PUSH/POP aliases for STM/LDM
4974def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>;
4975def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>;
4976
4977// SSAT/USAT optional shift operand.
4978def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn",
4979                (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
4980def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn",
4981                (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
4982
4983
4984// Extend instruction optional rotate operand.
4985def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm",
4986                (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4987def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm",
4988                (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4989def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm",
4990                (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
4991def : ARMInstAlias<"sxtb${p} $Rd, $Rm",
4992                (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4993def : ARMInstAlias<"sxtb16${p} $Rd, $Rm",
4994                (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4995def : ARMInstAlias<"sxth${p} $Rd, $Rm",
4996                (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
4997
4998def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm",
4999                (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
5000def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm",
5001                (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
5002def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
5003                (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
5004def : ARMInstAlias<"uxtb${p} $Rd, $Rm",
5005                (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
5006def : ARMInstAlias<"uxtb16${p} $Rd, $Rm",
5007                (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
5008def : ARMInstAlias<"uxth${p} $Rd, $Rm",
5009                (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
5010
5011
5012// RFE aliases
5013def : MnemonicAlias<"rfefa", "rfeda">;
5014def : MnemonicAlias<"rfeea", "rfedb">;
5015def : MnemonicAlias<"rfefd", "rfeia">;
5016def : MnemonicAlias<"rfeed", "rfeib">;
5017def : MnemonicAlias<"rfe", "rfeia">;
5018
5019// SRS aliases
5020def : MnemonicAlias<"srsfa", "srsda">;
5021def : MnemonicAlias<"srsea", "srsdb">;
5022def : MnemonicAlias<"srsfd", "srsia">;
5023def : MnemonicAlias<"srsed", "srsib">;
5024def : MnemonicAlias<"srs", "srsia">;
5025
5026// QSAX == QSUBADDX
5027def : MnemonicAlias<"qsubaddx", "qsax">;
5028// SASX == SADDSUBX
5029def : MnemonicAlias<"saddsubx", "sasx">;
5030// SHASX == SHADDSUBX
5031def : MnemonicAlias<"shaddsubx", "shasx">;
5032// SHSAX == SHSUBADDX
5033def : MnemonicAlias<"shsubaddx", "shsax">;
5034// SSAX == SSUBADDX
5035def : MnemonicAlias<"ssubaddx", "ssax">;
5036// UASX == UADDSUBX
5037def : MnemonicAlias<"uaddsubx", "uasx">;
5038// UHASX == UHADDSUBX
5039def : MnemonicAlias<"uhaddsubx", "uhasx">;
5040// UHSAX == UHSUBADDX
5041def : MnemonicAlias<"uhsubaddx", "uhsax">;
5042// UQASX == UQADDSUBX
5043def : MnemonicAlias<"uqaddsubx", "uqasx">;
5044// UQSAX == UQSUBADDX
5045def : MnemonicAlias<"uqsubaddx", "uqsax">;
5046// USAX == USUBADDX
5047def : MnemonicAlias<"usubaddx", "usax">;
5048
5049// "mov Rd, so_imm_not" can be handled via "mvn" in assembly, just like
5050// for isel.
5051def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
5052                   (MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
5053def : ARMInstAlias<"mvn${s}${p} $Rd, $imm",
5054                   (MOVi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
5055// Same for AND <--> BIC
5056def : ARMInstAlias<"bic${s}${p} $Rd, $Rn, $imm",
5057                   (ANDri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm,
5058                          pred:$p, cc_out:$s)>;
5059def : ARMInstAlias<"bic${s}${p} $Rdn, $imm",
5060                   (ANDri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm,
5061                          pred:$p, cc_out:$s)>;
5062def : ARMInstAlias<"and${s}${p} $Rd, $Rn, $imm",
5063                   (BICri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm,
5064                          pred:$p, cc_out:$s)>;
5065def : ARMInstAlias<"and${s}${p} $Rdn, $imm",
5066                   (BICri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm,
5067                          pred:$p, cc_out:$s)>;
5068
5069// Likewise, "add Rd, so_imm_neg" -> sub
5070def : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm",
5071                 (SUBri GPR:$Rd, GPR:$Rn, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
5072def : ARMInstAlias<"add${s}${p} $Rd, $imm",
5073                 (SUBri GPR:$Rd, GPR:$Rd, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
5074// Same for CMP <--> CMN via so_imm_neg
5075def : ARMInstAlias<"cmp${p} $Rd, $imm",
5076                   (CMNri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>;
5077def : ARMInstAlias<"cmn${p} $Rd, $imm",
5078                   (CMPri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>;
5079
5080// The shifter forms of the MOV instruction are aliased to the ASR, LSL,
5081// LSR, ROR, and RRX instructions.
5082// FIXME: We need C++ parser hooks to map the alias to the MOV
5083//        encoding. It seems we should be able to do that sort of thing
5084//        in tblgen, but it could get ugly.
5085let TwoOperandAliasConstraint = "$Rm = $Rd" in {
5086def ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm",
5087                        (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
5088                             cc_out:$s)>;
5089def LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm",
5090                        (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
5091                             cc_out:$s)>;
5092def LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm",
5093                        (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
5094                             cc_out:$s)>;
5095def RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm",
5096                        (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
5097                             cc_out:$s)>;
5098}
5099def RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm",
5100                        (ins GPRnopc:$Rd, GPRnopc:$Rm, pred:$p, cc_out:$s)>;
5101let TwoOperandAliasConstraint = "$Rn = $Rd" in {
5102def ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm",
5103                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5104                             cc_out:$s)>;
5105def LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm",
5106                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5107                             cc_out:$s)>;
5108def LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm",
5109                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5110                             cc_out:$s)>;
5111def RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm",
5112                        (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
5113                             cc_out:$s)>;
5114}
5115
5116// "neg" is and alias for "rsb rd, rn, #0"
5117def : ARMInstAlias<"neg${s}${p} $Rd, $Rm",
5118                   (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>;
5119
5120// Pre-v6, 'mov r0, r0' was used as a NOP encoding.
5121def : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg)>,
5122         Requires<[IsARM, NoV6]>;
5123
5124// UMULL/SMULL are available on all arches, but the instruction definitions
5125// need difference constraints pre-v6. Use these aliases for the assembly
5126// parsing on pre-v6.
5127def : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
5128            (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
5129         Requires<[IsARM, NoV6]>;
5130def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
5131            (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
5132         Requires<[IsARM, NoV6]>;
5133
5134// 'it' blocks in ARM mode just validate the predicates. The IT itself
5135// is discarded.
5136def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>;
5137