ARMInstrInfo.td revision b3e1bf54b29354c6d332cfaffcc86cd776fd4ca8
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, [SDTCisInt<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_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
42
43def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
45
46def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
48                                                 SDTCisInt<2>]>;
49
50def SDT_ARMMEMBARRIERV7  : SDTypeProfile<0, 0, []>;
51def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
52def SDT_ARMMEMBARRIERV6  : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
53def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
54
55// Node definitions.
56def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
57def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
58
59def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
60                              [SDNPHasChain, SDNPOutFlag]>;
61def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeqEnd,
62                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
63
64def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
65                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
66def ARMcall_pred    : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
67                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
68def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
69                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
70
71def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTNone,
72                              [SDNPHasChain, SDNPOptInFlag]>;
73
74def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
75                              [SDNPInFlag]>;
76def ARMcneg          : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
77                              [SDNPInFlag]>;
78
79def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
80                              [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
81
82def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
83                              [SDNPHasChain]>;
84def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
85                              [SDNPHasChain]>;
86
87def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
88                              [SDNPOutFlag]>;
89
90def ARMcmpZ          : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
91                              [SDNPOutFlag,SDNPCommutative]>;
92
93def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
94
95def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
97def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInFlag ]>;
98
99def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
100def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
101
102def ARMMemBarrierV7  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
103                              [SDNPHasChain]>;
104def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
105                              [SDNPHasChain]>;
106def ARMMemBarrierV6  : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
107                              [SDNPHasChain]>;
108def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
109                              [SDNPHasChain]>;
110
111def ARMrbit          : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
112
113//===----------------------------------------------------------------------===//
114// ARM Instruction Predicate Definitions.
115//
116def HasV5T    : Predicate<"Subtarget->hasV5TOps()">;
117def HasV5TE   : Predicate<"Subtarget->hasV5TEOps()">;
118def HasV6     : Predicate<"Subtarget->hasV6Ops()">;
119def HasV6T2   : Predicate<"Subtarget->hasV6T2Ops()">;
120def NoV6T2    : Predicate<"!Subtarget->hasV6T2Ops()">;
121def HasV7     : Predicate<"Subtarget->hasV7Ops()">;
122def HasVFP2   : Predicate<"Subtarget->hasVFP2()">;
123def HasVFP3   : Predicate<"Subtarget->hasVFP3()">;
124def HasNEON   : Predicate<"Subtarget->hasNEON()">;
125def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
126def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
127def IsThumb   : Predicate<"Subtarget->isThumb()">;
128def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
129def IsThumb2  : Predicate<"Subtarget->isThumb2()">;
130def IsARM     : Predicate<"!Subtarget->isThumb()">;
131def IsDarwin    : Predicate<"Subtarget->isTargetDarwin()">;
132def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
133def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
134def CarryDefIsUsed   : Predicate<"N->hasAnyUseOfValue(1)">;
135
136// FIXME: Eventually this will be just "hasV6T2Ops".
137def UseMovt   : Predicate<"Subtarget->useMovt()">;
138def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
139
140//===----------------------------------------------------------------------===//
141// ARM Flag Definitions.
142
143class RegConstraint<string C> {
144  string Constraints = C;
145}
146
147//===----------------------------------------------------------------------===//
148//  ARM specific transformation functions and pattern fragments.
149//
150
151// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
152// so_imm_neg def below.
153def so_imm_neg_XFORM : SDNodeXForm<imm, [{
154  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
155}]>;
156
157// so_imm_not_XFORM - Return a so_imm value packed into the format described for
158// so_imm_not def below.
159def so_imm_not_XFORM : SDNodeXForm<imm, [{
160  return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
161}]>;
162
163// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
164def rot_imm : PatLeaf<(i32 imm), [{
165  int32_t v = (int32_t)N->getZExtValue();
166  return v == 8 || v == 16 || v == 24;
167}]>;
168
169/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
170def imm1_15 : PatLeaf<(i32 imm), [{
171  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
172}]>;
173
174/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
175def imm16_31 : PatLeaf<(i32 imm), [{
176  return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
177}]>;
178
179def so_imm_neg : 
180  PatLeaf<(imm), [{
181    return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
182  }], so_imm_neg_XFORM>;
183
184def so_imm_not :
185  PatLeaf<(imm), [{
186    return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
187  }], so_imm_not_XFORM>;
188
189// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
190def sext_16_node : PatLeaf<(i32 GPR:$a), [{
191  return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
192}]>;
193
194/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
195/// e.g., 0xf000ffff
196def bf_inv_mask_imm : Operand<i32>,
197                      PatLeaf<(imm), [{ 
198  uint32_t v = (uint32_t)N->getZExtValue();
199  if (v == 0xffffffff)
200    return 0;
201  // there can be 1's on either or both "outsides", all the "inside"
202  // bits must be 0's
203  unsigned int lsb = 0, msb = 31;
204  while (v & (1 << msb)) --msb;
205  while (v & (1 << lsb)) ++lsb;
206  for (unsigned int i = lsb; i <= msb; ++i) {
207    if (v & (1 << i))
208      return 0;
209  }
210  return 1;
211}] > {
212  let PrintMethod = "printBitfieldInvMaskImmOperand";
213}
214
215/// Split a 32-bit immediate into two 16 bit parts.
216def lo16 : SDNodeXForm<imm, [{
217  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
218                                   MVT::i32);
219}]>;
220
221def hi16 : SDNodeXForm<imm, [{
222  return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
223}]>;
224
225def lo16AllZero : PatLeaf<(i32 imm), [{
226  // Returns true if all low 16-bits are 0.
227  return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
228}], hi16>;
229
230/// imm0_65535 predicate - True if the 32-bit immediate is in the range 
231/// [0.65535].
232def imm0_65535 : PatLeaf<(i32 imm), [{
233  return (uint32_t)N->getZExtValue() < 65536;
234}]>;
235
236class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
237class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
238
239//===----------------------------------------------------------------------===//
240// Operand Definitions.
241//
242
243// Branch target.
244def brtarget : Operand<OtherVT>;
245
246// A list of registers separated by comma. Used by load/store multiple.
247def reglist : Operand<i32> {
248  let PrintMethod = "printRegisterList";
249}
250
251// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
252def cpinst_operand : Operand<i32> {
253  let PrintMethod = "printCPInstOperand";
254}
255
256def jtblock_operand : Operand<i32> {
257  let PrintMethod = "printJTBlockOperand";
258}
259def jt2block_operand : Operand<i32> {
260  let PrintMethod = "printJT2BlockOperand";
261}
262
263// Local PC labels.
264def pclabel : Operand<i32> {
265  let PrintMethod = "printPCLabel";
266}
267
268// shifter_operand operands: so_reg and so_imm.
269def so_reg : Operand<i32>,    // reg reg imm
270            ComplexPattern<i32, 3, "SelectShifterOperandReg",
271                            [shl,srl,sra,rotr]> {
272  let PrintMethod = "printSORegOperand";
273  let MIOperandInfo = (ops GPR, GPR, i32imm);
274}
275
276// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
277// 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
278// represented in the imm field in the same 12-bit form that they are encoded
279// into so_imm instructions: the 8-bit immediate is the least significant bits
280// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
281def so_imm : Operand<i32>,
282             PatLeaf<(imm), [{
283      return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
284    }]> {
285  let PrintMethod = "printSOImmOperand";
286}
287
288// Break so_imm's up into two pieces.  This handles immediates with up to 16
289// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
290// get the first/second pieces.
291def so_imm2part : Operand<i32>,
292                  PatLeaf<(imm), [{
293      return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
294    }]> {
295  let PrintMethod = "printSOImm2PartOperand";
296}
297
298def so_imm2part_1 : SDNodeXForm<imm, [{
299  unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
300  return CurDAG->getTargetConstant(V, MVT::i32);
301}]>;
302
303def so_imm2part_2 : SDNodeXForm<imm, [{
304  unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
305  return CurDAG->getTargetConstant(V, MVT::i32);
306}]>;
307
308def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
309      return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
310    }]> {
311  let PrintMethod = "printSOImm2PartOperand";
312}
313
314def so_neg_imm2part_1 : SDNodeXForm<imm, [{
315  unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
316  return CurDAG->getTargetConstant(V, MVT::i32);
317}]>;
318
319def so_neg_imm2part_2 : SDNodeXForm<imm, [{
320  unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
321  return CurDAG->getTargetConstant(V, MVT::i32);
322}]>;
323
324/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
325def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
326  return (int32_t)N->getZExtValue() < 32;
327}]>;
328
329// Define ARM specific addressing modes.
330
331// addrmode2 := reg +/- reg shop imm
332// addrmode2 := reg +/- imm12
333//
334def addrmode2 : Operand<i32>,
335                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
336  let PrintMethod = "printAddrMode2Operand";
337  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
338}
339
340def am2offset : Operand<i32>,
341                ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
342  let PrintMethod = "printAddrMode2OffsetOperand";
343  let MIOperandInfo = (ops GPR, i32imm);
344}
345
346// addrmode3 := reg +/- reg
347// addrmode3 := reg +/- imm8
348//
349def addrmode3 : Operand<i32>,
350                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
351  let PrintMethod = "printAddrMode3Operand";
352  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
353}
354
355def am3offset : Operand<i32>,
356                ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
357  let PrintMethod = "printAddrMode3OffsetOperand";
358  let MIOperandInfo = (ops GPR, i32imm);
359}
360
361// addrmode4 := reg, <mode|W>
362//
363def addrmode4 : Operand<i32>,
364                ComplexPattern<i32, 2, "SelectAddrMode4", []> {
365  let PrintMethod = "printAddrMode4Operand";
366  let MIOperandInfo = (ops GPR, i32imm);
367}
368
369// addrmode5 := reg +/- imm8*4
370//
371def addrmode5 : Operand<i32>,
372                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
373  let PrintMethod = "printAddrMode5Operand";
374  let MIOperandInfo = (ops GPR, i32imm);
375}
376
377// addrmode6 := reg with optional writeback
378//
379def addrmode6 : Operand<i32>,
380                ComplexPattern<i32, 4, "SelectAddrMode6", []> {
381  let PrintMethod = "printAddrMode6Operand";
382  let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
383}
384
385// addrmodepc := pc + reg
386//
387def addrmodepc : Operand<i32>,
388                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
389  let PrintMethod = "printAddrModePCOperand";
390  let MIOperandInfo = (ops GPR, i32imm);
391}
392
393def nohash_imm : Operand<i32> {
394  let PrintMethod = "printNoHashImmediate";
395}
396
397//===----------------------------------------------------------------------===//
398
399include "ARMInstrFormats.td"
400
401//===----------------------------------------------------------------------===//
402// Multiclass helpers...
403//
404
405/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
406/// binop that produces a value.
407multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
408                        bit Commutable = 0> {
409  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
410               IIC_iALUi, opc, "\t$dst, $a, $b",
411               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
412    let Inst{25} = 1;
413  }
414  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
415               IIC_iALUr, opc, "\t$dst, $a, $b",
416               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
417    let Inst{11-4} = 0b00000000;
418    let Inst{25} = 0;
419    let isCommutable = Commutable;
420  }
421  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
422               IIC_iALUsr, opc, "\t$dst, $a, $b",
423               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
424    let Inst{25} = 0;
425  }
426}
427
428/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
429/// instruction modifies the CPSR register.
430let Defs = [CPSR] in {
431multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
432                         bit Commutable = 0> {
433  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
434               IIC_iALUi, opc, "\t$dst, $a, $b",
435               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
436    let Inst{20} = 1;
437    let Inst{25} = 1;
438  }
439  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
440               IIC_iALUr, opc, "\t$dst, $a, $b",
441               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
442    let isCommutable = Commutable;
443    let Inst{11-4} = 0b00000000;
444    let Inst{20} = 1;
445    let Inst{25} = 0;
446  }
447  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
448               IIC_iALUsr, opc, "\t$dst, $a, $b",
449               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
450    let Inst{20} = 1;
451    let Inst{25} = 0;
452  }
453}
454}
455
456/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
457/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
458/// a explicit result, only implicitly set CPSR.
459let Defs = [CPSR] in {
460multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
461                       bit Commutable = 0> {
462  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
463               opc, "\t$a, $b",
464               [(opnode GPR:$a, so_imm:$b)]> {
465    let Inst{20} = 1;
466    let Inst{25} = 1;
467  }
468  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
469               opc, "\t$a, $b",
470               [(opnode GPR:$a, GPR:$b)]> {
471    let Inst{11-4} = 0b00000000;
472    let Inst{20} = 1;
473    let Inst{25} = 0;
474    let isCommutable = Commutable;
475  }
476  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
477               opc, "\t$a, $b",
478               [(opnode GPR:$a, so_reg:$b)]> {
479    let Inst{20} = 1;
480    let Inst{25} = 0;
481  }
482}
483}
484
485/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
486/// register and one whose operand is a register rotated by 8/16/24.
487/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
488multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
489  def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
490                 IIC_iUNAr, opc, "\t$dst, $src",
491                 [(set GPR:$dst, (opnode GPR:$src))]>,
492              Requires<[IsARM, HasV6]> {
493    let Inst{11-10} = 0b00;
494    let Inst{19-16} = 0b1111;
495  }
496  def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
497                 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
498                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
499              Requires<[IsARM, HasV6]> {
500    let Inst{19-16} = 0b1111;
501  }
502}
503
504/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
505/// register and one whose operand is a register rotated by 8/16/24.
506multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
507  def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
508                  IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
509                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
510               Requires<[IsARM, HasV6]> {
511    let Inst{11-10} = 0b00;
512  }
513  def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
514                  IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
515                  [(set GPR:$dst, (opnode GPR:$LHS,
516                                          (rotr GPR:$RHS, rot_imm:$rot)))]>,
517                  Requires<[IsARM, HasV6]>;
518}
519
520/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
521let Uses = [CPSR] in {
522multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
523                             bit Commutable = 0> {
524  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
525                DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
526               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
527               Requires<[IsARM, CarryDefIsUnused]> {
528    let Inst{25} = 1;
529  }
530  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
531                DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
532               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
533               Requires<[IsARM, CarryDefIsUnused]> {
534    let isCommutable = Commutable;
535    let Inst{11-4} = 0b00000000;
536    let Inst{25} = 0;
537  }
538  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
539                DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
540               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
541               Requires<[IsARM, CarryDefIsUnused]> {
542    let Inst{25} = 0;
543  }
544}
545// Carry setting variants
546let Defs = [CPSR] in {
547multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
548                             bit Commutable = 0> {
549  def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
550                DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
551               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
552               Requires<[IsARM, CarryDefIsUsed]> {
553    let Defs = [CPSR];
554    let Inst{20} = 1;
555    let Inst{25} = 1;
556  }
557  def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
558                DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
559               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
560               Requires<[IsARM, CarryDefIsUsed]> {
561    let Defs = [CPSR];
562    let Inst{11-4} = 0b00000000;
563    let Inst{20} = 1;
564    let Inst{25} = 0;
565  }
566  def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
567                DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
568               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
569               Requires<[IsARM, CarryDefIsUsed]> {
570    let Defs = [CPSR];
571    let Inst{20} = 1;
572    let Inst{25} = 0;
573  }
574}
575}
576}
577
578//===----------------------------------------------------------------------===//
579// Instructions
580//===----------------------------------------------------------------------===//
581
582//===----------------------------------------------------------------------===//
583//  Miscellaneous Instructions.
584//
585
586/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
587/// the function.  The first operand is the ID# for this instruction, the second
588/// is the index into the MachineConstantPool that this is, the third is the
589/// size in bytes of this constant pool entry.
590let neverHasSideEffects = 1, isNotDuplicable = 1 in
591def CONSTPOOL_ENTRY :
592PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
593                    i32imm:$size), NoItinerary,
594           "${instid:label} ${cpidx:cpentry}", []>;
595
596let Defs = [SP], Uses = [SP] in {
597def ADJCALLSTACKUP :
598PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
599           "@ ADJCALLSTACKUP $amt1",
600           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
601
602def ADJCALLSTACKDOWN : 
603PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
604           "@ ADJCALLSTACKDOWN $amt",
605           [(ARMcallseq_start timm:$amt)]>;
606}
607
608def NOP : AI<(outs), (ins), Pseudo, NoItinerary, "nop", "",
609             [/* For disassembly only; pattern left blank */]>,
610          Requires<[IsARM, HasV6T2]> {
611  let Inst{27-16} = 0b001100100000;
612  let Inst{7-0} = 0b00000000;
613}
614
615// The i32imm operand $val can be used by a debugger to store more information
616// about the breakpoint.
617def BKPT : AI<(outs), (ins i32imm:$val), Pseudo, NoItinerary, "bkpt", "\t$val",
618              [/* For disassembly only; pattern left blank */]>,
619           Requires<[IsARM]> {
620  let Inst{27-20} = 0b00010010;
621  let Inst{7-4} = 0b0111;
622}
623
624// Change Processor State is a system instruction -- for disassembly only.
625// The singleton $opt operand contains the following information:
626// opt{4-0} = mode from Inst{4-0}
627// opt{5} = changemode from Inst{17}
628// opt{8-6} = AIF from Inst{8-6}
629// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
630def CPS : AXI<(outs),(ins i32imm:$opt), Pseudo, NoItinerary, "cps${opt:cps}",
631              [/* For disassembly only; pattern left blank */]>,
632          Requires<[IsARM]> {
633  let Inst{31-28} = 0b1111;
634  let Inst{27-20} = 0b00010000;
635  let Inst{16} = 0;
636  let Inst{5} = 0;
637}
638
639def DBG : AI<(outs), (ins i32imm:$opt), Pseudo, NoItinerary, "dbg", "\t$opt",
640             [/* For disassembly only; pattern left blank */]>,
641          Requires<[IsARM, HasV7]> {
642  let Inst{27-16} = 0b001100100000;
643  let Inst{7-4} = 0b1111;
644}
645
646// A5.4 Permanently UNDEFINED instructions.
647def TRAP : AI<(outs), (ins), Pseudo, NoItinerary, "trap", "",
648              [/* For disassembly only; pattern left blank */]>,
649           Requires<[IsARM]> {
650  let Inst{27-25} = 0b011;
651  let Inst{24-20} = 0b11111;
652  let Inst{7-5} = 0b111;
653  let Inst{4} = 0b1;
654}
655
656// Address computation and loads and stores in PIC mode.
657let isNotDuplicable = 1 in {
658def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
659                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
660                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
661
662let AddedComplexity = 10 in {
663def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
664                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
665                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
666
667def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
668                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
669                  [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
670
671def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
672                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
673                  [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
674
675def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
676               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
677                  [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
678
679def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
680               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
681                  [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
682}
683let AddedComplexity = 10 in {
684def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
685               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
686               [(store GPR:$src, addrmodepc:$addr)]>;
687
688def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
689               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
690               [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
691
692def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
693               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
694               [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
695}
696} // isNotDuplicable = 1
697
698
699// LEApcrel - Load a pc-relative address into a register without offending the
700// assembler.
701def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
702                    Pseudo, IIC_iALUi,
703           !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
704                                 "${:private}PCRELL${:uid}+8))\n"),
705                      !strconcat("${:private}PCRELL${:uid}:\n\t",
706                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
707                   []>;
708
709def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
710                           (ins i32imm:$label, nohash_imm:$id, pred:$p),
711          Pseudo, IIC_iALUi,
712   !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
713                         "(${label}_${id}-(",
714                                  "${:private}PCRELL${:uid}+8))\n"),
715                       !strconcat("${:private}PCRELL${:uid}:\n\t",
716                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
717                   []> {
718    let Inst{25} = 1;
719}
720
721//===----------------------------------------------------------------------===//
722//  Control Flow Instructions.
723//
724
725let isReturn = 1, isTerminator = 1, isBarrier = 1 in
726  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
727                  "bx", "\tlr", [(ARMretflag)]> {
728  let Inst{3-0}   = 0b1110;
729  let Inst{7-4}   = 0b0001;
730  let Inst{19-8}  = 0b111111111111;
731  let Inst{27-20} = 0b00010010;
732}
733
734// Indirect branches
735let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
736  def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
737                  [(brind GPR:$dst)]> {
738    let Inst{7-4}   = 0b0001;
739    let Inst{19-8}  = 0b111111111111;
740    let Inst{27-20} = 0b00010010;
741    let Inst{31-28} = 0b1110;
742  }
743}
744
745// FIXME: remove when we have a way to marking a MI with these properties.
746// FIXME: Should pc be an implicit operand like PICADD, etc?
747let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
748    hasExtraDefRegAllocReq = 1 in
749  def LDM_RET : AXI4ld<(outs),
750                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
751                    LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
752                    []>;
753
754// On non-Darwin platforms R9 is callee-saved.
755let isCall = 1,
756  Defs = [R0,  R1,  R2,  R3,  R12, LR,
757          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
758          D16, D17, D18, D19, D20, D21, D22, D23,
759          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
760  def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
761                IIC_Br, "bl\t${func:call}",
762                [(ARMcall tglobaladdr:$func)]>,
763            Requires<[IsARM, IsNotDarwin]> {
764    let Inst{31-28} = 0b1110;
765  }
766
767  def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
768                   IIC_Br, "bl", "\t${func:call}",
769                   [(ARMcall_pred tglobaladdr:$func)]>,
770                Requires<[IsARM, IsNotDarwin]>;
771
772  // ARMv5T and above
773  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
774                IIC_Br, "blx\t$func",
775                [(ARMcall GPR:$func)]>,
776            Requires<[IsARM, HasV5T, IsNotDarwin]> {
777    let Inst{7-4}   = 0b0011;
778    let Inst{19-8}  = 0b111111111111;
779    let Inst{27-20} = 0b00010010;
780  }
781
782  // ARMv4T
783  def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
784                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
785                  [(ARMcall_nolink GPR:$func)]>,
786           Requires<[IsARM, IsNotDarwin]> {
787    let Inst{7-4}   = 0b0001;
788    let Inst{19-8}  = 0b111111111111;
789    let Inst{27-20} = 0b00010010;
790  }
791}
792
793// On Darwin R9 is call-clobbered.
794let isCall = 1,
795  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
796          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
797          D16, D17, D18, D19, D20, D21, D22, D23,
798          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
799  def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
800                IIC_Br, "bl\t${func:call}",
801                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
802    let Inst{31-28} = 0b1110;
803  }
804
805  def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
806                   IIC_Br, "bl", "\t${func:call}",
807                   [(ARMcall_pred tglobaladdr:$func)]>,
808                  Requires<[IsARM, IsDarwin]>;
809
810  // ARMv5T and above
811  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
812                IIC_Br, "blx\t$func",
813                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
814    let Inst{7-4}   = 0b0011;
815    let Inst{19-8}  = 0b111111111111;
816    let Inst{27-20} = 0b00010010;
817  }
818
819  // ARMv4T
820  def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
821                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
822                  [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
823    let Inst{7-4}   = 0b0001;
824    let Inst{19-8}  = 0b111111111111;
825    let Inst{27-20} = 0b00010010;
826  }
827}
828
829let isBranch = 1, isTerminator = 1 in {
830  // B is "predicable" since it can be xformed into a Bcc.
831  let isBarrier = 1 in {
832    let isPredicable = 1 in
833    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
834                "b\t$target", [(br bb:$target)]>;
835
836  let isNotDuplicable = 1, isIndirectBranch = 1 in {
837  def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
838                    IIC_Br, "mov\tpc, $target \n$jt",
839                    [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
840    let Inst{11-4}  = 0b00000000;
841    let Inst{15-12} = 0b1111;
842    let Inst{20}    = 0; // S Bit
843    let Inst{24-21} = 0b1101;
844    let Inst{27-25} = 0b000;
845  }
846  def BR_JTm : JTI<(outs),
847                   (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
848                   IIC_Br, "ldr\tpc, $target \n$jt",
849                   [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
850                     imm:$id)]> {
851    let Inst{15-12} = 0b1111;
852    let Inst{20}    = 1; // L bit
853    let Inst{21}    = 0; // W bit
854    let Inst{22}    = 0; // B bit
855    let Inst{24}    = 1; // P bit
856    let Inst{27-25} = 0b011;
857  }
858  def BR_JTadd : JTI<(outs),
859                   (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
860                    IIC_Br, "add\tpc, $target, $idx \n$jt",
861                    [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
862                      imm:$id)]> {
863    let Inst{15-12} = 0b1111;
864    let Inst{20}    = 0; // S bit
865    let Inst{24-21} = 0b0100;
866    let Inst{27-25} = 0b000;
867  }
868  } // isNotDuplicable = 1, isIndirectBranch = 1
869  } // isBarrier = 1
870
871  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
872  // a two-value operand where a dag node expects two operands. :( 
873  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
874               IIC_Br, "b", "\t$target",
875               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
876}
877
878// Supervisor call (software interrupt) -- for disassembly only
879let isCall = 1 in {
880def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
881              [/* For disassembly only; pattern left blank */]>;
882}
883
884//===----------------------------------------------------------------------===//
885//  Load / store Instructions.
886//
887
888// Load
889let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 
890def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
891               "ldr", "\t$dst, $addr",
892               [(set GPR:$dst, (load addrmode2:$addr))]>;
893
894// Special LDR for loads from non-pc-relative constpools.
895let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
896    mayHaveSideEffects = 1  in
897def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
898                 "ldr", "\t$dst, $addr", []>;
899
900// Loads with zero extension
901def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
902                  IIC_iLoadr, "ldrh", "\t$dst, $addr",
903                  [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
904
905def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
906                  IIC_iLoadr, "ldrb", "\t$dst, $addr",
907                  [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
908
909// Loads with sign extension
910def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
911                   IIC_iLoadr, "ldrsh", "\t$dst, $addr",
912                   [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
913
914def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
915                   IIC_iLoadr, "ldrsb", "\t$dst, $addr",
916                   [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
917
918let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
919// Load doubleword
920def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
921                 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
922                 []>, Requires<[IsARM, HasV5TE]>;
923
924// Indexed loads
925def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
926                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
927                     "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
928
929def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
930                     (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
931                     "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
932
933def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
934                     (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
935                     "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
936
937def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
938                     (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
939                    "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
940
941def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
942                     (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
943                     "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
944
945def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
946                     (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
947                    "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
948
949def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
950                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
951                      "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
952
953def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
954                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
955                   "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
956
957def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
958                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
959                      "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
960
961def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
962                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
963                   "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
964}
965
966// LDRT and LDRBT are for disassembly only.
967
968def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
969                   (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
970                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
971  let Inst{21} = 1; // overwrite
972}
973
974def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
975                   (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
976                   "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
977  let Inst{21} = 1; // overwrite
978}
979
980// Store
981def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
982               "str", "\t$src, $addr",
983               [(store GPR:$src, addrmode2:$addr)]>;
984
985// Stores with truncate
986def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
987               "strh", "\t$src, $addr",
988               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
989
990def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
991               "strb", "\t$src, $addr",
992               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
993
994// Store doubleword
995let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
996def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
997               StMiscFrm, IIC_iStorer,
998               "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
999
1000// Indexed stores
1001def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
1002                     (ins GPR:$src, GPR:$base, am2offset:$offset), 
1003                     StFrm, IIC_iStoreru,
1004                    "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1005                    [(set GPR:$base_wb,
1006                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1007
1008def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1009                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1010                     StFrm, IIC_iStoreru,
1011                    "str", "\t$src, [$base], $offset", "$base = $base_wb",
1012                    [(set GPR:$base_wb,
1013                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1014
1015def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1016                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
1017                     StMiscFrm, IIC_iStoreru,
1018                     "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1019                    [(set GPR:$base_wb,
1020                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1021
1022def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1023                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
1024                     StMiscFrm, IIC_iStoreru,
1025                     "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1026                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1027                                         GPR:$base, am3offset:$offset))]>;
1028
1029def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1030                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1031                     StFrm, IIC_iStoreru,
1032                     "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1033                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1034                                         GPR:$base, am2offset:$offset))]>;
1035
1036def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1037                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1038                     StFrm, IIC_iStoreru,
1039                     "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1040                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1041                                         GPR:$base, am2offset:$offset))]>;
1042
1043// STRT and STRBT are for disassembly only.
1044
1045def STRT : AI2stwpo<(outs GPR:$base_wb),
1046                    (ins GPR:$src, GPR:$base,am2offset:$offset), 
1047                    StFrm, IIC_iStoreru,
1048                    "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1049                    [/* For disassembly only; pattern left blank */]> {
1050  let Inst{21} = 1; // overwrite
1051}
1052
1053def STRBT : AI2stbpo<(outs GPR:$base_wb),
1054                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
1055                     StFrm, IIC_iStoreru,
1056                     "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1057                     [/* For disassembly only; pattern left blank */]> {
1058  let Inst{21} = 1; // overwrite
1059}
1060
1061//===----------------------------------------------------------------------===//
1062//  Load / store multiple Instructions.
1063//
1064
1065let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1066def LDM : AXI4ld<(outs),
1067               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1068               LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1069               []>;
1070
1071let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1072def STM : AXI4st<(outs),
1073               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1074               LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1075               []>;
1076
1077//===----------------------------------------------------------------------===//
1078//  Move Instructions.
1079//
1080
1081let neverHasSideEffects = 1 in
1082def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1083                "mov", "\t$dst, $src", []>, UnaryDP {
1084  let Inst{11-4} = 0b00000000;
1085  let Inst{25} = 0;
1086}
1087
1088def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
1089                DPSoRegFrm, IIC_iMOVsr,
1090                "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1091  let Inst{25} = 0;
1092}
1093
1094let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1095def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1096                "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1097  let Inst{25} = 1;
1098}
1099
1100let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1101def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
1102                 DPFrm, IIC_iMOVi,
1103                 "movw", "\t$dst, $src",
1104                 [(set GPR:$dst, imm0_65535:$src)]>,
1105                 Requires<[IsARM, HasV6T2]>, UnaryDP {
1106  let Inst{20} = 0;
1107  let Inst{25} = 1;
1108}
1109
1110let Constraints = "$src = $dst" in
1111def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1112                  DPFrm, IIC_iMOVi,
1113                  "movt", "\t$dst, $imm",
1114                  [(set GPR:$dst,
1115                        (or (and GPR:$src, 0xffff), 
1116                            lo16AllZero:$imm))]>, UnaryDP,
1117                  Requires<[IsARM, HasV6T2]> {
1118  let Inst{20} = 0;
1119  let Inst{25} = 1;
1120}
1121
1122def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1123      Requires<[IsARM, HasV6T2]>;
1124
1125let Uses = [CPSR] in
1126def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1127                 "mov", "\t$dst, $src, rrx",
1128                 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1129
1130// These aren't really mov instructions, but we have to define them this way
1131// due to flag operands.
1132
1133let Defs = [CPSR] in {
1134def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
1135                      IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1136                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1137def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1138                      IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1139                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1140}
1141
1142//===----------------------------------------------------------------------===//
1143//  Extend Instructions.
1144//
1145
1146// Sign extenders
1147
1148defm SXTB  : AI_unary_rrot<0b01101010,
1149                           "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1150defm SXTH  : AI_unary_rrot<0b01101011,
1151                           "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1152
1153defm SXTAB : AI_bin_rrot<0b01101010,
1154               "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1155defm SXTAH : AI_bin_rrot<0b01101011,
1156               "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1157
1158// TODO: SXT(A){B|H}16
1159
1160// Zero extenders
1161
1162let AddedComplexity = 16 in {
1163defm UXTB   : AI_unary_rrot<0b01101110,
1164                            "uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1165defm UXTH   : AI_unary_rrot<0b01101111,
1166                            "uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1167defm UXTB16 : AI_unary_rrot<0b01101100,
1168                            "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1169
1170def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1171               (UXTB16r_rot GPR:$Src, 24)>;
1172def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1173               (UXTB16r_rot GPR:$Src, 8)>;
1174
1175defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1176                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1177defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1178                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1179}
1180
1181// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1182//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1183
1184// TODO: UXT(A){B|H}16
1185
1186def SBFX  : I<(outs GPR:$dst),
1187              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1188               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1189               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1190               Requires<[IsARM, HasV6T2]> {
1191  let Inst{27-21} = 0b0111101;
1192  let Inst{6-4}   = 0b101;
1193}
1194
1195def UBFX  : I<(outs GPR:$dst),
1196              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1197               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1198               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1199               Requires<[IsARM, HasV6T2]> {
1200  let Inst{27-21} = 0b0111111;
1201  let Inst{6-4}   = 0b101;
1202}
1203
1204//===----------------------------------------------------------------------===//
1205//  Arithmetic Instructions.
1206//
1207
1208defm ADD  : AsI1_bin_irs<0b0100, "add",
1209                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1210defm SUB  : AsI1_bin_irs<0b0010, "sub",
1211                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1212
1213// ADD and SUB with 's' bit set.
1214defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1215                          BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1216defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1217                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1218
1219defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1220                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1221defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1222                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1223defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1224                             BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1225defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1226                             BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1227
1228// These don't define reg/reg forms, because they are handled above.
1229def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1230                  IIC_iALUi, "rsb", "\t$dst, $a, $b",
1231                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1232    let Inst{25} = 1;
1233}
1234
1235def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1236                  IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1237                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1238    let Inst{25} = 0;
1239}
1240
1241// RSB with 's' bit set.
1242let Defs = [CPSR] in {
1243def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1244                 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1245                 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1246    let Inst{20} = 1;
1247    let Inst{25} = 1;
1248}
1249def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1250                 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1251                 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1252    let Inst{20} = 1;
1253    let Inst{25} = 0;
1254}
1255}
1256
1257let Uses = [CPSR] in {
1258def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1259                 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1260                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1261                 Requires<[IsARM, CarryDefIsUnused]> {
1262    let Inst{25} = 1;
1263}
1264def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1265                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1266                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1267                 Requires<[IsARM, CarryDefIsUnused]> {
1268    let Inst{25} = 0;
1269}
1270}
1271
1272// FIXME: Allow these to be predicated.
1273let Defs = [CPSR], Uses = [CPSR] in {
1274def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1275                  DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1276                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
1277                  Requires<[IsARM, CarryDefIsUnused]> {
1278    let Inst{20} = 1;
1279    let Inst{25} = 1;
1280}
1281def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1282                  DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1283                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1284                  Requires<[IsARM, CarryDefIsUnused]> {
1285    let Inst{20} = 1;
1286    let Inst{25} = 0;
1287}
1288}
1289
1290// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1291def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
1292             (SUBri  GPR:$src, so_imm_neg:$imm)>;
1293
1294//def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
1295//             (SUBSri GPR:$src, so_imm_neg:$imm)>;
1296//def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
1297//             (SBCri  GPR:$src, so_imm_neg:$imm)>;
1298
1299// Note: These are implemented in C++ code, because they have to generate
1300// ADD/SUBrs instructions, which use a complex pattern that a xform function
1301// cannot produce.
1302// (mul X, 2^n+1) -> (add (X << n), X)
1303// (mul X, 2^n-1) -> (rsb X, (X << n))
1304
1305
1306//===----------------------------------------------------------------------===//
1307//  Bitwise Instructions.
1308//
1309
1310defm AND   : AsI1_bin_irs<0b0000, "and",
1311                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1312defm ORR   : AsI1_bin_irs<0b1100, "orr",
1313                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1314defm EOR   : AsI1_bin_irs<0b0001, "eor",
1315                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1316defm BIC   : AsI1_bin_irs<0b1110, "bic",
1317                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1318
1319def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1320               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1321               "bfc", "\t$dst, $imm", "$src = $dst",
1322               [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1323               Requires<[IsARM, HasV6T2]> {
1324  let Inst{27-21} = 0b0111110;
1325  let Inst{6-0}   = 0b0011111;
1326}
1327
1328def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1329                  "mvn", "\t$dst, $src",
1330                  [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1331  let Inst{25} = 0;
1332  let Inst{11-4} = 0b00000000;
1333}
1334def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1335                  IIC_iMOVsr, "mvn", "\t$dst, $src",
1336                  [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1337  let Inst{25} = 0;
1338}
1339let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1340def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
1341                  IIC_iMOVi, "mvn", "\t$dst, $imm",
1342                  [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1343    let Inst{25} = 1;
1344}
1345
1346def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
1347             (BICri GPR:$src, so_imm_not:$imm)>;
1348
1349//===----------------------------------------------------------------------===//
1350//  Multiply Instructions.
1351//
1352
1353let isCommutable = 1 in
1354def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1355                   IIC_iMUL32, "mul", "\t$dst, $a, $b",
1356                   [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1357
1358def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1359                    IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1360                   [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1361
1362def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1363                   IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1364                   [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1365                   Requires<[IsARM, HasV6T2]>;
1366
1367// Extra precision multiplies with low / high results
1368let neverHasSideEffects = 1 in {
1369let isCommutable = 1 in {
1370def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1371                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1372                    "smull", "\t$ldst, $hdst, $a, $b", []>;
1373
1374def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1375                               (ins GPR:$a, GPR:$b), IIC_iMUL64,
1376                    "umull", "\t$ldst, $hdst, $a, $b", []>;
1377}
1378
1379// Multiply + accumulate
1380def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1381                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1382                    "smlal", "\t$ldst, $hdst, $a, $b", []>;
1383
1384def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1385                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1386                    "umlal", "\t$ldst, $hdst, $a, $b", []>;
1387
1388def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1389                               (ins GPR:$a, GPR:$b), IIC_iMAC64,
1390                    "umaal", "\t$ldst, $hdst, $a, $b", []>,
1391                    Requires<[IsARM, HasV6]>;
1392} // neverHasSideEffects
1393
1394// Most significant word multiply
1395def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1396               IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1397               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1398            Requires<[IsARM, HasV6]> {
1399  let Inst{7-4}   = 0b0001;
1400  let Inst{15-12} = 0b1111;
1401}
1402
1403def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1404               IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1405               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1406            Requires<[IsARM, HasV6]> {
1407  let Inst{7-4}   = 0b0001;
1408}
1409
1410
1411def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1412               IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1413               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1414            Requires<[IsARM, HasV6]> {
1415  let Inst{7-4}   = 0b1101;
1416}
1417
1418multiclass AI_smul<string opc, PatFrag opnode> {
1419  def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1420              IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1421              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1422                                      (sext_inreg GPR:$b, i16)))]>,
1423           Requires<[IsARM, HasV5TE]> {
1424             let Inst{5} = 0;
1425             let Inst{6} = 0;
1426           }
1427
1428  def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1429              IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1430              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1431                                      (sra GPR:$b, (i32 16))))]>,
1432           Requires<[IsARM, HasV5TE]> {
1433             let Inst{5} = 0;
1434             let Inst{6} = 1;
1435           }
1436
1437  def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1438              IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1439              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1440                                      (sext_inreg GPR:$b, i16)))]>,
1441           Requires<[IsARM, HasV5TE]> {
1442             let Inst{5} = 1;
1443             let Inst{6} = 0;
1444           }
1445
1446  def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1447              IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1448              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1449                                      (sra GPR:$b, (i32 16))))]>,
1450            Requires<[IsARM, HasV5TE]> {
1451             let Inst{5} = 1;
1452             let Inst{6} = 1;
1453           }
1454
1455  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1456              IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1457              [(set GPR:$dst, (sra (opnode GPR:$a,
1458                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1459           Requires<[IsARM, HasV5TE]> {
1460             let Inst{5} = 1;
1461             let Inst{6} = 0;
1462           }
1463
1464  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1465              IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1466              [(set GPR:$dst, (sra (opnode GPR:$a,
1467                                    (sra GPR:$b, (i32 16))), (i32 16)))]>,
1468            Requires<[IsARM, HasV5TE]> {
1469             let Inst{5} = 1;
1470             let Inst{6} = 1;
1471           }
1472}
1473
1474
1475multiclass AI_smla<string opc, PatFrag opnode> {
1476  def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1477              IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1478              [(set GPR:$dst, (add GPR:$acc,
1479                               (opnode (sext_inreg GPR:$a, i16),
1480                                       (sext_inreg GPR:$b, i16))))]>,
1481           Requires<[IsARM, HasV5TE]> {
1482             let Inst{5} = 0;
1483             let Inst{6} = 0;
1484           }
1485
1486  def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1487              IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1488              [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1489                                                     (sra GPR:$b, (i32 16)))))]>,
1490           Requires<[IsARM, HasV5TE]> {
1491             let Inst{5} = 0;
1492             let Inst{6} = 1;
1493           }
1494
1495  def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1496              IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1497              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1498                                                 (sext_inreg GPR:$b, i16))))]>,
1499           Requires<[IsARM, HasV5TE]> {
1500             let Inst{5} = 1;
1501             let Inst{6} = 0;
1502           }
1503
1504  def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1505              IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1506             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1507                                                    (sra GPR:$b, (i32 16)))))]>,
1508            Requires<[IsARM, HasV5TE]> {
1509             let Inst{5} = 1;
1510             let Inst{6} = 1;
1511           }
1512
1513  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1514              IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1515              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1516                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1517           Requires<[IsARM, HasV5TE]> {
1518             let Inst{5} = 0;
1519             let Inst{6} = 0;
1520           }
1521
1522  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1523              IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1524              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1525                                         (sra GPR:$b, (i32 16))), (i32 16))))]>,
1526            Requires<[IsARM, HasV5TE]> {
1527             let Inst{5} = 0;
1528             let Inst{6} = 1;
1529           }
1530}
1531
1532defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1533defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1534
1535// TODO: Halfword multiple accumulate long: SMLAL<x><y>
1536// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1537
1538//===----------------------------------------------------------------------===//
1539//  Misc. Arithmetic Instructions.
1540//
1541
1542def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1543              "clz", "\t$dst, $src",
1544              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1545  let Inst{7-4}   = 0b0001;
1546  let Inst{11-8}  = 0b1111;
1547  let Inst{19-16} = 0b1111;
1548}
1549
1550def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1551              "rbit", "\t$dst, $src",
1552              [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1553           Requires<[IsARM, HasV6T2]> {
1554  let Inst{7-4}   = 0b0011;
1555  let Inst{11-8}  = 0b1111;
1556  let Inst{19-16} = 0b1111;
1557}
1558
1559def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1560              "rev", "\t$dst, $src",
1561              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1562  let Inst{7-4}   = 0b0011;
1563  let Inst{11-8}  = 0b1111;
1564  let Inst{19-16} = 0b1111;
1565}
1566
1567def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1568               "rev16", "\t$dst, $src",
1569               [(set GPR:$dst,
1570                   (or (and (srl GPR:$src, (i32 8)), 0xFF),
1571                       (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1572                           (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1573                               (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1574               Requires<[IsARM, HasV6]> {
1575  let Inst{7-4}   = 0b1011;
1576  let Inst{11-8}  = 0b1111;
1577  let Inst{19-16} = 0b1111;
1578}
1579
1580def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1581               "revsh", "\t$dst, $src",
1582               [(set GPR:$dst,
1583                  (sext_inreg
1584                    (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1585                        (shl GPR:$src, (i32 8))), i16))]>,
1586               Requires<[IsARM, HasV6]> {
1587  let Inst{7-4}   = 0b1011;
1588  let Inst{11-8}  = 0b1111;
1589  let Inst{19-16} = 0b1111;
1590}
1591
1592def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1593                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1594               IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1595               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1596                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
1597                                        0xFFFF0000)))]>,
1598               Requires<[IsARM, HasV6]> {
1599  let Inst{6-4} = 0b001;
1600}
1601
1602// Alternate cases for PKHBT where identities eliminate some nodes.
1603def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1604               (PKHBT GPR:$src1, GPR:$src2, 0)>;
1605def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1606               (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1607
1608
1609def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1610                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1611               IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1612               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1613                                   (and (sra GPR:$src2, imm16_31:$shamt),
1614                                        0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1615  let Inst{6-4} = 0b101;
1616}
1617
1618// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1619// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1620def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1621               (PKHTB GPR:$src1, GPR:$src2, 16)>;
1622def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1623                   (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1624               (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1625
1626//===----------------------------------------------------------------------===//
1627//  Comparison Instructions...
1628//
1629
1630defm CMP  : AI1_cmp_irs<0b1010, "cmp",
1631                        BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1632//FIXME: Disable CMN, as CCodes are backwards from compare expectations
1633//       Compare-to-zero still works out, just not the relationals
1634//defm CMN  : AI1_cmp_irs<0b1011, "cmn",
1635//                        BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1636
1637// Note that TST/TEQ don't set all the same flags that CMP does!
1638defm TST  : AI1_cmp_irs<0b1000, "tst",
1639                        BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1640defm TEQ  : AI1_cmp_irs<0b1001, "teq",
1641                        BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1642
1643defm CMPz  : AI1_cmp_irs<0b1010, "cmp",
1644                         BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1645defm CMNz  : AI1_cmp_irs<0b1011, "cmn",
1646                         BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1647
1648//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1649//             (CMNri  GPR:$src, so_imm_neg:$imm)>;
1650
1651def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1652             (CMNzri  GPR:$src, so_imm_neg:$imm)>;
1653
1654
1655// Conditional moves
1656// FIXME: should be able to write a pattern for ARMcmov, but can't use
1657// a two-value operand where a dag node expects two operands. :( 
1658def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1659                IIC_iCMOVr, "mov", "\t$dst, $true",
1660      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1661                RegConstraint<"$false = $dst">, UnaryDP {
1662  let Inst{11-4} = 0b00000000;
1663  let Inst{25} = 0;
1664}
1665
1666def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1667                        (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1668                "mov", "\t$dst, $true",
1669   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1670                RegConstraint<"$false = $dst">, UnaryDP {
1671  let Inst{25} = 0;
1672}
1673
1674def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1675                        (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1676                "mov", "\t$dst, $true",
1677   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1678                RegConstraint<"$false = $dst">, UnaryDP {
1679  let Inst{25} = 1;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Atomic operations intrinsics
1684//
1685
1686// memory barriers protect the atomic sequences
1687let hasSideEffects = 1 in {
1688def Int_MemBarrierV7 : AInoP<(outs), (ins),
1689                        Pseudo, NoItinerary,
1690                        "dmb", "",
1691                        [(ARMMemBarrierV7)]>,
1692                        Requires<[IsARM, HasV7]> {
1693  let Inst{31-4} = 0xf57ff05;
1694  // FIXME: add support for options other than a full system DMB
1695  let Inst{3-0} = 0b1111;
1696}
1697
1698def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1699                        Pseudo, NoItinerary,
1700                        "dsb", "",
1701                        [(ARMSyncBarrierV7)]>,
1702                        Requires<[IsARM, HasV7]> {
1703  let Inst{31-4} = 0xf57ff04;
1704  // FIXME: add support for options other than a full system DSB
1705  let Inst{3-0} = 0b1111;
1706}
1707
1708def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1709                       Pseudo, NoItinerary,
1710                       "mcr", "\tp15, 0, $zero, c7, c10, 5",
1711                       [(ARMMemBarrierV6 GPR:$zero)]>,
1712                       Requires<[IsARM, HasV6]> {
1713  // FIXME: add support for options other than a full system DMB
1714  // FIXME: add encoding
1715}
1716
1717def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1718                        Pseudo, NoItinerary,
1719                        "mcr", "\tp15, 0, $zero, c7, c10, 4",
1720                        [(ARMSyncBarrierV6 GPR:$zero)]>,
1721                        Requires<[IsARM, HasV6]> {
1722  // FIXME: add support for options other than a full system DSB
1723  // FIXME: add encoding
1724}
1725}
1726
1727let usesCustomInserter = 1 in {
1728  let Uses = [CPSR] in {
1729    def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1730      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1731      "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1732      [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1733    def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1734      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1735      "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1736      [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1737    def ATOMIC_LOAD_AND_I8 : PseudoInst<
1738      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1739      "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1740      [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1741    def ATOMIC_LOAD_OR_I8 : PseudoInst<
1742      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1743      "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1744      [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1745    def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1746      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1747      "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1748      [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1749    def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1750      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1751      "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1752      [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1753    def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1754      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1755      "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1756      [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1757    def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1758      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1759      "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1760      [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1761    def ATOMIC_LOAD_AND_I16 : PseudoInst<
1762      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1763      "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1764      [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1765    def ATOMIC_LOAD_OR_I16 : PseudoInst<
1766      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1767      "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1768      [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1769    def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1770      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1771      "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1772      [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1773    def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1774      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1775      "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1776      [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1777    def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1778      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1779      "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1780      [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1781    def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1782      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1783      "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1784      [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1785    def ATOMIC_LOAD_AND_I32 : PseudoInst<
1786      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1787      "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1788      [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1789    def ATOMIC_LOAD_OR_I32 : PseudoInst<
1790      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1791      "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1792      [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1793    def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1794      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1795      "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1796      [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1797    def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1798      (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1799      "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1800      [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1801
1802    def ATOMIC_SWAP_I8 : PseudoInst<
1803      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1804      "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1805      [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1806    def ATOMIC_SWAP_I16 : PseudoInst<
1807      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1808      "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1809      [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1810    def ATOMIC_SWAP_I32 : PseudoInst<
1811      (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1812      "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1813      [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1814
1815    def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1816      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1817      "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1818      [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1819    def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1820      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1821      "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1822      [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1823    def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1824      (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1825      "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1826      [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1827}
1828}
1829
1830let mayLoad = 1 in {
1831def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1832                    "ldrexb", "\t$dest, [$ptr]",
1833                    []>;
1834def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1835                    "ldrexh", "\t$dest, [$ptr]",
1836                    []>;
1837def LDREX  : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1838                    "ldrex", "\t$dest, [$ptr]",
1839                    []>;
1840def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1841                    NoItinerary,
1842                    "ldrexd", "\t$dest, $dest2, [$ptr]",
1843                    []>;
1844}
1845
1846let mayStore = 1, Constraints = "@earlyclobber $success" in {
1847def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1848                    NoItinerary,
1849                    "strexb", "\t$success, $src, [$ptr]",
1850                    []>;
1851def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1852                    NoItinerary,
1853                    "strexh", "\t$success, $src, [$ptr]",
1854                    []>;
1855def STREX  : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1856                    NoItinerary,
1857                    "strex", "\t$success, $src, [$ptr]",
1858                    []>;
1859def STREXD : AIstrex<0b01, (outs GPR:$success),
1860                    (ins GPR:$src, GPR:$src2, GPR:$ptr),
1861                    NoItinerary,
1862                    "strexd", "\t$success, $src, $src2, [$ptr]",
1863                    []>;
1864}
1865
1866// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
1867let mayLoad = 1 in {
1868def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1869             "swp", "\t$dst, $src, [$ptr]",
1870             [/* For disassembly only; pattern left blank */]> {
1871  let Inst{27-23} = 0b00010;
1872  let Inst{22} = 0; // B = 0
1873  let Inst{21-20} = 0b00;
1874  let Inst{7-4} = 0b1001;
1875}
1876
1877def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
1878             "swpb", "\t$dst, $src, [$ptr]",
1879             [/* For disassembly only; pattern left blank */]> {
1880  let Inst{27-23} = 0b00010;
1881  let Inst{22} = 1; // B = 1
1882  let Inst{21-20} = 0b00;
1883  let Inst{7-4} = 0b1001;
1884}
1885}
1886
1887//===----------------------------------------------------------------------===//
1888// TLS Instructions
1889//
1890
1891// __aeabi_read_tp preserves the registers r1-r3.
1892let isCall = 1,
1893  Defs = [R0, R12, LR, CPSR] in {
1894  def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
1895               "bl\t__aeabi_read_tp",
1896               [(set R0, ARMthread_pointer)]>;
1897}
1898
1899//===----------------------------------------------------------------------===//
1900// SJLJ Exception handling intrinsics
1901//   eh_sjlj_setjmp() is an instruction sequence to store the return
1902//   address and save #0 in R0 for the non-longjmp case.
1903//   Since by its nature we may be coming from some other function to get
1904//   here, and we're using the stack frame for the containing function to
1905//   save/restore registers, we can't keep anything live in regs across
1906//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1907//   when we get here from a longjmp(). We force everthing out of registers
1908//   except for our own input by listing the relevant registers in Defs. By
1909//   doing so, we also cause the prologue/epilogue code to actively preserve
1910//   all of the callee-saved resgisters, which is exactly what we want.
1911//   A constant value is passed in $val, and we use the location as a scratch.
1912let Defs =
1913  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
1914    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
1915    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1916    D31 ] in {
1917  def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
1918                               AddrModeNone, SizeSpecial, IndexModeNone,
1919                               Pseudo, NoItinerary,
1920                               "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
1921                               "add\t$val, pc, #8\n\t"
1922                               "str\t$val, [$src, #+4]\n\t"
1923                               "mov\tr0, #0\n\t"
1924                               "add\tpc, pc, #0\n\t"
1925                               "mov\tr0, #1 @ eh_setjmp end", "",
1926                         [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
1927}
1928
1929//===----------------------------------------------------------------------===//
1930// Non-Instruction Patterns
1931//
1932
1933// Large immediate handling.
1934
1935// Two piece so_imms.
1936let isReMaterializable = 1 in
1937def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
1938                         Pseudo, IIC_iMOVi,
1939                         "mov", "\t$dst, $src",
1940                         [(set GPR:$dst, so_imm2part:$src)]>,
1941                  Requires<[IsARM, NoV6T2]>;
1942
1943def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1944             (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1945                    (so_imm2part_2 imm:$RHS))>;
1946def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1947             (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1948                    (so_imm2part_2 imm:$RHS))>;
1949def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
1950             (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1951                    (so_imm2part_2 imm:$RHS))>;
1952def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
1953             (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
1954                    (so_neg_imm2part_2 imm:$RHS))>;
1955
1956// 32-bit immediate using movw + movt.
1957// This is a single pseudo instruction, the benefit is that it can be remat'd
1958// as a single unit instead of having to handle reg inputs.
1959// FIXME: Remove this when we can do generalized remat.
1960let isReMaterializable = 1 in
1961def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
1962                    "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1963                     [(set GPR:$dst, (i32 imm:$src))]>,
1964               Requires<[IsARM, HasV6T2]>;
1965
1966// ConstantPool, GlobalAddress, and JumpTable
1967def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
1968            Requires<[IsARM, DontUseMovt]>;
1969def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
1970def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
1971            Requires<[IsARM, UseMovt]>;
1972def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1973             (LEApcrelJT tjumptable:$dst, imm:$id)>;
1974
1975// TODO: add,sub,and, 3-instr forms?
1976
1977
1978// Direct calls
1979def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1980      Requires<[IsARM, IsNotDarwin]>;
1981def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1982      Requires<[IsARM, IsDarwin]>;
1983
1984// zextload i1 -> zextload i8
1985def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1986
1987// extload -> zextload
1988def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1989def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
1990def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
1991
1992def : ARMPat<(extloadi8  addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1993def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1994
1995// smul* and smla*
1996def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1997                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
1998                 (SMULBB GPR:$a, GPR:$b)>;
1999def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2000                 (SMULBB GPR:$a, GPR:$b)>;
2001def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2002                      (sra GPR:$b, (i32 16))),
2003                 (SMULBT GPR:$a, GPR:$b)>;
2004def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2005                 (SMULBT GPR:$a, GPR:$b)>;
2006def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2007                      (sra (shl GPR:$b, (i32 16)), (i32 16))),
2008                 (SMULTB GPR:$a, GPR:$b)>;
2009def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2010                (SMULTB GPR:$a, GPR:$b)>;
2011def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2012                      (i32 16)),
2013                 (SMULWB GPR:$a, GPR:$b)>;
2014def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2015                 (SMULWB GPR:$a, GPR:$b)>;
2016
2017def : ARMV5TEPat<(add GPR:$acc,
2018                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2019                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2020                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2021def : ARMV5TEPat<(add GPR:$acc,
2022                      (mul sext_16_node:$a, sext_16_node:$b)),
2023                 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2024def : ARMV5TEPat<(add GPR:$acc,
2025                      (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2026                           (sra GPR:$b, (i32 16)))),
2027                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2028def : ARMV5TEPat<(add GPR:$acc,
2029                      (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2030                 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2031def : ARMV5TEPat<(add GPR:$acc,
2032                      (mul (sra GPR:$a, (i32 16)),
2033                           (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2034                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2035def : ARMV5TEPat<(add GPR:$acc,
2036                      (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2037                 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2038def : ARMV5TEPat<(add GPR:$acc,
2039                      (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2040                           (i32 16))),
2041                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2042def : ARMV5TEPat<(add GPR:$acc,
2043                      (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2044                 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2045
2046//===----------------------------------------------------------------------===//
2047// Thumb Support
2048//
2049
2050include "ARMInstrThumb.td"
2051
2052//===----------------------------------------------------------------------===//
2053// Thumb2 Support
2054//
2055
2056include "ARMInstrThumb2.td"
2057
2058//===----------------------------------------------------------------------===//
2059// Floating Point Support
2060//
2061
2062include "ARMInstrVFP.td"
2063
2064//===----------------------------------------------------------------------===//
2065// Advanced SIMD (NEON) Support
2066//
2067
2068include "ARMInstrNEON.td"
2069
2070//===----------------------------------------------------------------------===//
2071// Coprocessor Instructions.  For disassembly only.
2072//
2073
2074def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2075            nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2076            NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2077              [/* For disassembly only; pattern left blank */]> {
2078  let Inst{4} = 0;
2079}
2080
2081def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2082               nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2083               NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2084               [/* For disassembly only; pattern left blank */]> {
2085  let Inst{31-28} = 0b1111;
2086  let Inst{4} = 0;
2087}
2088
2089def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2090              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2091              NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2092              [/* For disassembly only; pattern left blank */]> {
2093  let Inst{20} = 0;
2094  let Inst{4} = 1;
2095}
2096
2097def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2098                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2099                NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2100                [/* For disassembly only; pattern left blank */]> {
2101  let Inst{31-28} = 0b1111;
2102  let Inst{20} = 0;
2103  let Inst{4} = 1;
2104}
2105
2106def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2107              GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2108              NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2109              [/* For disassembly only; pattern left blank */]> {
2110  let Inst{20} = 1;
2111  let Inst{4} = 1;
2112}
2113
2114def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2115                GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2116                NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2117                [/* For disassembly only; pattern left blank */]> {
2118  let Inst{31-28} = 0b1111;
2119  let Inst{20} = 1;
2120  let Inst{4} = 1;
2121}
2122
2123def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2124               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2125               NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2126               [/* For disassembly only; pattern left blank */]> {
2127  let Inst{23-20} = 0b0100;
2128}
2129
2130def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2131                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2132                 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2133                 [/* For disassembly only; pattern left blank */]> {
2134  let Inst{31-28} = 0b1111;
2135  let Inst{23-20} = 0b0100;
2136}
2137
2138def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2139               GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2140               NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2141               [/* For disassembly only; pattern left blank */]> {
2142  let Inst{23-20} = 0b0101;
2143}
2144
2145def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2146                 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2147                 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2148                 [/* For disassembly only; pattern left blank */]> {
2149  let Inst{31-28} = 0b1111;
2150  let Inst{23-20} = 0b0101;
2151}
2152
2153//===----------------------------------------------------------------------===//
2154// Move between special register and ARM core register -- for disassembly only
2155//
2156
2157def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2158              [/* For disassembly only; pattern left blank */]> {
2159  let Inst{23-20} = 0b0000;
2160  let Inst{7-4} = 0b0000;
2161}
2162
2163def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2164              [/* For disassembly only; pattern left blank */]> {
2165  let Inst{23-20} = 0b0100;
2166  let Inst{7-4} = 0b0000;
2167}
2168
2169// FIXME: mask is ignored for the time being.
2170def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "mrs", "\tcpsr, $src",
2171              [/* For disassembly only; pattern left blank */]> {
2172  let Inst{23-20} = 0b0010;
2173  let Inst{7-4} = 0b0000;
2174}
2175
2176// FIXME: mask is ignored for the time being.
2177def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"mrs","\tspsr, $src",
2178              [/* For disassembly only; pattern left blank */]> {
2179  let Inst{23-20} = 0b0110;
2180  let Inst{7-4} = 0b0000;
2181}
2182