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