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