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