ARMInstrInfo.td revision 5de5d4b6d0eb3fd379fa571d82f6fa764460b3b8
1//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the ARM instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// ARM specific DAG Nodes.
16//
17
18// Type profiles.
19def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20def SDT_ARMCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
21
22def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
23
24def SDT_ARMcall    : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
25
26def SDT_ARMCMov    : SDTypeProfile<1, 3,
27                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
28                                    SDTCisVT<3, i32>]>;
29
30def SDT_ARMBrcond  : SDTypeProfile<0, 2,
31                                   [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
32
33def SDT_ARMBrJT    : SDTypeProfile<0, 3,
34                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
35                                   SDTCisVT<2, i32>]>;
36
37def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
38                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39                                   SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
40
41def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
42                                  [SDTCisVT<0, i32>,
43                                   SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44                                   SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45                                   SDTCisVT<5, OtherVT>]>;
46
47def SDT_ARMAnd     : SDTypeProfile<1, 2,
48                                   [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
49                                    SDTCisVT<2, i32>]>;
50
51def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
52
53def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
55
56def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
58                                                 SDTCisInt<2>]>;
59def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
60
61def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
62
63def SDT_ARMMEMBARRIER     : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
64
65def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
66
67def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68                                      SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
69
70// Node definitions.
71def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
72def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
73def ARMWrapperPIC    : SDNode<"ARMISD::WrapperPIC",  SDTIntBinOp>;
74
75def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
76                              [SDNPHasChain, SDNPOutGlue]>;
77def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
78                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
79
80def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
81                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
82                               SDNPVariadic]>;
83def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
84                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
85                               SDNPVariadic]>;
86def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
87                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
88                               SDNPVariadic]>;
89
90def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
91                              [SDNPHasChain, SDNPOptInGlue]>;
92
93def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
94                              [SDNPInGlue]>;
95def ARMcneg          : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
96                              [SDNPInGlue]>;
97
98def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
99                              [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
100
101def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
102                              [SDNPHasChain]>;
103def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
104                              [SDNPHasChain]>;
105
106def ARMBcci64        : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
107                              [SDNPHasChain]>;
108
109def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
110                              [SDNPOutGlue]>;
111
112def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
113                              [SDNPOutGlue, SDNPCommutative]>;
114
115def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116
117def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
118def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
119def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInGlue ]>;
120
121def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
122def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
123                               SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
124def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
125                               SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
126def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
127                               SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
128
129
130def ARMMemBarrier     : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
131                               [SDNPHasChain]>;
132def ARMMemBarrierMCR  : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
133                               [SDNPHasChain]>;
134def ARMPreload        : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
135                               [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
136
137def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
138
139def ARMtcret         : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
140                        [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
141
142
143def ARMbfi           : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
144
145//===----------------------------------------------------------------------===//
146// ARM Instruction Predicate Definitions.
147//
148def HasV4T           : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
149def NoV4T            : Predicate<"!Subtarget->hasV4TOps()">;
150def HasV5T           : Predicate<"Subtarget->hasV5TOps()">;
151def HasV5TE          : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
152def HasV6            : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
153def NoV6             : Predicate<"!Subtarget->hasV6Ops()">;
154def HasV6T2          : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
155def NoV6T2           : Predicate<"!Subtarget->hasV6T2Ops()">;
156def HasV7            : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
157def NoVFP            : Predicate<"!Subtarget->hasVFP2()">;
158def HasVFP2          : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
159def HasVFP3          : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
160def HasNEON          : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
161def HasFP16          : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
162def HasDivide        : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
163def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
164                                 AssemblerPredicate;
165def HasDB            : Predicate<"Subtarget->hasDataBarrier()">,
166                                 AssemblerPredicate;
167def HasMP            : Predicate<"Subtarget->hasMPExtension()">,
168                                 AssemblerPredicate;
169def UseNEONForFP     : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
170def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
171def IsThumb          : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
172def IsThumb1Only     : Predicate<"Subtarget->isThumb1Only()">;
173def IsThumb2         : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
174def IsARM            : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
175def IsDarwin         : Predicate<"Subtarget->isTargetDarwin()">;
176def IsNotDarwin      : Predicate<"!Subtarget->isTargetDarwin()">;
177
178// FIXME: Eventually this will be just "hasV6T2Ops".
179def UseMovt          : Predicate<"Subtarget->useMovt()">;
180def DontUseMovt      : Predicate<"!Subtarget->useMovt()">;
181def UseFPVMLx        : Predicate<"Subtarget->useFPVMLx()">;
182
183//===----------------------------------------------------------------------===//
184// ARM Flag Definitions.
185
186class RegConstraint<string C> {
187  string Constraints = C;
188}
189
190//===----------------------------------------------------------------------===//
191//  ARM specific transformation functions and pattern fragments.
192//
193
194// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
195// so_imm_neg def below.
196def so_imm_neg_XFORM : SDNodeXForm<imm, [{
197  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
198}]>;
199
200// so_imm_not_XFORM - Return a so_imm value packed into the format described for
201// so_imm_not def below.
202def so_imm_not_XFORM : SDNodeXForm<imm, [{
203  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
204}]>;
205
206/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
207def imm1_15 : PatLeaf<(i32 imm), [{
208  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
209}]>;
210
211/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
212def imm16_31 : PatLeaf<(i32 imm), [{
213  return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
214}]>;
215
216def so_imm_neg :
217  PatLeaf<(imm), [{
218    return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
219  }], so_imm_neg_XFORM>;
220
221def so_imm_not :
222  PatLeaf<(imm), [{
223    return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
224  }], so_imm_not_XFORM>;
225
226// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
227def sext_16_node : PatLeaf<(i32 GPR:$a), [{
228  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
229}]>;
230
231/// Split a 32-bit immediate into two 16 bit parts.
232def hi16 : SDNodeXForm<imm, [{
233  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
234}]>;
235
236def lo16AllZero : PatLeaf<(i32 imm), [{
237  // Returns true if all low 16-bits are 0.
238  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
239}], hi16>;
240
241/// imm0_65535 predicate - True if the 32-bit immediate is in the range
242/// [0.65535].
243def imm0_65535 : PatLeaf<(i32 imm), [{
244  return (uint32_t)N->getZExtValue() < 65536;
245}]>;
246
247class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
248class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
249
250/// adde and sube predicates - True based on whether the carry flag output
251/// will be needed or not.
252def adde_dead_carry :
253  PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
254  [{return !N->hasAnyUseOfValue(1);}]>;
255def sube_dead_carry :
256  PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
257  [{return !N->hasAnyUseOfValue(1);}]>;
258def adde_live_carry :
259  PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
260  [{return N->hasAnyUseOfValue(1);}]>;
261def sube_live_carry :
262  PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
263  [{return N->hasAnyUseOfValue(1);}]>;
264
265// An 'and' node with a single use.
266def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
267  return N->hasOneUse();
268}]>;
269
270// An 'xor' node with a single use.
271def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
272  return N->hasOneUse();
273}]>;
274
275// An 'fmul' node with a single use.
276def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
277  return N->hasOneUse();
278}]>;
279
280// An 'fadd' node which checks for single non-hazardous use.
281def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
282  return hasNoVMLxHazardUse(N);
283}]>;
284
285// An 'fsub' node which checks for single non-hazardous use.
286def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
287  return hasNoVMLxHazardUse(N);
288}]>;
289
290//===----------------------------------------------------------------------===//
291// Operand Definitions.
292//
293
294// Branch target.
295def brtarget : Operand<OtherVT> {
296  let EncoderMethod = "getBranchTargetOpValue";
297}
298
299def uncondbrtarget : Operand<OtherVT> {
300  let EncoderMethod = "getUnconditionalBranchTargetOpValue";
301}
302
303// Call target.
304def bltarget : Operand<i32> {
305  // Encoded the same as branch targets.
306  let EncoderMethod = "getBranchTargetOpValue";
307}
308
309// A list of registers separated by comma. Used by load/store multiple.
310def RegListAsmOperand : AsmOperandClass {
311  let Name = "RegList";
312  let SuperClasses = [];
313}
314
315def DPRRegListAsmOperand : AsmOperandClass {
316  let Name = "DPRRegList";
317  let SuperClasses = [];
318}
319
320def SPRRegListAsmOperand : AsmOperandClass {
321  let Name = "SPRRegList";
322  let SuperClasses = [];
323}
324
325def reglist : Operand<i32> {
326  let EncoderMethod = "getRegisterListOpValue";
327  let ParserMatchClass = RegListAsmOperand;
328  let PrintMethod = "printRegisterList";
329}
330
331def dpr_reglist : Operand<i32> {
332  let EncoderMethod = "getRegisterListOpValue";
333  let ParserMatchClass = DPRRegListAsmOperand;
334  let PrintMethod = "printRegisterList";
335}
336
337def spr_reglist : Operand<i32> {
338  let EncoderMethod = "getRegisterListOpValue";
339  let ParserMatchClass = SPRRegListAsmOperand;
340  let PrintMethod = "printRegisterList";
341}
342
343// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
344def cpinst_operand : Operand<i32> {
345  let PrintMethod = "printCPInstOperand";
346}
347
348// Local PC labels.
349def pclabel : Operand<i32> {
350  let PrintMethod = "printPCLabel";
351}
352
353// ADR instruction labels.
354def adrlabel : Operand<i32> {
355  let EncoderMethod = "getAdrLabelOpValue";
356}
357
358def neon_vcvt_imm32 : Operand<i32> {
359  let EncoderMethod = "getNEONVcvtImm32OpValue";
360}
361
362// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
363def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
364    int32_t v = (int32_t)N->getZExtValue();
365    return v == 8 || v == 16 || v == 24; }]> {
366  let EncoderMethod = "getRotImmOpValue";
367}
368
369// shift_imm: An integer that encodes a shift amount and the type of shift
370// (currently either asr or lsl) using the same encoding used for the
371// immediates in so_reg operands.
372def shift_imm : Operand<i32> {
373  let PrintMethod = "printShiftImmOperand";
374}
375
376// shifter_operand operands: so_reg and so_imm.
377def so_reg : Operand<i32>,    // reg reg imm
378             ComplexPattern<i32, 3, "SelectShifterOperandReg",
379                            [shl,srl,sra,rotr]> {
380  let EncoderMethod = "getSORegOpValue";
381  let PrintMethod = "printSORegOperand";
382  let MIOperandInfo = (ops GPR, GPR, i32imm);
383}
384def shift_so_reg : Operand<i32>,    // reg reg imm
385                   ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
386                                  [shl,srl,sra,rotr]> {
387  let EncoderMethod = "getSORegOpValue";
388  let PrintMethod = "printSORegOperand";
389  let MIOperandInfo = (ops GPR, GPR, i32imm);
390}
391
392// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
393// 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
394// represented in the imm field in the same 12-bit form that they are encoded
395// into so_imm instructions: the 8-bit immediate is the least significant bits
396// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
397def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
398  let EncoderMethod = "getSOImmOpValue";
399  let PrintMethod = "printSOImmOperand";
400}
401
402// Break so_imm's up into two pieces.  This handles immediates with up to 16
403// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
404// get the first/second pieces.
405def so_imm2part : PatLeaf<(imm), [{
406      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
407}]>;
408
409/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
410///
411def arm_i32imm : PatLeaf<(imm), [{
412  if (Subtarget->hasV6T2Ops())
413    return true;
414  return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
415}]>;
416
417/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
418def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
419  return (int32_t)N->getZExtValue() < 32;
420}]>;
421
422/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
423def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
424  return (int32_t)N->getZExtValue() < 32;
425}]> {
426  let EncoderMethod = "getImmMinusOneOpValue";
427}
428
429// i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
430// The imm is split into imm{15-12}, imm{11-0}
431//
432def i32imm_hilo16 : Operand<i32> {
433  let EncoderMethod = "getHiLo16ImmOpValue";
434}
435
436/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
437/// e.g., 0xf000ffff
438def bf_inv_mask_imm : Operand<i32>,
439                      PatLeaf<(imm), [{
440  return ARM::isBitFieldInvertedMask(N->getZExtValue());
441}] > {
442  let EncoderMethod = "getBitfieldInvertedMaskOpValue";
443  let PrintMethod = "printBitfieldInvMaskImmOperand";
444}
445
446// Define ARM specific addressing modes.
447
448
449// addrmode_imm12 := reg +/- imm12
450//
451def addrmode_imm12 : Operand<i32>,
452                     ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
453  // 12-bit immediate operand. Note that instructions using this encode
454  // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
455  // immediate values are as normal.
456
457  let EncoderMethod = "getAddrModeImm12OpValue";
458  let PrintMethod = "printAddrModeImm12Operand";
459  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
460}
461// ldst_so_reg := reg +/- reg shop imm
462//
463def ldst_so_reg : Operand<i32>,
464                  ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
465  let EncoderMethod = "getLdStSORegOpValue";
466  // FIXME: Simplify the printer
467  let PrintMethod = "printAddrMode2Operand";
468  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
469}
470
471// addrmode2 := reg +/- imm12
472//           := reg +/- reg shop imm
473//
474def addrmode2 : Operand<i32>,
475                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
476  let EncoderMethod = "getAddrMode2OpValue";
477  let PrintMethod = "printAddrMode2Operand";
478  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
479}
480
481def am2offset : Operand<i32>,
482                ComplexPattern<i32, 2, "SelectAddrMode2Offset",
483                [], [SDNPWantRoot]> {
484  let EncoderMethod = "getAddrMode2OffsetOpValue";
485  let PrintMethod = "printAddrMode2OffsetOperand";
486  let MIOperandInfo = (ops GPR, i32imm);
487}
488
489// addrmode3 := reg +/- reg
490// addrmode3 := reg +/- imm8
491//
492def addrmode3 : Operand<i32>,
493                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
494  let EncoderMethod = "getAddrMode3OpValue";
495  let PrintMethod = "printAddrMode3Operand";
496  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
497}
498
499def am3offset : Operand<i32>,
500                ComplexPattern<i32, 2, "SelectAddrMode3Offset",
501                               [], [SDNPWantRoot]> {
502  let EncoderMethod = "getAddrMode3OffsetOpValue";
503  let PrintMethod = "printAddrMode3OffsetOperand";
504  let MIOperandInfo = (ops GPR, i32imm);
505}
506
507// ldstm_mode := {ia, ib, da, db}
508//
509def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
510  let EncoderMethod = "getLdStmModeOpValue";
511  let PrintMethod = "printLdStmModeOperand";
512}
513
514def MemMode5AsmOperand : AsmOperandClass {
515  let Name = "MemMode5";
516  let SuperClasses = [];
517}
518
519// addrmode5 := reg +/- imm8*4
520//
521def addrmode5 : Operand<i32>,
522                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
523  let PrintMethod = "printAddrMode5Operand";
524  let MIOperandInfo = (ops GPR:$base, i32imm);
525  let ParserMatchClass = MemMode5AsmOperand;
526  let EncoderMethod = "getAddrMode5OpValue";
527}
528
529// addrmode6 := reg with optional writeback
530//
531def addrmode6 : Operand<i32>,
532                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
533  let PrintMethod = "printAddrMode6Operand";
534  let MIOperandInfo = (ops GPR:$addr, i32imm);
535  let EncoderMethod = "getAddrMode6AddressOpValue";
536}
537
538def am6offset : Operand<i32> {
539  let PrintMethod = "printAddrMode6OffsetOperand";
540  let MIOperandInfo = (ops GPR);
541  let EncoderMethod = "getAddrMode6OffsetOpValue";
542}
543
544// Special version of addrmode6 to handle alignment encoding for VLD-dup
545// instructions, specifically VLD4-dup.
546def addrmode6dup : Operand<i32>,
547                ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
548  let PrintMethod = "printAddrMode6Operand";
549  let MIOperandInfo = (ops GPR:$addr, i32imm);
550  let EncoderMethod = "getAddrMode6DupAddressOpValue";
551}
552
553// addrmodepc := pc + reg
554//
555def addrmodepc : Operand<i32>,
556                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
557  let PrintMethod = "printAddrModePCOperand";
558  let MIOperandInfo = (ops GPR, i32imm);
559}
560
561def nohash_imm : Operand<i32> {
562  let PrintMethod = "printNoHashImmediate";
563}
564
565def p_imm : Operand<i32> {
566  let PrintMethod = "printPImmediate";
567}
568
569def c_imm : Operand<i32> {
570  let PrintMethod = "printCImmediate";
571}
572
573//===----------------------------------------------------------------------===//
574
575include "ARMInstrFormats.td"
576
577//===----------------------------------------------------------------------===//
578// Multiclass helpers...
579//
580
581/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
582/// binop that produces a value.
583multiclass AsI1_bin_irs<bits<4> opcod, string opc,
584                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
585                        PatFrag opnode, bit Commutable = 0> {
586  // The register-immediate version is re-materializable. This is useful
587  // in particular for taking the address of a local.
588  let isReMaterializable = 1 in {
589  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
590               iii, opc, "\t$Rd, $Rn, $imm",
591               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
592    bits<4> Rd;
593    bits<4> Rn;
594    bits<12> imm;
595    let Inst{25} = 1;
596    let Inst{19-16} = Rn;
597    let Inst{15-12} = Rd;
598    let Inst{11-0} = imm;
599  }
600  }
601  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
602               iir, opc, "\t$Rd, $Rn, $Rm",
603               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
604    bits<4> Rd;
605    bits<4> Rn;
606    bits<4> Rm;
607    let Inst{25} = 0;
608    let isCommutable = Commutable;
609    let Inst{19-16} = Rn;
610    let Inst{15-12} = Rd;
611    let Inst{11-4} = 0b00000000;
612    let Inst{3-0} = Rm;
613  }
614  def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
615               iis, opc, "\t$Rd, $Rn, $shift",
616               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
617    bits<4> Rd;
618    bits<4> Rn;
619    bits<12> shift;
620    let Inst{25} = 0;
621    let Inst{19-16} = Rn;
622    let Inst{15-12} = Rd;
623    let Inst{11-0} = shift;
624  }
625}
626
627/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
628/// instruction modifies the CPSR register.
629let isCodeGenOnly = 1, Defs = [CPSR] in {
630multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
631                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
632                         PatFrag opnode, bit Commutable = 0> {
633  def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
634               iii, opc, "\t$Rd, $Rn, $imm",
635               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
636    bits<4> Rd;
637    bits<4> Rn;
638    bits<12> imm;
639    let Inst{25} = 1;
640    let Inst{20} = 1;
641    let Inst{19-16} = Rn;
642    let Inst{15-12} = Rd;
643    let Inst{11-0} = imm;
644  }
645  def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
646               iir, opc, "\t$Rd, $Rn, $Rm",
647               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
648    bits<4> Rd;
649    bits<4> Rn;
650    bits<4> Rm;
651    let isCommutable = Commutable;
652    let Inst{25} = 0;
653    let Inst{20} = 1;
654    let Inst{19-16} = Rn;
655    let Inst{15-12} = Rd;
656    let Inst{11-4} = 0b00000000;
657    let Inst{3-0} = Rm;
658  }
659  def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
660               iis, opc, "\t$Rd, $Rn, $shift",
661               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
662    bits<4> Rd;
663    bits<4> Rn;
664    bits<12> shift;
665    let Inst{25} = 0;
666    let Inst{20} = 1;
667    let Inst{19-16} = Rn;
668    let Inst{15-12} = Rd;
669    let Inst{11-0} = shift;
670  }
671}
672}
673
674/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
675/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
676/// a explicit result, only implicitly set CPSR.
677let isCompare = 1, Defs = [CPSR] in {
678multiclass AI1_cmp_irs<bits<4> opcod, string opc,
679                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
680                       PatFrag opnode, bit Commutable = 0> {
681  def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
682               opc, "\t$Rn, $imm",
683               [(opnode GPR:$Rn, so_imm:$imm)]> {
684    bits<4> Rn;
685    bits<12> imm;
686    let Inst{25} = 1;
687    let Inst{20} = 1;
688    let Inst{19-16} = Rn;
689    let Inst{15-12} = 0b0000;
690    let Inst{11-0} = imm;
691  }
692  def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
693               opc, "\t$Rn, $Rm",
694               [(opnode GPR:$Rn, GPR:$Rm)]> {
695    bits<4> Rn;
696    bits<4> Rm;
697    let isCommutable = Commutable;
698    let Inst{25} = 0;
699    let Inst{20} = 1;
700    let Inst{19-16} = Rn;
701    let Inst{15-12} = 0b0000;
702    let Inst{11-4} = 0b00000000;
703    let Inst{3-0} = Rm;
704  }
705  def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
706               opc, "\t$Rn, $shift",
707               [(opnode GPR:$Rn, so_reg:$shift)]> {
708    bits<4> Rn;
709    bits<12> shift;
710    let Inst{25} = 0;
711    let Inst{20} = 1;
712    let Inst{19-16} = Rn;
713    let Inst{15-12} = 0b0000;
714    let Inst{11-0} = shift;
715  }
716}
717}
718
719/// AI_ext_rrot - A unary operation with two forms: one whose operand is a
720/// register and one whose operand is a register rotated by 8/16/24.
721/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
722multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
723  def r     : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
724                 IIC_iEXTr, opc, "\t$Rd, $Rm",
725                 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
726              Requires<[IsARM, HasV6]> {
727    bits<4> Rd;
728    bits<4> Rm;
729    let Inst{19-16} = 0b1111;
730    let Inst{15-12} = Rd;
731    let Inst{11-10} = 0b00;
732    let Inst{3-0}   = Rm;
733  }
734  def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
735                 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
736                 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
737              Requires<[IsARM, HasV6]> {
738    bits<4> Rd;
739    bits<4> Rm;
740    bits<2> rot;
741    let Inst{19-16} = 0b1111;
742    let Inst{15-12} = Rd;
743    let Inst{11-10} = rot;
744    let Inst{3-0}   = Rm;
745  }
746}
747
748multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
749  def r     : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
750                 IIC_iEXTr, opc, "\t$Rd, $Rm",
751                 [/* For disassembly only; pattern left blank */]>,
752              Requires<[IsARM, HasV6]> {
753    let Inst{19-16} = 0b1111;
754    let Inst{11-10} = 0b00;
755  }
756  def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
757                 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
758                 [/* For disassembly only; pattern left blank */]>,
759              Requires<[IsARM, HasV6]> {
760    bits<2> rot;
761    let Inst{19-16} = 0b1111;
762    let Inst{11-10} = rot;
763  }
764}
765
766/// AI_exta_rrot - A binary operation with two forms: one whose operand is a
767/// register and one whose operand is a register rotated by 8/16/24.
768multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
769  def rr     : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
770                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
771                  [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
772               Requires<[IsARM, HasV6]> {
773    bits<4> Rd;
774    bits<4> Rm;
775    bits<4> Rn;
776    let Inst{19-16} = Rn;
777    let Inst{15-12} = Rd;
778    let Inst{11-10} = 0b00;
779    let Inst{9-4}   = 0b000111;
780    let Inst{3-0}   = Rm;
781  }
782  def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
783                                             rot_imm:$rot),
784                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
785                  [(set GPR:$Rd, (opnode GPR:$Rn,
786                                          (rotr GPR:$Rm, rot_imm:$rot)))]>,
787                  Requires<[IsARM, HasV6]> {
788    bits<4> Rd;
789    bits<4> Rm;
790    bits<4> Rn;
791    bits<2> rot;
792    let Inst{19-16} = Rn;
793    let Inst{15-12} = Rd;
794    let Inst{11-10} = rot;
795    let Inst{9-4}   = 0b000111;
796    let Inst{3-0}   = Rm;
797  }
798}
799
800// For disassembly only.
801multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
802  def rr     : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
803                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
804                  [/* For disassembly only; pattern left blank */]>,
805               Requires<[IsARM, HasV6]> {
806    let Inst{11-10} = 0b00;
807  }
808  def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
809                                             rot_imm:$rot),
810                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
811                  [/* For disassembly only; pattern left blank */]>,
812                  Requires<[IsARM, HasV6]> {
813    bits<4> Rn;
814    bits<2> rot;
815    let Inst{19-16} = Rn;
816    let Inst{11-10} = rot;
817  }
818}
819
820/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
821let Uses = [CPSR] in {
822multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
823                             bit Commutable = 0> {
824  def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
825                DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
826               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
827               Requires<[IsARM]> {
828    bits<4> Rd;
829    bits<4> Rn;
830    bits<12> imm;
831    let Inst{25} = 1;
832    let Inst{15-12} = Rd;
833    let Inst{19-16} = Rn;
834    let Inst{11-0} = imm;
835  }
836  def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
837                DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
838               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
839               Requires<[IsARM]> {
840    bits<4> Rd;
841    bits<4> Rn;
842    bits<4> Rm;
843    let Inst{11-4} = 0b00000000;
844    let Inst{25} = 0;
845    let isCommutable = Commutable;
846    let Inst{3-0} = Rm;
847    let Inst{15-12} = Rd;
848    let Inst{19-16} = Rn;
849  }
850  def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
851                DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
852               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
853               Requires<[IsARM]> {
854    bits<4> Rd;
855    bits<4> Rn;
856    bits<12> shift;
857    let Inst{25} = 0;
858    let Inst{11-0} = shift;
859    let Inst{15-12} = Rd;
860    let Inst{19-16} = Rn;
861  }
862}
863// Carry setting variants
864let isCodeGenOnly = 1, Defs = [CPSR] in {
865multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
866                             bit Commutable = 0> {
867  def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
868                DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
869               [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
870               Requires<[IsARM]> {
871    bits<4> Rd;
872    bits<4> Rn;
873    bits<12> imm;
874    let Inst{15-12} = Rd;
875    let Inst{19-16} = Rn;
876    let Inst{11-0} = imm;
877    let Inst{20} = 1;
878    let Inst{25} = 1;
879  }
880  def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
881                DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
882               [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
883               Requires<[IsARM]> {
884    bits<4> Rd;
885    bits<4> Rn;
886    bits<4> Rm;
887    let Inst{11-4} = 0b00000000;
888    let isCommutable = Commutable;
889    let Inst{3-0} = Rm;
890    let Inst{15-12} = Rd;
891    let Inst{19-16} = Rn;
892    let Inst{20} = 1;
893    let Inst{25} = 0;
894  }
895  def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
896                DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
897               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
898               Requires<[IsARM]> {
899    bits<4> Rd;
900    bits<4> Rn;
901    bits<12> shift;
902    let Inst{11-0} = shift;
903    let Inst{15-12} = Rd;
904    let Inst{19-16} = Rn;
905    let Inst{20} = 1;
906    let Inst{25} = 0;
907  }
908}
909}
910}
911
912let canFoldAsLoad = 1, isReMaterializable = 1 in {
913multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
914           InstrItinClass iir, PatFrag opnode> {
915  // Note: We use the complex addrmode_imm12 rather than just an input
916  // GPR and a constrained immediate so that we can use this to match
917  // frame index references and avoid matching constant pool references.
918  def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
919                   AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
920                  [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
921    bits<4>  Rt;
922    bits<17> addr;
923    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
924    let Inst{19-16} = addr{16-13};  // Rn
925    let Inst{15-12} = Rt;
926    let Inst{11-0}  = addr{11-0};   // imm12
927  }
928  def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
929                  AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
930                 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
931    bits<4>  Rt;
932    bits<17> shift;
933    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
934    let Inst{19-16} = shift{16-13}; // Rn
935    let Inst{15-12} = Rt;
936    let Inst{11-0}  = shift{11-0};
937  }
938}
939}
940
941multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
942           InstrItinClass iir, PatFrag opnode> {
943  // Note: We use the complex addrmode_imm12 rather than just an input
944  // GPR and a constrained immediate so that we can use this to match
945  // frame index references and avoid matching constant pool references.
946  def i12 : AI2ldst<0b010, 0, isByte, (outs),
947                   (ins GPR:$Rt, addrmode_imm12:$addr),
948                   AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
949                  [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
950    bits<4> Rt;
951    bits<17> addr;
952    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
953    let Inst{19-16} = addr{16-13};  // Rn
954    let Inst{15-12} = Rt;
955    let Inst{11-0}  = addr{11-0};   // imm12
956  }
957  def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
958                  AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
959                 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
960    bits<4> Rt;
961    bits<17> shift;
962    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
963    let Inst{19-16} = shift{16-13}; // Rn
964    let Inst{15-12} = Rt;
965    let Inst{11-0}  = shift{11-0};
966  }
967}
968//===----------------------------------------------------------------------===//
969// Instructions
970//===----------------------------------------------------------------------===//
971
972//===----------------------------------------------------------------------===//
973//  Miscellaneous Instructions.
974//
975
976/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
977/// the function.  The first operand is the ID# for this instruction, the second
978/// is the index into the MachineConstantPool that this is, the third is the
979/// size in bytes of this constant pool entry.
980let neverHasSideEffects = 1, isNotDuplicable = 1 in
981def CONSTPOOL_ENTRY :
982PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
983                    i32imm:$size), NoItinerary, []>;
984
985// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
986// from removing one half of the matched pairs. That breaks PEI, which assumes
987// these will always be in pairs, and asserts if it finds otherwise. Better way?
988let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
989def ADJCALLSTACKUP :
990PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
991           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
992
993def ADJCALLSTACKDOWN :
994PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
995           [(ARMcallseq_start timm:$amt)]>;
996}
997
998def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
999             [/* For disassembly only; pattern left blank */]>,
1000          Requires<[IsARM, HasV6T2]> {
1001  let Inst{27-16} = 0b001100100000;
1002  let Inst{15-8} = 0b11110000;
1003  let Inst{7-0} = 0b00000000;
1004}
1005
1006def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1007             [/* For disassembly only; pattern left blank */]>,
1008          Requires<[IsARM, HasV6T2]> {
1009  let Inst{27-16} = 0b001100100000;
1010  let Inst{15-8} = 0b11110000;
1011  let Inst{7-0} = 0b00000001;
1012}
1013
1014def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1015             [/* For disassembly only; pattern left blank */]>,
1016          Requires<[IsARM, HasV6T2]> {
1017  let Inst{27-16} = 0b001100100000;
1018  let Inst{15-8} = 0b11110000;
1019  let Inst{7-0} = 0b00000010;
1020}
1021
1022def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1023             [/* For disassembly only; pattern left blank */]>,
1024          Requires<[IsARM, HasV6T2]> {
1025  let Inst{27-16} = 0b001100100000;
1026  let Inst{15-8} = 0b11110000;
1027  let Inst{7-0} = 0b00000011;
1028}
1029
1030def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1031             "\t$dst, $a, $b",
1032             [/* For disassembly only; pattern left blank */]>,
1033          Requires<[IsARM, HasV6]> {
1034  bits<4> Rd;
1035  bits<4> Rn;
1036  bits<4> Rm;
1037  let Inst{3-0} = Rm;
1038  let Inst{15-12} = Rd;
1039  let Inst{19-16} = Rn;
1040  let Inst{27-20} = 0b01101000;
1041  let Inst{7-4} = 0b1011;
1042  let Inst{11-8} = 0b1111;
1043}
1044
1045def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1046             [/* For disassembly only; pattern left blank */]>,
1047          Requires<[IsARM, HasV6T2]> {
1048  let Inst{27-16} = 0b001100100000;
1049  let Inst{15-8} = 0b11110000;
1050  let Inst{7-0} = 0b00000100;
1051}
1052
1053// The i32imm operand $val can be used by a debugger to store more information
1054// about the breakpoint.
1055def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1056              [/* For disassembly only; pattern left blank */]>,
1057           Requires<[IsARM]> {
1058  bits<16> val;
1059  let Inst{3-0} = val{3-0};
1060  let Inst{19-8} = val{15-4};
1061  let Inst{27-20} = 0b00010010;
1062  let Inst{7-4} = 0b0111;
1063}
1064
1065// Change Processor State is a system instruction -- for disassembly only.
1066// The singleton $opt operand contains the following information:
1067// opt{4-0} = mode from Inst{4-0}
1068// opt{5} = changemode from Inst{17}
1069// opt{8-6} = AIF from Inst{8-6}
1070// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1071// FIXME: Integrated assembler will need these split out.
1072def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1073              [/* For disassembly only; pattern left blank */]>,
1074          Requires<[IsARM]> {
1075  let Inst{31-28} = 0b1111;
1076  let Inst{27-20} = 0b00010000;
1077  let Inst{16} = 0;
1078  let Inst{5} = 0;
1079}
1080
1081// Preload signals the memory system of possible future data/instruction access.
1082// These are for disassembly only.
1083multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1084
1085  def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1086                !strconcat(opc, "\t$addr"),
1087                [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1088    bits<4> Rt;
1089    bits<17> addr;
1090    let Inst{31-26} = 0b111101;
1091    let Inst{25} = 0; // 0 for immediate form
1092    let Inst{24} = data;
1093    let Inst{23} = addr{12};        // U (add = ('U' == 1))
1094    let Inst{22} = read;
1095    let Inst{21-20} = 0b01;
1096    let Inst{19-16} = addr{16-13};  // Rn
1097    let Inst{15-12} = Rt;
1098    let Inst{11-0}  = addr{11-0};   // imm12
1099  }
1100
1101  def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1102               !strconcat(opc, "\t$shift"),
1103               [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1104    bits<4> Rt;
1105    bits<17> shift;
1106    let Inst{31-26} = 0b111101;
1107    let Inst{25} = 1; // 1 for register form
1108    let Inst{24} = data;
1109    let Inst{23} = shift{12};    // U (add = ('U' == 1))
1110    let Inst{22} = read;
1111    let Inst{21-20} = 0b01;
1112    let Inst{19-16} = shift{16-13}; // Rn
1113    let Inst{11-0}  = shift{11-0};
1114  }
1115}
1116
1117defm PLD  : APreLoad<1, 1, "pld">,  Requires<[IsARM]>;
1118defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1119defm PLI  : APreLoad<1, 0, "pli">,  Requires<[IsARM,HasV7]>;
1120
1121def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1122                 "setend\t$end",
1123                 [/* For disassembly only; pattern left blank */]>,
1124               Requires<[IsARM]> {
1125  bits<1> end;
1126  let Inst{31-10} = 0b1111000100000001000000;
1127  let Inst{9} = end;
1128  let Inst{8-0} = 0;
1129}
1130
1131def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1132             [/* For disassembly only; pattern left blank */]>,
1133          Requires<[IsARM, HasV7]> {
1134  bits<4> opt;
1135  let Inst{27-4} = 0b001100100000111100001111;
1136  let Inst{3-0} = opt;
1137}
1138
1139// A5.4 Permanently UNDEFINED instructions.
1140let isBarrier = 1, isTerminator = 1 in
1141def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1142               "trap", [(trap)]>,
1143           Requires<[IsARM]> {
1144  let Inst = 0xe7ffdefe;
1145}
1146
1147// Address computation and loads and stores in PIC mode.
1148let isNotDuplicable = 1 in {
1149def PICADD  : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1150                            Size4Bytes, IIC_iALUr,
1151                            [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1152
1153let AddedComplexity = 10 in {
1154def PICLDR  : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1155                            Size4Bytes, IIC_iLoad_r,
1156                            [(set GPR:$dst, (load addrmodepc:$addr))]>;
1157
1158def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1159                            Size4Bytes, IIC_iLoad_bh_r,
1160                            [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1161
1162def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1163                            Size4Bytes, IIC_iLoad_bh_r,
1164                            [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1165
1166def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1167                            Size4Bytes, IIC_iLoad_bh_r,
1168                            [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1169
1170def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1171                            Size4Bytes, IIC_iLoad_bh_r,
1172                            [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1173}
1174let AddedComplexity = 10 in {
1175def PICSTR  : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1176      Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1177
1178def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1179      Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1180                                                   addrmodepc:$addr)]>;
1181
1182def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1183      Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1184}
1185} // isNotDuplicable = 1
1186
1187
1188// LEApcrel - Load a pc-relative address into a register without offending the
1189// assembler.
1190let neverHasSideEffects = 1, isReMaterializable = 1 in
1191// The 'adr' mnemonic encodes differently if the label is before or after
1192// the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1193// know until then which form of the instruction will be used.
1194def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1195                 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1196  bits<4> Rd;
1197  bits<12> label;
1198  let Inst{27-25} = 0b001;
1199  let Inst{20} = 0;
1200  let Inst{19-16} = 0b1111;
1201  let Inst{15-12} = Rd;
1202  let Inst{11-0} = label;
1203}
1204def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1205                    Size4Bytes, IIC_iALUi, []>;
1206
1207def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1208                      (ins i32imm:$label, nohash_imm:$id, pred:$p),
1209                      Size4Bytes, IIC_iALUi, []>;
1210
1211//===----------------------------------------------------------------------===//
1212//  Control Flow Instructions.
1213//
1214
1215let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1216  // ARMV4T and above
1217  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1218                  "bx", "\tlr", [(ARMretflag)]>,
1219               Requires<[IsARM, HasV4T]> {
1220    let Inst{27-0}  = 0b0001001011111111111100011110;
1221  }
1222
1223  // ARMV4 only
1224  def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1225                  "mov", "\tpc, lr", [(ARMretflag)]>,
1226               Requires<[IsARM, NoV4T]> {
1227    let Inst{27-0} = 0b0001101000001111000000001110;
1228  }
1229}
1230
1231// Indirect branches
1232let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1233  // ARMV4T and above
1234  def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1235                  [(brind GPR:$dst)]>,
1236              Requires<[IsARM, HasV4T]> {
1237    bits<4> dst;
1238    let Inst{31-4} = 0b1110000100101111111111110001;
1239    let Inst{3-0}  = dst;
1240  }
1241
1242  // ARMV4 only
1243  // FIXME: We would really like to define this as a vanilla ARMPat like:
1244  // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1245  // With that, however, we can't set isBranch, isTerminator, etc..
1246  def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1247                    Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1248                    Requires<[IsARM, NoV4T]>;
1249}
1250
1251// All calls clobber the non-callee saved registers. SP is marked as
1252// a use to prevent stack-pointer assignments that appear immediately
1253// before calls from potentially appearing dead.
1254let isCall = 1,
1255  // On non-Darwin platforms R9 is callee-saved.
1256  Defs = [R0,  R1,  R2,  R3,  R12, LR,
1257          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
1258          D16, D17, D18, D19, D20, D21, D22, D23,
1259          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1260  Uses = [SP] in {
1261  def BL  : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1262                IIC_Br, "bl\t$func",
1263                [(ARMcall tglobaladdr:$func)]>,
1264            Requires<[IsARM, IsNotDarwin]> {
1265    let Inst{31-28} = 0b1110;
1266    bits<24> func;
1267    let Inst{23-0} = func;
1268  }
1269
1270  def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1271                   IIC_Br, "bl", "\t$func",
1272                   [(ARMcall_pred tglobaladdr:$func)]>,
1273                Requires<[IsARM, IsNotDarwin]> {
1274    bits<24> func;
1275    let Inst{23-0} = func;
1276  }
1277
1278  // ARMv5T and above
1279  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1280                IIC_Br, "blx\t$func",
1281                [(ARMcall GPR:$func)]>,
1282            Requires<[IsARM, HasV5T, IsNotDarwin]> {
1283    bits<4> func;
1284    let Inst{31-4} = 0b1110000100101111111111110011;
1285    let Inst{3-0}   = func;
1286  }
1287
1288  // ARMv4T
1289  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1290  def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1291                   Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1292                   Requires<[IsARM, HasV4T, IsNotDarwin]>;
1293
1294  // ARMv4
1295  def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1296                   Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1297                   Requires<[IsARM, NoV4T, IsNotDarwin]>;
1298}
1299
1300let isCall = 1,
1301  // On Darwin R9 is call-clobbered.
1302  // R7 is marked as a use to prevent frame-pointer assignments from being
1303  // moved above / below calls.
1304  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
1305          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
1306          D16, D17, D18, D19, D20, D21, D22, D23,
1307          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1308  Uses = [R7, SP] in {
1309  def BLr9  : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1310                IIC_Br, "bl\t$func",
1311                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1312    let Inst{31-28} = 0b1110;
1313    bits<24> func;
1314    let Inst{23-0} = func;
1315  }
1316
1317  def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1318                   IIC_Br, "bl", "\t$func",
1319                   [(ARMcall_pred tglobaladdr:$func)]>,
1320                  Requires<[IsARM, IsDarwin]> {
1321    bits<24> func;
1322    let Inst{23-0} = func;
1323  }
1324
1325  // ARMv5T and above
1326  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1327                IIC_Br, "blx\t$func",
1328                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1329    bits<4> func;
1330    let Inst{31-4} = 0b1110000100101111111111110011;
1331    let Inst{3-0}   = func;
1332  }
1333
1334  // ARMv4T
1335  // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1336  def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1337                  Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1338                  Requires<[IsARM, HasV4T, IsDarwin]>;
1339
1340  // ARMv4
1341  def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1342                  Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1343                  Requires<[IsARM, NoV4T, IsDarwin]>;
1344}
1345
1346// Tail calls.
1347
1348// FIXME: These should probably be xformed into the non-TC versions of the
1349// instructions as part of MC lowering.
1350// FIXME: These seem to be used for both Thumb and ARM instruction selection.
1351// Thumb should have its own version since the instruction is actually
1352// different, even though the mnemonic is the same.
1353let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1354  // Darwin versions.
1355  let Defs = [R0, R1, R2, R3, R9, R12,
1356              D0, D1, D2, D3, D4, D5, D6, D7,
1357              D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1358              D27, D28, D29, D30, D31, PC],
1359      Uses = [SP] in {
1360    def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1361                       IIC_Br, []>, Requires<[IsDarwin]>;
1362
1363    def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1364                       IIC_Br, []>, Requires<[IsDarwin]>;
1365
1366    def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1367                   IIC_Br, "b\t$dst  @ TAILCALL",
1368                   []>, Requires<[IsARM, IsDarwin]>;
1369
1370    def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1371                   IIC_Br, "b.w\t$dst  @ TAILCALL",
1372                   []>, Requires<[IsThumb, IsDarwin]>;
1373
1374    def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1375                     BrMiscFrm, IIC_Br, "bx\t$dst  @ TAILCALL",
1376                   []>, Requires<[IsDarwin]> {
1377      bits<4> dst;
1378      let Inst{31-4} = 0b1110000100101111111111110001;
1379      let Inst{3-0}  = dst;
1380    }
1381  }
1382
1383  // Non-Darwin versions (the difference is R9).
1384  let Defs = [R0, R1, R2, R3, R12,
1385              D0, D1, D2, D3, D4, D5, D6, D7,
1386              D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1387              D27, D28, D29, D30, D31, PC],
1388      Uses = [SP] in {
1389    def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1390                       IIC_Br, []>, Requires<[IsNotDarwin]>;
1391
1392    def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1393                       IIC_Br, []>, Requires<[IsNotDarwin]>;
1394
1395    def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1396                   IIC_Br, "b\t$dst  @ TAILCALL",
1397                   []>, Requires<[IsARM, IsNotDarwin]>;
1398
1399    def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1400                   IIC_Br, "b.w\t$dst  @ TAILCALL",
1401                   []>, Requires<[IsThumb, IsNotDarwin]>;
1402
1403    def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1404                     BrMiscFrm, IIC_Br, "bx\t$dst  @ TAILCALL",
1405                   []>, Requires<[IsNotDarwin]> {
1406      bits<4> dst;
1407      let Inst{31-4} = 0b1110000100101111111111110001;
1408      let Inst{3-0}  = dst;
1409    }
1410  }
1411}
1412
1413let isBranch = 1, isTerminator = 1 in {
1414  // B is "predicable" since it can be xformed into a Bcc.
1415  let isBarrier = 1 in {
1416    let isPredicable = 1 in
1417    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1418                "b\t$target", [(br bb:$target)]> {
1419      bits<24> target;
1420      let Inst{31-28} = 0b1110;
1421      let Inst{23-0} = target;
1422    }
1423
1424    let isNotDuplicable = 1, isIndirectBranch = 1 in {
1425    def BR_JTr : ARMPseudoInst<(outs),
1426                      (ins GPR:$target, i32imm:$jt, i32imm:$id),
1427                      SizeSpecial, IIC_Br,
1428                      [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1429    // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1430    // into i12 and rs suffixed versions.
1431    def BR_JTm : ARMPseudoInst<(outs),
1432                     (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1433                     SizeSpecial, IIC_Br,
1434                     [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1435                       imm:$id)]>;
1436    def BR_JTadd : ARMPseudoInst<(outs),
1437                   (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1438                   SizeSpecial, IIC_Br,
1439                   [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1440                     imm:$id)]>;
1441    } // isNotDuplicable = 1, isIndirectBranch = 1
1442  } // isBarrier = 1
1443
1444  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1445  // a two-value operand where a dag node expects two operands. :(
1446  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1447               IIC_Br, "b", "\t$target",
1448               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1449    bits<24> target;
1450    let Inst{23-0} = target;
1451  }
1452}
1453
1454// Branch and Exchange Jazelle -- for disassembly only
1455def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1456              [/* For disassembly only; pattern left blank */]> {
1457  let Inst{23-20} = 0b0010;
1458  //let Inst{19-8} = 0xfff;
1459  let Inst{7-4} = 0b0010;
1460}
1461
1462// Secure Monitor Call is a system instruction -- for disassembly only
1463def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1464              [/* For disassembly only; pattern left blank */]> {
1465  bits<4> opt;
1466  let Inst{23-4} = 0b01100000000000000111;
1467  let Inst{3-0} = opt;
1468}
1469
1470// Supervisor Call (Software Interrupt) -- for disassembly only
1471let isCall = 1, Uses = [SP] in {
1472def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1473              [/* For disassembly only; pattern left blank */]> {
1474  bits<24> svc;
1475  let Inst{23-0} = svc;
1476}
1477}
1478
1479// Store Return State is a system instruction -- for disassembly only
1480let isCodeGenOnly = 1 in {  // FIXME: This should not use submode!
1481def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1482                NoItinerary, "srs${amode}\tsp!, $mode",
1483                [/* For disassembly only; pattern left blank */]> {
1484  let Inst{31-28} = 0b1111;
1485  let Inst{22-20} = 0b110; // W = 1
1486}
1487
1488def SRS  : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1489                NoItinerary, "srs${amode}\tsp, $mode",
1490                [/* For disassembly only; pattern left blank */]> {
1491  let Inst{31-28} = 0b1111;
1492  let Inst{22-20} = 0b100; // W = 0
1493}
1494
1495// Return From Exception is a system instruction -- for disassembly only
1496def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1497                NoItinerary, "rfe${amode}\t$base!",
1498                [/* For disassembly only; pattern left blank */]> {
1499  let Inst{31-28} = 0b1111;
1500  let Inst{22-20} = 0b011; // W = 1
1501}
1502
1503def RFE  : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1504                NoItinerary, "rfe${amode}\t$base",
1505                [/* For disassembly only; pattern left blank */]> {
1506  let Inst{31-28} = 0b1111;
1507  let Inst{22-20} = 0b001; // W = 0
1508}
1509} // isCodeGenOnly = 1
1510
1511//===----------------------------------------------------------------------===//
1512//  Load / store Instructions.
1513//
1514
1515// Load
1516
1517
1518defm LDR  : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1519                    UnOpFrag<(load node:$Src)>>;
1520defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1521                    UnOpFrag<(zextloadi8 node:$Src)>>;
1522defm STR  : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1523                   BinOpFrag<(store node:$LHS, node:$RHS)>>;
1524defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1525                   BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1526
1527// Special LDR for loads from non-pc-relative constpools.
1528let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1529    isReMaterializable = 1 in
1530def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1531                 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1532                 []> {
1533  bits<4> Rt;
1534  bits<17> addr;
1535  let Inst{23}    = addr{12};     // U (add = ('U' == 1))
1536  let Inst{19-16} = 0b1111;
1537  let Inst{15-12} = Rt;
1538  let Inst{11-0}  = addr{11-0};   // imm12
1539}
1540
1541// Loads with zero extension
1542def LDRH  : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1543                  IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1544                  [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1545
1546// Loads with sign extension
1547def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1548                   IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1549                   [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1550
1551def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1552                   IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1553                   [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1554
1555let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1556    isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1557// FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1558//        how to represent that such that tblgen is happy and we don't
1559//        mark this codegen only?
1560// Load doubleword
1561def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1562                 (ins addrmode3:$addr), LdMiscFrm,
1563                 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1564                 []>, Requires<[IsARM, HasV5TE]>;
1565}
1566
1567// Indexed loads
1568multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1569  def _PRE  : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1570                      (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1571                      opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1572    // {17-14}  Rn
1573    // {13}     1 == Rm, 0 == imm12
1574    // {12}     isAdd
1575    // {11-0}   imm12/Rm
1576    bits<18> addr;
1577    let Inst{25} = addr{13};
1578    let Inst{23} = addr{12};
1579    let Inst{19-16} = addr{17-14};
1580    let Inst{11-0} = addr{11-0};
1581  }
1582  def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1583                      (ins GPR:$Rn, am2offset:$offset),
1584                      IndexModePost, LdFrm, itin,
1585                      opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1586    // {13}     1 == Rm, 0 == imm12
1587    // {12}     isAdd
1588    // {11-0}   imm12/Rm
1589    bits<14> offset;
1590    bits<4> Rn;
1591    let Inst{25} = offset{13};
1592    let Inst{23} = offset{12};
1593    let Inst{19-16} = Rn;
1594    let Inst{11-0} = offset{11-0};
1595  }
1596}
1597
1598let mayLoad = 1, neverHasSideEffects = 1 in {
1599defm LDR  : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1600defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1601}
1602
1603multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1604  def _PRE  : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1605                        (ins addrmode3:$addr), IndexModePre,
1606                        LdMiscFrm, itin,
1607                        opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1608    bits<14> addr;
1609    let Inst{23}    = addr{8};      // U bit
1610    let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
1611    let Inst{19-16} = addr{12-9};   // Rn
1612    let Inst{11-8}  = addr{7-4};    // imm7_4/zero
1613    let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
1614  }
1615  def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1616                        (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1617                        LdMiscFrm, itin,
1618                        opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1619    bits<10> offset;
1620    bits<4> Rn;
1621    let Inst{23}    = offset{8};      // U bit
1622    let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
1623    let Inst{19-16} = Rn;
1624    let Inst{11-8}  = offset{7-4};    // imm7_4/zero
1625    let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
1626  }
1627}
1628
1629let mayLoad = 1, neverHasSideEffects = 1 in {
1630defm LDRH  : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1631defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1632defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1633let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1634defm LDRD :  AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1635} // mayLoad = 1, neverHasSideEffects = 1
1636
1637// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1638let mayLoad = 1, neverHasSideEffects = 1 in {
1639def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1640                   (ins GPR:$base, am2offset:$offset), IndexModeNone,
1641                   LdFrm, IIC_iLoad_ru,
1642                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1643  let Inst{21} = 1; // overwrite
1644}
1645def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1646                  (ins GPR:$base, am2offset:$offset), IndexModeNone,
1647                  LdFrm, IIC_iLoad_bh_ru,
1648                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1649  let Inst{21} = 1; // overwrite
1650}
1651def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1652                 (ins GPR:$base, am3offset:$offset), IndexModePost,
1653                 LdMiscFrm, IIC_iLoad_bh_ru,
1654                 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1655  let Inst{21} = 1; // overwrite
1656}
1657def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1658                 (ins GPR:$base, am3offset:$offset), IndexModePost,
1659                 LdMiscFrm, IIC_iLoad_bh_ru,
1660                 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1661  let Inst{21} = 1; // overwrite
1662}
1663def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1664                 (ins GPR:$base, am3offset:$offset), IndexModePost,
1665                 LdMiscFrm, IIC_iLoad_bh_ru,
1666                 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1667  let Inst{21} = 1; // overwrite
1668}
1669}
1670
1671// Store
1672
1673// Stores with truncate
1674def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1675               IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1676               [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1677
1678// Store doubleword
1679let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1680    isCodeGenOnly = 1 in  // $src2 doesn't exist in asm string
1681def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1682               StMiscFrm, IIC_iStore_d_r,
1683               "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1684
1685// Indexed stores
1686def STR_PRE  : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1687                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1688                     IndexModePre, StFrm, IIC_iStore_ru,
1689                     "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1690                     [(set GPR:$Rn_wb,
1691                      (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1692
1693def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1694                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1695                     IndexModePost, StFrm, IIC_iStore_ru,
1696                     "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1697                     [(set GPR:$Rn_wb,
1698                      (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1699
1700def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1701                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1702                     IndexModePre, StFrm, IIC_iStore_bh_ru,
1703                     "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1704                     [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1705                                        GPR:$Rn, am2offset:$offset))]>;
1706def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1707                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1708                     IndexModePost, StFrm, IIC_iStore_bh_ru,
1709                     "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1710                     [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1711                                        GPR:$Rn, am2offset:$offset))]>;
1712
1713def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1714                     (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1715                     IndexModePre, StMiscFrm, IIC_iStore_ru,
1716                     "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1717                     [(set GPR:$Rn_wb,
1718                      (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1719
1720def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1721                     (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1722                     IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1723                     "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1724                     [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1725                                        GPR:$Rn, am3offset:$offset))]>;
1726
1727// For disassembly only
1728def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1729                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1730                     StMiscFrm, IIC_iStore_d_ru,
1731                     "strd", "\t$src1, $src2, [$base, $offset]!",
1732                     "$base = $base_wb", []>;
1733
1734// For disassembly only
1735def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1736                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1737                     StMiscFrm, IIC_iStore_d_ru,
1738                     "strd", "\t$src1, $src2, [$base], $offset",
1739                     "$base = $base_wb", []>;
1740
1741// STRT, STRBT, and STRHT are for disassembly only.
1742
1743def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1744                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1745                    IndexModeNone, StFrm, IIC_iStore_ru,
1746                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1747                    [/* For disassembly only; pattern left blank */]> {
1748  let Inst{21} = 1; // overwrite
1749}
1750
1751def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1752                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1753                     IndexModeNone, StFrm, IIC_iStore_bh_ru,
1754                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1755                     [/* For disassembly only; pattern left blank */]> {
1756  let Inst{21} = 1; // overwrite
1757}
1758
1759def STRHT: AI3sthpo<(outs GPR:$base_wb),
1760                    (ins GPR:$src, GPR:$base,am3offset:$offset),
1761                    StMiscFrm, IIC_iStore_bh_ru,
1762                    "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1763                    [/* For disassembly only; pattern left blank */]> {
1764  let Inst{21} = 1; // overwrite
1765}
1766
1767//===----------------------------------------------------------------------===//
1768//  Load / store multiple Instructions.
1769//
1770
1771multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1772                         InstrItinClass itin, InstrItinClass itin_upd> {
1773  def IA :
1774    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1775         IndexModeNone, f, itin,
1776         !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1777    let Inst{24-23} = 0b01;       // Increment After
1778    let Inst{21}    = 0;          // No writeback
1779    let Inst{20}    = L_bit;
1780  }
1781  def IA_UPD :
1782    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1783         IndexModeUpd, f, itin_upd,
1784         !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1785    let Inst{24-23} = 0b01;       // Increment After
1786    let Inst{21}    = 1;          // Writeback
1787    let Inst{20}    = L_bit;
1788  }
1789  def DA :
1790    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1791         IndexModeNone, f, itin,
1792         !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1793    let Inst{24-23} = 0b00;       // Decrement After
1794    let Inst{21}    = 0;          // No writeback
1795    let Inst{20}    = L_bit;
1796  }
1797  def DA_UPD :
1798    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1799         IndexModeUpd, f, itin_upd,
1800         !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1801    let Inst{24-23} = 0b00;       // Decrement After
1802    let Inst{21}    = 1;          // Writeback
1803    let Inst{20}    = L_bit;
1804  }
1805  def DB :
1806    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1807         IndexModeNone, f, itin,
1808         !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1809    let Inst{24-23} = 0b10;       // Decrement Before
1810    let Inst{21}    = 0;          // No writeback
1811    let Inst{20}    = L_bit;
1812  }
1813  def DB_UPD :
1814    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1815         IndexModeUpd, f, itin_upd,
1816         !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1817    let Inst{24-23} = 0b10;       // Decrement Before
1818    let Inst{21}    = 1;          // Writeback
1819    let Inst{20}    = L_bit;
1820  }
1821  def IB :
1822    AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1823         IndexModeNone, f, itin,
1824         !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1825    let Inst{24-23} = 0b11;       // Increment Before
1826    let Inst{21}    = 0;          // No writeback
1827    let Inst{20}    = L_bit;
1828  }
1829  def IB_UPD :
1830    AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1831         IndexModeUpd, f, itin_upd,
1832         !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1833    let Inst{24-23} = 0b11;       // Increment Before
1834    let Inst{21}    = 1;          // Writeback
1835    let Inst{20}    = L_bit;
1836  }
1837} 
1838
1839let neverHasSideEffects = 1 in {
1840
1841let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1842defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1843
1844let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1845defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1846
1847} // neverHasSideEffects
1848
1849// Load / Store Multiple Mnemonic Aliases
1850def : MnemonicAlias<"ldm", "ldmia">;
1851def : MnemonicAlias<"stm", "stmia">;
1852
1853// FIXME: remove when we have a way to marking a MI with these properties.
1854// FIXME: Should pc be an implicit operand like PICADD, etc?
1855let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1856    hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1857// FIXME: Should be a pseudo-instruction.
1858def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1859                                      reglist:$regs, variable_ops),
1860                     IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1861                     "ldmia${p}\t$Rn!, $regs",
1862                     "$Rn = $wb", []> {
1863  let Inst{24-23} = 0b01;       // Increment After
1864  let Inst{21}    = 1;          // Writeback
1865  let Inst{20}    = 1;          // Load
1866}
1867
1868//===----------------------------------------------------------------------===//
1869//  Move Instructions.
1870//
1871
1872let neverHasSideEffects = 1 in
1873def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1874                "mov", "\t$Rd, $Rm", []>, UnaryDP {
1875  bits<4> Rd;
1876  bits<4> Rm;
1877
1878  let Inst{11-4} = 0b00000000;
1879  let Inst{25} = 0;
1880  let Inst{3-0} = Rm;
1881  let Inst{15-12} = Rd;
1882}
1883
1884// A version for the smaller set of tail call registers.
1885let neverHasSideEffects = 1 in
1886def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1887                IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1888  bits<4> Rd;
1889  bits<4> Rm;
1890
1891  let Inst{11-4} = 0b00000000;
1892  let Inst{25} = 0;
1893  let Inst{3-0} = Rm;
1894  let Inst{15-12} = Rd;
1895}
1896
1897def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1898                DPSoRegFrm, IIC_iMOVsr,
1899                "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1900                UnaryDP {
1901  bits<4> Rd;
1902  bits<12> src;
1903  let Inst{15-12} = Rd;
1904  let Inst{11-0} = src;
1905  let Inst{25} = 0;
1906}
1907
1908let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1909def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1910                "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1911  bits<4> Rd;
1912  bits<12> imm;
1913  let Inst{25} = 1;
1914  let Inst{15-12} = Rd;
1915  let Inst{19-16} = 0b0000;
1916  let Inst{11-0} = imm;
1917}
1918
1919let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1920def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1921                 DPFrm, IIC_iMOVi,
1922                 "movw", "\t$Rd, $imm",
1923                 [(set GPR:$Rd, imm0_65535:$imm)]>,
1924                 Requires<[IsARM, HasV6T2]>, UnaryDP {
1925  bits<4> Rd;
1926  bits<16> imm;
1927  let Inst{15-12} = Rd;
1928  let Inst{11-0}  = imm{11-0};
1929  let Inst{19-16} = imm{15-12};
1930  let Inst{20} = 0;
1931  let Inst{25} = 1;
1932}
1933
1934def MOVi16_pic_ga : PseudoInst<(outs GPR:$Rd),
1935                               (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1936
1937let Constraints = "$src = $Rd" in {
1938def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1939                  DPFrm, IIC_iMOVi,
1940                  "movt", "\t$Rd, $imm",
1941                  [(set GPR:$Rd,
1942                        (or (and GPR:$src, 0xffff),
1943                            lo16AllZero:$imm))]>, UnaryDP,
1944                  Requires<[IsARM, HasV6T2]> {
1945  bits<4> Rd;
1946  bits<16> imm;
1947  let Inst{15-12} = Rd;
1948  let Inst{11-0}  = imm{11-0};
1949  let Inst{19-16} = imm{15-12};
1950  let Inst{20} = 0;
1951  let Inst{25} = 1;
1952}
1953
1954def MOVTi16_pic_ga : PseudoInst<(outs GPR:$Rd),
1955                     (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1956
1957} // Constraints
1958
1959def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1960      Requires<[IsARM, HasV6T2]>;
1961
1962let Uses = [CPSR] in
1963def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
1964                    [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1965                    Requires<[IsARM]>;
1966
1967// These aren't really mov instructions, but we have to define them this way
1968// due to flag operands.
1969
1970let Defs = [CPSR] in {
1971def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1972                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1973                      Requires<[IsARM]>;
1974def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1975                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1976                      Requires<[IsARM]>;
1977}
1978
1979//===----------------------------------------------------------------------===//
1980//  Extend Instructions.
1981//
1982
1983// Sign extenders
1984
1985defm SXTB  : AI_ext_rrot<0b01101010,
1986                         "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1987defm SXTH  : AI_ext_rrot<0b01101011,
1988                         "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1989
1990defm SXTAB : AI_exta_rrot<0b01101010,
1991               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1992defm SXTAH : AI_exta_rrot<0b01101011,
1993               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1994
1995// For disassembly only
1996defm SXTB16  : AI_ext_rrot_np<0b01101000, "sxtb16">;
1997
1998// For disassembly only
1999defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2000
2001// Zero extenders
2002
2003let AddedComplexity = 16 in {
2004defm UXTB   : AI_ext_rrot<0b01101110,
2005                          "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2006defm UXTH   : AI_ext_rrot<0b01101111,
2007                          "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2008defm UXTB16 : AI_ext_rrot<0b01101100,
2009                          "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2010
2011// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2012//        The transformation should probably be done as a combiner action
2013//        instead so we can include a check for masking back in the upper
2014//        eight bits of the source into the lower eight bits of the result.
2015//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2016//               (UXTB16r_rot GPR:$Src, 24)>;
2017def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2018               (UXTB16r_rot GPR:$Src, 8)>;
2019
2020defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2021                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2022defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2023                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2024}
2025
2026// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2027// For disassembly only
2028defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2029
2030
2031def SBFX  : I<(outs GPR:$Rd),
2032              (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2033               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2034               "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2035               Requires<[IsARM, HasV6T2]> {
2036  bits<4> Rd;
2037  bits<4> Rn;
2038  bits<5> lsb;
2039  bits<5> width;
2040  let Inst{27-21} = 0b0111101;
2041  let Inst{6-4}   = 0b101;
2042  let Inst{20-16} = width;
2043  let Inst{15-12} = Rd;
2044  let Inst{11-7}  = lsb;
2045  let Inst{3-0}   = Rn;
2046}
2047
2048def UBFX  : I<(outs GPR:$Rd),
2049              (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2050               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2051               "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2052               Requires<[IsARM, HasV6T2]> {
2053  bits<4> Rd;
2054  bits<4> Rn;
2055  bits<5> lsb;
2056  bits<5> width;
2057  let Inst{27-21} = 0b0111111;
2058  let Inst{6-4}   = 0b101;
2059  let Inst{20-16} = width;
2060  let Inst{15-12} = Rd;
2061  let Inst{11-7}  = lsb;
2062  let Inst{3-0}   = Rn;
2063}
2064
2065//===----------------------------------------------------------------------===//
2066//  Arithmetic Instructions.
2067//
2068
2069defm ADD  : AsI1_bin_irs<0b0100, "add",
2070                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2071                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
2072defm SUB  : AsI1_bin_irs<0b0010, "sub",
2073                         IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2074                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
2075
2076// ADD and SUB with 's' bit set.
2077defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2078                          IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2079                          BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2080defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2081                          IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2082                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2083
2084defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2085                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2086defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2087                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2088
2089// ADC and SUBC with 's' bit set.
2090defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2091                          BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2092defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2093                          BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2094
2095def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2096                 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2097                 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2098  bits<4> Rd;
2099  bits<4> Rn;
2100  bits<12> imm;
2101  let Inst{25} = 1;
2102  let Inst{15-12} = Rd;
2103  let Inst{19-16} = Rn;
2104  let Inst{11-0} = imm;
2105}
2106
2107// The reg/reg form is only defined for the disassembler; for codegen it is
2108// equivalent to SUBrr.
2109def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2110                 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2111                 [/* For disassembly only; pattern left blank */]> {
2112  bits<4> Rd;
2113  bits<4> Rn;
2114  bits<4> Rm;
2115  let Inst{11-4} = 0b00000000;
2116  let Inst{25} = 0;
2117  let Inst{3-0} = Rm;
2118  let Inst{15-12} = Rd;
2119  let Inst{19-16} = Rn;
2120}
2121
2122def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2123                 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2124                 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2125  bits<4> Rd;
2126  bits<4> Rn;
2127  bits<12> shift;
2128  let Inst{25} = 0;
2129  let Inst{11-0} = shift;
2130  let Inst{15-12} = Rd;
2131  let Inst{19-16} = Rn;
2132}
2133
2134// RSB with 's' bit set.
2135let isCodeGenOnly = 1, Defs = [CPSR] in {
2136def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2137                 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2138                 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2139  bits<4> Rd;
2140  bits<4> Rn;
2141  bits<12> imm;
2142  let Inst{25} = 1;
2143  let Inst{20} = 1;
2144  let Inst{15-12} = Rd;
2145  let Inst{19-16} = Rn;
2146  let Inst{11-0} = imm;
2147}
2148def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2149                 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2150                 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2151  bits<4> Rd;
2152  bits<4> Rn;
2153  bits<12> shift;
2154  let Inst{25} = 0;
2155  let Inst{20} = 1;
2156  let Inst{11-0} = shift;
2157  let Inst{15-12} = Rd;
2158  let Inst{19-16} = Rn;
2159}
2160}
2161
2162let Uses = [CPSR] in {
2163def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2164                 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2165                 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2166                 Requires<[IsARM]> {
2167  bits<4> Rd;
2168  bits<4> Rn;
2169  bits<12> imm;
2170  let Inst{25} = 1;
2171  let Inst{15-12} = Rd;
2172  let Inst{19-16} = Rn;
2173  let Inst{11-0} = imm;
2174}
2175// The reg/reg form is only defined for the disassembler; for codegen it is
2176// equivalent to SUBrr.
2177def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2178                 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2179                 [/* For disassembly only; pattern left blank */]> {
2180  bits<4> Rd;
2181  bits<4> Rn;
2182  bits<4> Rm;
2183  let Inst{11-4} = 0b00000000;
2184  let Inst{25} = 0;
2185  let Inst{3-0} = Rm;
2186  let Inst{15-12} = Rd;
2187  let Inst{19-16} = Rn;
2188}
2189def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2190                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2191                 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2192                 Requires<[IsARM]> {
2193  bits<4> Rd;
2194  bits<4> Rn;
2195  bits<12> shift;
2196  let Inst{25} = 0;
2197  let Inst{11-0} = shift;
2198  let Inst{15-12} = Rd;
2199  let Inst{19-16} = Rn;
2200}
2201}
2202
2203// FIXME: Allow these to be predicated.
2204let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2205def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2206                  DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2207                  [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2208                  Requires<[IsARM]> {
2209  bits<4> Rd;
2210  bits<4> Rn;
2211  bits<12> imm;
2212  let Inst{25} = 1;
2213  let Inst{20} = 1;
2214  let Inst{15-12} = Rd;
2215  let Inst{19-16} = Rn;
2216  let Inst{11-0} = imm;
2217}
2218def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2219                  DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2220                  [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2221                  Requires<[IsARM]> {
2222  bits<4> Rd;
2223  bits<4> Rn;
2224  bits<12> shift;
2225  let Inst{25} = 0;
2226  let Inst{20} = 1;
2227  let Inst{11-0} = shift;
2228  let Inst{15-12} = Rd;
2229  let Inst{19-16} = Rn;
2230}
2231}
2232
2233// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
2234// The assume-no-carry-in form uses the negation of the input since add/sub
2235// assume opposite meanings of the carry flag (i.e., carry == !borrow).
2236// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2237// details.
2238def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
2239             (SUBri  GPR:$src, so_imm_neg:$imm)>;
2240def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
2241             (SUBSri GPR:$src, so_imm_neg:$imm)>;
2242// The with-carry-in form matches bitwise not instead of the negation.
2243// Effectively, the inverse interpretation of the carry flag already accounts
2244// for part of the negation.
2245def : ARMPat<(adde   GPR:$src, so_imm_not:$imm),
2246             (SBCri  GPR:$src, so_imm_not:$imm)>;
2247
2248// Note: These are implemented in C++ code, because they have to generate
2249// ADD/SUBrs instructions, which use a complex pattern that a xform function
2250// cannot produce.
2251// (mul X, 2^n+1) -> (add (X << n), X)
2252// (mul X, 2^n-1) -> (rsb X, (X << n))
2253
2254// ARM Arithmetic Instruction -- for disassembly only
2255// GPR:$dst = GPR:$a op GPR:$b
2256class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2257          list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2258  : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2259       opc, "\t$Rd, $Rn, $Rm", pattern> {
2260  bits<4> Rd;
2261  bits<4> Rn;
2262  bits<4> Rm;
2263  let Inst{27-20} = op27_20;
2264  let Inst{11-4} = op11_4;
2265  let Inst{19-16} = Rn;
2266  let Inst{15-12} = Rd;
2267  let Inst{3-0}   = Rm;
2268}
2269
2270// Saturating add/subtract -- for disassembly only
2271
2272def QADD    : AAI<0b00010000, 0b00000101, "qadd",
2273                  [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2274def QSUB    : AAI<0b00010010, 0b00000101, "qsub",
2275                  [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2276def QDADD   : AAI<0b00010100, 0b00000101, "qdadd">;
2277def QDSUB   : AAI<0b00010110, 0b00000101, "qdsub">;
2278
2279def QADD16  : AAI<0b01100010, 0b11110001, "qadd16">;
2280def QADD8   : AAI<0b01100010, 0b11111001, "qadd8">;
2281def QASX    : AAI<0b01100010, 0b11110011, "qasx">;
2282def QSAX    : AAI<0b01100010, 0b11110101, "qsax">;
2283def QSUB16  : AAI<0b01100010, 0b11110111, "qsub16">;
2284def QSUB8   : AAI<0b01100010, 0b11111111, "qsub8">;
2285def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2286def UQADD8  : AAI<0b01100110, 0b11111001, "uqadd8">;
2287def UQASX   : AAI<0b01100110, 0b11110011, "uqasx">;
2288def UQSAX   : AAI<0b01100110, 0b11110101, "uqsax">;
2289def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2290def UQSUB8  : AAI<0b01100110, 0b11111111, "uqsub8">;
2291
2292// Signed/Unsigned add/subtract -- for disassembly only
2293
2294def SASX   : AAI<0b01100001, 0b11110011, "sasx">;
2295def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2296def SADD8  : AAI<0b01100001, 0b11111001, "sadd8">;
2297def SSAX   : AAI<0b01100001, 0b11110101, "ssax">;
2298def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2299def SSUB8  : AAI<0b01100001, 0b11111111, "ssub8">;
2300def UASX   : AAI<0b01100101, 0b11110011, "uasx">;
2301def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2302def UADD8  : AAI<0b01100101, 0b11111001, "uadd8">;
2303def USAX   : AAI<0b01100101, 0b11110101, "usax">;
2304def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2305def USUB8  : AAI<0b01100101, 0b11111111, "usub8">;
2306
2307// Signed/Unsigned halving add/subtract -- for disassembly only
2308
2309def SHASX   : AAI<0b01100011, 0b11110011, "shasx">;
2310def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2311def SHADD8  : AAI<0b01100011, 0b11111001, "shadd8">;
2312def SHSAX   : AAI<0b01100011, 0b11110101, "shsax">;
2313def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2314def SHSUB8  : AAI<0b01100011, 0b11111111, "shsub8">;
2315def UHASX   : AAI<0b01100111, 0b11110011, "uhasx">;
2316def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2317def UHADD8  : AAI<0b01100111, 0b11111001, "uhadd8">;
2318def UHSAX   : AAI<0b01100111, 0b11110101, "uhsax">;
2319def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2320def UHSUB8  : AAI<0b01100111, 0b11111111, "uhsub8">;
2321
2322// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2323
2324def USAD8  : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2325                MulFrm /* for convenience */, NoItinerary, "usad8",
2326                "\t$Rd, $Rn, $Rm", []>,
2327             Requires<[IsARM, HasV6]> {
2328  bits<4> Rd;
2329  bits<4> Rn;
2330  bits<4> Rm;
2331  let Inst{27-20} = 0b01111000;
2332  let Inst{15-12} = 0b1111;
2333  let Inst{7-4} = 0b0001;
2334  let Inst{19-16} = Rd;
2335  let Inst{11-8} = Rm;
2336  let Inst{3-0} = Rn;
2337}
2338def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2339                MulFrm /* for convenience */, NoItinerary, "usada8",
2340                "\t$Rd, $Rn, $Rm, $Ra", []>,
2341             Requires<[IsARM, HasV6]> {
2342  bits<4> Rd;
2343  bits<4> Rn;
2344  bits<4> Rm;
2345  bits<4> Ra;
2346  let Inst{27-20} = 0b01111000;
2347  let Inst{7-4} = 0b0001;
2348  let Inst{19-16} = Rd;
2349  let Inst{15-12} = Ra;
2350  let Inst{11-8} = Rm;
2351  let Inst{3-0} = Rn;
2352}
2353
2354// Signed/Unsigned saturate -- for disassembly only
2355
2356def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2357              SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2358              [/* For disassembly only; pattern left blank */]> {
2359  bits<4> Rd;
2360  bits<5> sat_imm;
2361  bits<4> Rn;
2362  bits<8> sh;
2363  let Inst{27-21} = 0b0110101;
2364  let Inst{5-4} = 0b01;
2365  let Inst{20-16} = sat_imm;
2366  let Inst{15-12} = Rd;
2367  let Inst{11-7} = sh{7-3};
2368  let Inst{6} = sh{0};
2369  let Inst{3-0} = Rn;
2370}
2371
2372def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2373                NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2374                [/* For disassembly only; pattern left blank */]> {
2375  bits<4> Rd;
2376  bits<4> sat_imm;
2377  bits<4> Rn;
2378  let Inst{27-20} = 0b01101010;
2379  let Inst{11-4} = 0b11110011;
2380  let Inst{15-12} = Rd;
2381  let Inst{19-16} = sat_imm;
2382  let Inst{3-0} = Rn;
2383}
2384
2385def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2386              SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2387              [/* For disassembly only; pattern left blank */]> {
2388  bits<4> Rd;
2389  bits<5> sat_imm;
2390  bits<4> Rn;
2391  bits<8> sh;
2392  let Inst{27-21} = 0b0110111;
2393  let Inst{5-4} = 0b01;
2394  let Inst{15-12} = Rd;
2395  let Inst{11-7} = sh{7-3};
2396  let Inst{6} = sh{0};
2397  let Inst{20-16} = sat_imm;
2398  let Inst{3-0} = Rn;
2399}
2400
2401def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2402                NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2403                [/* For disassembly only; pattern left blank */]> {
2404  bits<4> Rd;
2405  bits<4> sat_imm;
2406  bits<4> Rn;
2407  let Inst{27-20} = 0b01101110;
2408  let Inst{11-4} = 0b11110011;
2409  let Inst{15-12} = Rd;
2410  let Inst{19-16} = sat_imm;
2411  let Inst{3-0} = Rn;
2412}
2413
2414def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2415def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2416
2417//===----------------------------------------------------------------------===//
2418//  Bitwise Instructions.
2419//
2420
2421defm AND   : AsI1_bin_irs<0b0000, "and",
2422                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2423                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2424defm ORR   : AsI1_bin_irs<0b1100, "orr",
2425                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2426                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
2427defm EOR   : AsI1_bin_irs<0b0001, "eor",
2428                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2429                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2430defm BIC   : AsI1_bin_irs<0b1110, "bic",
2431                          IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2432                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2433
2434def BFC    : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2435               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2436               "bfc", "\t$Rd, $imm", "$src = $Rd",
2437               [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2438               Requires<[IsARM, HasV6T2]> {
2439  bits<4> Rd;
2440  bits<10> imm;
2441  let Inst{27-21} = 0b0111110;
2442  let Inst{6-0}   = 0b0011111;
2443  let Inst{15-12} = Rd;
2444  let Inst{11-7}  = imm{4-0}; // lsb
2445  let Inst{20-16} = imm{9-5}; // width
2446}
2447
2448// A8.6.18  BFI - Bitfield insert (Encoding A1)
2449def BFI    : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2450               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2451               "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2452               [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2453                                bf_inv_mask_imm:$imm))]>,
2454               Requires<[IsARM, HasV6T2]> {
2455  bits<4> Rd;
2456  bits<4> Rn;
2457  bits<10> imm;
2458  let Inst{27-21} = 0b0111110;
2459  let Inst{6-4}   = 0b001; // Rn: Inst{3-0} != 15
2460  let Inst{15-12} = Rd;
2461  let Inst{11-7}  = imm{4-0}; // lsb
2462  let Inst{20-16} = imm{9-5}; // width
2463  let Inst{3-0}   = Rn;
2464}
2465
2466def  MVNr  : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2467                  "mvn", "\t$Rd, $Rm",
2468                  [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2469  bits<4> Rd;
2470  bits<4> Rm;
2471  let Inst{25} = 0;
2472  let Inst{19-16} = 0b0000;
2473  let Inst{11-4} = 0b00000000;
2474  let Inst{15-12} = Rd;
2475  let Inst{3-0} = Rm;
2476}
2477def  MVNs  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2478                  IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2479                  [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2480  bits<4> Rd;
2481  bits<12> shift;
2482  let Inst{25} = 0;
2483  let Inst{19-16} = 0b0000;
2484  let Inst{15-12} = Rd;
2485  let Inst{11-0} = shift;
2486}
2487let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2488def  MVNi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2489                  IIC_iMVNi, "mvn", "\t$Rd, $imm",
2490                  [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2491  bits<4> Rd;
2492  bits<12> imm;
2493  let Inst{25} = 1;
2494  let Inst{19-16} = 0b0000;
2495  let Inst{15-12} = Rd;
2496  let Inst{11-0} = imm;
2497}
2498
2499def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
2500             (BICri GPR:$src, so_imm_not:$imm)>;
2501
2502//===----------------------------------------------------------------------===//
2503//  Multiply Instructions.
2504//
2505class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2506             string opc, string asm, list<dag> pattern>
2507  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2508  bits<4> Rd;
2509  bits<4> Rm;
2510  bits<4> Rn;
2511  let Inst{19-16} = Rd;
2512  let Inst{11-8}  = Rm;
2513  let Inst{3-0}   = Rn;
2514}
2515class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2516             string opc, string asm, list<dag> pattern>
2517  : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2518  bits<4> RdLo;
2519  bits<4> RdHi;
2520  bits<4> Rm;
2521  bits<4> Rn;
2522  let Inst{19-16} = RdHi;
2523  let Inst{15-12} = RdLo;
2524  let Inst{11-8}  = Rm;
2525  let Inst{3-0}   = Rn;
2526}
2527
2528let isCommutable = 1 in {
2529let Constraints = "@earlyclobber $Rd" in
2530def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2531                                          pred:$p, cc_out:$s),
2532                          Size4Bytes, IIC_iMUL32,
2533                         [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2534                        Requires<[IsARM, NoV6]>;
2535
2536def MUL  : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2537                   IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2538                   [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2539                   Requires<[IsARM, HasV6]>;
2540}
2541
2542let Constraints = "@earlyclobber $Rd" in
2543def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2544                         (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2545                         Size4Bytes, IIC_iMAC32, 
2546                         [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 
2547                        Requires<[IsARM, NoV6]> {
2548  bits<4> Ra;
2549  let Inst{15-12} = Ra;
2550}
2551def MLA  : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2552                    IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2553                   [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2554                   Requires<[IsARM, HasV6]> {
2555  bits<4> Ra;
2556  let Inst{15-12} = Ra;
2557}
2558
2559def MLS  : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2560                   IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2561                   [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2562                   Requires<[IsARM, HasV6T2]> {
2563  bits<4> Rd;
2564  bits<4> Rm;
2565  bits<4> Rn;
2566  bits<4> Ra;
2567  let Inst{19-16} = Rd;
2568  let Inst{15-12} = Ra;
2569  let Inst{11-8}  = Rm;
2570  let Inst{3-0}   = Rn;
2571}
2572
2573// Extra precision multiplies with low / high results
2574
2575let neverHasSideEffects = 1 in {
2576let isCommutable = 1 in {
2577let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2578def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2579                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
2580                            Size4Bytes, IIC_iMUL64, []>,
2581                           Requires<[IsARM, NoV6]>;
2582
2583def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2584                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2585                            Size4Bytes, IIC_iMUL64, []>,
2586                           Requires<[IsARM, NoV6]>;
2587}
2588
2589def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2590                               (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2591                    "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2592                    Requires<[IsARM, HasV6]>;
2593
2594def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2595                               (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2596                    "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2597                    Requires<[IsARM, HasV6]>;
2598}
2599
2600// Multiply + accumulate
2601let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2602def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2603                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
2604                            Size4Bytes, IIC_iMAC64, []>,
2605                           Requires<[IsARM, NoV6]>;
2606def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2607                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
2608                            Size4Bytes, IIC_iMAC64, []>,
2609                           Requires<[IsARM, NoV6]>;
2610def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2611                            (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
2612                            Size4Bytes, IIC_iMAC64, []>,
2613                           Requires<[IsARM, NoV6]>;
2614
2615}
2616
2617def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2618                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2619                    "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2620                    Requires<[IsARM, HasV6]>;
2621def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2622                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2623                    "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2624                    Requires<[IsARM, HasV6]>;
2625
2626def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2627                               (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2628                    "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2629                    Requires<[IsARM, HasV6]> {
2630  bits<4> RdLo;
2631  bits<4> RdHi;
2632  bits<4> Rm;
2633  bits<4> Rn;
2634  let Inst{19-16} = RdLo;
2635  let Inst{15-12} = RdHi;
2636  let Inst{11-8}  = Rm;
2637  let Inst{3-0}   = Rn;
2638}
2639} // neverHasSideEffects
2640
2641// Most significant word multiply
2642def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2643               IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2644               [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2645            Requires<[IsARM, HasV6]> {
2646  let Inst{15-12} = 0b1111;
2647}
2648
2649def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2650               IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2651               [/* For disassembly only; pattern left blank */]>,
2652            Requires<[IsARM, HasV6]> {
2653  let Inst{15-12} = 0b1111;
2654}
2655
2656def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2657               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2658               IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2659               [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2660            Requires<[IsARM, HasV6]>;
2661
2662def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2663               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2664               IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2665               [/* For disassembly only; pattern left blank */]>,
2666            Requires<[IsARM, HasV6]>;
2667
2668def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2669               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2670               IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2671               [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2672            Requires<[IsARM, HasV6]>;
2673
2674def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2675               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2676               IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2677               [/* For disassembly only; pattern left blank */]>,
2678            Requires<[IsARM, HasV6]>;
2679
2680multiclass AI_smul<string opc, PatFrag opnode> {
2681  def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2682              IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2683              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2684                                      (sext_inreg GPR:$Rm, i16)))]>,
2685           Requires<[IsARM, HasV5TE]>;
2686
2687  def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2688              IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2689              [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2690                                      (sra GPR:$Rm, (i32 16))))]>,
2691           Requires<[IsARM, HasV5TE]>;
2692
2693  def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2694              IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2695              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2696                                      (sext_inreg GPR:$Rm, i16)))]>,
2697           Requires<[IsARM, HasV5TE]>;
2698
2699  def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2700              IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2701              [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2702                                      (sra GPR:$Rm, (i32 16))))]>,
2703            Requires<[IsARM, HasV5TE]>;
2704
2705  def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2706              IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2707              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2708                                    (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2709           Requires<[IsARM, HasV5TE]>;
2710
2711  def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2712              IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2713              [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2714                                    (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2715            Requires<[IsARM, HasV5TE]>;
2716}
2717
2718
2719multiclass AI_smla<string opc, PatFrag opnode> {
2720  def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2721              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2722              IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2723              [(set GPR:$Rd, (add GPR:$Ra,
2724                               (opnode (sext_inreg GPR:$Rn, i16),
2725                                       (sext_inreg GPR:$Rm, i16))))]>,
2726           Requires<[IsARM, HasV5TE]>;
2727
2728  def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2729              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2730              IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2731              [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2732                                                   (sra GPR:$Rm, (i32 16)))))]>,
2733           Requires<[IsARM, HasV5TE]>;
2734
2735  def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2736              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2737              IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2738              [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2739                                                (sext_inreg GPR:$Rm, i16))))]>,
2740           Requires<[IsARM, HasV5TE]>;
2741
2742  def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2743              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2744              IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2745             [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2746                                                   (sra GPR:$Rm, (i32 16)))))]>,
2747            Requires<[IsARM, HasV5TE]>;
2748
2749  def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2750              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2751              IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2752              [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2753                                      (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2754           Requires<[IsARM, HasV5TE]>;
2755
2756  def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2757              (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2758              IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2759              [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2760                                        (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2761            Requires<[IsARM, HasV5TE]>;
2762}
2763
2764defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2765defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2766
2767// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2768def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2769                      (ins GPR:$Rn, GPR:$Rm),
2770                      IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2771                      [/* For disassembly only; pattern left blank */]>,
2772              Requires<[IsARM, HasV5TE]>;
2773
2774def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2775                      (ins GPR:$Rn, GPR:$Rm),
2776                      IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2777                      [/* For disassembly only; pattern left blank */]>,
2778              Requires<[IsARM, HasV5TE]>;
2779
2780def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2781                      (ins GPR:$Rn, GPR:$Rm),
2782                      IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2783                      [/* For disassembly only; pattern left blank */]>,
2784              Requires<[IsARM, HasV5TE]>;
2785
2786def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2787                      (ins GPR:$Rn, GPR:$Rm),
2788                      IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2789                      [/* For disassembly only; pattern left blank */]>,
2790              Requires<[IsARM, HasV5TE]>;
2791
2792// Helper class for AI_smld -- for disassembly only
2793class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2794                    InstrItinClass itin, string opc, string asm>
2795  : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2796  bits<4> Rn;
2797  bits<4> Rm;
2798  let Inst{4}     = 1;
2799  let Inst{5}     = swap;
2800  let Inst{6}     = sub;
2801  let Inst{7}     = 0;
2802  let Inst{21-20} = 0b00;
2803  let Inst{22}    = long;
2804  let Inst{27-23} = 0b01110;
2805  let Inst{11-8}  = Rm;
2806  let Inst{3-0}   = Rn;
2807}
2808class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2809                InstrItinClass itin, string opc, string asm>
2810  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2811  bits<4> Rd;
2812  let Inst{15-12} = 0b1111;
2813  let Inst{19-16} = Rd;
2814}
2815class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2816                InstrItinClass itin, string opc, string asm>
2817  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2818  bits<4> Ra;
2819  let Inst{15-12} = Ra;
2820}
2821class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2822                  InstrItinClass itin, string opc, string asm>
2823  : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2824  bits<4> RdLo;
2825  bits<4> RdHi;
2826  let Inst{19-16} = RdHi;
2827  let Inst{15-12} = RdLo;
2828}
2829
2830multiclass AI_smld<bit sub, string opc> {
2831
2832  def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2833                  NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2834
2835  def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2836                  NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2837
2838  def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2839                  (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2840                  !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2841
2842  def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2843                  (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2844                  !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2845
2846}
2847
2848defm SMLA : AI_smld<0, "smla">;
2849defm SMLS : AI_smld<1, "smls">;
2850
2851multiclass AI_sdml<bit sub, string opc> {
2852
2853  def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2854                    NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2855  def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2856                    NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2857}
2858
2859defm SMUA : AI_sdml<0, "smua">;
2860defm SMUS : AI_sdml<1, "smus">;
2861
2862//===----------------------------------------------------------------------===//
2863//  Misc. Arithmetic Instructions.
2864//
2865
2866def CLZ  : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2867              IIC_iUNAr, "clz", "\t$Rd, $Rm",
2868              [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2869
2870def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2871              IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2872              [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2873           Requires<[IsARM, HasV6T2]>;
2874
2875def REV  : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2876              IIC_iUNAr, "rev", "\t$Rd, $Rm",
2877              [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2878
2879def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2880               IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2881               [(set GPR:$Rd,
2882                   (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2883                       (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2884                           (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2885                               (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2886               Requires<[IsARM, HasV6]>;
2887
2888def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2889               IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2890               [(set GPR:$Rd,
2891                  (sext_inreg
2892                    (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2893                        (shl GPR:$Rm, (i32 8))), i16))]>,
2894               Requires<[IsARM, HasV6]>;
2895
2896def lsl_shift_imm : SDNodeXForm<imm, [{
2897  unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2898  return CurDAG->getTargetConstant(Sh, MVT::i32);
2899}]>;
2900
2901def lsl_amt : PatLeaf<(i32 imm), [{
2902  return (N->getZExtValue() < 32);
2903}], lsl_shift_imm>;
2904
2905def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2906                              (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2907               IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2908               [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2909                                  (and (shl GPR:$Rm, lsl_amt:$sh),
2910                                       0xFFFF0000)))]>,
2911               Requires<[IsARM, HasV6]>;
2912
2913// Alternate cases for PKHBT where identities eliminate some nodes.
2914def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2915               (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2916def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2917               (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2918
2919def asr_shift_imm : SDNodeXForm<imm, [{
2920  unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2921  return CurDAG->getTargetConstant(Sh, MVT::i32);
2922}]>;
2923
2924def asr_amt : PatLeaf<(i32 imm), [{
2925  return (N->getZExtValue() <= 32);
2926}], asr_shift_imm>;
2927
2928// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2929// will match the pattern below.
2930def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2931                              (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2932               IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2933               [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2934                                  (and (sra GPR:$Rm, asr_amt:$sh),
2935                                       0xFFFF)))]>,
2936               Requires<[IsARM, HasV6]>;
2937
2938// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
2939// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2940def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2941               (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2942def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2943                   (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2944               (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2945
2946//===----------------------------------------------------------------------===//
2947//  Comparison Instructions...
2948//
2949
2950defm CMP  : AI1_cmp_irs<0b1010, "cmp",
2951                        IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2952                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2953
2954// ARMcmpZ can re-use the above instruction definitions.
2955def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
2956             (CMPri   GPR:$src, so_imm:$imm)>;
2957def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
2958             (CMPrr   GPR:$src, GPR:$rhs)>;
2959def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
2960             (CMPrs   GPR:$src, so_reg:$rhs)>;
2961
2962// FIXME: We have to be careful when using the CMN instruction and comparison
2963// with 0. One would expect these two pieces of code should give identical
2964// results:
2965//
2966//   rsbs r1, r1, 0
2967//   cmp  r0, r1
2968//   mov  r0, #0
2969//   it   ls
2970//   mov  r0, #1
2971//
2972// and:
2973//
2974//   cmn  r0, r1
2975//   mov  r0, #0
2976//   it   ls
2977//   mov  r0, #1
2978//
2979// However, the CMN gives the *opposite* result when r1 is 0. This is because
2980// the carry flag is set in the CMP case but not in the CMN case. In short, the
2981// CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2982// value of r0 and the carry bit (because the "carry bit" parameter to
2983// AddWithCarry is defined as 1 in this case, the carry flag will always be set
2984// when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2985// never a "carry" when this AddWithCarry is performed (because the "carry bit"
2986// parameter to AddWithCarry is defined as 0).
2987//
2988// When x is 0 and unsigned:
2989//
2990//    x = 0
2991//   ~x = 0xFFFF FFFF
2992//   ~x + 1 = 0x1 0000 0000
2993//   (-x = 0) != (0x1 0000 0000 = ~x + 1)
2994//
2995// Therefore, we should disable CMN when comparing against zero, until we can
2996// limit when the CMN instruction is used (when we know that the RHS is not 0 or
2997// when it's a comparison which doesn't look at the 'carry' flag).
2998//
2999// (See the ARM docs for the "AddWithCarry" pseudo-code.)
3000//
3001// This is related to <rdar://problem/7569620>.
3002//
3003//defm CMN  : AI1_cmp_irs<0b1011, "cmn",
3004//                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3005
3006// Note that TST/TEQ don't set all the same flags that CMP does!
3007defm TST  : AI1_cmp_irs<0b1000, "tst",
3008                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3009                      BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3010defm TEQ  : AI1_cmp_irs<0b1001, "teq",
3011                        IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3012                      BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3013
3014defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
3015                         IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3016                         BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3017
3018//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3019//             (CMNri  GPR:$src, so_imm_neg:$imm)>;
3020
3021def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3022             (CMNzri  GPR:$src, so_imm_neg:$imm)>;
3023
3024// Pseudo i64 compares for some floating point compares.
3025let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3026    Defs = [CPSR] in {
3027def BCCi64 : PseudoInst<(outs),
3028    (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3029     IIC_Br,
3030    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3031
3032def BCCZi64 : PseudoInst<(outs),
3033     (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3034    [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3035} // usesCustomInserter
3036
3037
3038// Conditional moves
3039// FIXME: should be able to write a pattern for ARMcmov, but can't use
3040// a two-value operand where a dag node expects two operands. :(
3041// FIXME: These should all be pseudo-instructions that get expanded to
3042//        the normal MOV instructions. That would fix the dependency on
3043//        special casing them in tblgen.
3044let neverHasSideEffects = 1 in {
3045def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3046                IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3047      [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3048                RegConstraint<"$false = $Rd">, UnaryDP {
3049  bits<4> Rd;
3050  bits<4> Rm;
3051  let Inst{25} = 0;
3052  let Inst{20} = 0;
3053  let Inst{15-12} = Rd;
3054  let Inst{11-4} = 0b00000000;
3055  let Inst{3-0} = Rm;
3056}
3057
3058def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3059                 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3060                "mov", "\t$Rd, $shift",
3061   [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3062                RegConstraint<"$false = $Rd">, UnaryDP {
3063  bits<4> Rd;
3064  bits<12> shift;
3065  let Inst{25} = 0;
3066  let Inst{20} = 0;
3067  let Inst{19-16} = 0;
3068  let Inst{15-12} = Rd;
3069  let Inst{11-0} = shift;
3070}
3071
3072let isMoveImm = 1 in
3073def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3074                 DPFrm, IIC_iMOVi,
3075                 "movw", "\t$Rd, $imm",
3076                 []>,
3077                 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3078                 UnaryDP {
3079  bits<4> Rd;
3080  bits<16> imm;
3081  let Inst{25} = 1;
3082  let Inst{20} = 0;
3083  let Inst{19-16} = imm{15-12};
3084  let Inst{15-12} = Rd;
3085  let Inst{11-0}  = imm{11-0};
3086}
3087
3088let isMoveImm = 1 in
3089def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3090                         (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3091                "mov", "\t$Rd, $imm",
3092   [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3093                RegConstraint<"$false = $Rd">, UnaryDP {
3094  bits<4> Rd;
3095  bits<12> imm;
3096  let Inst{25} = 1;
3097  let Inst{20} = 0;
3098  let Inst{19-16} = 0b0000;
3099  let Inst{15-12} = Rd;
3100  let Inst{11-0} = imm;
3101}
3102
3103// Two instruction predicate mov immediate.
3104let isMoveImm = 1 in
3105def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3106                             (ins GPR:$false, i32imm:$src, pred:$p),
3107                  IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3108
3109let isMoveImm = 1 in
3110def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3111                         (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3112                "mvn", "\t$Rd, $imm",
3113 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3114                RegConstraint<"$false = $Rd">, UnaryDP {
3115  bits<4> Rd;
3116  bits<12> imm;
3117  let Inst{25} = 1;
3118  let Inst{20} = 0;
3119  let Inst{19-16} = 0b0000;
3120  let Inst{15-12} = Rd;
3121  let Inst{11-0} = imm;
3122}
3123} // neverHasSideEffects
3124
3125//===----------------------------------------------------------------------===//
3126// Atomic operations intrinsics
3127//
3128
3129def memb_opt : Operand<i32> {
3130  let PrintMethod = "printMemBOption";
3131}
3132
3133// memory barriers protect the atomic sequences
3134let hasSideEffects = 1 in {
3135def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3136                "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3137                Requires<[IsARM, HasDB]> {
3138  bits<4> opt;
3139  let Inst{31-4} = 0xf57ff05;
3140  let Inst{3-0} = opt;
3141}
3142
3143def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3144                       "mcr", "\tp15, 0, $zero, c7, c10, 5",
3145                       [(ARMMemBarrierMCR GPR:$zero)]>,
3146                       Requires<[IsARM, HasV6]> {
3147  // FIXME: add encoding
3148}
3149}
3150
3151def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3152                "dsb", "\t$opt",
3153                [/* For disassembly only; pattern left blank */]>,
3154                Requires<[IsARM, HasDB]> {
3155  bits<4> opt;
3156  let Inst{31-4} = 0xf57ff04;
3157  let Inst{3-0} = opt;
3158}
3159
3160// ISB has only full system option -- for disassembly only
3161def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3162                Requires<[IsARM, HasDB]> {
3163  let Inst{31-4} = 0xf57ff06;
3164  let Inst{3-0} = 0b1111;
3165}
3166
3167let usesCustomInserter = 1 in {
3168  let Uses = [CPSR] in {
3169    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3170      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3171      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3172    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3173      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3174      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3175    def ATOMIC_LOAD_AND_I8 : PseudoInst<
3176      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3177      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3178    def ATOMIC_LOAD_OR_I8 : PseudoInst<
3179      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3180      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3181    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3182      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3183      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3184    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3185      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3186      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3187    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3188      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3189      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3190    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3191      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3192      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3193    def ATOMIC_LOAD_AND_I16 : PseudoInst<
3194      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3195      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3196    def ATOMIC_LOAD_OR_I16 : PseudoInst<
3197      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3198      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3199    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3200      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3201      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3202    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3203      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3204      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3205    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3206      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3207      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3208    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3209      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3210      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3211    def ATOMIC_LOAD_AND_I32 : PseudoInst<
3212      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3213      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3214    def ATOMIC_LOAD_OR_I32 : PseudoInst<
3215      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3216      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3217    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3218      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3219      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3220    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3221      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3222      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3223
3224    def ATOMIC_SWAP_I8 : PseudoInst<
3225      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3226      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3227    def ATOMIC_SWAP_I16 : PseudoInst<
3228      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3229      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3230    def ATOMIC_SWAP_I32 : PseudoInst<
3231      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3232      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3233
3234    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3235      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3236      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3237    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3238      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3239      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3240    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3241      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3242      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3243}
3244}
3245
3246let mayLoad = 1 in {
3247def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3248                    "ldrexb", "\t$Rt, [$Rn]",
3249                    []>;
3250def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3251                    "ldrexh", "\t$Rt, [$Rn]",
3252                    []>;
3253def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3254                    "ldrex", "\t$Rt, [$Rn]",
3255                    []>;
3256def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3257                    NoItinerary,
3258                    "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3259                    []>;
3260}
3261
3262let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3263def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3264                    NoItinerary,
3265                    "strexb", "\t$Rd, $src, [$Rn]",
3266                    []>;
3267def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3268                    NoItinerary,
3269                    "strexh", "\t$Rd, $Rt, [$Rn]",
3270                    []>;
3271def STREX  : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3272                    NoItinerary,
3273                    "strex", "\t$Rd, $Rt, [$Rn]",
3274                    []>;
3275def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3276                    (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3277                    NoItinerary,
3278                    "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3279                    []>;
3280}
3281
3282// Clear-Exclusive is for disassembly only.
3283def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3284                [/* For disassembly only; pattern left blank */]>,
3285            Requires<[IsARM, HasV7]>  {
3286  let Inst{31-0} = 0b11110101011111111111000000011111;
3287}
3288
3289// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3290let mayLoad = 1 in {
3291def SWP  : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3292             [/* For disassembly only; pattern left blank */]>;
3293def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3294             [/* For disassembly only; pattern left blank */]>;
3295}
3296
3297//===----------------------------------------------------------------------===//
3298// TLS Instructions
3299//
3300
3301// __aeabi_read_tp preserves the registers r1-r3.
3302// This is a pseudo inst so that we can get the encoding right, 
3303// complete with fixup for the aeabi_read_tp function.
3304let isCall = 1,
3305  Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3306  def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3307               [(set R0, ARMthread_pointer)]>;
3308}
3309
3310//===----------------------------------------------------------------------===//
3311// SJLJ Exception handling intrinsics
3312//   eh_sjlj_setjmp() is an instruction sequence to store the return
3313//   address and save #0 in R0 for the non-longjmp case.
3314//   Since by its nature we may be coming from some other function to get
3315//   here, and we're using the stack frame for the containing function to
3316//   save/restore registers, we can't keep anything live in regs across
3317//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3318//   when we get here from a longjmp(). We force everthing out of registers
3319//   except for our own input by listing the relevant registers in Defs. By
3320//   doing so, we also cause the prologue/epilogue code to actively preserve
3321//   all of the callee-saved resgisters, which is exactly what we want.
3322//   A constant value is passed in $val, and we use the location as a scratch.
3323//
3324// These are pseudo-instructions and are lowered to individual MC-insts, so
3325// no encoding information is necessary.
3326let Defs =
3327  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
3328    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
3329    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3330    D31 ], hasSideEffects = 1, isBarrier = 1 in {
3331  def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3332                               NoItinerary,
3333                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3334                           Requires<[IsARM, HasVFP2]>;
3335}
3336
3337let Defs =
3338  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR ],
3339  hasSideEffects = 1, isBarrier = 1 in {
3340  def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3341                                   NoItinerary,
3342                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3343                                Requires<[IsARM, NoVFP]>;
3344}
3345
3346// FIXME: Non-Darwin version(s)
3347let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3348    Defs = [ R7, LR, SP ] in {
3349def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3350                             NoItinerary,
3351                         [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3352                                Requires<[IsARM, IsDarwin]>;
3353}
3354
3355// eh.sjlj.dispatchsetup pseudo-instruction.
3356// This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3357// handled when the pseudo is expanded (which happens before any passes
3358// that need the instruction size).
3359let isBarrier = 1, hasSideEffects = 1 in
3360def Int_eh_sjlj_dispatchsetup :
3361 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3362            [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3363              Requires<[IsDarwin]>;
3364
3365//===----------------------------------------------------------------------===//
3366// Non-Instruction Patterns
3367//
3368
3369// Large immediate handling.
3370
3371// 32-bit immediate using two piece so_imms or movw + movt.
3372// This is a single pseudo instruction, the benefit is that it can be remat'd
3373// as a single unit instead of having to handle reg inputs.
3374// FIXME: Remove this when we can do generalized remat.
3375let isReMaterializable = 1, isMoveImm = 1 in {
3376def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3377                           [(set GPR:$dst, (arm_i32imm:$src))]>,
3378                           Requires<[IsARM]>;
3379
3380def MOV_pic_ga : PseudoInst<(outs GPR:$dst),
3381                            (ins i32imm:$addr, pclabel:$id), IIC_iMOVix2,
3382                 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>,
3383                 Requires<[IsARM, UseMovt]>;
3384} // isReMaterializable = 1, isMoveImm = 1 in
3385
3386// ConstantPool, GlobalAddress, and JumpTable
3387def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3388            Requires<[IsARM, DontUseMovt]>;
3389def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
3390def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3391            Requires<[IsARM, UseMovt]>;
3392def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3393             (LEApcrelJT tjumptable:$dst, imm:$id)>;
3394
3395// TODO: add,sub,and, 3-instr forms?
3396
3397// Tail calls
3398def : ARMPat<(ARMtcret tcGPR:$dst),
3399          (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3400
3401def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3402          (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3403
3404def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3405          (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3406
3407def : ARMPat<(ARMtcret tcGPR:$dst),
3408          (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3409
3410def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3411          (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3412
3413def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3414          (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3415
3416// Direct calls
3417def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3418      Requires<[IsARM, IsNotDarwin]>;
3419def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3420      Requires<[IsARM, IsDarwin]>;
3421
3422// zextload i1 -> zextload i8
3423def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3424def : ARMPat<(zextloadi1 ldst_so_reg:$addr),    (LDRBrs ldst_so_reg:$addr)>;
3425
3426// extload -> zextload
3427def : ARMPat<(extloadi1 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
3428def : ARMPat<(extloadi1 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
3429def : ARMPat<(extloadi8 addrmode_imm12:$addr),  (LDRBi12 addrmode_imm12:$addr)>;
3430def : ARMPat<(extloadi8 ldst_so_reg:$addr),     (LDRBrs ldst_so_reg:$addr)>;
3431
3432def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
3433
3434def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3435def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3436
3437// smul* and smla*
3438def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3439                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
3440                 (SMULBB GPR:$a, GPR:$b)>;
3441def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3442                 (SMULBB GPR:$a, GPR:$b)>;
3443def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3444                      (sra GPR:$b, (i32 16))),
3445                 (SMULBT GPR:$a, GPR:$b)>;
3446def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3447                 (SMULBT GPR:$a, GPR:$b)>;
3448def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3449                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
3450                 (SMULTB GPR:$a, GPR:$b)>;
3451def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3452                (SMULTB GPR:$a, GPR:$b)>;
3453def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3454                      (i32 16)),
3455                 (SMULWB GPR:$a, GPR:$b)>;
3456def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3457                 (SMULWB GPR:$a, GPR:$b)>;
3458
3459def : ARMV5TEPat<(add GPR:$acc,
3460                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3461                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3462                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3463def : ARMV5TEPat<(add GPR:$acc,
3464                      (mul sext_16_node:$a, sext_16_node:$b)),
3465                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3466def : ARMV5TEPat<(add GPR:$acc,
3467                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3468                           (sra GPR:$b, (i32 16)))),
3469                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3470def : ARMV5TEPat<(add GPR:$acc,
3471                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3472                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3473def : ARMV5TEPat<(add GPR:$acc,
3474                      (mul (sra GPR:$a, (i32 16)),
3475                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3476                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3477def : ARMV5TEPat<(add GPR:$acc,
3478                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3479                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3480def : ARMV5TEPat<(add GPR:$acc,
3481                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3482                           (i32 16))),
3483                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3484def : ARMV5TEPat<(add GPR:$acc,
3485                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3486                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3487
3488//===----------------------------------------------------------------------===//
3489// Thumb Support
3490//
3491
3492include "ARMInstrThumb.td"
3493
3494//===----------------------------------------------------------------------===//
3495// Thumb2 Support
3496//
3497
3498include "ARMInstrThumb2.td"
3499
3500//===----------------------------------------------------------------------===//
3501// Floating Point Support
3502//
3503
3504include "ARMInstrVFP.td"
3505
3506//===----------------------------------------------------------------------===//
3507// Advanced SIMD (NEON) Support
3508//
3509
3510include "ARMInstrNEON.td"
3511
3512//===----------------------------------------------------------------------===//
3513// Coprocessor Instructions.  For disassembly only.
3514//
3515
3516def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3517            nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3518            NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3519              [/* For disassembly only; pattern left blank */]> {
3520  let Inst{4} = 0;
3521}
3522
3523def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3524               nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3525               NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3526               [/* For disassembly only; pattern left blank */]> {
3527  let Inst{31-28} = 0b1111;
3528  let Inst{4} = 0;
3529}
3530
3531class ACI<dag oops, dag iops, string opc, string asm>
3532  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3533      opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3534  let Inst{27-25} = 0b110;
3535}
3536
3537multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3538
3539  def _OFFSET : ACI<(outs),
3540      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3541      opc, "\tp$cop, cr$CRd, $addr"> {
3542    let Inst{31-28} = op31_28;
3543    let Inst{24} = 1; // P = 1
3544    let Inst{21} = 0; // W = 0
3545    let Inst{22} = 0; // D = 0
3546    let Inst{20} = load;
3547  }
3548
3549  def _PRE : ACI<(outs),
3550      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3551      opc, "\tp$cop, cr$CRd, $addr!"> {
3552    let Inst{31-28} = op31_28;
3553    let Inst{24} = 1; // P = 1
3554    let Inst{21} = 1; // W = 1
3555    let Inst{22} = 0; // D = 0
3556    let Inst{20} = load;
3557  }
3558
3559  def _POST : ACI<(outs),
3560      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3561      opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3562    let Inst{31-28} = op31_28;
3563    let Inst{24} = 0; // P = 0
3564    let Inst{21} = 1; // W = 1
3565    let Inst{22} = 0; // D = 0
3566    let Inst{20} = load;
3567  }
3568
3569  def _OPTION : ACI<(outs),
3570      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3571      opc, "\tp$cop, cr$CRd, [$base], $option"> {
3572    let Inst{31-28} = op31_28;
3573    let Inst{24} = 0; // P = 0
3574    let Inst{23} = 1; // U = 1
3575    let Inst{21} = 0; // W = 0
3576    let Inst{22} = 0; // D = 0
3577    let Inst{20} = load;
3578  }
3579
3580  def L_OFFSET : ACI<(outs),
3581      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3582      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3583    let Inst{31-28} = op31_28;
3584    let Inst{24} = 1; // P = 1
3585    let Inst{21} = 0; // W = 0
3586    let Inst{22} = 1; // D = 1
3587    let Inst{20} = load;
3588  }
3589
3590  def L_PRE : ACI<(outs),
3591      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3592      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3593    let Inst{31-28} = op31_28;
3594    let Inst{24} = 1; // P = 1
3595    let Inst{21} = 1; // W = 1
3596    let Inst{22} = 1; // D = 1
3597    let Inst{20} = load;
3598  }
3599
3600  def L_POST : ACI<(outs),
3601      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3602      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3603    let Inst{31-28} = op31_28;
3604    let Inst{24} = 0; // P = 0
3605    let Inst{21} = 1; // W = 1
3606    let Inst{22} = 1; // D = 1
3607    let Inst{20} = load;
3608  }
3609
3610  def L_OPTION : ACI<(outs),
3611      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3612      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3613    let Inst{31-28} = op31_28;
3614    let Inst{24} = 0; // P = 0
3615    let Inst{23} = 1; // U = 1
3616    let Inst{21} = 0; // W = 0
3617    let Inst{22} = 1; // D = 1
3618    let Inst{20} = load;
3619  }
3620}
3621
3622defm LDC  : LdStCop<{?,?,?,?}, 1, "ldc">;
3623defm LDC2 : LdStCop<0b1111,    1, "ldc2">;
3624defm STC  : LdStCop<{?,?,?,?}, 0, "stc">;
3625defm STC2 : LdStCop<0b1111,    0, "stc2">;
3626
3627def MCR : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3628              GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3629              NoItinerary, "mcr", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3630              [/* For disassembly only; pattern left blank */]> {
3631  let Inst{20} = 0;
3632  let Inst{4} = 1;
3633  
3634  bits<4> Rt;
3635  bits<4> cop;
3636  bits<3> opc1;
3637  bits<3> opc2;
3638  bits<4> CRm;
3639  bits<4> CRn;
3640  
3641  let Inst{15-12} = Rt;
3642  let Inst{11-8}  = cop;
3643  let Inst{23-21} = opc1;
3644  let Inst{7-5}   = opc2;
3645  let Inst{3-0}   = CRm;
3646  let Inst{19-16} = CRn;
3647}
3648
3649def MCR2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3650                GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3651                NoItinerary, "mcr2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3652                [/* For disassembly only; pattern left blank */]> {
3653  let Inst{31-28} = 0b1111;
3654  let Inst{20} = 0;
3655  let Inst{4} = 1;
3656  
3657  bits<4> Rt;
3658  bits<4> cop;
3659  bits<3> opc1;
3660  bits<3> opc2;
3661  bits<4> CRm;
3662  bits<4> CRn;
3663  
3664  let Inst{15-12} = Rt;
3665  let Inst{11-8}  = cop;
3666  let Inst{23-21} = opc1;
3667  let Inst{7-5}   = opc2;
3668  let Inst{3-0}   = CRm;
3669  let Inst{19-16} = CRn;
3670}
3671
3672def MRC : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3673              GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3674              NoItinerary, "mrc", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3675              [/* For disassembly only; pattern left blank */]> {
3676  let Inst{20} = 1;
3677  let Inst{4} = 1;
3678  
3679  bits<4> Rt;
3680  bits<4> cop;
3681  bits<3> opc1;
3682  bits<3> opc2;
3683  bits<4> CRm;
3684  bits<4> CRn;
3685  
3686  let Inst{15-12} = Rt;
3687  let Inst{11-8}  = cop;
3688  let Inst{23-21} = opc1;
3689  let Inst{7-5}   = opc2;
3690  let Inst{3-0}   = CRm;
3691  let Inst{19-16} = CRn;
3692}
3693
3694def MRC2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3695                GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3696                NoItinerary, "mrc2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3697                [/* For disassembly only; pattern left blank */]> {
3698  let Inst{31-28} = 0b1111;
3699  let Inst{20} = 1;
3700  let Inst{4} = 1;
3701  
3702  bits<4> Rt;
3703  bits<4> cop;
3704  bits<3> opc1;
3705  bits<3> opc2;
3706  bits<4> CRm;
3707  bits<4> CRn;
3708  
3709  let Inst{15-12} = Rt;
3710  let Inst{11-8}  = cop;
3711  let Inst{23-21} = opc1;
3712  let Inst{7-5}   = opc2;
3713  let Inst{3-0}   = CRm;
3714  let Inst{19-16} = CRn;
3715}
3716
3717def MCRR : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3718               GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3719               NoItinerary, "mcrr", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3720               [/* For disassembly only; pattern left blank */]> {
3721  let Inst{23-20} = 0b0100;
3722  
3723  bits<4> Rt;
3724  bits<4> Rt2;
3725  bits<4> cop;
3726  bits<3> opc1;
3727  bits<4> CRm;
3728  
3729  let Inst{15-12} = Rt;
3730  let Inst{19-16} = Rt2;
3731  let Inst{11-8}  = cop;
3732  let Inst{7-5}   = opc1;
3733  let Inst{3-0}   = CRm;
3734}
3735
3736def MCRR2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3737                 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3738                 NoItinerary, "mcrr2\t$cop, $opc, $Rt, $Rt2, $CRm",
3739                 [/* For disassembly only; pattern left blank */]> {
3740  let Inst{31-28} = 0b1111;
3741  let Inst{23-20} = 0b0100;
3742  
3743  bits<4> Rt;
3744  bits<4> Rt2;
3745  bits<4> cop;
3746  bits<3> opc1;
3747  bits<4> CRm;
3748  
3749  let Inst{15-12} = Rt;
3750  let Inst{19-16} = Rt2;
3751  let Inst{11-8}  = cop;
3752  let Inst{7-5}   = opc1;
3753  let Inst{3-0}   = CRm;
3754}
3755
3756def MRRC : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3757               GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3758               NoItinerary, "mrrc", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3759               [/* For disassembly only; pattern left blank */]> {
3760  let Inst{23-20} = 0b0101;
3761  
3762  bits<4> Rt;
3763  bits<4> Rt2;
3764  bits<4> cop;
3765  bits<3> opc1;
3766  bits<4> CRm;
3767  
3768  let Inst{15-12} = Rt;
3769  let Inst{19-16} = Rt2;
3770  let Inst{11-8}  = cop;
3771  let Inst{7-5}   = opc1;
3772  let Inst{3-0}   = CRm;
3773}
3774
3775def MRRC2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3776                 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3777                 NoItinerary, "mrrc2\t$cop, $opc, $Rt, $Rt2, $CRm",
3778                 [/* For disassembly only; pattern left blank */]> {
3779  let Inst{31-28} = 0b1111;
3780  let Inst{23-20} = 0b0101;
3781  
3782  bits<4> Rt;
3783  bits<4> Rt2;
3784  bits<4> cop;
3785  bits<3> opc1;
3786  bits<4> CRm;
3787  
3788  let Inst{15-12} = Rt;
3789  let Inst{19-16} = Rt2;
3790  let Inst{11-8}  = cop;
3791  let Inst{7-5}   = opc1;
3792  let Inst{3-0}   = CRm;
3793}
3794
3795//===----------------------------------------------------------------------===//
3796// Move between special register and ARM core register -- for disassembly only
3797//
3798
3799def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3800              [/* For disassembly only; pattern left blank */]> {
3801  let Inst{23-20} = 0b0000;
3802  let Inst{7-4} = 0b0000;
3803}
3804
3805def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3806              [/* For disassembly only; pattern left blank */]> {
3807  let Inst{23-20} = 0b0100;
3808  let Inst{7-4} = 0b0000;
3809}
3810
3811def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3812              "msr", "\tcpsr$mask, $src",
3813              [/* For disassembly only; pattern left blank */]> {
3814  let Inst{23-20} = 0b0010;
3815  let Inst{7-4} = 0b0000;
3816}
3817
3818def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3819              "msr", "\tcpsr$mask, $a",
3820              [/* For disassembly only; pattern left blank */]> {
3821  let Inst{23-20} = 0b0010;
3822  let Inst{7-4} = 0b0000;
3823}
3824
3825def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3826              "msr", "\tspsr$mask, $src",
3827              [/* For disassembly only; pattern left blank */]> {
3828  let Inst{23-20} = 0b0110;
3829  let Inst{7-4} = 0b0000;
3830}
3831
3832def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3833              "msr", "\tspsr$mask, $a",
3834              [/* For disassembly only; pattern left blank */]> {
3835  let Inst{23-20} = 0b0110;
3836  let Inst{7-4} = 0b0000;
3837}
3838