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