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