ARMInstrThumb2.td revision 8d66b7852afec301a1a667069f8c497da2eec964
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:$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), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1701                    "movt", "\t$Rd, $imm",
1702                    [(set rGPR:$Rd,
1703                          (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1704  let Inst{31-27} = 0b11110;
1705  let Inst{25} = 1;
1706  let Inst{24-21} = 0b0110;
1707  let Inst{20} = 0; // The S bit.
1708  let Inst{15} = 0;
1709
1710  bits<4> Rd;
1711  bits<16> imm;
1712
1713  let Inst{11-8}  = Rd;
1714  let Inst{19-16} = imm{15-12};
1715  let Inst{26}    = imm{11};
1716  let Inst{14-12} = imm{10-8};
1717  let Inst{7-0}   = imm{7-0};
1718}
1719
1720def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1721
1722//===----------------------------------------------------------------------===//
1723//  Extend Instructions.
1724//
1725
1726// Sign extenders
1727
1728defm t2SXTB  : T2I_ext_rrot<0b100, "sxtb",
1729                              UnOpFrag<(sext_inreg node:$Src, i8)>>;
1730defm t2SXTH  : T2I_ext_rrot<0b000, "sxth",
1731                              UnOpFrag<(sext_inreg node:$Src, i16)>>;
1732defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1733
1734defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1735                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1736defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1737                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1738defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1739
1740// TODO: SXT(A){B|H}16 - done for disassembly only
1741
1742// Zero extenders
1743
1744let AddedComplexity = 16 in {
1745defm t2UXTB   : T2I_ext_rrot<0b101, "uxtb",
1746                               UnOpFrag<(and node:$Src, 0x000000FF)>>;
1747defm t2UXTH   : T2I_ext_rrot<0b001, "uxth",
1748                               UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1749defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1750                               UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1751
1752// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1753//        The transformation should probably be done as a combiner action
1754//        instead so we can include a check for masking back in the upper
1755//        eight bits of the source into the lower eight bits of the result.
1756//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1757//            (t2UXTB16r_rot rGPR:$Src, 24)>,
1758//          Requires<[HasT2ExtractPack, IsThumb2]>;
1759def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1760            (t2UXTB16r_rot rGPR:$Src, 8)>,
1761        Requires<[HasT2ExtractPack, IsThumb2]>;
1762
1763defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1764                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1765defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1766                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1767defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1768}
1769
1770//===----------------------------------------------------------------------===//
1771//  Arithmetic Instructions.
1772//
1773
1774defm t2ADD  : T2I_bin_ii12rs<0b000, "add",
1775                             BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
1776defm t2SUB  : T2I_bin_ii12rs<0b101, "sub",
1777                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1778
1779// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1780defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1781                             IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1782                             BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1783defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1784                             IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1785                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1786
1787defm t2ADC  : T2I_adde_sube_irs<0b1010, "adc",
1788                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1789defm t2SBC  : T2I_adde_sube_irs<0b1011, "sbc",
1790                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1791defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1792                          BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1793defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1794                          BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1795
1796// RSB
1797defm t2RSB  : T2I_rbin_irs  <0b1110, "rsb",
1798                             BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
1799defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1800                             BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1801
1802// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
1803// The assume-no-carry-in form uses the negation of the input since add/sub
1804// assume opposite meanings of the carry flag (i.e., carry == !borrow).
1805// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1806// details.
1807// The AddedComplexity preferences the first variant over the others since
1808// it can be shrunk to a 16-bit wide encoding, while the others cannot.
1809let AddedComplexity = 1 in
1810def : T2Pat<(add        GPR:$src, imm0_255_neg:$imm),
1811            (t2SUBri    GPR:$src, imm0_255_neg:$imm)>;
1812def : T2Pat<(add        GPR:$src, t2_so_imm_neg:$imm),
1813            (t2SUBri    GPR:$src, t2_so_imm_neg:$imm)>;
1814def : T2Pat<(add        GPR:$src, imm0_4095_neg:$imm),
1815            (t2SUBri12  GPR:$src, imm0_4095_neg:$imm)>;
1816let AddedComplexity = 1 in
1817def : T2Pat<(addc       rGPR:$src, imm0_255_neg:$imm),
1818            (t2SUBSri   rGPR:$src, imm0_255_neg:$imm)>;
1819def : T2Pat<(addc       rGPR:$src, t2_so_imm_neg:$imm),
1820            (t2SUBSri   rGPR:$src, t2_so_imm_neg:$imm)>;
1821// The with-carry-in form matches bitwise not instead of the negation.
1822// Effectively, the inverse interpretation of the carry flag already accounts
1823// for part of the negation.
1824let AddedComplexity = 1 in
1825def : T2Pat<(adde       rGPR:$src, imm0_255_not:$imm),
1826            (t2SBCSri   rGPR:$src, imm0_255_not:$imm)>;
1827def : T2Pat<(adde       rGPR:$src, t2_so_imm_not:$imm),
1828            (t2SBCSri   rGPR:$src, t2_so_imm_not:$imm)>;
1829
1830// Select Bytes -- for disassembly only
1831
1832def t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1833                NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []> {
1834  let Inst{31-27} = 0b11111;
1835  let Inst{26-24} = 0b010;
1836  let Inst{23} = 0b1;
1837  let Inst{22-20} = 0b010;
1838  let Inst{15-12} = 0b1111;
1839  let Inst{7} = 0b1;
1840  let Inst{6-4} = 0b000;
1841}
1842
1843// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1844// And Miscellaneous operations -- for disassembly only
1845class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1846              list<dag> pat = [/* For disassembly only; pattern left blank */]>
1847  : T2I<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), NoItinerary, opc,
1848        "\t$Rd, $Rn, $Rm", pat> {
1849  let Inst{31-27} = 0b11111;
1850  let Inst{26-23} = 0b0101;
1851  let Inst{22-20} = op22_20;
1852  let Inst{15-12} = 0b1111;
1853  let Inst{7-4} = op7_4;
1854
1855  bits<4> Rd;
1856  bits<4> Rn;
1857  bits<4> Rm;
1858
1859  let Inst{11-8}  = Rd;
1860  let Inst{19-16} = Rn;
1861  let Inst{3-0}   = Rm;
1862}
1863
1864// Saturating add/subtract -- for disassembly only
1865
1866def t2QADD    : T2I_pam<0b000, 0b1000, "qadd",
1867                        [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))]>;
1868def t2QADD16  : T2I_pam<0b001, 0b0001, "qadd16">;
1869def t2QADD8   : T2I_pam<0b000, 0b0001, "qadd8">;
1870def t2QASX    : T2I_pam<0b010, 0b0001, "qasx">;
1871def t2QDADD   : T2I_pam<0b000, 0b1001, "qdadd">;
1872def t2QDSUB   : T2I_pam<0b000, 0b1011, "qdsub">;
1873def t2QSAX    : T2I_pam<0b110, 0b0001, "qsax">;
1874def t2QSUB    : T2I_pam<0b000, 0b1010, "qsub",
1875                        [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))]>;
1876def t2QSUB16  : T2I_pam<0b101, 0b0001, "qsub16">;
1877def t2QSUB8   : T2I_pam<0b100, 0b0001, "qsub8">;
1878def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1879def t2UQADD8  : T2I_pam<0b000, 0b0101, "uqadd8">;
1880def t2UQASX   : T2I_pam<0b010, 0b0101, "uqasx">;
1881def t2UQSAX   : T2I_pam<0b110, 0b0101, "uqsax">;
1882def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1883def t2UQSUB8  : T2I_pam<0b100, 0b0101, "uqsub8">;
1884
1885// Signed/Unsigned add/subtract -- for disassembly only
1886
1887def t2SASX    : T2I_pam<0b010, 0b0000, "sasx">;
1888def t2SADD16  : T2I_pam<0b001, 0b0000, "sadd16">;
1889def t2SADD8   : T2I_pam<0b000, 0b0000, "sadd8">;
1890def t2SSAX    : T2I_pam<0b110, 0b0000, "ssax">;
1891def t2SSUB16  : T2I_pam<0b101, 0b0000, "ssub16">;
1892def t2SSUB8   : T2I_pam<0b100, 0b0000, "ssub8">;
1893def t2UASX    : T2I_pam<0b010, 0b0100, "uasx">;
1894def t2UADD16  : T2I_pam<0b001, 0b0100, "uadd16">;
1895def t2UADD8   : T2I_pam<0b000, 0b0100, "uadd8">;
1896def t2USAX    : T2I_pam<0b110, 0b0100, "usax">;
1897def t2USUB16  : T2I_pam<0b101, 0b0100, "usub16">;
1898def t2USUB8   : T2I_pam<0b100, 0b0100, "usub8">;
1899
1900// Signed/Unsigned halving add/subtract -- for disassembly only
1901
1902def t2SHASX   : T2I_pam<0b010, 0b0010, "shasx">;
1903def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1904def t2SHADD8  : T2I_pam<0b000, 0b0010, "shadd8">;
1905def t2SHSAX   : T2I_pam<0b110, 0b0010, "shsax">;
1906def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1907def t2SHSUB8  : T2I_pam<0b100, 0b0010, "shsub8">;
1908def t2UHASX   : T2I_pam<0b010, 0b0110, "uhasx">;
1909def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1910def t2UHADD8  : T2I_pam<0b000, 0b0110, "uhadd8">;
1911def t2UHSAX   : T2I_pam<0b110, 0b0110, "uhsax">;
1912def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1913def t2UHSUB8  : T2I_pam<0b100, 0b0110, "uhsub8">;
1914
1915// Helper class for disassembly only
1916// A6.3.16 & A6.3.17
1917// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1918class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1919  dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1920  : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
1921  let Inst{31-27} = 0b11111;
1922  let Inst{26-24} = 0b011;
1923  let Inst{23}    = long;
1924  let Inst{22-20} = op22_20;
1925  let Inst{7-4}   = op7_4;
1926}
1927
1928class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1929  dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1930  : T2FourReg<oops, iops, itin, opc, asm, pattern> {
1931  let Inst{31-27} = 0b11111;
1932  let Inst{26-24} = 0b011;
1933  let Inst{23}    = long;
1934  let Inst{22-20} = op22_20;
1935  let Inst{7-4}   = op7_4;
1936}
1937
1938// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1939
1940def t2USAD8   : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1941                                           (ins rGPR:$Rn, rGPR:$Rm),
1942                        NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []> {
1943  let Inst{15-12} = 0b1111;
1944}
1945def t2USADA8  : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1946                       (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
1947                        "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>;
1948
1949// Signed/Unsigned saturate -- for disassembly only
1950
1951class T2SatI<dag oops, dag iops, InstrItinClass itin,
1952           string opc, string asm, list<dag> pattern>
1953  : T2I<oops, iops, itin, opc, asm, pattern> {
1954  bits<4> Rd;
1955  bits<4> Rn;
1956  bits<5> sat_imm;
1957  bits<7> sh;
1958
1959  let Inst{11-8}  = Rd;
1960  let Inst{19-16} = Rn;
1961  let Inst{4-0}   = sat_imm{4-0};
1962  let Inst{21}    = sh{6};
1963  let Inst{14-12} = sh{4-2};
1964  let Inst{7-6}   = sh{1-0};
1965}
1966
1967def t2SSAT: T2SatI<
1968                (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1969                NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
1970                [/* For disassembly only; pattern left blank */]> {
1971  let Inst{31-27} = 0b11110;
1972  let Inst{25-22} = 0b1100;
1973  let Inst{20} = 0;
1974  let Inst{15} = 0;
1975}
1976
1977def t2SSAT16: T2SatI<
1978                   (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
1979                   "ssat16", "\t$Rd, $sat_imm, $Rn",
1980                   [/* For disassembly only; pattern left blank */]> {
1981  let Inst{31-27} = 0b11110;
1982  let Inst{25-22} = 0b1100;
1983  let Inst{20} = 0;
1984  let Inst{15} = 0;
1985  let Inst{21} = 1;        // sh = '1'
1986  let Inst{14-12} = 0b000; // imm3 = '000'
1987  let Inst{7-6} = 0b00;    // imm2 = '00'
1988}
1989
1990def t2USAT: T2SatI<
1991                (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1992                NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh",
1993                [/* For disassembly only; pattern left blank */]> {
1994  let Inst{31-27} = 0b11110;
1995  let Inst{25-22} = 0b1110;
1996  let Inst{20} = 0;
1997  let Inst{15} = 0;
1998}
1999
2000def t2USAT16: T2SatI<
2001                    (outs rGPR:$dst), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
2002                   "usat16", "\t$dst, $sat_imm, $Rn",
2003                   [/* For disassembly only; pattern left blank */]> {
2004  let Inst{31-27} = 0b11110;
2005  let Inst{25-22} = 0b1110;
2006  let Inst{20} = 0;
2007  let Inst{15} = 0;
2008  let Inst{21} = 1;        // sh = '1'
2009  let Inst{14-12} = 0b000; // imm3 = '000'
2010  let Inst{7-6} = 0b00;    // imm2 = '00'
2011}
2012
2013def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
2014def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
2015
2016//===----------------------------------------------------------------------===//
2017//  Shift and rotate Instructions.
2018//
2019
2020defm t2LSL  : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl  node:$LHS, node:$RHS)>>;
2021defm t2LSR  : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl  node:$LHS, node:$RHS)>>;
2022defm t2ASR  : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra  node:$LHS, node:$RHS)>>;
2023defm t2ROR  : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
2024
2025let Uses = [CPSR] in {
2026def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2027                   "rrx", "\t$Rd, $Rm",
2028                   [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> {
2029  let Inst{31-27} = 0b11101;
2030  let Inst{26-25} = 0b01;
2031  let Inst{24-21} = 0b0010;
2032  let Inst{19-16} = 0b1111; // Rn
2033  let Inst{14-12} = 0b000;
2034  let Inst{7-4} = 0b0011;
2035}
2036}
2037
2038let isCodeGenOnly = 1, Defs = [CPSR] in {
2039def t2MOVsrl_flag : T2TwoRegShiftImm<
2040                        (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2041                        "lsrs", ".w\t$Rd, $Rm, #1",
2042                        [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> {
2043  let Inst{31-27} = 0b11101;
2044  let Inst{26-25} = 0b01;
2045  let Inst{24-21} = 0b0010;
2046  let Inst{20} = 1; // The S bit.
2047  let Inst{19-16} = 0b1111; // Rn
2048  let Inst{5-4} = 0b01; // Shift type.
2049  // Shift amount = Inst{14-12:7-6} = 1.
2050  let Inst{14-12} = 0b000;
2051  let Inst{7-6} = 0b01;
2052}
2053def t2MOVsra_flag : T2TwoRegShiftImm<
2054                        (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2055                        "asrs", ".w\t$Rd, $Rm, #1",
2056                        [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> {
2057  let Inst{31-27} = 0b11101;
2058  let Inst{26-25} = 0b01;
2059  let Inst{24-21} = 0b0010;
2060  let Inst{20} = 1; // The S bit.
2061  let Inst{19-16} = 0b1111; // Rn
2062  let Inst{5-4} = 0b10; // Shift type.
2063  // Shift amount = Inst{14-12:7-6} = 1.
2064  let Inst{14-12} = 0b000;
2065  let Inst{7-6} = 0b01;
2066}
2067}
2068
2069//===----------------------------------------------------------------------===//
2070//  Bitwise Instructions.
2071//
2072
2073defm t2AND  : T2I_bin_w_irs<0b0000, "and",
2074                            IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2075                            BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2076defm t2ORR  : T2I_bin_w_irs<0b0010, "orr",
2077                            IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2078                            BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
2079defm t2EOR  : T2I_bin_w_irs<0b0100, "eor",
2080                            IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2081                            BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2082
2083defm t2BIC  : T2I_bin_w_irs<0b0001, "bic",
2084                            IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2085                            BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2086
2087class T2BitFI<dag oops, dag iops, InstrItinClass itin,
2088              string opc, string asm, list<dag> pattern>
2089    : T2I<oops, iops, itin, opc, asm, pattern> {
2090  bits<4> Rd;
2091  bits<5> msb;
2092  bits<5> lsb;
2093
2094  let Inst{11-8}  = Rd;
2095  let Inst{4-0}   = msb{4-0};
2096  let Inst{14-12} = lsb{4-2};
2097  let Inst{7-6}   = lsb{1-0};
2098}
2099
2100class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2101              string opc, string asm, list<dag> pattern>
2102    : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2103  bits<4> Rn;
2104
2105  let Inst{19-16} = Rn;
2106}
2107
2108let Constraints = "$src = $Rd" in
2109def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2110                IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2111                [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2112  let Inst{31-27} = 0b11110;
2113  let Inst{25} = 1;
2114  let Inst{24-20} = 0b10110;
2115  let Inst{19-16} = 0b1111; // Rn
2116  let Inst{15} = 0;
2117
2118  bits<10> imm;
2119  let msb{4-0} = imm{9-5};
2120  let lsb{4-0} = imm{4-0};
2121}
2122
2123def t2SBFX: T2TwoRegBitFI<
2124                (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2125                 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2126  let Inst{31-27} = 0b11110;
2127  let Inst{25} = 1;
2128  let Inst{24-20} = 0b10100;
2129  let Inst{15} = 0;
2130}
2131
2132def t2UBFX: T2TwoRegBitFI<
2133                (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2134                 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2135  let Inst{31-27} = 0b11110;
2136  let Inst{25} = 1;
2137  let Inst{24-20} = 0b11100;
2138  let Inst{15} = 0;
2139}
2140
2141// A8.6.18  BFI - Bitfield insert (Encoding T1)
2142let Constraints = "$src = $Rd" in
2143def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2144                (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2145                IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2146                [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2147                                 bf_inv_mask_imm:$imm))]> {
2148  let Inst{31-27} = 0b11110;
2149  let Inst{25} = 1;
2150  let Inst{24-20} = 0b10110;
2151  let Inst{15} = 0;
2152
2153  bits<10> imm;
2154  let msb{4-0} = imm{9-5};
2155  let lsb{4-0} = imm{4-0};
2156}
2157
2158defm t2ORN  : T2I_bin_irs<0b0011, "orn",
2159                          IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2160                          BinOpFrag<(or  node:$LHS, (not node:$RHS))>, 0, "">;
2161
2162// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2163let AddedComplexity = 1 in
2164defm t2MVN  : T2I_un_irs <0b0011, "mvn",
2165                          IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2166                          UnOpFrag<(not node:$Src)>, 1, 1>;
2167
2168
2169let AddedComplexity = 1 in
2170def : T2Pat<(and     rGPR:$src, t2_so_imm_not:$imm),
2171            (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2172
2173// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2174def : T2Pat<(or      rGPR:$src, t2_so_imm_not:$imm),
2175            (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2176            Requires<[IsThumb2]>;
2177
2178def : T2Pat<(t2_so_imm_not:$src),
2179            (t2MVNi t2_so_imm_not:$src)>;
2180
2181//===----------------------------------------------------------------------===//
2182//  Multiply Instructions.
2183//
2184let isCommutable = 1 in
2185def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2186                "mul", "\t$Rd, $Rn, $Rm",
2187                [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2188  let Inst{31-27} = 0b11111;
2189  let Inst{26-23} = 0b0110;
2190  let Inst{22-20} = 0b000;
2191  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2192  let Inst{7-4} = 0b0000; // Multiply
2193}
2194
2195def t2MLA: T2FourReg<
2196                (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2197                "mla", "\t$Rd, $Rn, $Rm, $Ra",
2198                [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> {
2199  let Inst{31-27} = 0b11111;
2200  let Inst{26-23} = 0b0110;
2201  let Inst{22-20} = 0b000;
2202  let Inst{7-4} = 0b0000; // Multiply
2203}
2204
2205def t2MLS: T2FourReg<
2206                (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2207                "mls", "\t$Rd, $Rn, $Rm, $Ra",
2208                [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> {
2209  let Inst{31-27} = 0b11111;
2210  let Inst{26-23} = 0b0110;
2211  let Inst{22-20} = 0b000;
2212  let Inst{7-4} = 0b0001; // Multiply and Subtract
2213}
2214
2215// Extra precision multiplies with low / high results
2216let neverHasSideEffects = 1 in {
2217let isCommutable = 1 in {
2218def t2SMULL : T2MulLong<0b000, 0b0000,
2219                  (outs rGPR:$Rd, rGPR:$Ra),
2220                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2221                   "smull", "\t$Rd, $Ra, $Rn, $Rm", []>;
2222
2223def t2UMULL : T2MulLong<0b010, 0b0000,
2224                  (outs rGPR:$RdLo, rGPR:$RdHi),
2225                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2226                   "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2227} // isCommutable
2228
2229// Multiply + accumulate
2230def t2SMLAL : T2MulLong<0b100, 0b0000,
2231                  (outs rGPR:$RdLo, rGPR:$RdHi),
2232                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2233                  "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2234
2235def t2UMLAL : T2MulLong<0b110, 0b0000,
2236                  (outs rGPR:$RdLo, rGPR:$RdHi),
2237                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2238                  "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2239
2240def t2UMAAL : T2MulLong<0b110, 0b0110,
2241                  (outs rGPR:$RdLo, rGPR:$RdHi),
2242                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2243                  "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2244} // neverHasSideEffects
2245
2246// Rounding variants of the below included for disassembly only
2247
2248// Most significant word multiply
2249def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2250                  "smmul", "\t$Rd, $Rn, $Rm",
2251                  [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]> {
2252  let Inst{31-27} = 0b11111;
2253  let Inst{26-23} = 0b0110;
2254  let Inst{22-20} = 0b101;
2255  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2256  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2257}
2258
2259def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2260                  "smmulr", "\t$Rd, $Rn, $Rm", []> {
2261  let Inst{31-27} = 0b11111;
2262  let Inst{26-23} = 0b0110;
2263  let Inst{22-20} = 0b101;
2264  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2265  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2266}
2267
2268def t2SMMLA : T2FourReg<
2269        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2270                "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2271                [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]> {
2272  let Inst{31-27} = 0b11111;
2273  let Inst{26-23} = 0b0110;
2274  let Inst{22-20} = 0b101;
2275  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2276}
2277
2278def t2SMMLAR: T2FourReg<
2279        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2280                  "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []> {
2281  let Inst{31-27} = 0b11111;
2282  let Inst{26-23} = 0b0110;
2283  let Inst{22-20} = 0b101;
2284  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2285}
2286
2287def t2SMMLS: T2FourReg<
2288        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2289                "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2290                [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]> {
2291  let Inst{31-27} = 0b11111;
2292  let Inst{26-23} = 0b0110;
2293  let Inst{22-20} = 0b110;
2294  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2295}
2296
2297def t2SMMLSR:T2FourReg<
2298        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2299                "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []> {
2300  let Inst{31-27} = 0b11111;
2301  let Inst{26-23} = 0b0110;
2302  let Inst{22-20} = 0b110;
2303  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2304}
2305
2306multiclass T2I_smul<string opc, PatFrag opnode> {
2307  def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2308              !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2309              [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2310                                      (sext_inreg rGPR:$Rm, i16)))]> {
2311    let Inst{31-27} = 0b11111;
2312    let Inst{26-23} = 0b0110;
2313    let Inst{22-20} = 0b001;
2314    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2315    let Inst{7-6} = 0b00;
2316    let Inst{5-4} = 0b00;
2317  }
2318
2319  def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2320              !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2321              [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2322                                      (sra rGPR:$Rm, (i32 16))))]> {
2323    let Inst{31-27} = 0b11111;
2324    let Inst{26-23} = 0b0110;
2325    let Inst{22-20} = 0b001;
2326    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2327    let Inst{7-6} = 0b00;
2328    let Inst{5-4} = 0b01;
2329  }
2330
2331  def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2332              !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2333              [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2334                                      (sext_inreg rGPR:$Rm, i16)))]> {
2335    let Inst{31-27} = 0b11111;
2336    let Inst{26-23} = 0b0110;
2337    let Inst{22-20} = 0b001;
2338    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2339    let Inst{7-6} = 0b00;
2340    let Inst{5-4} = 0b10;
2341  }
2342
2343  def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2344              !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2345              [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2346                                      (sra rGPR:$Rm, (i32 16))))]> {
2347    let Inst{31-27} = 0b11111;
2348    let Inst{26-23} = 0b0110;
2349    let Inst{22-20} = 0b001;
2350    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2351    let Inst{7-6} = 0b00;
2352    let Inst{5-4} = 0b11;
2353  }
2354
2355  def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2356              !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2357              [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2358                                    (sext_inreg rGPR:$Rm, i16)), (i32 16)))]> {
2359    let Inst{31-27} = 0b11111;
2360    let Inst{26-23} = 0b0110;
2361    let Inst{22-20} = 0b011;
2362    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2363    let Inst{7-6} = 0b00;
2364    let Inst{5-4} = 0b00;
2365  }
2366
2367  def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2368              !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2369              [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2370                                    (sra rGPR:$Rm, (i32 16))), (i32 16)))]> {
2371    let Inst{31-27} = 0b11111;
2372    let Inst{26-23} = 0b0110;
2373    let Inst{22-20} = 0b011;
2374    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2375    let Inst{7-6} = 0b00;
2376    let Inst{5-4} = 0b01;
2377  }
2378}
2379
2380
2381multiclass T2I_smla<string opc, PatFrag opnode> {
2382  def BB : T2FourReg<
2383        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2384              !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2385              [(set rGPR:$Rd, (add rGPR:$Ra,
2386                               (opnode (sext_inreg rGPR:$Rn, i16),
2387                                       (sext_inreg rGPR:$Rm, i16))))]> {
2388    let Inst{31-27} = 0b11111;
2389    let Inst{26-23} = 0b0110;
2390    let Inst{22-20} = 0b001;
2391    let Inst{7-6} = 0b00;
2392    let Inst{5-4} = 0b00;
2393  }
2394
2395  def BT : T2FourReg<
2396       (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2397             !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2398             [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
2399                                                 (sra rGPR:$Rm, (i32 16)))))]> {
2400    let Inst{31-27} = 0b11111;
2401    let Inst{26-23} = 0b0110;
2402    let Inst{22-20} = 0b001;
2403    let Inst{7-6} = 0b00;
2404    let Inst{5-4} = 0b01;
2405  }
2406
2407  def TB : T2FourReg<
2408        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2409              !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2410              [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2411                                               (sext_inreg rGPR:$Rm, i16))))]> {
2412    let Inst{31-27} = 0b11111;
2413    let Inst{26-23} = 0b0110;
2414    let Inst{22-20} = 0b001;
2415    let Inst{7-6} = 0b00;
2416    let Inst{5-4} = 0b10;
2417  }
2418
2419  def TT : T2FourReg<
2420        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2421              !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2422             [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2423                                                 (sra rGPR:$Rm, (i32 16)))))]> {
2424    let Inst{31-27} = 0b11111;
2425    let Inst{26-23} = 0b0110;
2426    let Inst{22-20} = 0b001;
2427    let Inst{7-6} = 0b00;
2428    let Inst{5-4} = 0b11;
2429  }
2430
2431  def WB : T2FourReg<
2432        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2433              !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2434              [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2435                                    (sext_inreg rGPR:$Rm, i16)), (i32 16))))]> {
2436    let Inst{31-27} = 0b11111;
2437    let Inst{26-23} = 0b0110;
2438    let Inst{22-20} = 0b011;
2439    let Inst{7-6} = 0b00;
2440    let Inst{5-4} = 0b00;
2441  }
2442
2443  def WT : T2FourReg<
2444        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2445              !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2446              [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2447                                      (sra rGPR:$Rm, (i32 16))), (i32 16))))]> {
2448    let Inst{31-27} = 0b11111;
2449    let Inst{26-23} = 0b0110;
2450    let Inst{22-20} = 0b011;
2451    let Inst{7-6} = 0b00;
2452    let Inst{5-4} = 0b01;
2453  }
2454}
2455
2456defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2457defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2458
2459// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2460def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
2461         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
2462           [/* For disassembly only; pattern left blank */]>;
2463def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
2464         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
2465           [/* For disassembly only; pattern left blank */]>;
2466def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
2467         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
2468           [/* For disassembly only; pattern left blank */]>;
2469def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
2470         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
2471           [/* For disassembly only; pattern left blank */]>;
2472
2473// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2474// These are for disassembly only.
2475
2476def t2SMUAD: T2ThreeReg_mac<
2477            0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2478            IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []> {
2479  let Inst{15-12} = 0b1111;
2480}
2481def t2SMUADX:T2ThreeReg_mac<
2482            0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2483            IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []> {
2484  let Inst{15-12} = 0b1111;
2485}
2486def t2SMUSD: T2ThreeReg_mac<
2487            0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2488            IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []> {
2489  let Inst{15-12} = 0b1111;
2490}
2491def t2SMUSDX:T2ThreeReg_mac<
2492            0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2493            IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []> {
2494  let Inst{15-12} = 0b1111;
2495}
2496def t2SMLAD   : T2ThreeReg_mac<
2497            0, 0b010, 0b0000, (outs rGPR:$Rd),
2498            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
2499            "\t$Rd, $Rn, $Rm, $Ra", []>;
2500def t2SMLADX  : T2FourReg_mac<
2501            0, 0b010, 0b0001, (outs rGPR:$Rd),
2502            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
2503            "\t$Rd, $Rn, $Rm, $Ra", []>;
2504def t2SMLSD   : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
2505            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
2506            "\t$Rd, $Rn, $Rm, $Ra", []>;
2507def t2SMLSDX  : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
2508            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
2509            "\t$Rd, $Rn, $Rm, $Ra", []>;
2510def t2SMLALD  : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2511                        (ins rGPR:$Rm, rGPR:$Rn), IIC_iMAC64, "smlald",
2512                        "\t$Ra, $Rd, $Rm, $Rn", []>;
2513def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2514                        (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlaldx",
2515                        "\t$Ra, $Rd, $Rm, $Rn", []>;
2516def t2SMLSLD  : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2517                        (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsld",
2518                        "\t$Ra, $Rd, $Rm, $Rn", []>;
2519def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2520                        (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
2521                        "\t$Ra, $Rd, $Rm, $Rn", []>;
2522
2523//===----------------------------------------------------------------------===//
2524//  Misc. Arithmetic Instructions.
2525//
2526
2527class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2528      InstrItinClass itin, string opc, string asm, list<dag> pattern>
2529  : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2530  let Inst{31-27} = 0b11111;
2531  let Inst{26-22} = 0b01010;
2532  let Inst{21-20} = op1;
2533  let Inst{15-12} = 0b1111;
2534  let Inst{7-6} = 0b10;
2535  let Inst{5-4} = op2;
2536  let Rn{3-0} = Rm;
2537}
2538
2539def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2540                    "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>;
2541
2542def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2543                      "rbit", "\t$Rd, $Rm",
2544                      [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>;
2545
2546def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2547                 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>;
2548
2549def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2550                       "rev16", ".w\t$Rd, $Rm",
2551                [(set rGPR:$Rd,
2552                    (or (and (srl rGPR:$Rm, (i32 8)), 0xFF),
2553                        (or (and (shl rGPR:$Rm, (i32 8)), 0xFF00),
2554                            (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000),
2555                               (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)))))]>;
2556
2557def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2558                       "revsh", ".w\t$Rd, $Rm",
2559                 [(set rGPR:$Rd,
2560                    (sext_inreg
2561                      (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)),
2562                          (shl rGPR:$Rm, (i32 8))), i16))]>;
2563
2564def t2PKHBT : T2ThreeReg<
2565            (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2566                  IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2567                  [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2568                                      (and (shl rGPR:$Rm, lsl_amt:$sh),
2569                                           0xFFFF0000)))]>,
2570                  Requires<[HasT2ExtractPack, IsThumb2]> {
2571  let Inst{31-27} = 0b11101;
2572  let Inst{26-25} = 0b01;
2573  let Inst{24-20} = 0b01100;
2574  let Inst{5} = 0; // BT form
2575  let Inst{4} = 0;
2576
2577  bits<8> sh;
2578  let Inst{14-12} = sh{7-5};
2579  let Inst{7-6}   = sh{4-3};
2580}
2581
2582// Alternate cases for PKHBT where identities eliminate some nodes.
2583def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2584            (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2585            Requires<[HasT2ExtractPack, IsThumb2]>;
2586def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2587            (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2588            Requires<[HasT2ExtractPack, IsThumb2]>;
2589
2590// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2591// will match the pattern below.
2592def t2PKHTB : T2ThreeReg<
2593                  (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2594                  IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2595                  [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
2596                                       (and (sra rGPR:$Rm, asr_amt:$sh),
2597                                            0xFFFF)))]>,
2598                  Requires<[HasT2ExtractPack, IsThumb2]> {
2599  let Inst{31-27} = 0b11101;
2600  let Inst{26-25} = 0b01;
2601  let Inst{24-20} = 0b01100;
2602  let Inst{5} = 1; // TB form
2603  let Inst{4} = 0;
2604
2605  bits<8> sh;
2606  let Inst{14-12} = sh{7-5};
2607  let Inst{7-6}   = sh{4-3};
2608}
2609
2610// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
2611// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2612def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2613            (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2614            Requires<[HasT2ExtractPack, IsThumb2]>;
2615def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2616                (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2617            (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2618            Requires<[HasT2ExtractPack, IsThumb2]>;
2619
2620//===----------------------------------------------------------------------===//
2621//  Comparison Instructions...
2622//
2623defm t2CMP  : T2I_cmp_irs<0b1101, "cmp",
2624                          IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2625                          BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2626
2627def : T2Pat<(ARMcmpZ  GPR:$lhs, t2_so_imm:$imm),
2628            (t2CMPri  GPR:$lhs, t2_so_imm:$imm)>;
2629def : T2Pat<(ARMcmpZ  GPR:$lhs, rGPR:$rhs),
2630            (t2CMPrr  GPR:$lhs, rGPR:$rhs)>;
2631def : T2Pat<(ARMcmpZ  GPR:$lhs, t2_so_reg:$rhs),
2632            (t2CMPrs  GPR:$lhs, t2_so_reg:$rhs)>;
2633
2634//FIXME: Disable CMN, as CCodes are backwards from compare expectations
2635//       Compare-to-zero still works out, just not the relationals
2636//defm t2CMN  : T2I_cmp_irs<0b1000, "cmn",
2637//                          BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2638defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2639                          IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2640                          BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2641
2642//def : T2Pat<(ARMcmp  GPR:$src, t2_so_imm_neg:$imm),
2643//            (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2644
2645def : T2Pat<(ARMcmpZ  GPR:$src, t2_so_imm_neg:$imm),
2646            (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2647
2648defm t2TST  : T2I_cmp_irs<0b0000, "tst",
2649                          IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2650                         BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
2651defm t2TEQ  : T2I_cmp_irs<0b0100, "teq",
2652                          IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2653                         BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
2654
2655// Conditional moves
2656// FIXME: should be able to write a pattern for ARMcmov, but can't use
2657// a two-value operand where a dag node expects two operands. :(
2658let neverHasSideEffects = 1 in {
2659def t2MOVCCr : T2TwoReg<
2660                   (outs rGPR:$Rd), (ins rGPR:$false, rGPR:$Rm), IIC_iCMOVr,
2661                   "mov", ".w\t$Rd, $Rm",
2662   [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2663                RegConstraint<"$false = $Rd"> {
2664  let Inst{31-27} = 0b11101;
2665  let Inst{26-25} = 0b01;
2666  let Inst{24-21} = 0b0010;
2667  let Inst{20} = 0; // The S bit.
2668  let Inst{19-16} = 0b1111; // Rn
2669  let Inst{14-12} = 0b000;
2670  let Inst{7-4} = 0b0000;
2671}
2672
2673let isMoveImm = 1 in
2674def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2675                   IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
2676[/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2677                   RegConstraint<"$false = $Rd"> {
2678  let Inst{31-27} = 0b11110;
2679  let Inst{25} = 0;
2680  let Inst{24-21} = 0b0010;
2681  let Inst{20} = 0; // The S bit.
2682  let Inst{19-16} = 0b1111; // Rn
2683  let Inst{15} = 0;
2684}
2685
2686let isMoveImm = 1 in
2687def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm:$imm),
2688                      IIC_iCMOVi,
2689                      "movw", "\t$Rd, $imm", []>,
2690                      RegConstraint<"$false = $Rd"> {
2691  let Inst{31-27} = 0b11110;
2692  let Inst{25} = 1;
2693  let Inst{24-21} = 0b0010;
2694  let Inst{20} = 0; // The S bit.
2695  let Inst{15} = 0;
2696
2697  bits<4> Rd;
2698  bits<16> imm;
2699
2700  let Inst{11-8}  = Rd;
2701  let Inst{19-16} = imm{15-12};
2702  let Inst{26}    = imm{11};
2703  let Inst{14-12} = imm{10-8};
2704  let Inst{7-0}   = imm{7-0};
2705}
2706
2707let isMoveImm = 1 in
2708def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2709                               (ins rGPR:$false, i32imm:$src, pred:$p),
2710                    IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">;
2711
2712let isMoveImm = 1 in
2713def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2714                   IIC_iCMOVi, "mvn", ".w\t$Rd, $imm",
2715[/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm,
2716                   imm:$cc, CCR:$ccr))*/]>,
2717                   RegConstraint<"$false = $Rd"> {
2718  let Inst{31-27} = 0b11110;
2719  let Inst{25} = 0;
2720  let Inst{24-21} = 0b0011;
2721  let Inst{20} = 0; // The S bit.
2722  let Inst{19-16} = 0b1111; // Rn
2723  let Inst{15} = 0;
2724}
2725
2726class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2727                   string opc, string asm, list<dag> pattern>
2728  : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> {
2729  let Inst{31-27} = 0b11101;
2730  let Inst{26-25} = 0b01;
2731  let Inst{24-21} = 0b0010;
2732  let Inst{20} = 0; // The S bit.
2733  let Inst{19-16} = 0b1111; // Rn
2734  let Inst{5-4} = opcod; // Shift type.
2735}
2736def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd),
2737                             (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2738                             IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>,
2739                 RegConstraint<"$false = $Rd">;
2740def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd),
2741                             (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2742                             IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>,
2743                 RegConstraint<"$false = $Rd">;
2744def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd),
2745                             (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2746                             IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>,
2747                 RegConstraint<"$false = $Rd">;
2748def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
2749                             (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2750                             IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
2751                 RegConstraint<"$false = $Rd">;
2752} // neverHasSideEffects
2753
2754//===----------------------------------------------------------------------===//
2755// Atomic operations intrinsics
2756//
2757
2758// memory barriers protect the atomic sequences
2759let hasSideEffects = 1 in {
2760def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2761                  "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2762                  Requires<[IsThumb, HasDB]> {
2763  bits<4> opt;
2764  let Inst{31-4} = 0xf3bf8f5;
2765  let Inst{3-0} = opt;
2766}
2767}
2768
2769def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2770                  "dsb", "\t$opt",
2771                  [/* For disassembly only; pattern left blank */]>,
2772                  Requires<[IsThumb, HasDB]> {
2773  bits<4> opt;
2774  let Inst{31-4} = 0xf3bf8f4;
2775  let Inst{3-0} = opt;
2776}
2777
2778// ISB has only full system option -- for disassembly only
2779def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2780                  [/* For disassembly only; pattern left blank */]>,
2781                  Requires<[IsThumb2, HasV7]> {
2782  let Inst{31-4} = 0xf3bf8f6;
2783  let Inst{3-0} = 0b1111;
2784}
2785
2786class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2787                InstrItinClass itin, string opc, string asm, string cstr,
2788                list<dag> pattern, bits<4> rt2 = 0b1111>
2789  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2790  let Inst{31-27} = 0b11101;
2791  let Inst{26-20} = 0b0001101;
2792  let Inst{11-8} = rt2;
2793  let Inst{7-6} = 0b01;
2794  let Inst{5-4} = opcod;
2795  let Inst{3-0} = 0b1111;
2796
2797  bits<4> Rn;
2798  bits<4> Rt;
2799  let Inst{19-16} = Rn;
2800  let Inst{15-12} = Rt;
2801}
2802class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2803                InstrItinClass itin, string opc, string asm, string cstr,
2804                list<dag> pattern, bits<4> rt2 = 0b1111>
2805  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2806  let Inst{31-27} = 0b11101;
2807  let Inst{26-20} = 0b0001100;
2808  let Inst{11-8} = rt2;
2809  let Inst{7-6} = 0b01;
2810  let Inst{5-4} = opcod;
2811
2812  bits<4> Rd;
2813  bits<4> Rn;
2814  bits<4> Rt;
2815  let Inst{11-8}  = Rd;
2816  let Inst{19-16} = Rn;
2817  let Inst{15-12} = Rt;
2818}
2819
2820let mayLoad = 1 in {
2821def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2822                         Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
2823                         "", []>;
2824def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2825                         Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
2826                         "", []>;
2827def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2828                       Size4Bytes, NoItinerary,
2829                       "ldrex", "\t$Rt, [$Rn]", "",
2830                      []> {
2831  let Inst{31-27} = 0b11101;
2832  let Inst{26-20} = 0b0000101;
2833  let Inst{11-8} = 0b1111;
2834  let Inst{7-0} = 0b00000000; // imm8 = 0
2835
2836  bits<4> Rn;
2837  bits<4> Rt;
2838  let Inst{19-16} = Rn;
2839  let Inst{15-12} = Rt;
2840}
2841def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
2842                         AddrModeNone, Size4Bytes, NoItinerary,
2843                         "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
2844                         [], {?, ?, ?, ?}> {
2845  bits<4> Rt2;
2846  let Inst{11-8} = Rt2;
2847}
2848}
2849
2850let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2851def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2852                         AddrModeNone, Size4Bytes, NoItinerary,
2853                         "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
2854def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2855                         AddrModeNone, Size4Bytes, NoItinerary,
2856                         "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
2857def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2858                       AddrModeNone, Size4Bytes, NoItinerary,
2859                       "strex", "\t$Rd, $Rt, [$Rn]", "",
2860                      []> {
2861  let Inst{31-27} = 0b11101;
2862  let Inst{26-20} = 0b0000100;
2863  let Inst{7-0} = 0b00000000; // imm8 = 0
2864
2865  bits<4> Rd;
2866  bits<4> Rn;
2867  bits<4> Rt;
2868  let Inst{11-8}  = Rd;
2869  let Inst{19-16} = Rn;
2870  let Inst{15-12} = Rt;
2871}
2872def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2873                         (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
2874                         AddrModeNone, Size4Bytes, NoItinerary,
2875                         "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
2876                         {?, ?, ?, ?}> {
2877  bits<4> Rt2;
2878  let Inst{11-8} = Rt2;
2879}
2880}
2881
2882// Clear-Exclusive is for disassembly only.
2883def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2884                  [/* For disassembly only; pattern left blank */]>,
2885            Requires<[IsARM, HasV7]>  {
2886  let Inst{31-20} = 0xf3b;
2887  let Inst{15-14} = 0b10;
2888  let Inst{12} = 0;
2889  let Inst{7-4} = 0b0010;
2890}
2891
2892//===----------------------------------------------------------------------===//
2893// TLS Instructions
2894//
2895
2896// __aeabi_read_tp preserves the registers r1-r3.
2897let isCall = 1,
2898  Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
2899  def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2900                     "bl\t__aeabi_read_tp",
2901                     [(set R0, ARMthread_pointer)]> {
2902    let Inst{31-27} = 0b11110;
2903    let Inst{15-14} = 0b11;
2904    let Inst{12} = 1;
2905  }
2906}
2907
2908//===----------------------------------------------------------------------===//
2909// SJLJ Exception handling intrinsics
2910//   eh_sjlj_setjmp() is an instruction sequence to store the return
2911//   address and save #0 in R0 for the non-longjmp case.
2912//   Since by its nature we may be coming from some other function to get
2913//   here, and we're using the stack frame for the containing function to
2914//   save/restore registers, we can't keep anything live in regs across
2915//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2916//   when we get here from a longjmp(). We force everthing out of registers
2917//   except for our own input by listing the relevant registers in Defs. By
2918//   doing so, we also cause the prologue/epilogue code to actively preserve
2919//   all of the callee-saved resgisters, which is exactly what we want.
2920//   $val is a scratch register for our use.
2921let Defs =
2922  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR,  D0,
2923    D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
2924    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2925    D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2926  def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2927                               AddrModeNone, SizeSpecial, NoItinerary, "", "",
2928                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2929                             Requires<[IsThumb2, HasVFP2]>;
2930}
2931
2932let Defs =
2933  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR ],
2934  hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2935  def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2936                               AddrModeNone, SizeSpecial, NoItinerary, "", "",
2937                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2938                                  Requires<[IsThumb2, NoVFP]>;
2939}
2940
2941
2942//===----------------------------------------------------------------------===//
2943// Control-Flow Instructions
2944//
2945
2946// FIXME: remove when we have a way to marking a MI with these properties.
2947// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2948// operand list.
2949// FIXME: Should pc be an implicit operand like PICADD, etc?
2950let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2951    hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2952def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2953                                        reglist:$regs, variable_ops),
2954                        IIC_iLoad_mBr,
2955                        "ldmia${p}.w\t$Rn!, $regs",
2956                        "$Rn = $wb", []> {
2957  bits<4>  Rn;
2958  bits<16> regs;
2959
2960  let Inst{31-27} = 0b11101;
2961  let Inst{26-25} = 0b00;
2962  let Inst{24-23} = 0b01;     // Increment After
2963  let Inst{22}    = 0;
2964  let Inst{21}    = 1;        // Writeback
2965  let Inst{20}    = 1;
2966  let Inst{19-16} = Rn;
2967  let Inst{15-0}  = regs;
2968}
2969
2970let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2971let isPredicable = 1 in
2972def t2B   : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br,
2973                 "b.w\t$target",
2974                 [(br bb:$target)]> {
2975  let Inst{31-27} = 0b11110;
2976  let Inst{15-14} = 0b10;
2977  let Inst{12} = 1;
2978
2979  bits<20> target;
2980  let Inst{26} = target{19};
2981  let Inst{11} = target{18};
2982  let Inst{13} = target{17};
2983  let Inst{21-16} = target{16-11};
2984  let Inst{10-0} = target{10-0};
2985}
2986
2987let isNotDuplicable = 1, isIndirectBranch = 1 in {
2988def t2BR_JT : t2PseudoInst<(outs),
2989          (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id),
2990           SizeSpecial, IIC_Br,
2991          [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
2992
2993// FIXME: Add a non-pc based case that can be predicated.
2994def t2TBB_JT : t2PseudoInst<(outs),
2995        (ins GPR:$index, i32imm:$jt, i32imm:$id),
2996         SizeSpecial, IIC_Br, []>;
2997
2998def t2TBH_JT : t2PseudoInst<(outs),
2999        (ins GPR:$index, i32imm:$jt, i32imm:$id),
3000         SizeSpecial, IIC_Br, []>;
3001
3002def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3003                    "tbb", "\t[$Rn, $Rm]", []> {
3004  bits<4> Rn;
3005  bits<4> Rm;
3006  let Inst{31-20} = 0b111010001101;
3007  let Inst{19-16} = Rn;
3008  let Inst{15-5} = 0b11110000000;
3009  let Inst{4} = 0; // B form
3010  let Inst{3-0} = Rm;
3011}
3012
3013def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3014                   "tbh", "\t[$Rn, $Rm, lsl #1]", []> {
3015  bits<4> Rn;
3016  bits<4> Rm;
3017  let Inst{31-20} = 0b111010001101;
3018  let Inst{19-16} = Rn;
3019  let Inst{15-5} = 0b11110000000;
3020  let Inst{4} = 1; // H form
3021  let Inst{3-0} = Rm;
3022}
3023} // isNotDuplicable, isIndirectBranch
3024
3025} // isBranch, isTerminator, isBarrier
3026
3027// FIXME: should be able to write a pattern for ARMBrcond, but can't use
3028// a two-value operand where a dag node expects two operands. :(
3029let isBranch = 1, isTerminator = 1 in
3030def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3031                "b", ".w\t$target",
3032                [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
3033  let Inst{31-27} = 0b11110;
3034  let Inst{15-14} = 0b10;
3035  let Inst{12} = 0;
3036
3037  bits<4> p;
3038  let Inst{25-22} = p;
3039
3040  bits<21> target;
3041  let Inst{26} = target{20};
3042  let Inst{11} = target{19};
3043  let Inst{13} = target{18};
3044  let Inst{21-16} = target{17-12};
3045  let Inst{10-0} = target{11-1};
3046}
3047
3048
3049// IT block
3050let Defs = [ITSTATE] in
3051def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3052                    AddrModeNone, Size2Bytes,  IIC_iALUx,
3053                    "it$mask\t$cc", "", []> {
3054  // 16-bit instruction.
3055  let Inst{31-16} = 0x0000;
3056  let Inst{15-8} = 0b10111111;
3057
3058  bits<4> cc;
3059  bits<4> mask;
3060  let Inst{7-4} = cc;
3061  let Inst{3-0} = mask;
3062}
3063
3064// Branch and Exchange Jazelle -- for disassembly only
3065// Rm = Inst{19-16}
3066def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
3067              [/* For disassembly only; pattern left blank */]> {
3068  let Inst{31-27} = 0b11110;
3069  let Inst{26} = 0;
3070  let Inst{25-20} = 0b111100;
3071  let Inst{15-14} = 0b10;
3072  let Inst{12} = 0;
3073
3074  bits<4> func;
3075  let Inst{19-16} = func;
3076}
3077
3078// Change Processor State is a system instruction -- for disassembly only.
3079// The singleton $opt operand contains the following information:
3080// opt{4-0} = mode from Inst{4-0}
3081// opt{5} = changemode from Inst{17}
3082// opt{8-6} = AIF from Inst{8-6}
3083// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
3084def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
3085                 [/* For disassembly only; pattern left blank */]> {
3086  let Inst{31-27} = 0b11110;
3087  let Inst{26} = 0;
3088  let Inst{25-20} = 0b111010;
3089  let Inst{15-14} = 0b10;
3090  let Inst{12} = 0;
3091
3092  bits<11> opt;
3093
3094  // mode number
3095  let Inst{4-0} = opt{4-0};
3096
3097  // M flag
3098  let Inst{8} = opt{5};
3099
3100  // F flag
3101  let Inst{5} = opt{6};
3102
3103  // I flag
3104  let Inst{6} = opt{7};
3105
3106  // A flag
3107  let Inst{7} = opt{8};
3108
3109  // imod flag
3110  let Inst{10-9} = opt{10-9};
3111}
3112
3113// A6.3.4 Branches and miscellaneous control
3114// Table A6-14 Change Processor State, and hint instructions
3115// Helper class for disassembly only.
3116class T2I_hint<bits<8> op7_0, string opc, string asm>
3117  : T2I<(outs), (ins), NoItinerary, opc, asm,
3118        [/* For disassembly only; pattern left blank */]> {
3119  let Inst{31-20} = 0xf3a;
3120  let Inst{15-14} = 0b10;
3121  let Inst{12} = 0;
3122  let Inst{10-8} = 0b000;
3123  let Inst{7-0} = op7_0;
3124}
3125
3126def t2NOP   : T2I_hint<0b00000000, "nop",   ".w">;
3127def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
3128def t2WFE   : T2I_hint<0b00000010, "wfe",   ".w">;
3129def t2WFI   : T2I_hint<0b00000011, "wfi",   ".w">;
3130def t2SEV   : T2I_hint<0b00000100, "sev",   ".w">;
3131
3132def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
3133                [/* For disassembly only; pattern left blank */]> {
3134  let Inst{31-20} = 0xf3a;
3135  let Inst{15-14} = 0b10;
3136  let Inst{12} = 0;
3137  let Inst{10-8} = 0b000;
3138  let Inst{7-4} = 0b1111;
3139
3140  bits<4> opt;
3141  let Inst{3-0} = opt;
3142}
3143
3144// Secure Monitor Call is a system instruction -- for disassembly only
3145// Option = Inst{19-16}
3146def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
3147                [/* For disassembly only; pattern left blank */]> {
3148  let Inst{31-27} = 0b11110;
3149  let Inst{26-20} = 0b1111111;
3150  let Inst{15-12} = 0b1000;
3151
3152  bits<4> opt;
3153  let Inst{19-16} = opt;
3154}
3155
3156class T2SRS<bits<12> op31_20,
3157           dag oops, dag iops, InstrItinClass itin,
3158          string opc, string asm, list<dag> pattern>
3159  : T2I<oops, iops, itin, opc, asm, pattern> {
3160  let Inst{31-20} = op31_20{11-0};
3161
3162  bits<5> mode;
3163  let Inst{4-0} = mode{4-0};
3164}
3165
3166// Store Return State is a system instruction -- for disassembly only
3167def t2SRSDBW : T2SRS<0b111010000010,
3168                   (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
3169                   [/* For disassembly only; pattern left blank */]>;
3170def t2SRSDB  : T2SRS<0b111010000000,
3171                   (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
3172                   [/* For disassembly only; pattern left blank */]>;
3173def t2SRSIAW : T2SRS<0b111010011010,
3174                   (outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
3175                   [/* For disassembly only; pattern left blank */]>;
3176def t2SRSIA  : T2SRS<0b111010011000,
3177                   (outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
3178                   [/* For disassembly only; pattern left blank */]>;
3179
3180// Return From Exception is a system instruction -- for disassembly only
3181
3182class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3183          string opc, string asm, list<dag> pattern>
3184  : T2I<oops, iops, itin, opc, asm, pattern> {
3185  let Inst{31-20} = op31_20{11-0};
3186
3187  bits<4> Rn;
3188  let Inst{19-16} = Rn;
3189}
3190
3191def t2RFEDBW : T2RFE<0b111010000011,
3192                   (outs), (ins rGPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3193                   [/* For disassembly only; pattern left blank */]>;
3194def t2RFEDB  : T2RFE<0b111010000001,
3195                   (outs), (ins rGPR:$Rn), NoItinerary, "rfeab", "\t$Rn",
3196                   [/* For disassembly only; pattern left blank */]>;
3197def t2RFEIAW : T2RFE<0b111010011011,
3198                   (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3199                   [/* For disassembly only; pattern left blank */]>;
3200def t2RFEIA  : T2RFE<0b111010011001,
3201                   (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3202                   [/* For disassembly only; pattern left blank */]>;
3203
3204//===----------------------------------------------------------------------===//
3205// Non-Instruction Patterns
3206//
3207
3208// 32-bit immediate using movw + movt.
3209// This is a single pseudo instruction to make it re-materializable.
3210// FIXME: Remove this when we can do generalized remat.
3211let isReMaterializable = 1, isMoveImm = 1 in
3212def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3213                            [(set rGPR:$dst, (i32 imm:$src))]>,
3214                            Requires<[IsThumb, HasV6T2]>;
3215
3216// ConstantPool, GlobalAddress, and JumpTable
3217def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
3218           Requires<[IsThumb2, DontUseMovt]>;
3219def : T2Pat<(ARMWrapper  tconstpool  :$dst), (t2LEApcrel tconstpool  :$dst)>;
3220def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3221           Requires<[IsThumb2, UseMovt]>;
3222
3223def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3224            (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
3225
3226// Pseudo instruction that combines ldr from constpool and add pc. This should
3227// be expanded into two instructions late to allow if-conversion and
3228// scheduling.
3229let canFoldAsLoad = 1, isReMaterializable = 1 in
3230def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3231                   IIC_iLoadiALU,
3232               [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3233                                           imm:$cp))]>,
3234               Requires<[IsThumb2]>;
3235
3236//===----------------------------------------------------------------------===//
3237// Move between special register and ARM core register -- for disassembly only
3238//
3239
3240class T2SpecialReg<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3241          dag oops, dag iops, InstrItinClass itin,
3242          string opc, string asm, list<dag> pattern>
3243  : T2I<oops, iops, itin, opc, asm, pattern> {
3244  let Inst{31-20} = op31_20{11-0};
3245  let Inst{15-14} = op15_14{1-0};
3246  let Inst{12} = op12{0};
3247}
3248
3249class T2MRS<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3250          dag oops, dag iops, InstrItinClass itin,
3251          string opc, string asm, list<dag> pattern>
3252  : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3253  bits<4> Rd;
3254  let Inst{11-8} = Rd;
3255}
3256
3257def t2MRS : T2MRS<0b111100111110, 0b10, 0,
3258                (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3259                [/* For disassembly only; pattern left blank */]>;
3260def t2MRSsys : T2MRS<0b111100111111, 0b10, 0,
3261                   (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
3262                   [/* For disassembly only; pattern left blank */]>;
3263
3264class T2MSR<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3265            dag oops, dag iops, InstrItinClass itin,
3266          string opc, string asm, list<dag> pattern>
3267  : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3268  bits<4> Rn;
3269  bits<4> mask;
3270  let Inst{19-16} = Rn;
3271  let Inst{11-8} = mask;
3272}
3273
3274def t2MSR : T2MSR<0b111100111000, 0b10, 0,
3275                (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3276                "\tcpsr$mask, $Rn",
3277                [/* For disassembly only; pattern left blank */]>;
3278def t2MSRsys : T2MSR<0b111100111001, 0b10, 0,
3279                   (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3280                   "\tspsr$mask, $Rn",
3281                   [/* For disassembly only; pattern left blank */]>;
3282