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