ARMInstrThumb2.td revision dd0f3cf189c34542901178bfca0a319b74d69a05
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 = "printMandatoryPredicateOperand";
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 : T2I<(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 ri : 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 rr : 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 rs : 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_unary_rrot - A unary operation with two forms: one whose operand is a
634/// register and one whose operand is a register rotated by 8/16/24.
635multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
636  def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
637                  opc, ".w\t$dst, $src",
638                 [(set GPR:$dst, (opnode GPR:$src))]> {
639     let Inst{31-27} = 0b11111;
640     let Inst{26-23} = 0b0100;
641     let Inst{22-20} = opcod;
642     let Inst{19-16} = 0b1111; // Rn
643     let Inst{15-12} = 0b1111;
644     let Inst{7} = 1;
645     let Inst{5-4} = 0b00; // rotate
646   }
647  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
648                  opc, ".w\t$dst, $src, ror $rot",
649                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
650     let Inst{31-27} = 0b11111;
651     let Inst{26-23} = 0b0100;
652     let Inst{22-20} = opcod;
653     let Inst{19-16} = 0b1111; // Rn
654     let Inst{15-12} = 0b1111;
655     let Inst{7} = 1;
656     let Inst{5-4} = {?,?}; // rotate
657   }
658}
659
660// SXTB16 and UXTB16 do not need the .w qualifier.
661multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
662  def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
663                  opc, "\t$dst, $src",
664                 [(set GPR:$dst, (opnode GPR:$src))]> {
665     let Inst{31-27} = 0b11111;
666     let Inst{26-23} = 0b0100;
667     let Inst{22-20} = opcod;
668     let Inst{19-16} = 0b1111; // Rn
669     let Inst{15-12} = 0b1111;
670     let Inst{7} = 1;
671     let Inst{5-4} = 0b00; // rotate
672   }
673  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
674                  opc, "\t$dst, $src, ror $rot",
675                 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
676     let Inst{31-27} = 0b11111;
677     let Inst{26-23} = 0b0100;
678     let Inst{22-20} = opcod;
679     let Inst{19-16} = 0b1111; // Rn
680     let Inst{15-12} = 0b1111;
681     let Inst{7} = 1;
682     let Inst{5-4} = {?,?}; // rotate
683   }
684}
685
686// DO variant - disassembly only, no pattern
687
688multiclass T2I_unary_rrot_DO<bits<3> opcod, string opc> {
689  def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
690                  opc, "\t$dst, $src", []> {
691     let Inst{31-27} = 0b11111;
692     let Inst{26-23} = 0b0100;
693     let Inst{22-20} = opcod;
694     let Inst{19-16} = 0b1111; // Rn
695     let Inst{15-12} = 0b1111;
696     let Inst{7} = 1;
697     let Inst{5-4} = 0b00; // rotate
698   }
699  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
700                  opc, "\t$dst, $src, ror $rot", []> {
701     let Inst{31-27} = 0b11111;
702     let Inst{26-23} = 0b0100;
703     let Inst{22-20} = opcod;
704     let Inst{19-16} = 0b1111; // Rn
705     let Inst{15-12} = 0b1111;
706     let Inst{7} = 1;
707     let Inst{5-4} = {?,?}; // rotate
708   }
709}
710
711/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
712/// register and one whose operand is a register rotated by 8/16/24.
713multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
714  def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
715                  opc, "\t$dst, $LHS, $RHS",
716                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]> {
717     let Inst{31-27} = 0b11111;
718     let Inst{26-23} = 0b0100;
719     let Inst{22-20} = opcod;
720     let Inst{15-12} = 0b1111;
721     let Inst{7} = 1;
722     let Inst{5-4} = 0b00; // rotate
723   }
724  def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
725                  IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
726                  [(set GPR:$dst, (opnode GPR:$LHS,
727                                          (rotr GPR:$RHS, rot_imm:$rot)))]> {
728     let Inst{31-27} = 0b11111;
729     let Inst{26-23} = 0b0100;
730     let Inst{22-20} = opcod;
731     let Inst{15-12} = 0b1111;
732     let Inst{7} = 1;
733     let Inst{5-4} = {?,?}; // rotate
734   }
735}
736
737// DO variant - disassembly only, no pattern
738
739multiclass T2I_bin_rrot_DO<bits<3> opcod, string opc> {
740  def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
741                  opc, "\t$dst, $LHS, $RHS", []> {
742     let Inst{31-27} = 0b11111;
743     let Inst{26-23} = 0b0100;
744     let Inst{22-20} = opcod;
745     let Inst{15-12} = 0b1111;
746     let Inst{7} = 1;
747     let Inst{5-4} = 0b00; // rotate
748   }
749  def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
750                  IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
751     let Inst{31-27} = 0b11111;
752     let Inst{26-23} = 0b0100;
753     let Inst{22-20} = opcod;
754     let Inst{15-12} = 0b1111;
755     let Inst{7} = 1;
756     let Inst{5-4} = {?,?}; // rotate
757   }
758}
759
760//===----------------------------------------------------------------------===//
761// Instructions
762//===----------------------------------------------------------------------===//
763
764//===----------------------------------------------------------------------===//
765//  Miscellaneous Instructions.
766//
767
768// LEApcrel - Load a pc-relative address into a register without offending the
769// assembler.
770def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
771                      "adr$p.w\t$dst, #$label", []> {
772  let Inst{31-27} = 0b11110;
773  let Inst{25-24} = 0b10;
774  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
775  let Inst{22} = 0;
776  let Inst{20} = 0;
777  let Inst{19-16} = 0b1111; // Rn
778  let Inst{15} = 0;
779}
780def t2LEApcrelJT : T2XI<(outs GPR:$dst),
781                        (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
782                        "adr$p.w\t$dst, #${label}_${id}", []> {
783  let Inst{31-27} = 0b11110;
784  let Inst{25-24} = 0b10;
785  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
786  let Inst{22} = 0;
787  let Inst{20} = 0;
788  let Inst{19-16} = 0b1111; // Rn
789  let Inst{15} = 0;
790}
791
792// ADD r, sp, {so_imm|i12}
793def t2ADDrSPi   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
794                        IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
795  let Inst{31-27} = 0b11110;
796  let Inst{25} = 0;
797  let Inst{24-21} = 0b1000;
798  let Inst{20} = ?; // The S bit.
799  let Inst{19-16} = 0b1101; // Rn = sp
800  let Inst{15} = 0;
801}
802def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
803                       IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
804  let Inst{31-27} = 0b11110;
805  let Inst{25} = 1;
806  let Inst{24-21} = 0b0000;
807  let Inst{20} = 0; // The S bit.
808  let Inst{19-16} = 0b1101; // Rn = sp
809  let Inst{15} = 0;
810}
811
812// ADD r, sp, so_reg
813def t2ADDrSPs   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
814                        IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
815  let Inst{31-27} = 0b11101;
816  let Inst{26-25} = 0b01;
817  let Inst{24-21} = 0b1000;
818  let Inst{20} = ?; // The S bit.
819  let Inst{19-16} = 0b1101; // Rn = sp
820  let Inst{15} = 0;
821}
822
823// SUB r, sp, {so_imm|i12}
824def t2SUBrSPi   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
825                        IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
826  let Inst{31-27} = 0b11110;
827  let Inst{25} = 0;
828  let Inst{24-21} = 0b1101;
829  let Inst{20} = ?; // The S bit.
830  let Inst{19-16} = 0b1101; // Rn = sp
831  let Inst{15} = 0;
832}
833def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
834                       IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
835  let Inst{31-27} = 0b11110;
836  let Inst{25} = 1;
837  let Inst{24-21} = 0b0101;
838  let Inst{20} = 0; // The S bit.
839  let Inst{19-16} = 0b1101; // Rn = sp
840  let Inst{15} = 0;
841}
842
843// SUB r, sp, so_reg
844def t2SUBrSPs   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
845                       IIC_iALUsi,
846                       "sub", "\t$dst, $sp, $rhs", []> {
847  let Inst{31-27} = 0b11101;
848  let Inst{26-25} = 0b01;
849  let Inst{24-21} = 0b1101;
850  let Inst{20} = ?; // The S bit.
851  let Inst{19-16} = 0b1101; // Rn = sp
852  let Inst{15} = 0;
853}
854
855// Signed and unsigned division, for disassembly only
856def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, 
857                 "sdiv", "\t$dst, $a, $b", []> {
858  let Inst{31-27} = 0b11111;
859  let Inst{26-21} = 0b011100;
860  let Inst{20} = 0b1;
861  let Inst{15-12} = 0b1111;
862  let Inst{7-4} = 0b1111;
863}
864
865def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, 
866                 "udiv", "\t$dst, $a, $b", []> {
867  let Inst{31-27} = 0b11111;
868  let Inst{26-21} = 0b011101;
869  let Inst{20} = 0b1;
870  let Inst{15-12} = 0b1111;
871  let Inst{7-4} = 0b1111;
872}
873
874// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
875let usesCustomInserter = 1 in { // Expanded after instruction selection.
876def t2SUBrSPi_   : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
877                   NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
878def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
879                   NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
880def t2SUBrSPs_   : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
881                   NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
882} // usesCustomInserter
883
884
885//===----------------------------------------------------------------------===//
886//  Load / store Instructions.
887//
888
889// Load
890let canFoldAsLoad = 1, isReMaterializable = 1  in
891defm t2LDR   : T2I_ld<0, 0b10, "ldr",  UnOpFrag<(load node:$Src)>>;
892
893// Loads with zero extension
894defm t2LDRH  : T2I_ld<0, 0b01, "ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
895defm t2LDRB  : T2I_ld<0, 0b00, "ldrb", UnOpFrag<(zextloadi8  node:$Src)>>;
896
897// Loads with sign extension
898defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
899defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", UnOpFrag<(sextloadi8  node:$Src)>>;
900
901let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
902// Load doubleword
903def t2LDRDi8  : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
904                        (ins t2addrmode_imm8s4:$addr),
905                        IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
906def t2LDRDpci : T2Ii8s4<?, ?, 1, (outs GPR:$dst1, GPR:$dst2),
907                        (ins i32imm:$addr), IIC_iLoadi,
908                       "ldrd", "\t$dst1, $addr", []> {
909  let Inst{19-16} = 0b1111; // Rn
910}
911}
912
913// zextload i1 -> zextload i8
914def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
915            (t2LDRBi12  t2addrmode_imm12:$addr)>;
916def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
917            (t2LDRBi8   t2addrmode_imm8:$addr)>;
918def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
919            (t2LDRBs    t2addrmode_so_reg:$addr)>;
920def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
921            (t2LDRBpci  tconstpool:$addr)>;
922
923// extload -> zextload
924// FIXME: Reduce the number of patterns by legalizing extload to zextload
925// earlier?
926def : T2Pat<(extloadi1  t2addrmode_imm12:$addr),
927            (t2LDRBi12  t2addrmode_imm12:$addr)>;
928def : T2Pat<(extloadi1  t2addrmode_imm8:$addr),
929            (t2LDRBi8   t2addrmode_imm8:$addr)>;
930def : T2Pat<(extloadi1  t2addrmode_so_reg:$addr),
931            (t2LDRBs    t2addrmode_so_reg:$addr)>;
932def : T2Pat<(extloadi1  (ARMWrapper tconstpool:$addr)),
933            (t2LDRBpci  tconstpool:$addr)>;
934
935def : T2Pat<(extloadi8  t2addrmode_imm12:$addr),
936            (t2LDRBi12  t2addrmode_imm12:$addr)>;
937def : T2Pat<(extloadi8  t2addrmode_imm8:$addr),
938            (t2LDRBi8   t2addrmode_imm8:$addr)>;
939def : T2Pat<(extloadi8  t2addrmode_so_reg:$addr),
940            (t2LDRBs    t2addrmode_so_reg:$addr)>;
941def : T2Pat<(extloadi8  (ARMWrapper tconstpool:$addr)),
942            (t2LDRBpci  tconstpool:$addr)>;
943
944def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
945            (t2LDRHi12  t2addrmode_imm12:$addr)>;
946def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
947            (t2LDRHi8   t2addrmode_imm8:$addr)>;
948def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
949            (t2LDRHs    t2addrmode_so_reg:$addr)>;
950def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
951            (t2LDRHpci  tconstpool:$addr)>;
952
953// Indexed loads
954let mayLoad = 1 in {
955def t2LDR_PRE  : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
956                            (ins t2addrmode_imm8:$addr),
957                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
958                            "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
959                            []>;
960
961def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
962                            (ins GPR:$base, t2am_imm8_offset:$offset),
963                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
964                          "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
965                            []>;
966
967def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
968                            (ins t2addrmode_imm8:$addr),
969                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
970                            "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
971                            []>;
972def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
973                            (ins GPR:$base, t2am_imm8_offset:$offset),
974                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
975                         "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
976                            []>;
977
978def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
979                            (ins t2addrmode_imm8:$addr),
980                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
981                            "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
982                            []>;
983def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
984                            (ins GPR:$base, t2am_imm8_offset:$offset),
985                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
986                         "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
987                            []>;
988
989def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
990                            (ins t2addrmode_imm8:$addr),
991                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
992                            "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
993                            []>;
994def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
995                            (ins GPR:$base, t2am_imm8_offset:$offset),
996                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
997                        "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
998                            []>;
999
1000def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1001                            (ins t2addrmode_imm8:$addr),
1002                            AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1003                            "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1004                            []>;
1005def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1006                            (ins GPR:$base, t2am_imm8_offset:$offset),
1007                            AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1008                        "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1009                            []>;
1010}
1011
1012// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1013// for disassembly only.
1014// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1015class T2IldT<bit signed, bits<2> type, string opc>
1016  : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
1017          "\t$dst, $addr", []> {
1018  let Inst{31-27} = 0b11111;
1019  let Inst{26-25} = 0b00;
1020  let Inst{24} = signed;
1021  let Inst{23} = 0;
1022  let Inst{22-21} = type;
1023  let Inst{20} = 1; // load
1024  let Inst{11} = 1;
1025  let Inst{10-8} = 0b110; // PUW.
1026}
1027
1028def t2LDRT   : T2IldT<0, 0b10, "ldrt">;
1029def t2LDRBT  : T2IldT<0, 0b00, "ldrbt">;
1030def t2LDRHT  : T2IldT<0, 0b01, "ldrht">;
1031def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt">;
1032def t2LDRSHT : T2IldT<1, 0b01, "ldrsht">;
1033
1034// Store
1035defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
1036defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1037defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1038
1039// Store doubleword
1040let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
1041def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1042                       (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1043               IIC_iStorer, "strd", "\t$src1, $addr", []>;
1044
1045// Indexed stores
1046def t2STR_PRE  : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1047                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1048                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1049                         "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1050             [(set GPR:$base_wb,
1051                   (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1052
1053def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1054                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1055                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1056                          "str", "\t$src, [$base], $offset", "$base = $base_wb",
1057             [(set GPR:$base_wb,
1058                  (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1059
1060def t2STRH_PRE  : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1061                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1062                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1063                        "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1064        [(set GPR:$base_wb,
1065              (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1066
1067def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1068                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1069                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1070                         "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1071       [(set GPR:$base_wb,
1072             (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1073
1074def t2STRB_PRE  : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1075                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1076                            AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1077                        "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1078         [(set GPR:$base_wb,
1079               (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1080
1081def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1082                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1083                            AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1084                         "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1085        [(set GPR:$base_wb,
1086              (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1087
1088// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1089// only.
1090// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1091class T2IstT<bits<2> type, string opc>
1092  : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), IIC_iStorei, opc,
1093          "\t$src, $addr", []> {
1094  let Inst{31-27} = 0b11111;
1095  let Inst{26-25} = 0b00;
1096  let Inst{24} = 0; // not signed
1097  let Inst{23} = 0;
1098  let Inst{22-21} = type;
1099  let Inst{20} = 0; // store
1100  let Inst{11} = 1;
1101  let Inst{10-8} = 0b110; // PUW
1102}
1103
1104def t2STRT   : T2IstT<0b10, "strt">;
1105def t2STRBT  : T2IstT<0b00, "strbt">;
1106def t2STRHT  : T2IstT<0b01, "strht">;
1107
1108// FIXME: ldrd / strd pre / post variants
1109
1110// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1111// data/instruction access.  These are for disassembly only.
1112//
1113// A8.6.117, A8.6.118.  Different instructions are generated for #0 and #-0.
1114// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
1115multiclass T2Ipl<bit instr, bit write, string opc> {
1116
1117  def i12 : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
1118                "\t[$base, $imm]", []> {
1119    let Inst{31-25} = 0b1111100;
1120    let Inst{24} = instr;
1121    let Inst{23} = 1; // U = 1
1122    let Inst{22} = 0;
1123    let Inst{21} = write;
1124    let Inst{20} = 1;
1125    let Inst{15-12} = 0b1111;
1126  }
1127
1128  def i8 : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
1129                "\t[$base, $imm]", []> {
1130    let Inst{31-25} = 0b1111100;
1131    let Inst{24} = instr;
1132    let Inst{23} = 0; // U = 0
1133    let Inst{22} = 0;
1134    let Inst{21} = write;
1135    let Inst{20} = 1;
1136    let Inst{15-12} = 0b1111;
1137    let Inst{11-8} = 0b1100;
1138  }
1139
1140  def pci : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
1141                "\t[pc, $imm]", []> {
1142    let Inst{31-25} = 0b1111100;
1143    let Inst{24} = instr;
1144    let Inst{23} = ?; // add = (U == 1)
1145    let Inst{22} = 0;
1146    let Inst{21} = write;
1147    let Inst{20} = 1;
1148    let Inst{19-16} = 0b1111; // Rn = 0b1111
1149    let Inst{15-12} = 0b1111;
1150  }
1151
1152  def r   : T2I<(outs), (ins GPR:$base, GPR:$a), IIC_iLoadi, opc,
1153                "\t[$base, $a]", []> {
1154    let Inst{31-25} = 0b1111100;
1155    let Inst{24} = instr;
1156    let Inst{23} = 0; // add = TRUE for T1
1157    let Inst{22} = 0;
1158    let Inst{21} = write;
1159    let Inst{20} = 1;
1160    let Inst{15-12} = 0b1111;
1161    let Inst{11-6} = 0000000;
1162    let Inst{5-4} = 0b00; // no shift is applied
1163  }
1164
1165  def s   : T2I<(outs), (ins GPR:$base, GPR:$a, i32imm:$shamt), IIC_iLoadi, opc,
1166                "\t[$base, $a, lsl $shamt]", []> {
1167    let Inst{31-25} = 0b1111100;
1168    let Inst{24} = instr;
1169    let Inst{23} = 0; // add = TRUE for T1
1170    let Inst{22} = 0;
1171    let Inst{21} = write;
1172    let Inst{20} = 1;
1173    let Inst{15-12} = 0b1111;
1174    let Inst{11-6} = 0000000;
1175  }
1176}
1177
1178defm t2PLD  : T2Ipl<0, 0, "pld">;
1179defm t2PLDW : T2Ipl<0, 1, "pldw">;
1180defm t2PLI  : T2Ipl<1, 0, "pli">;
1181
1182//===----------------------------------------------------------------------===//
1183//  Load / store multiple Instructions.
1184//
1185
1186let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1187def t2LDM : T2XI<(outs),
1188                 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1189             IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1190  let Inst{31-27} = 0b11101;
1191  let Inst{26-25} = 0b00;
1192  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1193  let Inst{22} = 0;
1194  let Inst{21} = ?; // The W bit.
1195  let Inst{20} = 1; // Load
1196}
1197
1198let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1199def t2STM : T2XI<(outs),
1200                 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1201            IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1202  let Inst{31-27} = 0b11101;
1203  let Inst{26-25} = 0b00;
1204  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1205  let Inst{22} = 0;
1206  let Inst{21} = ?; // The W bit.
1207  let Inst{20} = 0; // Store
1208}
1209
1210//===----------------------------------------------------------------------===//
1211//  Move Instructions.
1212//
1213
1214let neverHasSideEffects = 1 in
1215def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1216                   "mov", ".w\t$dst, $src", []> {
1217  let Inst{31-27} = 0b11101;
1218  let Inst{26-25} = 0b01;
1219  let Inst{24-21} = 0b0010;
1220  let Inst{20} = ?; // The S bit.
1221  let Inst{19-16} = 0b1111; // Rn
1222  let Inst{14-12} = 0b000;
1223  let Inst{7-4} = 0b0000;
1224}
1225
1226// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1227let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1228def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1229                   "mov", ".w\t$dst, $src",
1230                   [(set GPR:$dst, t2_so_imm:$src)]> {
1231  let Inst{31-27} = 0b11110;
1232  let Inst{25} = 0;
1233  let Inst{24-21} = 0b0010;
1234  let Inst{20} = ?; // The S bit.
1235  let Inst{19-16} = 0b1111; // Rn
1236  let Inst{15} = 0;
1237}
1238
1239let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1240def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1241                   "movw", "\t$dst, $src",
1242                   [(set GPR:$dst, imm0_65535:$src)]> {
1243  let Inst{31-27} = 0b11110;
1244  let Inst{25} = 1;
1245  let Inst{24-21} = 0b0010;
1246  let Inst{20} = 0; // The S bit.
1247  let Inst{15} = 0;
1248}
1249
1250let Constraints = "$src = $dst" in
1251def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
1252                    "movt", "\t$dst, $imm",
1253                    [(set GPR:$dst,
1254                          (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]> {
1255  let Inst{31-27} = 0b11110;
1256  let Inst{25} = 1;
1257  let Inst{24-21} = 0b0110;
1258  let Inst{20} = 0; // The S bit.
1259  let Inst{15} = 0;
1260}
1261
1262def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
1263
1264//===----------------------------------------------------------------------===//
1265//  Extend Instructions.
1266//
1267
1268// Sign extenders
1269
1270defm t2SXTB  : T2I_unary_rrot<0b100, "sxtb",
1271                              UnOpFrag<(sext_inreg node:$Src, i8)>>;
1272defm t2SXTH  : T2I_unary_rrot<0b000, "sxth",
1273                              UnOpFrag<(sext_inreg node:$Src, i16)>>;
1274defm t2SXTB16 : T2I_unary_rrot_DO<0b010, "sxtb16">;
1275
1276defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
1277                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1278defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
1279                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1280defm t2SXTAB16 : T2I_bin_rrot_DO<0b010, "sxtab16">;
1281
1282// TODO: SXT(A){B|H}16 - done for disassembly only
1283
1284// Zero extenders
1285
1286let AddedComplexity = 16 in {
1287defm t2UXTB   : T2I_unary_rrot<0b101, "uxtb",
1288                               UnOpFrag<(and node:$Src, 0x000000FF)>>;
1289defm t2UXTH   : T2I_unary_rrot<0b001, "uxth",
1290                               UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1291defm t2UXTB16 : T2I_unary_rrot_nw<0b011, "uxtb16",
1292                               UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1293
1294def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1295            (t2UXTB16r_rot GPR:$Src, 24)>;
1296def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1297            (t2UXTB16r_rot GPR:$Src, 8)>;
1298
1299defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
1300                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1301defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
1302                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1303defm t2UXTAB16 : T2I_bin_rrot_DO<0b011, "uxtab16">;
1304}
1305
1306//===----------------------------------------------------------------------===//
1307//  Arithmetic Instructions.
1308//
1309
1310defm t2ADD  : T2I_bin_ii12rs<0b000, "add",
1311                             BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1312defm t2SUB  : T2I_bin_ii12rs<0b101, "sub",
1313                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1314
1315// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1316defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1317                             BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1318defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1319                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1320
1321defm t2ADC  : T2I_adde_sube_irs<0b1010, "adc",
1322                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1323defm t2SBC  : T2I_adde_sube_irs<0b1011, "sbc",
1324                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1325defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1326                          BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1327defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1328                          BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1329
1330// RSB
1331defm t2RSB  : T2I_rbin_is   <0b1110, "rsb",
1332                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1333defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1334                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1335
1336// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1337let AddedComplexity = 1 in
1338def : T2Pat<(add       GPR:$src, imm0_255_neg:$imm),
1339            (t2SUBri   GPR:$src, imm0_255_neg:$imm)>;
1340def : T2Pat<(add       GPR:$src, t2_so_imm_neg:$imm),
1341            (t2SUBri   GPR:$src, t2_so_imm_neg:$imm)>;
1342def : T2Pat<(add       GPR:$src, imm0_4095_neg:$imm),
1343            (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1344
1345// Select Bytes -- for disassembly only
1346
1347def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1348                "\t$dst, $a, $b", []> {
1349  let Inst{31-27} = 0b11111;
1350  let Inst{26-24} = 0b010;
1351  let Inst{23} = 0b1;
1352  let Inst{22-20} = 0b010;
1353  let Inst{15-12} = 0b1111;
1354  let Inst{7} = 0b1;
1355  let Inst{6-4} = 0b000;
1356}
1357
1358// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1359// And Miscellaneous operations -- for disassembly only
1360class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc>
1361  : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, opc,
1362        "\t$dst, $a, $b", [/* For disassembly only; pattern left blank */]> {
1363  let Inst{31-27} = 0b11111;
1364  let Inst{26-23} = 0b0101;
1365  let Inst{22-20} = op22_20;
1366  let Inst{15-12} = 0b1111;
1367  let Inst{7-4} = op7_4;
1368}
1369
1370// Saturating add/subtract -- for disassembly only
1371
1372def t2QADD    : T2I_pam<0b000, 0b1000, "qadd">;
1373def t2QADD16  : T2I_pam<0b001, 0b0001, "qadd16">;
1374def t2QADD8   : T2I_pam<0b000, 0b0001, "qadd8">;
1375def t2QASX    : T2I_pam<0b010, 0b0001, "qasx">;
1376def t2QDADD   : T2I_pam<0b000, 0b1001, "qdadd">;
1377def t2QDSUB   : T2I_pam<0b000, 0b1011, "qdsub">;
1378def t2QSAX    : T2I_pam<0b110, 0b0001, "qsax">;
1379def t2QSUB    : T2I_pam<0b000, 0b1010, "qsub">;
1380def t2QSUB16  : T2I_pam<0b101, 0b0001, "qsub16">;
1381def t2QSUB8   : T2I_pam<0b100, 0b0001, "qsub8">;
1382def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1383def t2UQADD8  : T2I_pam<0b000, 0b0101, "uqadd8">;
1384def t2UQASX   : T2I_pam<0b010, 0b0101, "uqasx">;
1385def t2UQSAX   : T2I_pam<0b110, 0b0101, "uqsax">;
1386def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1387def t2UQSUB8  : T2I_pam<0b100, 0b0101, "uqsub8">;
1388
1389// Signed/Unsigned add/subtract -- for disassembly only
1390
1391def t2SASX    : T2I_pam<0b010, 0b0000, "sasx">;
1392def t2SADD16  : T2I_pam<0b001, 0b0000, "sadd16">;
1393def t2SADD8   : T2I_pam<0b000, 0b0000, "sadd8">;
1394def t2SSAX    : T2I_pam<0b110, 0b0000, "ssax">;
1395def t2SSUB16  : T2I_pam<0b101, 0b0000, "ssub16">;
1396def t2SSUB8   : T2I_pam<0b100, 0b0000, "ssub8">;
1397def t2UASX    : T2I_pam<0b010, 0b0100, "uasx">;
1398def t2UADD16  : T2I_pam<0b001, 0b0100, "uadd16">;
1399def t2UADD8   : T2I_pam<0b000, 0b0100, "uadd8">;
1400def t2USAX    : T2I_pam<0b110, 0b0100, "usax">;
1401def t2USUB16  : T2I_pam<0b101, 0b0100, "usub16">;
1402def t2USUB8   : T2I_pam<0b100, 0b0100, "usub8">;
1403
1404// Signed/Unsigned halving add/subtract -- for disassembly only
1405
1406def t2SHASX   : T2I_pam<0b010, 0b0010, "shasx">;
1407def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1408def t2SHADD8  : T2I_pam<0b000, 0b0010, "shadd8">;
1409def t2SHSAX   : T2I_pam<0b110, 0b0010, "shsax">;
1410def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1411def t2SHSUB8  : T2I_pam<0b100, 0b0010, "shsub8">;
1412def t2UHASX   : T2I_pam<0b010, 0b0110, "uhasx">;
1413def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1414def t2UHADD8  : T2I_pam<0b000, 0b0110, "uhadd8">;
1415def t2UHSAX   : T2I_pam<0b110, 0b0110, "uhsax">;
1416def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1417def t2UHSUB8  : T2I_pam<0b100, 0b0110, "uhsub8">;
1418
1419// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1420
1421def t2USAD8   : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1422                        NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1423  let Inst{15-12} = 0b1111;
1424}
1425def t2USADA8  : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst),
1426                        (ins GPR:$a, GPR:$b, GPR:$acc), NoItinerary, "usada8",
1427                        "\t$dst, $a, $b, $acc", []>;
1428
1429// Signed/Unsigned saturate -- for disassembly only
1430
1431def t2SSATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1432                    NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1433                    [/* For disassembly only; pattern left blank */]> {
1434  let Inst{31-27} = 0b11110;
1435  let Inst{25-22} = 0b1100;
1436  let Inst{20} = 0;
1437  let Inst{15} = 0;
1438  let Inst{21} = 0;        // sh = '0'
1439}
1440
1441def t2SSATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1442                    NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1443                    [/* For disassembly only; pattern left blank */]> {
1444  let Inst{31-27} = 0b11110;
1445  let Inst{25-22} = 0b1100;
1446  let Inst{20} = 0;
1447  let Inst{15} = 0;
1448  let Inst{21} = 1;        // sh = '1'
1449}
1450
1451def t2SSAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1452                   "ssat16", "\t$dst, $bit_pos, $a",
1453                   [/* For disassembly only; pattern left blank */]> {
1454  let Inst{31-27} = 0b11110;
1455  let Inst{25-22} = 0b1100;
1456  let Inst{20} = 0;
1457  let Inst{15} = 0;
1458  let Inst{21} = 1;        // sh = '1'
1459  let Inst{14-12} = 0b000; // imm3 = '000'
1460  let Inst{7-6} = 0b00;    // imm2 = '00'
1461}
1462
1463def t2USATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1464                     NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1465                     [/* For disassembly only; pattern left blank */]> {
1466  let Inst{31-27} = 0b11110;
1467  let Inst{25-22} = 0b1110;
1468  let Inst{20} = 0;
1469  let Inst{15} = 0;
1470  let Inst{21} = 0;        // sh = '0'
1471}
1472
1473def t2USATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1474                     NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1475                     [/* For disassembly only; pattern left blank */]> {
1476  let Inst{31-27} = 0b11110;
1477  let Inst{25-22} = 0b1110;
1478  let Inst{20} = 0;
1479  let Inst{15} = 0;
1480  let Inst{21} = 1;        // sh = '1'
1481}
1482
1483def t2USAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1484                   "usat16", "\t$dst, $bit_pos, $a",
1485                   [/* For disassembly only; pattern left blank */]> {
1486  let Inst{31-27} = 0b11110;
1487  let Inst{25-22} = 0b1110;
1488  let Inst{20} = 0;
1489  let Inst{15} = 0;
1490  let Inst{21} = 1;        // sh = '1'
1491  let Inst{14-12} = 0b000; // imm3 = '000'
1492  let Inst{7-6} = 0b00;    // imm2 = '00'
1493}
1494
1495//===----------------------------------------------------------------------===//
1496//  Shift and rotate Instructions.
1497//
1498
1499defm t2LSL  : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl  node:$LHS, node:$RHS)>>;
1500defm t2LSR  : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl  node:$LHS, node:$RHS)>>;
1501defm t2ASR  : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra  node:$LHS, node:$RHS)>>;
1502defm t2ROR  : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1503
1504let Uses = [CPSR] in {
1505def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1506                   "rrx", "\t$dst, $src",
1507                   [(set GPR:$dst, (ARMrrx GPR:$src))]> {
1508  let Inst{31-27} = 0b11101;
1509  let Inst{26-25} = 0b01;
1510  let Inst{24-21} = 0b0010;
1511  let Inst{20} = ?; // The S bit.
1512  let Inst{19-16} = 0b1111; // Rn
1513  let Inst{14-12} = 0b000;
1514  let Inst{7-4} = 0b0011;
1515}
1516}
1517
1518let Defs = [CPSR] in {
1519def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1520                         "lsrs.w\t$dst, $src, #1",
1521                         [(set GPR:$dst, (ARMsrl_flag GPR:$src))]> {
1522  let Inst{31-27} = 0b11101;
1523  let Inst{26-25} = 0b01;
1524  let Inst{24-21} = 0b0010;
1525  let Inst{20} = 1; // The S bit.
1526  let Inst{19-16} = 0b1111; // Rn
1527  let Inst{5-4} = 0b01; // Shift type.
1528  // Shift amount = Inst{14-12:7-6} = 1.
1529  let Inst{14-12} = 0b000;
1530  let Inst{7-6} = 0b01;
1531}
1532def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1533                         "asrs.w\t$dst, $src, #1",
1534                         [(set GPR:$dst, (ARMsra_flag GPR:$src))]> {
1535  let Inst{31-27} = 0b11101;
1536  let Inst{26-25} = 0b01;
1537  let Inst{24-21} = 0b0010;
1538  let Inst{20} = 1; // The S bit.
1539  let Inst{19-16} = 0b1111; // Rn
1540  let Inst{5-4} = 0b10; // Shift type.
1541  // Shift amount = Inst{14-12:7-6} = 1.
1542  let Inst{14-12} = 0b000;
1543  let Inst{7-6} = 0b01;
1544}
1545}
1546
1547//===----------------------------------------------------------------------===//
1548//  Bitwise Instructions.
1549//
1550
1551defm t2AND  : T2I_bin_w_irs<0b0000, "and",
1552                            BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1553defm t2ORR  : T2I_bin_w_irs<0b0010, "orr",
1554                            BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
1555defm t2EOR  : T2I_bin_w_irs<0b0100, "eor",
1556                            BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1557
1558defm t2BIC  : T2I_bin_w_irs<0b0001, "bic",
1559                            BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1560
1561let Constraints = "$src = $dst" in
1562def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1563                IIC_iUNAsi, "bfc", "\t$dst, $imm",
1564                [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]> {
1565  let Inst{31-27} = 0b11110;
1566  let Inst{25} = 1;
1567  let Inst{24-20} = 0b10110;
1568  let Inst{19-16} = 0b1111; // Rn
1569  let Inst{15} = 0;
1570}
1571
1572def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1573                 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1574  let Inst{31-27} = 0b11110;
1575  let Inst{25} = 1;
1576  let Inst{24-20} = 0b10100;
1577  let Inst{15} = 0;
1578}
1579
1580def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1581                 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1582  let Inst{31-27} = 0b11110;
1583  let Inst{25} = 1;
1584  let Inst{24-20} = 0b11100;
1585  let Inst{15} = 0;
1586}
1587
1588// A8.6.18  BFI - Bitfield insert (Encoding T1)
1589// Added for disassembler with the pattern field purposely left blank.
1590// FIXME: Utilize this instruction in codgen.
1591def t2BFI : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1592                IIC_iALUi, "bfi", "\t$dst, $src, $lsb, $width", []> {
1593  let Inst{31-27} = 0b11110;
1594  let Inst{25} = 1;
1595  let Inst{24-20} = 0b10110;
1596  let Inst{15} = 0;
1597}
1598
1599defm t2ORN  : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or  node:$LHS,
1600                          (not node:$RHS))>>;
1601
1602// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1603let AddedComplexity = 1 in
1604defm t2MVN  : T2I_un_irs <0b0011, "mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
1605
1606
1607def : T2Pat<(and     GPR:$src, t2_so_imm_not:$imm),
1608            (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
1609
1610// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1611def : T2Pat<(or      GPR:$src, t2_so_imm_not:$imm),
1612            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
1613            Requires<[IsThumb2]>;
1614
1615def : T2Pat<(t2_so_imm_not:$src),
1616            (t2MVNi t2_so_imm_not:$src)>;
1617
1618//===----------------------------------------------------------------------===//
1619//  Multiply Instructions.
1620//
1621let isCommutable = 1 in
1622def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1623                "mul", "\t$dst, $a, $b",
1624                [(set GPR:$dst, (mul GPR:$a, GPR:$b))]> {
1625  let Inst{31-27} = 0b11111;
1626  let Inst{26-23} = 0b0110;
1627  let Inst{22-20} = 0b000;
1628  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1629  let Inst{7-4} = 0b0000; // Multiply
1630}
1631
1632def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1633		"mla", "\t$dst, $a, $b, $c",
1634		[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]> {
1635  let Inst{31-27} = 0b11111;
1636  let Inst{26-23} = 0b0110;
1637  let Inst{22-20} = 0b000;
1638  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1639  let Inst{7-4} = 0b0000; // Multiply
1640}
1641
1642def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1643		"mls", "\t$dst, $a, $b, $c",
1644                [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]> {
1645  let Inst{31-27} = 0b11111;
1646  let Inst{26-23} = 0b0110;
1647  let Inst{22-20} = 0b000;
1648  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1649  let Inst{7-4} = 0b0001; // Multiply and Subtract
1650}
1651
1652// Extra precision multiplies with low / high results
1653let neverHasSideEffects = 1 in {
1654let isCommutable = 1 in {
1655def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1656                   "smull", "\t$ldst, $hdst, $a, $b", []> {
1657  let Inst{31-27} = 0b11111;
1658  let Inst{26-23} = 0b0111;
1659  let Inst{22-20} = 0b000;
1660  let Inst{7-4} = 0b0000;
1661}
1662
1663def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1664                   "umull", "\t$ldst, $hdst, $a, $b", []> {
1665  let Inst{31-27} = 0b11111;
1666  let Inst{26-23} = 0b0111;
1667  let Inst{22-20} = 0b010;
1668  let Inst{7-4} = 0b0000;
1669}
1670} // isCommutable
1671
1672// Multiply + accumulate
1673def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1674                  "smlal", "\t$ldst, $hdst, $a, $b", []>{
1675  let Inst{31-27} = 0b11111;
1676  let Inst{26-23} = 0b0111;
1677  let Inst{22-20} = 0b100;
1678  let Inst{7-4} = 0b0000;
1679}
1680
1681def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1682                  "umlal", "\t$ldst, $hdst, $a, $b", []>{
1683  let Inst{31-27} = 0b11111;
1684  let Inst{26-23} = 0b0111;
1685  let Inst{22-20} = 0b110;
1686  let Inst{7-4} = 0b0000;
1687}
1688
1689def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1690                  "umaal", "\t$ldst, $hdst, $a, $b", []>{
1691  let Inst{31-27} = 0b11111;
1692  let Inst{26-23} = 0b0111;
1693  let Inst{22-20} = 0b110;
1694  let Inst{7-4} = 0b0110;
1695}
1696} // neverHasSideEffects
1697
1698// Rounding variants of the below included for disassembly only
1699
1700// Most significant word multiply
1701def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1702                  "smmul", "\t$dst, $a, $b",
1703                  [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]> {
1704  let Inst{31-27} = 0b11111;
1705  let Inst{26-23} = 0b0110;
1706  let Inst{22-20} = 0b101;
1707  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1708  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1709}
1710
1711def t2SMMULR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1712                  "smmulr", "\t$dst, $a, $b", []> {
1713  let Inst{31-27} = 0b11111;
1714  let Inst{26-23} = 0b0110;
1715  let Inst{22-20} = 0b101;
1716  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1717  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1718}
1719
1720def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1721                  "smmla", "\t$dst, $a, $b, $c",
1722                  [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]> {
1723  let Inst{31-27} = 0b11111;
1724  let Inst{26-23} = 0b0110;
1725  let Inst{22-20} = 0b101;
1726  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1727  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1728}
1729
1730def t2SMMLAR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1731                  "smmlar", "\t$dst, $a, $b, $c", []> {
1732  let Inst{31-27} = 0b11111;
1733  let Inst{26-23} = 0b0110;
1734  let Inst{22-20} = 0b101;
1735  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1736  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1737}
1738
1739def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1740                   "smmls", "\t$dst, $a, $b, $c",
1741                   [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]> {
1742  let Inst{31-27} = 0b11111;
1743  let Inst{26-23} = 0b0110;
1744  let Inst{22-20} = 0b110;
1745  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1746  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1747}
1748
1749def t2SMMLSR : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1750                   "smmlsr", "\t$dst, $a, $b, $c", []> {
1751  let Inst{31-27} = 0b11111;
1752  let Inst{26-23} = 0b0110;
1753  let Inst{22-20} = 0b110;
1754  let Inst{15-12} = {?, ?, ?, ?}; // Ra
1755  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1756}
1757
1758multiclass T2I_smul<string opc, PatFrag opnode> {
1759  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1760              !strconcat(opc, "bb"), "\t$dst, $a, $b",
1761              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1762                                      (sext_inreg GPR:$b, i16)))]> {
1763    let Inst{31-27} = 0b11111;
1764    let Inst{26-23} = 0b0110;
1765    let Inst{22-20} = 0b001;
1766    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1767    let Inst{7-6} = 0b00;
1768    let Inst{5-4} = 0b00;
1769  }
1770
1771  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1772              !strconcat(opc, "bt"), "\t$dst, $a, $b",
1773              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1774                                      (sra GPR:$b, (i32 16))))]> {
1775    let Inst{31-27} = 0b11111;
1776    let Inst{26-23} = 0b0110;
1777    let Inst{22-20} = 0b001;
1778    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1779    let Inst{7-6} = 0b00;
1780    let Inst{5-4} = 0b01;
1781  }
1782
1783  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1784              !strconcat(opc, "tb"), "\t$dst, $a, $b",
1785              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1786                                      (sext_inreg GPR:$b, i16)))]> {
1787    let Inst{31-27} = 0b11111;
1788    let Inst{26-23} = 0b0110;
1789    let Inst{22-20} = 0b001;
1790    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1791    let Inst{7-6} = 0b00;
1792    let Inst{5-4} = 0b10;
1793  }
1794
1795  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1796              !strconcat(opc, "tt"), "\t$dst, $a, $b",
1797              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1798                                      (sra GPR:$b, (i32 16))))]> {
1799    let Inst{31-27} = 0b11111;
1800    let Inst{26-23} = 0b0110;
1801    let Inst{22-20} = 0b001;
1802    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1803    let Inst{7-6} = 0b00;
1804    let Inst{5-4} = 0b11;
1805  }
1806
1807  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1808              !strconcat(opc, "wb"), "\t$dst, $a, $b",
1809              [(set GPR:$dst, (sra (opnode GPR:$a,
1810                                    (sext_inreg GPR:$b, i16)), (i32 16)))]> {
1811    let Inst{31-27} = 0b11111;
1812    let Inst{26-23} = 0b0110;
1813    let Inst{22-20} = 0b011;
1814    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1815    let Inst{7-6} = 0b00;
1816    let Inst{5-4} = 0b00;
1817  }
1818
1819  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1820              !strconcat(opc, "wt"), "\t$dst, $a, $b",
1821              [(set GPR:$dst, (sra (opnode GPR:$a,
1822                                    (sra GPR:$b, (i32 16))), (i32 16)))]> {
1823    let Inst{31-27} = 0b11111;
1824    let Inst{26-23} = 0b0110;
1825    let Inst{22-20} = 0b011;
1826    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1827    let Inst{7-6} = 0b00;
1828    let Inst{5-4} = 0b01;
1829  }
1830}
1831
1832
1833multiclass T2I_smla<string opc, PatFrag opnode> {
1834  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1835              !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1836              [(set GPR:$dst, (add GPR:$acc,
1837                               (opnode (sext_inreg GPR:$a, i16),
1838                                       (sext_inreg GPR:$b, i16))))]> {
1839    let Inst{31-27} = 0b11111;
1840    let Inst{26-23} = 0b0110;
1841    let Inst{22-20} = 0b001;
1842    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1843    let Inst{7-6} = 0b00;
1844    let Inst{5-4} = 0b00;
1845  }
1846
1847  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1848             !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1849             [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1850                                                   (sra GPR:$b, (i32 16)))))]> {
1851    let Inst{31-27} = 0b11111;
1852    let Inst{26-23} = 0b0110;
1853    let Inst{22-20} = 0b001;
1854    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1855    let Inst{7-6} = 0b00;
1856    let Inst{5-4} = 0b01;
1857  }
1858
1859  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1860              !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1861              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1862                                                 (sext_inreg GPR:$b, i16))))]> {
1863    let Inst{31-27} = 0b11111;
1864    let Inst{26-23} = 0b0110;
1865    let Inst{22-20} = 0b001;
1866    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1867    let Inst{7-6} = 0b00;
1868    let Inst{5-4} = 0b10;
1869  }
1870
1871  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1872              !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1873             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1874                                                   (sra GPR:$b, (i32 16)))))]> {
1875    let Inst{31-27} = 0b11111;
1876    let Inst{26-23} = 0b0110;
1877    let Inst{22-20} = 0b001;
1878    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1879    let Inst{7-6} = 0b00;
1880    let Inst{5-4} = 0b11;
1881  }
1882
1883  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1884              !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1885              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1886                                      (sext_inreg GPR:$b, i16)), (i32 16))))]> {
1887    let Inst{31-27} = 0b11111;
1888    let Inst{26-23} = 0b0110;
1889    let Inst{22-20} = 0b011;
1890    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1891    let Inst{7-6} = 0b00;
1892    let Inst{5-4} = 0b00;
1893  }
1894
1895  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1896              !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1897              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1898                                        (sra GPR:$b, (i32 16))), (i32 16))))]> {
1899    let Inst{31-27} = 0b11111;
1900    let Inst{26-23} = 0b0110;
1901    let Inst{22-20} = 0b011;
1902    let Inst{15-12} = {?, ?, ?, ?}; // Ra
1903    let Inst{7-6} = 0b00;
1904    let Inst{5-4} = 0b01;
1905  }
1906}
1907
1908defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1909defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1910
1911// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
1912def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs GPR:$ldst,GPR:$hdst),
1913           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1914           [/* For disassembly only; pattern left blank */]>;
1915def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs GPR:$ldst,GPR:$hdst),
1916           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1917           [/* For disassembly only; pattern left blank */]>;
1918def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs GPR:$ldst,GPR:$hdst),
1919           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1920           [/* For disassembly only; pattern left blank */]>;
1921def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs GPR:$ldst,GPR:$hdst),
1922           (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1923           [/* For disassembly only; pattern left blank */]>;
1924
1925// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1926// These are for disassembly only.
1927
1928def t2SMUAD   : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1929                        IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
1930  let Inst{15-12} = 0b1111;
1931}
1932def t2SMUADX  : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1933                        IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
1934  let Inst{15-12} = 0b1111;
1935}
1936def t2SMUSD   : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1937                        IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
1938  let Inst{15-12} = 0b1111;
1939}
1940def t2SMUSDX  : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1941                        IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
1942  let Inst{15-12} = 0b1111;
1943}
1944def t2SMLAD   : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst),
1945                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlad",
1946                        "\t$dst, $a, $b, $acc", []>;
1947def t2SMLADX  : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst),
1948                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smladx",
1949                        "\t$dst, $a, $b, $acc", []>;
1950def t2SMLSD   : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst),
1951                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsd",
1952                        "\t$dst, $a, $b, $acc", []>;
1953def t2SMLSDX  : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst),
1954                        (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsdx",
1955                        "\t$dst, $a, $b, $acc", []>;
1956def t2SMLALD  : T2I_mac<1, 0b100, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1957                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlald",
1958                        "\t$ldst, $hdst, $a, $b", []>;
1959def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1960                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaldx",
1961                        "\t$ldst, $hdst, $a, $b", []>;
1962def t2SMLSLD  : T2I_mac<1, 0b101, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1963                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsld",
1964                        "\t$ldst, $hdst, $a, $b", []>;
1965def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1966                        (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsldx",
1967                        "\t$ldst, $hdst, $a, $b", []>;
1968
1969//===----------------------------------------------------------------------===//
1970//  Misc. Arithmetic Instructions.
1971//
1972
1973class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
1974      InstrItinClass itin, string opc, string asm, list<dag> pattern>
1975  : T2I<oops, iops, itin, opc, asm, pattern> {
1976  let Inst{31-27} = 0b11111;
1977  let Inst{26-22} = 0b01010;
1978  let Inst{21-20} = op1;
1979  let Inst{15-12} = 0b1111;
1980  let Inst{7-6} = 0b10;
1981  let Inst{5-4} = op2;
1982}
1983
1984def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1985                    "clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
1986
1987def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1988                      "rbit", "\t$dst, $src",
1989                      [(set GPR:$dst, (ARMrbit GPR:$src))]>;
1990
1991def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1992                   "rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
1993
1994def t2REV16 : T2I_misc<0b01, 0b01, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1995                       "rev16", ".w\t$dst, $src",
1996                [(set GPR:$dst,
1997                    (or (and (srl GPR:$src, (i32 8)), 0xFF),
1998                        (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1999                            (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2000                                (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
2001
2002def t2REVSH : T2I_misc<0b01, 0b11, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2003                       "revsh", ".w\t$dst, $src",
2004                 [(set GPR:$dst,
2005                    (sext_inreg
2006                      (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2007                          (shl GPR:$src, (i32 8))), i16))]>;
2008
2009def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2010                  IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2011                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2012                                      (and (shl GPR:$src2, (i32 imm:$shamt)),
2013                                           0xFFFF0000)))]> {
2014  let Inst{31-27} = 0b11101;
2015  let Inst{26-25} = 0b01;
2016  let Inst{24-20} = 0b01100;
2017  let Inst{5} = 0; // BT form
2018  let Inst{4} = 0;
2019}
2020
2021// Alternate cases for PKHBT where identities eliminate some nodes.
2022def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2023            (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
2024def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2025            (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2026
2027def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2028                  IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2029                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2030                                      (and (sra GPR:$src2, imm16_31:$shamt),
2031                                           0xFFFF)))]> {
2032  let Inst{31-27} = 0b11101;
2033  let Inst{26-25} = 0b01;
2034  let Inst{24-20} = 0b01100;
2035  let Inst{5} = 1; // TB form
2036  let Inst{4} = 0;
2037}
2038
2039// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
2040// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2041def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2042            (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
2043def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
2044                     (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2045            (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2046
2047//===----------------------------------------------------------------------===//
2048//  Comparison Instructions...
2049//
2050
2051defm t2CMP  : T2I_cmp_irs<0b1101, "cmp",
2052                          BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2053defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2054                          BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2055
2056//FIXME: Disable CMN, as CCodes are backwards from compare expectations
2057//       Compare-to-zero still works out, just not the relationals
2058//defm t2CMN  : T2I_cmp_irs<0b1000, "cmn",
2059//                          BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2060defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2061                          BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2062
2063//def : T2Pat<(ARMcmp  GPR:$src, t2_so_imm_neg:$imm),
2064//            (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2065
2066def : T2Pat<(ARMcmpZ  GPR:$src, t2_so_imm_neg:$imm),
2067            (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2068
2069defm t2TST  : T2I_cmp_irs<0b0000, "tst",
2070                          BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2071defm t2TEQ  : T2I_cmp_irs<0b0100, "teq",
2072                          BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2073
2074// A8.6.27  CBNZ, CBZ - Compare and branch on (non)zero.
2075// Short range conditional branch. Looks awesome for loops. Need to figure
2076// out how to use this one.
2077
2078
2079// Conditional moves
2080// FIXME: should be able to write a pattern for ARMcmov, but can't use
2081// a two-value operand where a dag node expects two operands. :(
2082def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
2083                   "mov", ".w\t$dst, $true",
2084      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2085                RegConstraint<"$false = $dst"> {
2086  let Inst{31-27} = 0b11101;
2087  let Inst{26-25} = 0b01;
2088  let Inst{24-21} = 0b0010;
2089  let Inst{20} = 0; // The S bit.
2090  let Inst{19-16} = 0b1111; // Rn
2091  let Inst{14-12} = 0b000;
2092  let Inst{7-4} = 0b0000;
2093}
2094
2095def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
2096                   IIC_iCMOVi, "mov", ".w\t$dst, $true",
2097[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2098                   RegConstraint<"$false = $dst"> {
2099  let Inst{31-27} = 0b11110;
2100  let Inst{25} = 0;
2101  let Inst{24-21} = 0b0010;
2102  let Inst{20} = 0; // The S bit.
2103  let Inst{19-16} = 0b1111; // Rn
2104  let Inst{15} = 0;
2105}
2106
2107class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2108                   string opc, string asm, list<dag> pattern>
2109  : T2I<oops, iops, itin, opc, asm, pattern> {
2110  let Inst{31-27} = 0b11101;
2111  let Inst{26-25} = 0b01;
2112  let Inst{24-21} = 0b0010;
2113  let Inst{20} = 0; // The S bit.
2114  let Inst{19-16} = 0b1111; // Rn
2115  let Inst{5-4} = opcod; // Shift type.
2116}
2117def t2MOVCClsl : T2I_movcc_sh<0b00, (outs GPR:$dst),
2118                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
2119                             IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2120                 RegConstraint<"$false = $dst">;
2121def t2MOVCClsr : T2I_movcc_sh<0b01, (outs GPR:$dst),
2122                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
2123                             IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2124                 RegConstraint<"$false = $dst">;
2125def t2MOVCCasr : T2I_movcc_sh<0b10, (outs GPR:$dst),
2126                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
2127                             IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2128                 RegConstraint<"$false = $dst">;
2129def t2MOVCCror : T2I_movcc_sh<0b11, (outs GPR:$dst),
2130                             (ins GPR:$false, GPR:$true, i32imm:$rhs),
2131                             IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2132                 RegConstraint<"$false = $dst">;
2133
2134//===----------------------------------------------------------------------===//
2135// Atomic operations intrinsics
2136//
2137
2138// memory barriers protect the atomic sequences
2139let hasSideEffects = 1 in {
2140def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
2141                        Pseudo, NoItinerary,
2142                        "dmb", "",
2143                        [(ARMMemBarrierV7)]>,
2144                        Requires<[IsThumb2]> {
2145  let Inst{31-4} = 0xF3BF8F5;
2146  // FIXME: add support for options other than a full system DMB
2147  let Inst{3-0} = 0b1111;
2148}
2149
2150def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
2151                        Pseudo, NoItinerary,
2152                        "dsb", "",
2153                        [(ARMSyncBarrierV7)]>,
2154                        Requires<[IsThumb2]> {
2155  let Inst{31-4} = 0xF3BF8F4;
2156  // FIXME: add support for options other than a full system DSB
2157  let Inst{3-0} = 0b1111;
2158}
2159}
2160
2161// Helper class for multiclass T2MemB -- for disassembly only
2162class T2I_memb<string opc, string asm>
2163  : T2I<(outs), (ins), NoItinerary, opc, asm,
2164        [/* For disassembly only; pattern left blank */]>,
2165    Requires<[IsThumb2, HasV7]> {
2166  let Inst{31-20} = 0xf3b;
2167  let Inst{15-14} = 0b10;
2168  let Inst{12} = 0;
2169}
2170
2171multiclass T2MemB<bits<4> op7_4, string opc> {
2172
2173  def st : T2I_memb<opc, "\tst"> {
2174    let Inst{7-4} = op7_4;
2175    let Inst{3-0} = 0b1110;
2176  }
2177
2178  def ish : T2I_memb<opc, "\tish"> {
2179    let Inst{7-4} = op7_4;
2180    let Inst{3-0} = 0b1011;
2181  }
2182
2183  def ishst : T2I_memb<opc, "\tishst"> {
2184    let Inst{7-4} = op7_4;
2185    let Inst{3-0} = 0b1010;
2186  }
2187
2188  def nsh : T2I_memb<opc, "\tnsh"> {
2189    let Inst{7-4} = op7_4;
2190    let Inst{3-0} = 0b0111;
2191  }
2192
2193  def nshst : T2I_memb<opc, "\tnshst"> {
2194    let Inst{7-4} = op7_4;
2195    let Inst{3-0} = 0b0110;
2196  }
2197
2198  def osh : T2I_memb<opc, "\tosh"> {
2199    let Inst{7-4} = op7_4;
2200    let Inst{3-0} = 0b0011;
2201  }
2202
2203  def oshst : T2I_memb<opc, "\toshst"> {
2204    let Inst{7-4} = op7_4;
2205    let Inst{3-0} = 0b0010;
2206  }
2207}
2208
2209// These DMB variants are for disassembly only.
2210defm t2DMB : T2MemB<0b0101, "dmb">;
2211
2212// These DSB variants are for disassembly only.
2213defm t2DSB : T2MemB<0b0100, "dsb">;
2214
2215// ISB has only full system option -- for disassembly only
2216def t2ISBsy : T2I_memb<"isb", ""> {
2217  let Inst{7-4} = 0b0110;
2218  let Inst{3-0} = 0b1111;
2219}
2220
2221class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2222                InstrItinClass itin, string opc, string asm, string cstr,
2223                list<dag> pattern, bits<4> rt2 = 0b1111>
2224  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2225  let Inst{31-27} = 0b11101;
2226  let Inst{26-20} = 0b0001101;
2227  let Inst{11-8} = rt2;
2228  let Inst{7-6} = 0b01;
2229  let Inst{5-4} = opcod;
2230  let Inst{3-0} = 0b1111;
2231}
2232class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2233                InstrItinClass itin, string opc, string asm, string cstr,
2234                list<dag> pattern, bits<4> rt2 = 0b1111>
2235  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2236  let Inst{31-27} = 0b11101;
2237  let Inst{26-20} = 0b0001100;
2238  let Inst{11-8} = rt2;
2239  let Inst{7-6} = 0b01;
2240  let Inst{5-4} = opcod;
2241}
2242
2243let mayLoad = 1 in {
2244def t2LDREXB : T2I_ldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2245                         Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2246                         "", []>;
2247def t2LDREXH : T2I_ldrex<0b01, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2248                         Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2249                         "", []>;
2250def t2LDREX  : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2251                       Size4Bytes, NoItinerary,
2252                       "ldrex", "\t$dest, [$ptr]", "",
2253                      []> {
2254  let Inst{31-27} = 0b11101;
2255  let Inst{26-20} = 0b0000101;
2256  let Inst{11-8} = 0b1111;
2257  let Inst{7-0} = 0b00000000; // imm8 = 0
2258}
2259def t2LDREXD : T2I_ldrex<0b11, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2260                         AddrModeNone, Size4Bytes, NoItinerary,
2261                         "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2262                         [], {?, ?, ?, ?}>;
2263}
2264
2265let mayStore = 1, Constraints = "@earlyclobber $success" in {
2266def t2STREXB : T2I_strex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2267                         AddrModeNone, Size4Bytes, NoItinerary,
2268                         "strexb", "\t$success, $src, [$ptr]", "", []>;
2269def t2STREXH : T2I_strex<0b01, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2270                         AddrModeNone, Size4Bytes, NoItinerary,
2271                         "strexh", "\t$success, $src, [$ptr]", "", []>;
2272def t2STREX  : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2273                       AddrModeNone, Size4Bytes, NoItinerary,
2274                       "strex", "\t$success, $src, [$ptr]", "",
2275                      []> {
2276  let Inst{31-27} = 0b11101;
2277  let Inst{26-20} = 0b0000100;
2278  let Inst{7-0} = 0b00000000; // imm8 = 0
2279}
2280def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
2281                         (ins GPR:$src, GPR:$src2, GPR:$ptr),
2282                         AddrModeNone, Size4Bytes, NoItinerary,
2283                         "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2284                         {?, ?, ?, ?}>;
2285}
2286
2287// Clear-Exclusive is for disassembly only.
2288def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2289                  [/* For disassembly only; pattern left blank */]>,
2290            Requires<[IsARM, HasV7]>  {
2291  let Inst{31-20} = 0xf3b;
2292  let Inst{15-14} = 0b10;
2293  let Inst{12} = 0;
2294  let Inst{7-4} = 0b0010;
2295}
2296
2297//===----------------------------------------------------------------------===//
2298// TLS Instructions
2299//
2300
2301// __aeabi_read_tp preserves the registers r1-r3.
2302let isCall = 1,
2303  Defs = [R0, R12, LR, CPSR] in {
2304  def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2305                     "bl\t__aeabi_read_tp",
2306                     [(set R0, ARMthread_pointer)]> {
2307    let Inst{31-27} = 0b11110;
2308    let Inst{15-14} = 0b11;
2309    let Inst{12} = 1;
2310  }
2311}
2312
2313//===----------------------------------------------------------------------===//
2314// SJLJ Exception handling intrinsics
2315//   eh_sjlj_setjmp() is an instruction sequence to store the return
2316//   address and save #0 in R0 for the non-longjmp case.
2317//   Since by its nature we may be coming from some other function to get
2318//   here, and we're using the stack frame for the containing function to
2319//   save/restore registers, we can't keep anything live in regs across
2320//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2321//   when we get here from a longjmp(). We force everthing out of registers
2322//   except for our own input by listing the relevant registers in Defs. By
2323//   doing so, we also cause the prologue/epilogue code to actively preserve
2324//   all of the callee-saved resgisters, which is exactly what we want.
2325//   The current SP is passed in $val, and we reuse the reg as a scratch.
2326let Defs =
2327  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
2328    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
2329    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2330    D31 ] in {
2331  def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
2332                               AddrModeNone, SizeSpecial, NoItinerary,
2333                               "str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
2334                               "\tmov\t$val, pc\n"
2335                               "\tadds\t$val, #9\n"
2336                               "\tstr\t$val, [$src, #4]\n"
2337                               "\tmovs\tr0, #0\n"
2338                               "\tb\t1f\n"
2339                               "\tmovs\tr0, #1\t@ end eh.setjmp\n"
2340                               "1:", "",
2341                          [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
2342}
2343
2344
2345
2346//===----------------------------------------------------------------------===//
2347// Control-Flow Instructions
2348//
2349
2350// FIXME: remove when we have a way to marking a MI with these properties.
2351// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2352// operand list.
2353// FIXME: Should pc be an implicit operand like PICADD, etc?
2354let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2355    hasExtraDefRegAllocReq = 1 in
2356  def t2LDM_RET : T2XI<(outs),
2357                    (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
2358                    IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
2359                    []> {
2360  let Inst{31-27} = 0b11101;
2361  let Inst{26-25} = 0b00;
2362  let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2363  let Inst{22} = 0;
2364  let Inst{21} = ?; // The W bit.
2365  let Inst{20} = 1; // Load
2366}
2367
2368let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2369let isPredicable = 1 in
2370def t2B   : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2371                 "b.w\t$target",
2372                 [(br bb:$target)]> {
2373  let Inst{31-27} = 0b11110;
2374  let Inst{15-14} = 0b10;
2375  let Inst{12} = 1;
2376}
2377
2378let isNotDuplicable = 1, isIndirectBranch = 1 in {
2379def t2BR_JT :
2380    T2JTI<(outs),
2381          (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2382           IIC_Br, "mov\tpc, $target\n$jt",
2383          [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2384  let Inst{31-27} = 0b11101;
2385  let Inst{26-20} = 0b0100100;
2386  let Inst{19-16} = 0b1111;
2387  let Inst{14-12} = 0b000;
2388  let Inst{11-8} = 0b1111; // Rd = pc
2389  let Inst{7-4} = 0b0000;
2390}
2391
2392// FIXME: Add a non-pc based case that can be predicated.
2393def t2TBB :
2394    T2JTI<(outs),
2395        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2396         IIC_Br, "tbb\t$index\n$jt", []> {
2397  let Inst{31-27} = 0b11101;
2398  let Inst{26-20} = 0b0001101;
2399  let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2400  let Inst{15-8} = 0b11110000;
2401  let Inst{7-4} = 0b0000; // B form
2402}
2403
2404def t2TBH :
2405    T2JTI<(outs),
2406        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2407         IIC_Br, "tbh\t$index\n$jt", []> {
2408  let Inst{31-27} = 0b11101;
2409  let Inst{26-20} = 0b0001101;
2410  let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2411  let Inst{15-8} = 0b11110000;
2412  let Inst{7-4} = 0b0001; // H form
2413}
2414
2415// Generic versions of the above two instructions, for disassembly only
2416
2417def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2418                    "tbb", "\t[$a, $b]", []>{
2419  let Inst{31-27} = 0b11101;
2420  let Inst{26-20} = 0b0001101;
2421  let Inst{15-8} = 0b11110000;
2422  let Inst{7-4} = 0b0000; // B form
2423}
2424
2425def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2426                   "tbh", "\t[$a, $b, lsl #1]", []> {
2427  let Inst{31-27} = 0b11101;
2428  let Inst{26-20} = 0b0001101;
2429  let Inst{15-8} = 0b11110000;
2430  let Inst{7-4} = 0b0001; // H form
2431}
2432} // isNotDuplicable, isIndirectBranch
2433
2434} // isBranch, isTerminator, isBarrier
2435
2436// FIXME: should be able to write a pattern for ARMBrcond, but can't use
2437// a two-value operand where a dag node expects two operands. :(
2438let isBranch = 1, isTerminator = 1 in
2439def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2440                "b", ".w\t$target",
2441                [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2442  let Inst{31-27} = 0b11110;
2443  let Inst{15-14} = 0b10;
2444  let Inst{12} = 0;
2445}
2446
2447
2448// IT block
2449def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2450                    AddrModeNone, Size2Bytes,  IIC_iALUx,
2451                    "it$mask\t$cc", "", []> {
2452  // 16-bit instruction.
2453  let Inst{31-16} = 0x0000;
2454  let Inst{15-8} = 0b10111111;
2455}
2456
2457// Branch and Exchange Jazelle -- for disassembly only
2458// Rm = Inst{19-16}
2459def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
2460              [/* For disassembly only; pattern left blank */]> {
2461  let Inst{31-27} = 0b11110;
2462  let Inst{26} = 0;
2463  let Inst{25-20} = 0b111100;
2464  let Inst{15-14} = 0b10;
2465  let Inst{12} = 0;
2466}
2467
2468// Change Processor State is a system instruction -- for disassembly only.
2469// The singleton $opt operand contains the following information:
2470// opt{4-0} = mode from Inst{4-0}
2471// opt{5} = changemode from Inst{17}
2472// opt{8-6} = AIF from Inst{8-6}
2473// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2474def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2475                 [/* For disassembly only; pattern left blank */]> {
2476  let Inst{31-27} = 0b11110;
2477  let Inst{26} = 0;
2478  let Inst{25-20} = 0b111010;
2479  let Inst{15-14} = 0b10;
2480  let Inst{12} = 0;
2481}
2482
2483// A6.3.4 Branches and miscellaneous control
2484// Table A6-14 Change Processor State, and hint instructions
2485// Helper class for disassembly only.
2486class T2I_hint<bits<8> op7_0, string opc, string asm>
2487  : T2I<(outs), (ins), NoItinerary, opc, asm,
2488        [/* For disassembly only; pattern left blank */]> {
2489  let Inst{31-20} = 0xf3a;
2490  let Inst{15-14} = 0b10;
2491  let Inst{12} = 0;
2492  let Inst{10-8} = 0b000;
2493  let Inst{7-0} = op7_0;
2494}
2495
2496def t2NOP   : T2I_hint<0b00000000, "nop",   ".w">;
2497def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2498def t2WFE   : T2I_hint<0b00000010, "wfe",   ".w">;
2499def t2WFI   : T2I_hint<0b00000011, "wfi",   ".w">;
2500def t2SEV   : T2I_hint<0b00000100, "sev",   ".w">;
2501
2502def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2503                [/* For disassembly only; pattern left blank */]> {
2504  let Inst{31-20} = 0xf3a;
2505  let Inst{15-14} = 0b10;
2506  let Inst{12} = 0;
2507  let Inst{10-8} = 0b000;
2508  let Inst{7-4} = 0b1111;
2509}
2510
2511// Secure Monitor Call is a system instruction -- for disassembly only
2512// Option = Inst{19-16}
2513def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2514                [/* For disassembly only; pattern left blank */]> {
2515  let Inst{31-27} = 0b11110;
2516  let Inst{26-20} = 0b1111111;
2517  let Inst{15-12} = 0b1000;
2518}
2519
2520// Store Return State is a system instruction -- for disassembly only
2521def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2522                   [/* For disassembly only; pattern left blank */]> {
2523  let Inst{31-27} = 0b11101;
2524  let Inst{26-20} = 0b0000010; // W = 1
2525}
2526
2527def t2SRSDB  : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2528                   [/* For disassembly only; pattern left blank */]> {
2529  let Inst{31-27} = 0b11101;
2530  let Inst{26-20} = 0b0000000; // W = 0
2531}
2532
2533def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2534                   [/* For disassembly only; pattern left blank */]> {
2535  let Inst{31-27} = 0b11101;
2536  let Inst{26-20} = 0b0011010; // W = 1
2537}
2538
2539def t2SRSIA  : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2540                   [/* For disassembly only; pattern left blank */]> {
2541  let Inst{31-27} = 0b11101;
2542  let Inst{26-20} = 0b0011000; // W = 0
2543}
2544
2545// Return From Exception is a system instruction -- for disassembly only
2546def t2RFEDBW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfedb", "\t$base!",
2547                   [/* For disassembly only; pattern left blank */]> {
2548  let Inst{31-27} = 0b11101;
2549  let Inst{26-20} = 0b0000011; // W = 1
2550}
2551
2552def t2RFEDB  : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeab", "\t$base",
2553                   [/* For disassembly only; pattern left blank */]> {
2554  let Inst{31-27} = 0b11101;
2555  let Inst{26-20} = 0b0000001; // W = 0
2556}
2557
2558def t2RFEIAW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base!",
2559                   [/* For disassembly only; pattern left blank */]> {
2560  let Inst{31-27} = 0b11101;
2561  let Inst{26-20} = 0b0011011; // W = 1
2562}
2563
2564def t2RFEIA  : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base",
2565                   [/* For disassembly only; pattern left blank */]> {
2566  let Inst{31-27} = 0b11101;
2567  let Inst{26-20} = 0b0011001; // W = 0
2568}
2569
2570//===----------------------------------------------------------------------===//
2571// Non-Instruction Patterns
2572//
2573
2574// Two piece so_imms.
2575def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
2576             (t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2577                    (t2_so_imm2part_2 imm:$RHS))>;
2578def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
2579             (t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2580                    (t2_so_imm2part_2 imm:$RHS))>;
2581def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
2582             (t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2583                    (t2_so_imm2part_2 imm:$RHS))>;
2584def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
2585             (t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2586                    (t2_so_neg_imm2part_2 imm:$RHS))>;
2587
2588// 32-bit immediate using movw + movt.
2589// This is a single pseudo instruction to make it re-materializable. Remove
2590// when we can do generalized remat.
2591let isReMaterializable = 1 in
2592def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
2593                   "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2594                     [(set GPR:$dst, (i32 imm:$src))]>;
2595
2596// ConstantPool, GlobalAddress, and JumpTable
2597def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2598           Requires<[IsThumb2, DontUseMovt]>;
2599def : T2Pat<(ARMWrapper  tconstpool  :$dst), (t2LEApcrel tconstpool  :$dst)>;
2600def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2601           Requires<[IsThumb2, UseMovt]>;
2602
2603def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2604            (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2605
2606// Pseudo instruction that combines ldr from constpool and add pc. This should
2607// be expanded into two instructions late to allow if-conversion and
2608// scheduling.
2609let canFoldAsLoad = 1, isReMaterializable = 1 in
2610def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2611                   NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
2612               [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2613                                           imm:$cp))]>,
2614               Requires<[IsThumb2]>;
2615
2616//===----------------------------------------------------------------------===//
2617// Move between special register and ARM core register -- for disassembly only
2618//
2619
2620// Rd = Instr{11-8}
2621def t2MRS : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2622                [/* For disassembly only; pattern left blank */]> {
2623  let Inst{31-27} = 0b11110;
2624  let Inst{26} = 0;
2625  let Inst{25-21} = 0b11111;
2626  let Inst{20} = 0; // The R bit.
2627  let Inst{15-14} = 0b10;
2628  let Inst{12} = 0;
2629}
2630
2631// Rd = Instr{11-8}
2632def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2633                   [/* For disassembly only; pattern left blank */]> {
2634  let Inst{31-27} = 0b11110;
2635  let Inst{26} = 0;
2636  let Inst{25-21} = 0b11111;
2637  let Inst{20} = 1; // The R bit.
2638  let Inst{15-14} = 0b10;
2639  let Inst{12} = 0;
2640}
2641
2642// Rn = Inst{19-16}
2643def t2MSR : T2I<(outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, "msr",
2644                "\tcpsr$mask, $src",
2645                [/* For disassembly only; pattern left blank */]> {
2646  let Inst{31-27} = 0b11110;
2647  let Inst{26} = 0;
2648  let Inst{25-21} = 0b11100;
2649  let Inst{20} = 0; // The R bit.
2650  let Inst{15-14} = 0b10;
2651  let Inst{12} = 0;
2652}
2653
2654// Rn = Inst{19-16}
2655def t2MSRsys : T2I<(outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, "msr",
2656                   "\tspsr$mask, $src",
2657                   [/* For disassembly only; pattern left blank */]> {
2658  let Inst{31-27} = 0b11110;
2659  let Inst{26} = 0;
2660  let Inst{25-21} = 0b11100;
2661  let Inst{20} = 1; // The R bit.
2662  let Inst{15-14} = 0b10;
2663  let Inst{12} = 0;
2664}
2665