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