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