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