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