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