ARMInstrThumb2.td revision adc7733a64b65096cbd6066c212a9daa6e278a9a
1//===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
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 Thumb2 instruction set.
11//
12//===----------------------------------------------------------------------===//
13
14// IT block predicate field
15def it_pred : Operand<i32> {
16  let PrintMethod = "printPredicateOperand";
17}
18
19// IT block condition mask
20def it_mask : Operand<i32> {
21  let PrintMethod = "printThumbITMask";
22}
23
24// Table branch address
25def tb_addrmode : Operand<i32> {
26  let PrintMethod = "printTBAddrMode";
27}
28
29// Shifted operands. No register controlled shifts for Thumb2.
30// Note: We do not support rrx shifted operands yet.
31def t2_so_reg : Operand<i32>,    // reg imm
32                ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
33                               [shl,srl,sra,rotr]> {
34  let PrintMethod = "printT2SOOperand";
35  let MIOperandInfo = (ops GPR, i32imm);
36}
37
38// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
39def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
40  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
41}]>;
42
43// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
44def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
45  return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
46}]>;
47
48// t2_so_imm - Match a 32-bit immediate operand, which is an
49// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
50// immediate splatted into multiple bytes of the word. t2_so_imm values are
51// represented in the imm field in the same 12-bit form that they are encoded
52// into t2_so_imm instructions: the 8-bit immediate is the least significant
53// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
54def t2_so_imm : Operand<i32>,
55                PatLeaf<(imm), [{
56  return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
57}]>;
58
59// t2_so_imm_not - Match an immediate that is a complement
60// of a t2_so_imm.
61def t2_so_imm_not : Operand<i32>,
62                    PatLeaf<(imm), [{
63  return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64}], t2_so_imm_not_XFORM>;
65
66// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67def t2_so_imm_neg : Operand<i32>,
68                    PatLeaf<(imm), [{
69  return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
70}], t2_so_imm_neg_XFORM>;
71
72// Break t2_so_imm's up into two pieces.  This handles immediates with up to 16
73// bits set in them.  This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74// to get the first/second pieces.
75def t2_so_imm2part : Operand<i32>,
76                  PatLeaf<(imm), [{
77      return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
78    }]> {
79}
80
81def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82  unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83  return CurDAG->getTargetConstant(V, MVT::i32);
84}]>;
85
86def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87  unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88  return CurDAG->getTargetConstant(V, MVT::i32);
89}]>;
90
91def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92      return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
93    }]> {
94}
95
96def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97  unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98  return CurDAG->getTargetConstant(V, MVT::i32);
99}]>;
100
101def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102  unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103  return CurDAG->getTargetConstant(V, MVT::i32);
104}]>;
105
106/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107def imm1_31 : PatLeaf<(i32 imm), [{
108  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
109}]>;
110
111/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
112def imm0_4095 : Operand<i32>,
113                PatLeaf<(i32 imm), [{
114  return (uint32_t)N->getZExtValue() < 4096;
115}]>;
116
117def imm0_4095_neg : PatLeaf<(i32 imm), [{
118 return (uint32_t)(-N->getZExtValue()) < 4096;
119}], imm_neg_XFORM>;
120
121def imm0_255_neg : PatLeaf<(i32 imm), [{
122  return (uint32_t)(-N->getZExtValue()) < 255;
123}], imm_neg_XFORM>;
124
125// Define Thumb2 specific addressing modes.
126
127// t2addrmode_imm12  := reg + imm12
128def t2addrmode_imm12 : Operand<i32>,
129                       ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
130  let PrintMethod = "printT2AddrModeImm12Operand";
131  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
132}
133
134// t2addrmode_imm8  := reg - imm8
135def t2addrmode_imm8 : Operand<i32>,
136                      ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
137  let PrintMethod = "printT2AddrModeImm8Operand";
138  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
139}
140
141def t2am_imm8_offset : Operand<i32>,
142                       ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
143  let PrintMethod = "printT2AddrModeImm8OffsetOperand";
144}
145
146// t2addrmode_imm8s4  := reg +/- (imm8 << 2)
147def t2addrmode_imm8s4 : Operand<i32>,
148                        ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
149  let PrintMethod = "printT2AddrModeImm8s4Operand";
150  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
151}
152
153// t2addrmode_so_reg  := reg + (reg << imm2)
154def t2addrmode_so_reg : Operand<i32>,
155                        ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
156  let PrintMethod = "printT2AddrModeSoRegOperand";
157  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
158}
159
160
161//===----------------------------------------------------------------------===//
162// Multiclass helpers...
163//
164
165/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
166/// unary operation that produces a value. These are predicable and can be
167/// changed to modify CPSR.
168multiclass T2I_un_irs<bits<4> opcod, string opc, PatFrag opnode,
169                      bit Cheap = 0, bit ReMat = 0> {
170   // shifted imm
171   def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
172                opc, "\t$dst, $src",
173                [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
174     let isAsCheapAsAMove = Cheap;
175     let isReMaterializable = ReMat;
176     let Inst{31-27} = 0b11110;
177     let Inst{25} = 0;
178     let Inst{24-21} = opcod;
179     let Inst{20} = ?; // The S bit.
180     let Inst{19-16} = 0b1111; // Rn
181     let Inst{15} = 0;
182   }
183   // register
184   def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
185               opc, ".w\t$dst, $src",
186                [(set GPR:$dst, (opnode GPR:$src))]> {
187     let Inst{31-27} = 0b11101;
188     let Inst{26-25} = 0b01;
189     let Inst{24-21} = opcod;
190     let Inst{20} = ?; // The S bit.
191     let Inst{19-16} = 0b1111; // Rn
192     let Inst{14-12} = 0b000; // imm3
193     let Inst{7-6} = 0b00; // imm2
194     let Inst{5-4} = 0b00; // type
195   }
196   // shifted register
197   def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
198               opc, ".w\t$dst, $src",
199               [(set GPR:$dst, (opnode t2_so_reg:$src))]> {
200     let Inst{31-27} = 0b11101;
201     let Inst{26-25} = 0b01;
202     let Inst{24-21} = opcod;
203     let Inst{20} = ?; // The S bit.
204     let Inst{19-16} = 0b1111; // Rn
205   }
206}
207
208/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
209//  binary operation that produces a value. These are predicable and can be
210/// changed to modify CPSR.
211multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
212                       bit Commutable = 0, string wide =""> {
213   // shifted imm
214   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
215                 opc, "\t$dst, $lhs, $rhs",
216                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
217     let Inst{31-27} = 0b11110;
218     let Inst{25} = 0;
219     let Inst{24-21} = opcod;
220     let Inst{20} = ?; // The S bit.
221     let Inst{15} = 0;
222   }
223   // register
224   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
225                 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
226                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
227     let isCommutable = Commutable;
228     let Inst{31-27} = 0b11101;
229     let Inst{26-25} = 0b01;
230     let Inst{24-21} = opcod;
231     let Inst{20} = ?; // The S bit.
232     let Inst{14-12} = 0b000; // imm3
233     let Inst{7-6} = 0b00; // imm2
234     let Inst{5-4} = 0b00; // type
235   }
236   // shifted register
237   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
238                 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
239                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
240     let Inst{31-27} = 0b11101;
241     let Inst{26-25} = 0b01;
242     let Inst{24-21} = opcod;
243     let Inst{20} = ?; // The S bit.
244   }
245}
246
247/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
248//  the ".w" prefix to indicate that they are wide.
249multiclass T2I_bin_w_irs<bits<4> opcod, string opc, PatFrag opnode,
250                         bit Commutable = 0> :
251    T2I_bin_irs<opcod, opc, opnode, Commutable, ".w">;
252
253/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
254/// reversed. It doesn't define the 'rr' form since it's handled by its
255/// T2I_bin_irs counterpart.
256multiclass T2I_rbin_is<bits<4> opcod, string opc, PatFrag opnode> {
257   // shifted imm
258   def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
259                opc, ".w\t$dst, $rhs, $lhs",
260                [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
261     let Inst{31-27} = 0b11110;
262     let Inst{25} = 0;
263     let Inst{24-21} = opcod;
264     let Inst{20} = 0; // The S bit.
265     let Inst{15} = 0;
266   }
267   // shifted register
268   def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
269                opc, "\t$dst, $rhs, $lhs",
270                [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
271     let Inst{31-27} = 0b11101;
272     let Inst{26-25} = 0b01;
273     let Inst{24-21} = opcod;
274     let Inst{20} = 0; // The S bit.
275   }
276}
277
278/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
279/// instruction modifies the CPSR register.
280let Defs = [CPSR] in {
281multiclass T2I_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
282                         bit Commutable = 0> {
283   // shifted imm
284   def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
285                !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
286                [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
287     let Inst{31-27} = 0b11110;
288     let Inst{25} = 0;
289     let Inst{24-21} = opcod;
290     let Inst{20} = 1; // The S bit.
291     let Inst{15} = 0;
292   }
293   // register
294   def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
295                !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
296                [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
297     let isCommutable = Commutable;
298     let Inst{31-27} = 0b11101;
299     let Inst{26-25} = 0b01;
300     let Inst{24-21} = opcod;
301     let Inst{20} = 1; // The S bit.
302     let Inst{14-12} = 0b000; // imm3
303     let Inst{7-6} = 0b00; // imm2
304     let Inst{5-4} = 0b00; // type
305   }
306   // shifted register
307   def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
308                !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
309                [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
310     let Inst{31-27} = 0b11101;
311     let Inst{26-25} = 0b01;
312     let Inst{24-21} = opcod;
313     let Inst{20} = 1; // The S bit.
314   }
315}
316}
317
318/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
319/// patterns for a binary operation that produces a value.
320multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
321                          bit Commutable = 0> {
322   // shifted imm
323   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
324                 opc, ".w\t$dst, $lhs, $rhs",
325                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
326     let Inst{31-27} = 0b11110;
327     let Inst{25} = 0;
328     let Inst{24} = 1;
329     let Inst{23-21} = op23_21;
330     let Inst{20} = 0; // The S bit.
331     let Inst{15} = 0;
332   }
333   // 12-bit imm
334   def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
335                   !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
336                   [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
337     let Inst{31-27} = 0b11110;
338     let Inst{25} = 1;
339     let Inst{24} = 0;
340     let Inst{23-21} = op23_21;
341     let Inst{20} = 0; // The S bit.
342     let Inst{15} = 0;
343   }
344   // register
345   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
346                 opc, ".w\t$dst, $lhs, $rhs",
347                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
348     let isCommutable = Commutable;
349     let Inst{31-27} = 0b11101;
350     let Inst{26-25} = 0b01;
351     let Inst{24} = 1;
352     let Inst{23-21} = op23_21;
353     let Inst{20} = 0; // The S bit.
354     let Inst{14-12} = 0b000; // imm3
355     let Inst{7-6} = 0b00; // imm2
356     let Inst{5-4} = 0b00; // type
357   }
358   // shifted register
359   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
360                 opc, ".w\t$dst, $lhs, $rhs",
361                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
362     let Inst{31-27} = 0b11101;
363     let Inst{26-25} = 0b01;
364     let Inst{24} = 1;
365     let Inst{23-21} = op23_21;
366     let Inst{20} = 0; // The S bit.
367   }
368}
369
370/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
371/// for a binary operation that produces a value and use the carry
372/// bit. It's not predicable.
373let Uses = [CPSR] in {
374multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
375                             bit Commutable = 0> {
376   // shifted imm
377   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
378                 opc, "\t$dst, $lhs, $rhs",
379                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
380                 Requires<[IsThumb2]> {
381     let Inst{31-27} = 0b11110;
382     let Inst{25} = 0;
383     let Inst{24-21} = opcod;
384     let Inst{20} = 0; // The S bit.
385     let Inst{15} = 0;
386   }
387   // register
388   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
389                 opc, ".w\t$dst, $lhs, $rhs",
390                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
391                 Requires<[IsThumb2]> {
392     let isCommutable = Commutable;
393     let Inst{31-27} = 0b11101;
394     let Inst{26-25} = 0b01;
395     let Inst{24-21} = opcod;
396     let Inst{20} = 0; // The S bit.
397     let Inst{14-12} = 0b000; // imm3
398     let Inst{7-6} = 0b00; // imm2
399     let Inst{5-4} = 0b00; // type
400   }
401   // shifted register
402   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
403                 opc, ".w\t$dst, $lhs, $rhs",
404                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
405                 Requires<[IsThumb2]> {
406     let Inst{31-27} = 0b11101;
407     let Inst{26-25} = 0b01;
408     let Inst{24-21} = opcod;
409     let Inst{20} = 0; // The S bit.
410   }
411}
412
413// Carry setting variants
414let Defs = [CPSR] in {
415multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
416                               bit Commutable = 0> {
417   // shifted imm
418   def Sri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
419                  opc, "\t$dst, $lhs, $rhs",
420                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
421                  Requires<[IsThumb2]> {
422     let Inst{31-27} = 0b11110;
423     let Inst{25} = 0;
424     let Inst{24-21} = opcod;
425     let Inst{20} = 1; // The S bit.
426     let Inst{15} = 0;
427   }
428   // register
429   def Srr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
430                  opc, ".w\t$dst, $lhs, $rhs",
431                  [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
432                  Requires<[IsThumb2]> {
433     let isCommutable = Commutable;
434     let Inst{31-27} = 0b11101;
435     let Inst{26-25} = 0b01;
436     let Inst{24-21} = opcod;
437     let Inst{20} = 1; // The S bit.
438     let Inst{14-12} = 0b000; // imm3
439     let Inst{7-6} = 0b00; // imm2
440     let Inst{5-4} = 0b00; // type
441   }
442   // shifted register
443   def Srs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
444                  opc, ".w\t$dst, $lhs, $rhs",
445                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
446                  Requires<[IsThumb2]> {
447     let Inst{31-27} = 0b11101;
448     let Inst{26-25} = 0b01;
449     let Inst{24-21} = opcod;
450     let Inst{20} = 1; // The S bit.
451   }
452}
453}
454}
455
456/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
457let Defs = [CPSR] in {
458multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
459   // shifted imm
460   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
461                 IIC_iALUi,
462                 !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"),
463                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
464     let Inst{31-27} = 0b11110;
465     let Inst{25} = 0;
466     let Inst{24-21} = opcod;
467     let Inst{20} = 1; // The S bit.
468     let Inst{15} = 0;
469   }
470   // shifted register
471   def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
472                 IIC_iALUsi,
473                 !strconcat(opc, "${s}\t$dst, $rhs, $lhs"),
474                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
475     let Inst{31-27} = 0b11101;
476     let Inst{26-25} = 0b01;
477     let Inst{24-21} = opcod;
478     let Inst{20} = 1; // The S bit.
479   }
480}
481}
482
483/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
484//  rotate operation that produces a value.
485multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
486   // 5-bit imm
487   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
488                 opc, ".w\t$dst, $lhs, $rhs",
489                 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]> {
490     let Inst{31-27} = 0b11101;
491     let Inst{26-21} = 0b010010;
492     let Inst{19-16} = 0b1111; // Rn
493     let Inst{5-4} = opcod;
494   }
495   // register
496   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr,
497                 opc, ".w\t$dst, $lhs, $rhs",
498                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
499     let Inst{31-27} = 0b11111;
500     let Inst{26-23} = 0b0100;
501     let Inst{22-21} = opcod;
502     let Inst{15-12} = 0b1111;
503     let Inst{7-4} = 0b0000;
504   }
505}
506
507/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
508/// patterns. Similar to T2I_bin_irs except the instruction does not produce
509/// a explicit result, only implicitly set CPSR.
510let Defs = [CPSR] in {
511multiclass T2I_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
512   // shifted imm
513   def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
514                opc, ".w\t$lhs, $rhs",
515                [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
516     let Inst{31-27} = 0b11110;
517     let Inst{25} = 0;
518     let Inst{24-21} = opcod;
519     let Inst{20} = 1; // The S bit.
520     let Inst{15} = 0;
521     let Inst{11-8} = 0b1111; // Rd
522   }
523   // register
524   def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
525                opc, ".w\t$lhs, $rhs",
526                [(opnode GPR:$lhs, GPR:$rhs)]> {
527     let Inst{31-27} = 0b11101;
528     let Inst{26-25} = 0b01;
529     let Inst{24-21} = opcod;
530     let Inst{20} = 1; // The S bit.
531     let Inst{14-12} = 0b000; // imm3
532     let Inst{11-8} = 0b1111; // Rd
533     let Inst{7-6} = 0b00; // imm2
534     let Inst{5-4} = 0b00; // type
535   }
536   // shifted register
537   def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
538                opc, ".w\t$lhs, $rhs",
539                [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
540     let Inst{31-27} = 0b11101;
541     let Inst{26-25} = 0b01;
542     let Inst{24-21} = opcod;
543     let Inst{20} = 1; // The S bit.
544     let Inst{11-8} = 0b1111; // Rd
545   }
546}
547}
548
549/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
550multiclass T2I_ld<bit signed, bits<2> opcod, string opc, PatFrag opnode> {
551  def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
552                   opc, ".w\t$dst, $addr",
553                   [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
554    let Inst{31-27} = 0b11111;
555    let Inst{26-25} = 0b00;
556    let Inst{24} = signed;
557    let Inst{23} = 1;
558    let Inst{22-21} = opcod;
559    let Inst{20} = 1; // load
560  }
561  def i8  : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
562                   opc, "\t$dst, $addr",
563                   [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
564    let Inst{31-27} = 0b11111;
565    let Inst{26-25} = 0b00;
566    let Inst{24} = signed;
567    let Inst{23} = 0;
568    let Inst{22-21} = opcod;
569    let Inst{20} = 1; // load
570    let Inst{11} = 1;
571    // Offset: index==TRUE, wback==FALSE
572    let Inst{10} = 1; // The P bit.
573    let Inst{8} = 0; // The W bit.
574  }
575  def s   : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
576                   opc, ".w\t$dst, $addr",
577                   [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
578    let Inst{31-27} = 0b11111;
579    let Inst{26-25} = 0b00;
580    let Inst{24} = signed;
581    let Inst{23} = 0;
582    let Inst{22-21} = opcod;
583    let Inst{20} = 1; // load
584    let Inst{11-6} = 0b000000;
585  }
586  def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
587                   opc, ".w\t$dst, $addr",
588                   [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
589    let isReMaterializable = 1;
590    let Inst{31-27} = 0b11111;
591    let Inst{26-25} = 0b00;
592    let Inst{24} = signed;
593    let Inst{23} = ?; // add = (U == '1')
594    let Inst{22-21} = opcod;
595    let Inst{20} = 1; // load
596    let Inst{19-16} = 0b1111; // Rn
597  }
598}
599
600/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
601multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
602  def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
603                   opc, ".w\t$src, $addr",
604                   [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
605    let Inst{31-27} = 0b11111;
606    let Inst{26-23} = 0b0001;
607    let Inst{22-21} = opcod;
608    let Inst{20} = 0; // !load
609  }
610  def i8  : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
611                   opc, "\t$src, $addr",
612                   [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
613    let Inst{31-27} = 0b11111;
614    let Inst{26-23} = 0b0000;
615    let Inst{22-21} = opcod;
616    let Inst{20} = 0; // !load
617    let Inst{11} = 1;
618    // Offset: index==TRUE, wback==FALSE
619    let Inst{10} = 1; // The P bit.
620    let Inst{8} = 0; // The W bit.
621  }
622  def s   : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
623                   opc, ".w\t$src, $addr",
624                   [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
625    let Inst{31-27} = 0b11111;
626    let Inst{26-23} = 0b0000;
627    let Inst{22-21} = opcod;
628    let Inst{20} = 0; // !load
629    let Inst{11-6} = 0b000000;
630  }
631}
632
633/// T2I_picld - Defines the PIC load pattern.
634class T2I_picld<string opc, PatFrag opnode> :
635      T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi,
636          !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr",
637          [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
638
639/// T2I_picst - Defines the PIC store pattern.
640class T2I_picst<string opc, PatFrag opnode> :
641      T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer,
642          !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr",
643          [(opnode GPR:$src, addrmodepc:$addr)]>;
644
645
646/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
647/// register and one whose operand is a register rotated by 8/16/24.
648multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
649  def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
650                  opc, ".w\t$dst, $src",
651                 [(set GPR:$dst, (opnode GPR:$src))]> {
652     let Inst{31-27} = 0b11111;
653     let Inst{26-23} = 0b0100;
654     let Inst{22-20} = opcod;
655     let Inst{19-16} = 0b1111; // Rn
656     let Inst{15-12} = 0b1111;
657     let Inst{7} = 1;
658     let Inst{5-4} = 0b00; // rotate
659   }
660  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
661                  opc, ".w\t$dst, $src, ror $rot",
662                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
663     let Inst{31-27} = 0b11111;
664     let Inst{26-23} = 0b0100;
665     let Inst{22-20} = opcod;
666     let Inst{19-16} = 0b1111; // Rn
667     let Inst{15-12} = 0b1111;
668     let Inst{7} = 1;
669     let Inst{5-4} = {?,?}; // rotate
670   }
671}
672
673/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
674/// register and one whose operand is a register rotated by 8/16/24.
675multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
676  def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
677                  opc, "\t$dst, $LHS, $RHS",
678                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]> {
679     let Inst{31-27} = 0b11111;
680     let Inst{26-23} = 0b0100;
681     let Inst{22-20} = opcod;
682     let Inst{15-12} = 0b1111;
683     let Inst{7} = 1;
684     let Inst{5-4} = 0b00; // rotate
685   }
686  def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
687                  IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
688                  [(set GPR:$dst, (opnode GPR:$LHS,
689                                          (rotr GPR:$RHS, rot_imm:$rot)))]> {
690     let Inst{31-27} = 0b11111;
691     let Inst{26-23} = 0b0100;
692     let Inst{22-20} = opcod;
693     let Inst{15-12} = 0b1111;
694     let Inst{7} = 1;
695     let Inst{5-4} = {?,?}; // rotate
696   }
697}
698
699//===----------------------------------------------------------------------===//
700// Instructions
701//===----------------------------------------------------------------------===//
702
703//===----------------------------------------------------------------------===//
704//  Miscellaneous Instructions.
705//
706
707// LEApcrel - Load a pc-relative address into a register without offending the
708// assembler.
709def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
710                      "adr$p.w\t$dst, #$label", []> {
711  let Inst{31-27} = 0b11110;
712  let Inst{25-24} = 0b10;
713  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
714  let Inst{22} = 0;
715  let Inst{20} = 0;
716  let Inst{19-16} = 0b1111; // Rn
717  let Inst{15} = 0;
718}
719def t2LEApcrelJT : T2XI<(outs GPR:$dst),
720                        (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
721                        "adr$p.w\t$dst, #${label}_${id}", []> {
722  let Inst{31-27} = 0b11110;
723  let Inst{25-24} = 0b10;
724  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
725  let Inst{22} = 0;
726  let Inst{20} = 0;
727  let Inst{19-16} = 0b1111; // Rn
728  let Inst{15} = 0;
729}
730
731// ADD r, sp, {so_imm|i12}
732def t2ADDrSPi   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
733                        IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
734  let Inst{31-27} = 0b11110;
735  let Inst{25} = 0;
736  let Inst{24-21} = 0b1000;
737  let Inst{20} = ?; // The S bit.
738  let Inst{19-16} = 0b1101; // Rn = sp
739  let Inst{15} = 0;
740}
741def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
742                       IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
743  let Inst{31-27} = 0b11110;
744  let Inst{25} = 1;
745  let Inst{24-21} = 0b0000;
746  let Inst{20} = 0; // The S bit.
747  let Inst{19-16} = 0b1101; // Rn = sp
748  let Inst{15} = 0;
749}
750
751// ADD r, sp, so_reg
752def t2ADDrSPs   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
753                        IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
754  let Inst{31-27} = 0b11101;
755  let Inst{26-25} = 0b01;
756  let Inst{24-21} = 0b1000;
757  let Inst{20} = ?; // The S bit.
758  let Inst{19-16} = 0b1101; // Rn = sp
759  let Inst{15} = 0;
760}
761
762// SUB r, sp, {so_imm|i12}
763def t2SUBrSPi   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
764                        IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
765  let Inst{31-27} = 0b11110;
766  let Inst{25} = 0;
767  let Inst{24-21} = 0b1101;
768  let Inst{20} = ?; // The S bit.
769  let Inst{19-16} = 0b1101; // Rn = sp
770  let Inst{15} = 0;
771}
772def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
773                       IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
774  let Inst{31-27} = 0b11110;
775  let Inst{25} = 1;
776  let Inst{24-21} = 0b0101;
777  let Inst{20} = 0; // The S bit.
778  let Inst{19-16} = 0b1101; // Rn = sp
779  let Inst{15} = 0;
780}
781
782// SUB r, sp, so_reg
783def t2SUBrSPs   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
784                       IIC_iALUsi,
785                       "sub", "\t$dst, $sp, $rhs", []> {
786  let Inst{31-27} = 0b11101;
787  let Inst{26-25} = 0b01;
788  let Inst{24-21} = 0b1101;
789  let Inst{20} = ?; // The S bit.
790  let Inst{19-16} = 0b1101; // Rn = sp
791  let Inst{15} = 0;
792}
793
794// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
795let usesCustomInserter = 1 in { // Expanded after instruction selection.
796def t2SUBrSPi_   : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
797                   NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
798def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
799                   NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
800def t2SUBrSPs_   : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
801                   NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
802} // usesCustomInserter
803
804
805//===----------------------------------------------------------------------===//
806//  Load / store Instructions.
807//
808
809// Load
810let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1  in
811defm t2LDR   : T2I_ld<0, 0b10, "ldr",  UnOpFrag<(load node:$Src)>>;
812
813// Loads with zero extension
814defm t2LDRH  : T2I_ld<0, 0b01, "ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
815defm t2LDRB  : T2I_ld<0, 0b00, "ldrb", UnOpFrag<(zextloadi8  node:$Src)>>;
816
817// Loads with sign extension
818defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
819defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", UnOpFrag<(sextloadi8  node:$Src)>>;
820
821let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
822// Load doubleword
823def t2LDRDi8  : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
824                        (ins t2addrmode_imm8s4:$addr),
825                        IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
826def t2LDRDpci : T2Ii8s4<?, ?, 1, (outs GPR:$dst1, GPR:$dst2),
827                        (ins i32imm:$addr), IIC_iLoadi,
828                       "ldrd", "\t$dst1, $addr", []> {
829  let Inst{19-16} = 0b1111; // Rn
830}
831}
832
833// zextload i1 -> zextload i8
834def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
835            (t2LDRBi12  t2addrmode_imm12:$addr)>;
836def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
837            (t2LDRBi8   t2addrmode_imm8:$addr)>;
838def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
839            (t2LDRBs    t2addrmode_so_reg:$addr)>;
840def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
841            (t2LDRBpci  tconstpool:$addr)>;
842
843// extload -> zextload
844// FIXME: Reduce the number of patterns by legalizing extload to zextload
845// earlier?
846def : T2Pat<(extloadi1  t2addrmode_imm12:$addr),
847            (t2LDRBi12  t2addrmode_imm12:$addr)>;
848def : T2Pat<(extloadi1  t2addrmode_imm8:$addr),
849            (t2LDRBi8   t2addrmode_imm8:$addr)>;
850def : T2Pat<(extloadi1  t2addrmode_so_reg:$addr),
851            (t2LDRBs    t2addrmode_so_reg:$addr)>;
852def : T2Pat<(extloadi1  (ARMWrapper tconstpool:$addr)),
853            (t2LDRBpci  tconstpool:$addr)>;
854
855def : T2Pat<(extloadi8  t2addrmode_imm12:$addr),
856            (t2LDRBi12  t2addrmode_imm12:$addr)>;
857def : T2Pat<(extloadi8  t2addrmode_imm8:$addr),
858            (t2LDRBi8   t2addrmode_imm8:$addr)>;
859def : T2Pat<(extloadi8  t2addrmode_so_reg:$addr),
860            (t2LDRBs    t2addrmode_so_reg:$addr)>;
861def : T2Pat<(extloadi8  (ARMWrapper tconstpool:$addr)),
862            (t2LDRBpci  tconstpool:$addr)>;
863
864def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
865            (t2LDRHi12  t2addrmode_imm12:$addr)>;
866def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
867            (t2LDRHi8   t2addrmode_imm8:$addr)>;
868def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
869            (t2LDRHs    t2addrmode_so_reg:$addr)>;
870def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
871            (t2LDRHpci  tconstpool:$addr)>;
872
873// Indexed loads
874let mayLoad = 1 in {
875def t2LDR_PRE  : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
876                            (ins t2addrmode_imm8:$addr),
877                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
878                            "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
879                            []>;
880
881def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
882                            (ins GPR:$base, t2am_imm8_offset:$offset),
883                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
884                          "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
885                            []>;
886
887def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
888                            (ins t2addrmode_imm8:$addr),
889                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
890                            "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
891                            []>;
892def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
893                            (ins GPR:$base, t2am_imm8_offset:$offset),
894                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
895                         "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
896                            []>;
897
898def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
899                            (ins t2addrmode_imm8:$addr),
900                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
901                            "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
902                            []>;
903def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
904                            (ins GPR:$base, t2am_imm8_offset:$offset),
905                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
906                         "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
907                            []>;
908
909def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
910                            (ins t2addrmode_imm8:$addr),
911                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
912                            "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
913                            []>;
914def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
915                            (ins GPR:$base, t2am_imm8_offset:$offset),
916                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
917                        "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
918                            []>;
919
920def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
921                            (ins t2addrmode_imm8:$addr),
922                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
923                            "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
924                            []>;
925def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
926                            (ins GPR:$base, t2am_imm8_offset:$offset),
927                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
928                        "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
929                            []>;
930}
931
932// Store
933defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
934defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
935defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
936
937// Store doubleword
938let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
939def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
940                       (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
941               IIC_iStorer, "strd", "\t$src1, $addr", []>;
942
943// Indexed stores
944def t2STR_PRE  : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
945                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
946                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
947                         "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
948             [(set GPR:$base_wb,
949                   (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
950
951def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
952                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
953                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
954                          "str", "\t$src, [$base], $offset", "$base = $base_wb",
955             [(set GPR:$base_wb,
956                  (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
957
958def t2STRH_PRE  : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
959                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
960                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
961                        "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
962        [(set GPR:$base_wb,
963              (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
964
965def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
966                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
967                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
968                         "strh", "\t$src, [$base], $offset", "$base = $base_wb",
969       [(set GPR:$base_wb,
970             (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
971
972def t2STRB_PRE  : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
973                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
974                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
975                        "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
976         [(set GPR:$base_wb,
977               (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
978
979def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
980                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
981                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
982                         "strb", "\t$src, [$base], $offset", "$base = $base_wb",
983        [(set GPR:$base_wb,
984              (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
985
986
987// FIXME: ldrd / strd pre / post variants
988
989//===----------------------------------------------------------------------===//
990//  Load / store multiple Instructions.
991//
992
993let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
994def t2LDM : T2XI<(outs),
995                 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
996             IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
997  let Inst{31-27} = 0b11101;
998  let Inst{26-25} = 0b00;
999  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1000  let Inst{22} = 0;
1001  let Inst{21} = ?; // The W bit.
1002  let Inst{20} = 1; // Load
1003}
1004
1005let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1006def t2STM : T2XI<(outs),
1007                 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1008            IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1009  let Inst{31-27} = 0b11101;
1010  let Inst{26-25} = 0b00;
1011  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1012  let Inst{22} = 0;
1013  let Inst{21} = ?; // The W bit.
1014  let Inst{20} = 0; // Store
1015}
1016
1017//===----------------------------------------------------------------------===//
1018//  Move Instructions.
1019//
1020
1021let neverHasSideEffects = 1 in
1022def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1023                   "mov", ".w\t$dst, $src", []> {
1024  let Inst{31-27} = 0b11101;
1025  let Inst{26-25} = 0b01;
1026  let Inst{24-21} = 0b0010;
1027  let Inst{20} = ?; // The S bit.
1028  let Inst{19-16} = 0b1111; // Rn
1029  let Inst{14-12} = 0b000;
1030  let Inst{7-4} = 0b0000;
1031}
1032
1033// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1034let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1035def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1036                   "mov", ".w\t$dst, $src",
1037                   [(set GPR:$dst, t2_so_imm:$src)]> {
1038  let Inst{31-27} = 0b11110;
1039  let Inst{25} = 0;
1040  let Inst{24-21} = 0b0010;
1041  let Inst{20} = ?; // The S bit.
1042  let Inst{19-16} = 0b1111; // Rn
1043  let Inst{15} = 0;
1044}
1045
1046let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1047def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1048                   "movw", "\t$dst, $src",
1049                   [(set GPR:$dst, imm0_65535:$src)]> {
1050  let Inst{31-27} = 0b11110;
1051  let Inst{25} = 1;
1052  let Inst{24-21} = 0b0010;
1053  let Inst{20} = 0; // The S bit.
1054  let Inst{15} = 0;
1055}
1056
1057let Constraints = "$src = $dst" in
1058def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
1059                    "movt", "\t$dst, $imm",
1060                    [(set GPR:$dst,
1061                          (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]> {
1062  let Inst{31-27} = 0b11110;
1063  let Inst{25} = 1;
1064  let Inst{24-21} = 0b0110;
1065  let Inst{20} = 0; // The S bit.
1066  let Inst{15} = 0;
1067}
1068
1069def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
1070
1071//===----------------------------------------------------------------------===//
1072//  Extend Instructions.
1073//
1074
1075// Sign extenders
1076
1077defm t2SXTB  : T2I_unary_rrot<0b100, "sxtb",
1078                              UnOpFrag<(sext_inreg node:$Src, i8)>>;
1079defm t2SXTH  : T2I_unary_rrot<0b000, "sxth",
1080                              UnOpFrag<(sext_inreg node:$Src, i16)>>;
1081
1082defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
1083                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1084defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
1085                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1086
1087// TODO: SXT(A){B|H}16
1088
1089// Zero extenders
1090
1091let AddedComplexity = 16 in {
1092defm t2UXTB   : T2I_unary_rrot<0b101, "uxtb",
1093                               UnOpFrag<(and node:$Src, 0x000000FF)>>;
1094defm t2UXTH   : T2I_unary_rrot<0b001, "uxth",
1095                               UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1096defm t2UXTB16 : T2I_unary_rrot<0b011, "uxtb16",
1097                               UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1098
1099def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1100            (t2UXTB16r_rot GPR:$Src, 24)>;
1101def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1102            (t2UXTB16r_rot GPR:$Src, 8)>;
1103
1104defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
1105                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1106defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
1107                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1108}
1109
1110//===----------------------------------------------------------------------===//
1111//  Arithmetic Instructions.
1112//
1113
1114defm t2ADD  : T2I_bin_ii12rs<0b000, "add",
1115                             BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1116defm t2SUB  : T2I_bin_ii12rs<0b101, "sub",
1117                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1118
1119// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1120defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1121                             BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1122defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1123                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1124
1125defm t2ADC  : T2I_adde_sube_irs<0b1010, "adc",
1126                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1127defm t2SBC  : T2I_adde_sube_irs<0b1011, "sbc",
1128                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1129defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adcs",
1130                          BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1131defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbcs",
1132                          BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1133
1134// RSB
1135defm t2RSB  : T2I_rbin_is   <0b1110, "rsb",
1136                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1137defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1138                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1139
1140// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1141let AddedComplexity = 1 in
1142def : T2Pat<(add       GPR:$src, imm0_255_neg:$imm),
1143            (t2SUBri   GPR:$src, imm0_255_neg:$imm)>;
1144def : T2Pat<(add       GPR:$src, t2_so_imm_neg:$imm),
1145            (t2SUBri   GPR:$src, t2_so_imm_neg:$imm)>;
1146def : T2Pat<(add       GPR:$src, imm0_4095_neg:$imm),
1147            (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1148
1149// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1150// And Miscellaneous operations -- for disassembly only
1151class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc>
1152  : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, opc,
1153        "\t$dst, $a, $b", [/* For disassembly only; pattern left blank */]> {
1154  let Inst{31-27} = 0b11111;
1155  let Inst{26-23} = 0b0101;
1156  let Inst{22-20} = op22_20;
1157  let Inst{15-12} = 0b1111;
1158  let Inst{7-4} = op7_4;
1159}
1160
1161// Saturating add/subtract -- for disassembly only
1162
1163def t2QADD    : T2I_pam<0b000, 0b1000, "qadd">;
1164def t2QADD16  : T2I_pam<0b001, 0b0001, "qadd16">;
1165def t2QADD8   : T2I_pam<0b000, 0b0001, "qadd8">;
1166def t2QASX    : T2I_pam<0b010, 0b0001, "qasx">;
1167def t2QDADD   : T2I_pam<0b000, 0b1001, "qdadd">;
1168def t2QDSUB   : T2I_pam<0b000, 0b1011, "qdsub">;
1169def t2QSAX    : T2I_pam<0b110, 0b0001, "qsax">;
1170def t2QSUB    : T2I_pam<0b000, 0b1010, "qsub">;
1171def t2QSUB16  : T2I_pam<0b101, 0b0001, "qsub16">;
1172def t2QSUB8   : T2I_pam<0b100, 0b0001, "qsub8">;
1173def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1174def t2UQADD8  : T2I_pam<0b000, 0b0101, "uqadd8">;
1175def t2UQASX   : T2I_pam<0b010, 0b0101, "uqasx">;
1176def t2UQSAX   : T2I_pam<0b110, 0b0101, "uqsax">;
1177def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1178def t2UQSUB8  : T2I_pam<0b100, 0b0101, "uqsub8">;
1179
1180// Signed/Unsigned add/subtract -- for disassembly only
1181
1182def t2SASX    : T2I_pam<0b010, 0b0000, "sasx">;
1183def t2SADD16  : T2I_pam<0b001, 0b0000, "sadd16">;
1184def t2SADD8   : T2I_pam<0b000, 0b0000, "sadd8">;
1185def t2SSAX    : T2I_pam<0b110, 0b0000, "ssax">;
1186def t2SSUB16  : T2I_pam<0b101, 0b0000, "ssub16">;
1187def t2SSUB8   : T2I_pam<0b100, 0b0000, "ssub8">;
1188def t2UASX    : T2I_pam<0b010, 0b0100, "uasx">;
1189def t2UADD16  : T2I_pam<0b001, 0b0100, "uadd16">;
1190def t2UADD8   : T2I_pam<0b000, 0b0100, "uadd8">;
1191def t2USAX    : T2I_pam<0b110, 0b0100, "usax">;
1192def t2USUB16  : T2I_pam<0b101, 0b0100, "usub16">;
1193def t2USUB8   : T2I_pam<0b100, 0b0100, "usub8">;
1194
1195// Signed/Unsigned halving add/subtract -- for disassembly only
1196
1197def t2SHASX   : T2I_pam<0b010, 0b0010, "shasx">;
1198def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1199def t2SHADD8  : T2I_pam<0b000, 0b0010, "shadd8">;
1200def t2SHSAX   : T2I_pam<0b110, 0b0010, "shsax">;
1201def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1202def t2SHSUB8  : T2I_pam<0b100, 0b0010, "shsub8">;
1203def t2UHASX   : T2I_pam<0b010, 0b0110, "uhasx">;
1204def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1205def t2UHADD8  : T2I_pam<0b000, 0b0110, "uhadd8">;
1206def t2UHSAX   : T2I_pam<0b110, 0b0110, "uhsax">;
1207def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1208def t2UHSUB8  : T2I_pam<0b100, 0b0110, "uhsub8">;
1209
1210// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1211
1212def t2USAD8   : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1213                        NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1214  let Inst{15-12} = 0b1111;
1215}
1216def t2USADA8  : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst),
1217                        (ins GPR:$a, GPR:$b, GPR:$acc), NoItinerary, "usada8",
1218                        "\t$dst, $a, $b, $acc", []>;
1219
1220// Signed/Unsigned saturate -- for disassembly only
1221
1222def t2SSATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1223                    NoItinerary, "ssat", "\t$dst, $bit_pos, $a, LSL $shamt",
1224                    [/* For disassembly only; pattern left blank */]> {
1225  let Inst{31-27} = 0b11110;
1226  let Inst{25-22} = 0b1100;
1227  let Inst{20} = 0;
1228  let Inst{15} = 0;
1229  let Inst{21} = 0;        // sh = '0'
1230}
1231
1232def t2SSATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1233                    NoItinerary, "ssat", "\t$dst, $bit_pos, $a, ASR $shamt",
1234                    [/* For disassembly only; pattern left blank */]> {
1235  let Inst{31-27} = 0b11110;
1236  let Inst{25-22} = 0b1100;
1237  let Inst{20} = 0;
1238  let Inst{15} = 0;
1239  let Inst{21} = 1;        // sh = '1'
1240}
1241
1242def t2SSAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1243                   "ssat16", "\t$dst, $bit_pos, $a",
1244                   [/* For disassembly only; pattern left blank */]> {
1245  let Inst{31-27} = 0b11110;
1246  let Inst{25-22} = 0b1100;
1247  let Inst{20} = 0;
1248  let Inst{15} = 0;
1249  let Inst{21} = 1;        // sh = '1'
1250  let Inst{14-12} = 0b000; // imm3 = '000'
1251  let Inst{7-6} = 0b00;    // imm2 = '00'
1252}
1253
1254def t2USATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1255                     NoItinerary, "usat", "\t$dst, $bit_pos, $a, LSL $shamt",
1256                     [/* For disassembly only; pattern left blank */]> {
1257  let Inst{31-27} = 0b11110;
1258  let Inst{25-22} = 0b1110;
1259  let Inst{20} = 0;
1260  let Inst{15} = 0;
1261  let Inst{21} = 0;        // sh = '0'
1262}
1263
1264def t2USATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1265                     NoItinerary, "usat", "\t$dst, $bit_pos, $a, ASR $shamt",
1266                     [/* For disassembly only; pattern left blank */]> {
1267  let Inst{31-27} = 0b11110;
1268  let Inst{25-22} = 0b1110;
1269  let Inst{20} = 0;
1270  let Inst{15} = 0;
1271  let Inst{21} = 1;        // sh = '1'
1272}
1273
1274def t2USAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1275                   "usat16", "\t$dst, $bit_pos, $a",
1276                   [/* For disassembly only; pattern left blank */]> {
1277  let Inst{31-27} = 0b11110;
1278  let Inst{25-22} = 0b1110;
1279  let Inst{20} = 0;
1280  let Inst{15} = 0;
1281  let Inst{21} = 1;        // sh = '1'
1282  let Inst{14-12} = 0b000; // imm3 = '000'
1283  let Inst{7-6} = 0b00;    // imm2 = '00'
1284}
1285
1286//===----------------------------------------------------------------------===//
1287//  Shift and rotate Instructions.
1288//
1289
1290defm t2LSL  : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl  node:$LHS, node:$RHS)>>;
1291defm t2LSR  : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl  node:$LHS, node:$RHS)>>;
1292defm t2ASR  : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra  node:$LHS, node:$RHS)>>;
1293defm t2ROR  : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1294
1295let Uses = [CPSR] in {
1296def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1297                   "rrx", "\t$dst, $src",
1298                   [(set GPR:$dst, (ARMrrx GPR:$src))]> {
1299  let Inst{31-27} = 0b11101;
1300  let Inst{26-25} = 0b01;
1301  let Inst{24-21} = 0b0010;
1302  let Inst{20} = ?; // The S bit.
1303  let Inst{19-16} = 0b1111; // Rn
1304  let Inst{14-12} = 0b000;
1305  let Inst{7-4} = 0b0011;
1306}
1307}
1308
1309let Defs = [CPSR] in {
1310def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1311                         "lsrs.w\t$dst, $src, #1",
1312                         [(set GPR:$dst, (ARMsrl_flag GPR:$src))]> {
1313  let Inst{31-27} = 0b11101;
1314  let Inst{26-25} = 0b01;
1315  let Inst{24-21} = 0b0010;
1316  let Inst{20} = 1; // The S bit.
1317  let Inst{19-16} = 0b1111; // Rn
1318  let Inst{5-4} = 0b01; // Shift type.
1319  // Shift amount = Inst{14-12:7-6} = 1.
1320  let Inst{14-12} = 0b000;
1321  let Inst{7-6} = 0b01;
1322}
1323def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1324                         "asrs.w\t$dst, $src, #1",
1325                         [(set GPR:$dst, (ARMsra_flag GPR:$src))]> {
1326  let Inst{31-27} = 0b11101;
1327  let Inst{26-25} = 0b01;
1328  let Inst{24-21} = 0b0010;
1329  let Inst{20} = 1; // The S bit.
1330  let Inst{19-16} = 0b1111; // Rn
1331  let Inst{5-4} = 0b10; // Shift type.
1332  // Shift amount = Inst{14-12:7-6} = 1.
1333  let Inst{14-12} = 0b000;
1334  let Inst{7-6} = 0b01;
1335}
1336}
1337
1338//===----------------------------------------------------------------------===//
1339//  Bitwise Instructions.
1340//
1341
1342defm t2AND  : T2I_bin_w_irs<0b0000, "and",
1343                            BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1344defm t2ORR  : T2I_bin_w_irs<0b0010, "orr",
1345                            BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1346defm t2EOR  : T2I_bin_w_irs<0b0100, "eor",
1347                            BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1348
1349defm t2BIC  : T2I_bin_w_irs<0b0001, "bic",
1350                            BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1351
1352let Constraints = "$src = $dst" in
1353def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1354                IIC_iUNAsi, "bfc", "\t$dst, $imm",
1355                [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]> {
1356  let Inst{31-27} = 0b11110;
1357  let Inst{25} = 1;
1358  let Inst{24-20} = 0b10110;
1359  let Inst{19-16} = 0b1111; // Rn
1360  let Inst{15} = 0;
1361}
1362
1363def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1364                 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1365  let Inst{31-27} = 0b11110;
1366  let Inst{25} = 1;
1367  let Inst{24-20} = 0b10100;
1368  let Inst{15} = 0;
1369}
1370
1371def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1372                 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1373  let Inst{31-27} = 0b11110;
1374  let Inst{25} = 1;
1375  let Inst{24-20} = 0b11100;
1376  let Inst{15} = 0;
1377}
1378
1379// A8.6.18  BFI - Bitfield insert (Encoding T1)
1380// Added for disassembler with the pattern field purposely left blank.
1381// FIXME: Utilize this instruction in codgen.
1382def t2BFI : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1383                IIC_iALUi, "bfi", "\t$dst, $src, $lsb, $width", []> {
1384  let Inst{31-27} = 0b11110;
1385  let Inst{25} = 1;
1386  let Inst{24-20} = 0b10110;
1387  let Inst{15} = 0;
1388}
1389
1390defm t2ORN  : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or  node:$LHS,
1391                          (not node:$RHS))>>;
1392
1393// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1394let AddedComplexity = 1 in
1395defm t2MVN  : T2I_un_irs <0b0011, "mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
1396
1397
1398def : T2Pat<(and     GPR:$src, t2_so_imm_not:$imm),
1399            (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
1400
1401// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1402def : T2Pat<(or      GPR:$src, t2_so_imm_not:$imm),
1403            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
1404            Requires<[IsThumb2]>;
1405
1406def : T2Pat<(t2_so_imm_not:$src),
1407            (t2MVNi t2_so_imm_not:$src)>;
1408
1409//===----------------------------------------------------------------------===//
1410//  Multiply Instructions.
1411//
1412let isCommutable = 1 in
1413def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1414                "mul", "\t$dst, $a, $b",
1415                [(set GPR:$dst, (mul GPR:$a, GPR:$b))]> {
1416  let Inst{31-27} = 0b11111;
1417  let Inst{26-23} = 0b0110;
1418  let Inst{22-20} = 0b000;
1419  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1420  let Inst{7-4} = 0b0000; // Multiply
1421}
1422
1423def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1424		"mla", "\t$dst, $a, $b, $c",
1425		[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]> {
1426  let Inst{31-27} = 0b11111;
1427  let Inst{26-23} = 0b0110;
1428  let Inst{22-20} = 0b000;
1429  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1430  let Inst{7-4} = 0b0000; // Multiply
1431}
1432
1433def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1434		"mls", "\t$dst, $a, $b, $c",
1435                [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]> {
1436  let Inst{31-27} = 0b11111;
1437  let Inst{26-23} = 0b0110;
1438  let Inst{22-20} = 0b000;
1439  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1440  let Inst{7-4} = 0b0001; // Multiply and Subtract
1441}
1442
1443// Extra precision multiplies with low / high results
1444let neverHasSideEffects = 1 in {
1445let isCommutable = 1 in {
1446def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1447                   "smull", "\t$ldst, $hdst, $a, $b", []> {
1448  let Inst{31-27} = 0b11111;
1449  let Inst{26-23} = 0b0111;
1450  let Inst{22-20} = 0b000;
1451  let Inst{7-4} = 0b0000;
1452}
1453
1454def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1455                   "umull", "\t$ldst, $hdst, $a, $b", []> {
1456  let Inst{31-27} = 0b11111;
1457  let Inst{26-23} = 0b0111;
1458  let Inst{22-20} = 0b010;
1459  let Inst{7-4} = 0b0000;
1460}
1461} // isCommutable
1462
1463// Multiply + accumulate
1464def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1465                  "smlal", "\t$ldst, $hdst, $a, $b", []>{
1466  let Inst{31-27} = 0b11111;
1467  let Inst{26-23} = 0b0111;
1468  let Inst{22-20} = 0b100;
1469  let Inst{7-4} = 0b0000;
1470}
1471
1472def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1473                  "umlal", "\t$ldst, $hdst, $a, $b", []>{
1474  let Inst{31-27} = 0b11111;
1475  let Inst{26-23} = 0b0111;
1476  let Inst{22-20} = 0b110;
1477  let Inst{7-4} = 0b0000;
1478}
1479
1480def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1481                  "umaal", "\t$ldst, $hdst, $a, $b", []>{
1482  let Inst{31-27} = 0b11111;
1483  let Inst{26-23} = 0b0111;
1484  let Inst{22-20} = 0b110;
1485  let Inst{7-4} = 0b0110;
1486}
1487} // neverHasSideEffects
1488
1489// Most significant word multiply
1490def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1491                  "smmul", "\t$dst, $a, $b",
1492                  [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]> {
1493  let Inst{31-27} = 0b11111;
1494  let Inst{26-23} = 0b0110;
1495  let Inst{22-20} = 0b101;
1496  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1497  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1498}
1499
1500def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1501                  "smmla", "\t$dst, $a, $b, $c",
1502                  [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]> {
1503  let Inst{31-27} = 0b11111;
1504  let Inst{26-23} = 0b0110;
1505  let Inst{22-20} = 0b101;
1506  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1507  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1508}
1509
1510
1511def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1512                   "smmls", "\t$dst, $a, $b, $c",
1513                   [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]> {
1514  let Inst{31-27} = 0b11111;
1515  let Inst{26-23} = 0b0110;
1516  let Inst{22-20} = 0b110;
1517  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1518  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1519}
1520
1521multiclass T2I_smul<string opc, PatFrag opnode> {
1522  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1523              !strconcat(opc, "bb"), "\t$dst, $a, $b",
1524              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1525                                      (sext_inreg GPR:$b, i16)))]> {
1526    let Inst{31-27} = 0b11111;
1527    let Inst{26-23} = 0b0110;
1528    let Inst{22-20} = 0b001;
1529    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1530    let Inst{7-6} = 0b00;
1531    let Inst{5-4} = 0b00;
1532  }
1533
1534  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1535              !strconcat(opc, "bt"), "\t$dst, $a, $b",
1536              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1537                                      (sra GPR:$b, (i32 16))))]> {
1538    let Inst{31-27} = 0b11111;
1539    let Inst{26-23} = 0b0110;
1540    let Inst{22-20} = 0b001;
1541    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1542    let Inst{7-6} = 0b00;
1543    let Inst{5-4} = 0b01;
1544  }
1545
1546  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1547              !strconcat(opc, "tb"), "\t$dst, $a, $b",
1548              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1549                                      (sext_inreg GPR:$b, i16)))]> {
1550    let Inst{31-27} = 0b11111;
1551    let Inst{26-23} = 0b0110;
1552    let Inst{22-20} = 0b001;
1553    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1554    let Inst{7-6} = 0b00;
1555    let Inst{5-4} = 0b10;
1556  }
1557
1558  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1559              !strconcat(opc, "tt"), "\t$dst, $a, $b",
1560              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1561                                      (sra GPR:$b, (i32 16))))]> {
1562    let Inst{31-27} = 0b11111;
1563    let Inst{26-23} = 0b0110;
1564    let Inst{22-20} = 0b001;
1565    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1566    let Inst{7-6} = 0b00;
1567    let Inst{5-4} = 0b11;
1568  }
1569
1570  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1571              !strconcat(opc, "wb"), "\t$dst, $a, $b",
1572              [(set GPR:$dst, (sra (opnode GPR:$a,
1573                                    (sext_inreg GPR:$b, i16)), (i32 16)))]> {
1574    let Inst{31-27} = 0b11111;
1575    let Inst{26-23} = 0b0110;
1576    let Inst{22-20} = 0b011;
1577    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1578    let Inst{7-6} = 0b00;
1579    let Inst{5-4} = 0b00;
1580  }
1581
1582  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1583              !strconcat(opc, "wt"), "\t$dst, $a, $b",
1584              [(set GPR:$dst, (sra (opnode GPR:$a,
1585                                    (sra GPR:$b, (i32 16))), (i32 16)))]> {
1586    let Inst{31-27} = 0b11111;
1587    let Inst{26-23} = 0b0110;
1588    let Inst{22-20} = 0b011;
1589    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1590    let Inst{7-6} = 0b00;
1591    let Inst{5-4} = 0b01;
1592  }
1593}
1594
1595
1596multiclass T2I_smla<string opc, PatFrag opnode> {
1597  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1598              !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1599              [(set GPR:$dst, (add GPR:$acc,
1600                               (opnode (sext_inreg GPR:$a, i16),
1601                                       (sext_inreg GPR:$b, i16))))]> {
1602    let Inst{31-27} = 0b11111;
1603    let Inst{26-23} = 0b0110;
1604    let Inst{22-20} = 0b001;
1605    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1606    let Inst{7-6} = 0b00;
1607    let Inst{5-4} = 0b00;
1608  }
1609
1610  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1611             !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1612             [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1613                                                   (sra GPR:$b, (i32 16)))))]> {
1614    let Inst{31-27} = 0b11111;
1615    let Inst{26-23} = 0b0110;
1616    let Inst{22-20} = 0b001;
1617    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1618    let Inst{7-6} = 0b00;
1619    let Inst{5-4} = 0b01;
1620  }
1621
1622  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1623              !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1624              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1625                                                 (sext_inreg GPR:$b, i16))))]> {
1626    let Inst{31-27} = 0b11111;
1627    let Inst{26-23} = 0b0110;
1628    let Inst{22-20} = 0b001;
1629    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1630    let Inst{7-6} = 0b00;
1631    let Inst{5-4} = 0b10;
1632  }
1633
1634  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1635              !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1636             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1637                                                   (sra GPR:$b, (i32 16)))))]> {
1638    let Inst{31-27} = 0b11111;
1639    let Inst{26-23} = 0b0110;
1640    let Inst{22-20} = 0b001;
1641    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1642    let Inst{7-6} = 0b00;
1643    let Inst{5-4} = 0b11;
1644  }
1645
1646  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1647              !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1648              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1649                                      (sext_inreg GPR:$b, i16)), (i32 16))))]> {
1650    let Inst{31-27} = 0b11111;
1651    let Inst{26-23} = 0b0110;
1652    let Inst{22-20} = 0b011;
1653    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1654    let Inst{7-6} = 0b00;
1655    let Inst{5-4} = 0b00;
1656  }
1657
1658  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1659              !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1660              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1661                                        (sra GPR:$b, (i32 16))), (i32 16))))]> {
1662    let Inst{31-27} = 0b11111;
1663    let Inst{26-23} = 0b0110;
1664    let Inst{22-20} = 0b011;
1665    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1666    let Inst{7-6} = 0b00;
1667    let Inst{5-4} = 0b01;
1668  }
1669}
1670
1671defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1672defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1673
1674// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
1675def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs GPR:$ldst,GPR:$hdst),
1676           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1677           [/* For disassembly only; pattern left blank */]>;
1678def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs GPR:$ldst,GPR:$hdst),
1679           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1680           [/* For disassembly only; pattern left blank */]>;
1681def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs GPR:$ldst,GPR:$hdst),
1682           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1683           [/* For disassembly only; pattern left blank */]>;
1684def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs GPR:$ldst,GPR:$hdst),
1685           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1686           [/* For disassembly only; pattern left blank */]>;
1687
1688// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1689// These are for disassembly only.
1690
1691def t2SMUAD   : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1692                        IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
1693  let Inst{15-12} = 0b1111;
1694}
1695def t2SMUADX  : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1696                        IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
1697  let Inst{15-12} = 0b1111;
1698}
1699def t2SMUSD   : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1700                        IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
1701  let Inst{15-12} = 0b1111;
1702}
1703def t2SMUSDX  : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1704                        IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
1705  let Inst{15-12} = 0b1111;
1706}
1707def t2SMLAD   : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst),
1708                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlad",
1709                        "\t$dst, $a, $b, $acc", []>;
1710def t2SMLADX  : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst),
1711                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smladx",
1712                        "\t$dst, $a, $b, $acc", []>;
1713def t2SMLSD   : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst),
1714                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsd",
1715                        "\t$dst, $a, $b, $acc", []>;
1716def t2SMLSDX  : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst),
1717                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsdx",
1718                        "\t$dst, $a, $b, $acc", []>;
1719def t2SMLALD  : T2I_mac<1, 0b100, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1720                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlald",
1721                        "\t$ldst, $hdst, $a, $b", []>;
1722def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1723                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaldx",
1724                        "\t$ldst, $hdst, $a, $b", []>;
1725def t2SMLSLD  : T2I_mac<1, 0b101, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1726                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsld",
1727                        "\t$ldst, $hdst, $a, $b", []>;
1728def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1729                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsldx",
1730                        "\t$ldst, $hdst, $a, $b", []>;
1731
1732//===----------------------------------------------------------------------===//
1733//  Misc. Arithmetic Instructions.
1734//
1735
1736class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
1737      InstrItinClass itin, string opc, string asm, list<dag> pattern>
1738  : T2I<oops, iops, itin, opc, asm, pattern> {
1739  let Inst{31-27} = 0b11111;
1740  let Inst{26-22} = 0b01010;
1741  let Inst{21-20} = op1;
1742  let Inst{15-12} = 0b1111;
1743  let Inst{7-6} = 0b10;
1744  let Inst{5-4} = op2;
1745}
1746
1747def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1748                    "clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
1749
1750def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1751                      "rbit", "\t$dst, $src",
1752                      [(set GPR:$dst, (ARMrbit GPR:$src))]>;
1753
1754def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1755                   "rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
1756
1757def t2REV16 : T2I_misc<0b01, 0b01, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1758                       "rev16", ".w\t$dst, $src",
1759                [(set GPR:$dst,
1760                    (or (and (srl GPR:$src, (i32 8)), 0xFF),
1761                        (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1762                            (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1763                                (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
1764
1765def t2REVSH : T2I_misc<0b01, 0b11, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1766                       "revsh", ".w\t$dst, $src",
1767                 [(set GPR:$dst,
1768                    (sext_inreg
1769                      (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1770                          (shl GPR:$src, (i32 8))), i16))]>;
1771
1772def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1773                  IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1774                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1775                                      (and (shl GPR:$src2, (i32 imm:$shamt)),
1776                                           0xFFFF0000)))]> {
1777  let Inst{31-27} = 0b11101;
1778  let Inst{26-25} = 0b01;
1779  let Inst{24-20} = 0b01100;
1780  let Inst{5} = 0; // BT form
1781  let Inst{4} = 0;
1782}
1783
1784// Alternate cases for PKHBT where identities eliminate some nodes.
1785def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1786            (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
1787def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1788            (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1789
1790def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1791                  IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1792                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1793                                      (and (sra GPR:$src2, imm16_31:$shamt),
1794                                           0xFFFF)))]> {
1795  let Inst{31-27} = 0b11101;
1796  let Inst{26-25} = 0b01;
1797  let Inst{24-20} = 0b01100;
1798  let Inst{5} = 1; // TB form
1799  let Inst{4} = 0;
1800}
1801
1802// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
1803// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1804def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1805            (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
1806def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
1807                     (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1808            (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1809
1810//===----------------------------------------------------------------------===//
1811//  Comparison Instructions...
1812//
1813
1814defm t2CMP  : T2I_cmp_irs<0b1101, "cmp",
1815                          BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1816defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
1817                          BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1818
1819//FIXME: Disable CMN, as CCodes are backwards from compare expectations
1820//       Compare-to-zero still works out, just not the relationals
1821//defm t2CMN  : T2I_cmp_irs<0b1000, "cmn",
1822//                          BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1823defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
1824                          BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1825
1826//def : T2Pat<(ARMcmp  GPR:$src, t2_so_imm_neg:$imm),
1827//            (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
1828
1829def : T2Pat<(ARMcmpZ  GPR:$src, t2_so_imm_neg:$imm),
1830            (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
1831
1832defm t2TST  : T2I_cmp_irs<0b0000, "tst",
1833                          BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1834defm t2TEQ  : T2I_cmp_irs<0b0100, "teq",
1835                          BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
1836
1837// A8.6.27  CBNZ, CBZ - Compare and branch on (non)zero.
1838// Short range conditional branch. Looks awesome for loops. Need to figure
1839// out how to use this one.
1840
1841
1842// Conditional moves
1843// FIXME: should be able to write a pattern for ARMcmov, but can't use
1844// a two-value operand where a dag node expects two operands. :(
1845def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
1846                   "mov", ".w\t$dst, $true",
1847      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1848                RegConstraint<"$false = $dst"> {
1849  let Inst{31-27} = 0b11101;
1850  let Inst{26-25} = 0b01;
1851  let Inst{24-21} = 0b0010;
1852  let Inst{20} = 0; // The S bit.
1853  let Inst{19-16} = 0b1111; // Rn
1854  let Inst{14-12} = 0b000;
1855  let Inst{7-4} = 0b0000;
1856}
1857
1858def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
1859                   IIC_iCMOVi, "mov", ".w\t$dst, $true",
1860[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1861                   RegConstraint<"$false = $dst"> {
1862  let Inst{31-27} = 0b11110;
1863  let Inst{25} = 0;
1864  let Inst{24-21} = 0b0010;
1865  let Inst{20} = 0; // The S bit.
1866  let Inst{19-16} = 0b1111; // Rn
1867  let Inst{15} = 0;
1868}
1869
1870class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
1871                   string opc, string asm, list<dag> pattern>
1872  : T2I<oops, iops, itin, opc, asm, pattern> {
1873  let Inst{31-27} = 0b11101;
1874  let Inst{26-25} = 0b01;
1875  let Inst{24-21} = 0b0010;
1876  let Inst{20} = 0; // The S bit.
1877  let Inst{19-16} = 0b1111; // Rn
1878  let Inst{5-4} = opcod; // Shift type.
1879}
1880def t2MOVCClsl : T2I_movcc_sh<0b00, (outs GPR:$dst),
1881                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
1882                             IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
1883                 RegConstraint<"$false = $dst">;
1884def t2MOVCClsr : T2I_movcc_sh<0b01, (outs GPR:$dst),
1885                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
1886                             IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
1887                 RegConstraint<"$false = $dst">;
1888def t2MOVCCasr : T2I_movcc_sh<0b10, (outs GPR:$dst),
1889                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
1890                             IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
1891                 RegConstraint<"$false = $dst">;
1892def t2MOVCCror : T2I_movcc_sh<0b11, (outs GPR:$dst),
1893                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
1894                             IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
1895                 RegConstraint<"$false = $dst">;
1896
1897//===----------------------------------------------------------------------===//
1898// Atomic operations intrinsics
1899//
1900
1901// memory barriers protect the atomic sequences
1902let hasSideEffects = 1 in {
1903def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
1904                        Pseudo, NoItinerary,
1905                        "dmb", "",
1906                        [(ARMMemBarrierV7)]>,
1907                        Requires<[IsThumb2]> {
1908  let Inst{31-4} = 0xF3BF8F5;
1909  // FIXME: add support for options other than a full system DMB
1910  let Inst{3-0} = 0b1111;
1911}
1912
1913def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
1914                        Pseudo, NoItinerary,
1915                        "dsb", "",
1916                        [(ARMSyncBarrierV7)]>,
1917                        Requires<[IsThumb2]> {
1918  let Inst{31-4} = 0xF3BF8F4;
1919  // FIXME: add support for options other than a full system DSB
1920  let Inst{3-0} = 0b1111;
1921}
1922}
1923
1924class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1925                InstrItinClass itin, string opc, string asm, string cstr,
1926                list<dag> pattern, bits<4> rt2 = 0b1111>
1927  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
1928  let Inst{31-27} = 0b11101;
1929  let Inst{26-20} = 0b0001101;
1930  let Inst{11-8} = rt2;
1931  let Inst{7-6} = 0b01;
1932  let Inst{5-4} = opcod;
1933  let Inst{3-0} = 0b1111;
1934}
1935class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1936                InstrItinClass itin, string opc, string asm, string cstr,
1937                list<dag> pattern, bits<4> rt2 = 0b1111>
1938  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
1939  let Inst{31-27} = 0b11101;
1940  let Inst{26-20} = 0b0001100;
1941  let Inst{11-8} = rt2;
1942  let Inst{7-6} = 0b01;
1943  let Inst{5-4} = opcod;
1944}
1945
1946let mayLoad = 1 in {
1947def t2LDREXB : T2I_ldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1948                         Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
1949                         "", []>;
1950def t2LDREXH : T2I_ldrex<0b01, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1951                         Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
1952                         "", []>;
1953def t2LDREX  : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1954                       Size4Bytes, NoItinerary,
1955                       "ldrex", "\t$dest, [$ptr]", "",
1956                      []> {
1957  let Inst{31-27} = 0b11101;
1958  let Inst{26-20} = 0b0000101;
1959  let Inst{11-8} = 0b1111;
1960  let Inst{7-0} = 0b00000000; // imm8 = 0
1961}
1962def t2LDREXD : T2I_ldrex<0b11, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1963                         AddrModeNone, Size4Bytes, NoItinerary,
1964                         "ldrexd", "\t$dest, $dest2, [$ptr]", "",
1965                         [], {?, ?, ?, ?}>;
1966}
1967
1968let mayStore = 1, Constraints = "@earlyclobber $success" in {
1969def t2STREXB : T2I_strex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1970                         AddrModeNone, Size4Bytes, NoItinerary,
1971                         "strexb", "\t$success, $src, [$ptr]", "", []>;
1972def t2STREXH : T2I_strex<0b01, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1973                         AddrModeNone, Size4Bytes, NoItinerary,
1974                         "strexh", "\t$success, $src, [$ptr]", "", []>;
1975def t2STREX  : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1976                       AddrModeNone, Size4Bytes, NoItinerary,
1977                       "strex", "\t$success, $src, [$ptr]", "",
1978                      []> {
1979  let Inst{31-27} = 0b11101;
1980  let Inst{26-20} = 0b0000100;
1981  let Inst{7-0} = 0b00000000; // imm8 = 0
1982}
1983def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
1984                         (ins GPR:$src, GPR:$src2, GPR:$ptr),
1985                         AddrModeNone, Size4Bytes, NoItinerary,
1986                         "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
1987                         {?, ?, ?, ?}>;
1988}
1989
1990//===----------------------------------------------------------------------===//
1991// TLS Instructions
1992//
1993
1994// __aeabi_read_tp preserves the registers r1-r3.
1995let isCall = 1,
1996  Defs = [R0, R12, LR, CPSR] in {
1997  def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
1998                     "bl\t__aeabi_read_tp",
1999                     [(set R0, ARMthread_pointer)]> {
2000    let Inst{31-27} = 0b11110;
2001    let Inst{15-14} = 0b11;
2002    let Inst{12} = 1;
2003  }
2004}
2005
2006//===----------------------------------------------------------------------===//
2007// SJLJ Exception handling intrinsics
2008//   eh_sjlj_setjmp() is an instruction sequence to store the return
2009//   address and save #0 in R0 for the non-longjmp case.
2010//   Since by its nature we may be coming from some other function to get
2011//   here, and we're using the stack frame for the containing function to
2012//   save/restore registers, we can't keep anything live in regs across
2013//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2014//   when we get here from a longjmp(). We force everthing out of registers
2015//   except for our own input by listing the relevant registers in Defs. By
2016//   doing so, we also cause the prologue/epilogue code to actively preserve
2017//   all of the callee-saved resgisters, which is exactly what we want.
2018//   The current SP is passed in $val, and we reuse the reg as a scratch.
2019let Defs =
2020  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
2021    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
2022    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2023    D31 ] in {
2024  def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
2025                               AddrModeNone, SizeSpecial, NoItinerary,
2026                               "str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
2027                               "\tmov\t$val, pc\n"
2028                               "\tadds\t$val, #9\n"
2029                               "\tstr\t$val, [$src, #4]\n"
2030                               "\tmovs\tr0, #0\n"
2031                               "\tb\t1f\n"
2032                               "\tmovs\tr0, #1\t@ end eh.setjmp\n"
2033                               "1:", "",
2034                          [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
2035}
2036
2037
2038
2039//===----------------------------------------------------------------------===//
2040// Control-Flow Instructions
2041//
2042
2043// FIXME: remove when we have a way to marking a MI with these properties.
2044// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2045// operand list.
2046// FIXME: Should pc be an implicit operand like PICADD, etc?
2047let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2048    hasExtraDefRegAllocReq = 1 in
2049  def t2LDM_RET : T2XI<(outs),
2050                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
2051                    IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
2052                    []> {
2053  let Inst{31-27} = 0b11101;
2054  let Inst{26-25} = 0b00;
2055  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2056  let Inst{22} = 0;
2057  let Inst{21} = ?; // The W bit.
2058  let Inst{20} = 1; // Load
2059}
2060
2061let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2062let isPredicable = 1 in
2063def t2B   : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2064                 "b.w\t$target",
2065                 [(br bb:$target)]> {
2066  let Inst{31-27} = 0b11110;
2067  let Inst{15-14} = 0b10;
2068  let Inst{12} = 1;
2069}
2070
2071let isNotDuplicable = 1, isIndirectBranch = 1 in {
2072def t2BR_JT :
2073    T2JTI<(outs),
2074          (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2075           IIC_Br, "mov\tpc, $target\n$jt",
2076          [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2077  let Inst{31-27} = 0b11101;
2078  let Inst{26-20} = 0b0100100;
2079  let Inst{19-16} = 0b1111;
2080  let Inst{14-12} = 0b000;
2081  let Inst{11-8} = 0b1111; // Rd = pc
2082  let Inst{7-4} = 0b0000;
2083}
2084
2085// FIXME: Add a non-pc based case that can be predicated.
2086def t2TBB :
2087    T2JTI<(outs),
2088        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2089         IIC_Br, "tbb\t$index\n$jt", []> {
2090  let Inst{31-27} = 0b11101;
2091  let Inst{26-20} = 0b0001101;
2092  let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2093  let Inst{15-8} = 0b11110000;
2094  let Inst{7-4} = 0b0000; // B form
2095}
2096
2097def t2TBH :
2098    T2JTI<(outs),
2099        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2100         IIC_Br, "tbh\t$index\n$jt", []> {
2101  let Inst{31-27} = 0b11101;
2102  let Inst{26-20} = 0b0001101;
2103  let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2104  let Inst{15-8} = 0b11110000;
2105  let Inst{7-4} = 0b0001; // H form
2106}
2107} // isNotDuplicable, isIndirectBranch
2108
2109} // isBranch, isTerminator, isBarrier
2110
2111// FIXME: should be able to write a pattern for ARMBrcond, but can't use
2112// a two-value operand where a dag node expects two operands. :(
2113let isBranch = 1, isTerminator = 1 in
2114def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2115                "b", ".w\t$target",
2116                [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2117  let Inst{31-27} = 0b11110;
2118  let Inst{15-14} = 0b10;
2119  let Inst{12} = 0;
2120}
2121
2122
2123// IT block
2124def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2125                    AddrModeNone, Size2Bytes,  IIC_iALUx,
2126                    "it$mask\t$cc", "", []> {
2127  // 16-bit instruction.
2128  let Inst{31-16} = 0x0000;
2129  let Inst{15-8} = 0b10111111;
2130}
2131
2132// Branch and Exchange Jazelle -- for disassembly only
2133// Rm = Inst{19-16}
2134def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
2135              [/* For disassembly only; pattern left blank */]> {
2136  let Inst{31-27} = 0b11110;
2137  let Inst{26} = 0;
2138  let Inst{25-20} = 0b111100;
2139  let Inst{15-14} = 0b10;
2140  let Inst{12} = 0;
2141}
2142
2143// Secure Monitor Call is a system instruction -- for disassembly only
2144// Option = Inst{19-16}
2145def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2146                [/* For disassembly only; pattern left blank */]> {
2147  let Inst{31-27} = 0b11110;
2148  let Inst{26-20} = 0b1111111;
2149  let Inst{15-12} = 0b1000;
2150}
2151
2152// Store Return State is a system instruction -- for disassembly only
2153def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2154                   [/* For disassembly only; pattern left blank */]> {
2155  let Inst{31-27} = 0b11101;
2156  let Inst{26-20} = 0b0000010; // W = 1
2157}
2158
2159def t2SRSDB  : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2160                   [/* For disassembly only; pattern left blank */]> {
2161  let Inst{31-27} = 0b11101;
2162  let Inst{26-20} = 0b0000000; // W = 0
2163}
2164
2165def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2166                   [/* For disassembly only; pattern left blank */]> {
2167  let Inst{31-27} = 0b11101;
2168  let Inst{26-20} = 0b0011010; // W = 1
2169}
2170
2171def t2SRSIA  : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2172                   [/* For disassembly only; pattern left blank */]> {
2173  let Inst{31-27} = 0b11101;
2174  let Inst{26-20} = 0b0011000; // W = 0
2175}
2176
2177// Return From Exception is a system instruction -- for disassembly only
2178def t2RFEDBW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfedb", "\t$base!",
2179                   [/* For disassembly only; pattern left blank */]> {
2180  let Inst{31-27} = 0b11101;
2181  let Inst{26-20} = 0b0000011; // W = 1
2182}
2183
2184def t2RFEDB  : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeab", "\t$base",
2185                   [/* For disassembly only; pattern left blank */]> {
2186  let Inst{31-27} = 0b11101;
2187  let Inst{26-20} = 0b0000001; // W = 0
2188}
2189
2190def t2RFEIAW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base!",
2191                   [/* For disassembly only; pattern left blank */]> {
2192  let Inst{31-27} = 0b11101;
2193  let Inst{26-20} = 0b0011011; // W = 1
2194}
2195
2196def t2RFEIA  : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base",
2197                   [/* For disassembly only; pattern left blank */]> {
2198  let Inst{31-27} = 0b11101;
2199  let Inst{26-20} = 0b0011001; // W = 0
2200}
2201
2202//===----------------------------------------------------------------------===//
2203// Non-Instruction Patterns
2204//
2205
2206// Two piece so_imms.
2207def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
2208             (t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2209                    (t2_so_imm2part_2 imm:$RHS))>;
2210def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
2211             (t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2212                    (t2_so_imm2part_2 imm:$RHS))>;
2213def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
2214             (t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2215                    (t2_so_imm2part_2 imm:$RHS))>;
2216def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
2217             (t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2218                    (t2_so_neg_imm2part_2 imm:$RHS))>;
2219
2220// 32-bit immediate using movw + movt.
2221// This is a single pseudo instruction to make it re-materializable. Remove
2222// when we can do generalized remat.
2223let isReMaterializable = 1 in
2224def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
2225                   "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2226                     [(set GPR:$dst, (i32 imm:$src))]>;
2227
2228// ConstantPool, GlobalAddress, and JumpTable
2229def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2230           Requires<[IsThumb2, DontUseMovt]>;
2231def : T2Pat<(ARMWrapper  tconstpool  :$dst), (t2LEApcrel tconstpool  :$dst)>;
2232def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2233           Requires<[IsThumb2, UseMovt]>;
2234
2235def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2236            (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2237
2238// Pseudo instruction that combines ldr from constpool and add pc. This should
2239// be expanded into two instructions late to allow if-conversion and
2240// scheduling.
2241let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
2242def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2243                   NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
2244               [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2245                                           imm:$cp))]>,
2246               Requires<[IsThumb2]>;
2247
2248//===----------------------------------------------------------------------===//
2249// Move between special register and ARM core register -- for disassembly only
2250//
2251
2252// Rd = Instr{11-8}
2253def t2MRS : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2254                [/* For disassembly only; pattern left blank */]> {
2255  let Inst{31-27} = 0b11110;
2256  let Inst{26} = 0;
2257  let Inst{25-21} = 0b11111;
2258  let Inst{20} = 0; // The R bit.
2259  let Inst{15-14} = 0b10;
2260  let Inst{12} = 0;
2261}
2262
2263// Rd = Instr{11-8}
2264def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2265                   [/* For disassembly only; pattern left blank */]> {
2266  let Inst{31-27} = 0b11110;
2267  let Inst{26} = 0;
2268  let Inst{25-21} = 0b11111;
2269  let Inst{20} = 1; // The R bit.
2270  let Inst{15-14} = 0b10;
2271  let Inst{12} = 0;
2272}
2273
2274// FIXME: mask is ignored for the time being.
2275// Rn = Inst{19-16}
2276def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2277                [/* For disassembly only; pattern left blank */]> {
2278  let Inst{31-27} = 0b11110;
2279  let Inst{26} = 0;
2280  let Inst{25-21} = 0b11100;
2281  let Inst{20} = 0; // The R bit.
2282  let Inst{15-14} = 0b10;
2283  let Inst{12} = 0;
2284}
2285
2286// FIXME: mask is ignored for the time being.
2287// Rn = Inst{19-16}
2288def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src",
2289                   [/* For disassembly only; pattern left blank */]> {
2290  let Inst{31-27} = 0b11110;
2291  let Inst{26} = 0;
2292  let Inst{25-21} = 0b11100;
2293  let Inst{20} = 1; // The R bit.
2294  let Inst{15-14} = 0b10;
2295  let Inst{12} = 0;
2296}
2297