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