1 //===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Thumb2 instruction set.
12 //===----------------------------------------------------------------------===//
14 // IT block predicate field
15 def it_pred : Operand<i32> {
16 let PrintMethod = "printPredicateOperand";
19 // IT block condition mask
20 def it_mask : Operand<i32> {
21 let PrintMethod = "printThumbITMask";
24 // Table branch address
25 def tb_addrmode : Operand<i32> {
26 let PrintMethod = "printTBAddrMode";
29 // Shifted operands. No register controlled shifts for Thumb2.
30 // Note: We do not support rrx shifted operands yet.
31 def t2_so_reg : Operand<i32>, // reg imm
32 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
34 let PrintMethod = "printT2SOOperand";
35 let MIOperandInfo = (ops GPR, i32imm);
38 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
39 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
40 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
43 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
44 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
45 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
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].
54 def t2_so_imm : Operand<i32>,
56 return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
59 // t2_so_imm_not - Match an immediate that is a complement
61 def t2_so_imm_not : Operand<i32>,
63 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64 }], t2_so_imm_not_XFORM>;
66 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67 def t2_so_imm_neg : Operand<i32>,
69 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
70 }], t2_so_imm_neg_XFORM>;
72 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
73 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74 // to get the first/second pieces.
75 def t2_so_imm2part : Operand<i32>,
77 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
81 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83 return CurDAG->getTargetConstant(V, MVT::i32);
86 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88 return CurDAG->getTargetConstant(V, MVT::i32);
91 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
96 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98 return CurDAG->getTargetConstant(V, MVT::i32);
101 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103 return CurDAG->getTargetConstant(V, MVT::i32);
106 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107 def imm1_31 : PatLeaf<(i32 imm), [{
108 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
111 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
112 def imm0_4095 : Operand<i32>,
113 PatLeaf<(i32 imm), [{
114 return (uint32_t)N->getZExtValue() < 4096;
117 def imm0_4095_neg : PatLeaf<(i32 imm), [{
118 return (uint32_t)(-N->getZExtValue()) < 4096;
121 def imm0_255_neg : PatLeaf<(i32 imm), [{
122 return (uint32_t)(-N->getZExtValue()) < 255;
125 // Define Thumb2 specific addressing modes.
127 // t2addrmode_imm12 := reg + imm12
128 def t2addrmode_imm12 : Operand<i32>,
129 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
130 let PrintMethod = "printT2AddrModeImm12Operand";
131 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
134 // t2addrmode_imm8 := reg - imm8
135 def t2addrmode_imm8 : Operand<i32>,
136 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
137 let PrintMethod = "printT2AddrModeImm8Operand";
138 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
141 def t2am_imm8_offset : Operand<i32>,
142 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
143 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
146 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
147 def t2addrmode_imm8s4 : Operand<i32>,
148 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
149 let PrintMethod = "printT2AddrModeImm8s4Operand";
150 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
153 // t2addrmode_so_reg := reg + (reg << imm2)
154 def t2addrmode_so_reg : Operand<i32>,
155 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
156 let PrintMethod = "printT2AddrModeSoRegOperand";
157 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
161 //===----------------------------------------------------------------------===//
162 // Multiclass helpers...
165 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
166 /// unary operation that produces a value. These are predicable and can be
167 /// changed to modify CPSR.
168 multiclass T2I_un_irs<bits<4> opcod, string opc, PatFrag opnode,
169 bit Cheap = 0, bit ReMat = 0> {
171 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
173 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
174 let isAsCheapAsAMove = Cheap;
175 let isReMaterializable = ReMat;
176 let Inst{31-27} = 0b11110;
178 let Inst{24-21} = opcod;
179 let Inst{20} = ?; // The S bit.
180 let Inst{19-16} = 0b1111; // Rn
184 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
185 opc, ".w\t$dst, $src",
186 [(set GPR:$dst, (opnode GPR:$src))]> {
187 let Inst{31-27} = 0b11101;
188 let Inst{26-25} = 0b01;
189 let Inst{24-21} = opcod;
190 let Inst{20} = ?; // The S bit.
191 let Inst{19-16} = 0b1111; // Rn
192 let Inst{14-12} = 0b000; // imm3
193 let Inst{7-6} = 0b00; // imm2
194 let Inst{5-4} = 0b00; // type
197 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
198 opc, ".w\t$dst, $src",
199 [(set GPR:$dst, (opnode t2_so_reg:$src))]> {
200 let Inst{31-27} = 0b11101;
201 let Inst{26-25} = 0b01;
202 let Inst{24-21} = opcod;
203 let Inst{20} = ?; // The S bit.
204 let Inst{19-16} = 0b1111; // Rn
208 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
209 // binary operation that produces a value. These are predicable and can be
210 /// changed to modify CPSR.
211 multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
212 bit Commutable = 0, string wide =""> {
214 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
215 opc, "\t$dst, $lhs, $rhs",
216 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
217 let Inst{31-27} = 0b11110;
219 let Inst{24-21} = opcod;
220 let Inst{20} = ?; // The S bit.
224 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
225 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
226 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
227 let isCommutable = Commutable;
228 let Inst{31-27} = 0b11101;
229 let Inst{26-25} = 0b01;
230 let Inst{24-21} = opcod;
231 let Inst{20} = ?; // The S bit.
232 let Inst{14-12} = 0b000; // imm3
233 let Inst{7-6} = 0b00; // imm2
234 let Inst{5-4} = 0b00; // type
237 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
238 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
239 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
240 let Inst{31-27} = 0b11101;
241 let Inst{26-25} = 0b01;
242 let Inst{24-21} = opcod;
243 let Inst{20} = ?; // The S bit.
247 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
248 // the ".w" prefix to indicate that they are wide.
249 multiclass T2I_bin_w_irs<bits<4> opcod, string opc, PatFrag opnode,
250 bit Commutable = 0> :
251 T2I_bin_irs<opcod, opc, opnode, Commutable, ".w">;
253 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
254 /// reversed. It doesn't define the 'rr' form since it's handled by its
255 /// T2I_bin_irs counterpart.
256 multiclass T2I_rbin_is<bits<4> opcod, string opc, PatFrag opnode> {
258 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
259 opc, ".w\t$dst, $rhs, $lhs",
260 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
261 let Inst{31-27} = 0b11110;
263 let Inst{24-21} = opcod;
264 let Inst{20} = 0; // The S bit.
268 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
269 opc, "\t$dst, $rhs, $lhs",
270 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
271 let Inst{31-27} = 0b11101;
272 let Inst{26-25} = 0b01;
273 let Inst{24-21} = opcod;
274 let Inst{20} = 0; // The S bit.
278 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
279 /// instruction modifies the CPSR register.
280 let Defs = [CPSR] in {
281 multiclass T2I_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
282 bit Commutable = 0> {
284 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
285 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
286 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
287 let Inst{31-27} = 0b11110;
289 let Inst{24-21} = opcod;
290 let Inst{20} = 1; // The S bit.
294 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
295 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
296 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
297 let isCommutable = Commutable;
298 let Inst{31-27} = 0b11101;
299 let Inst{26-25} = 0b01;
300 let Inst{24-21} = opcod;
301 let Inst{20} = 1; // The S bit.
302 let Inst{14-12} = 0b000; // imm3
303 let Inst{7-6} = 0b00; // imm2
304 let Inst{5-4} = 0b00; // type
307 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
308 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
309 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
310 let Inst{31-27} = 0b11101;
311 let Inst{26-25} = 0b01;
312 let Inst{24-21} = opcod;
313 let Inst{20} = 1; // The S bit.
318 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
319 /// patterns for a binary operation that produces a value.
320 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
321 bit Commutable = 0> {
323 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
324 opc, ".w\t$dst, $lhs, $rhs",
325 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
326 let Inst{31-27} = 0b11110;
329 let Inst{23-21} = op23_21;
330 let Inst{20} = 0; // The S bit.
334 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
335 !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
336 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
337 let Inst{31-27} = 0b11110;
340 let Inst{23-21} = op23_21;
341 let Inst{20} = 0; // The S bit.
345 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
346 opc, ".w\t$dst, $lhs, $rhs",
347 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
348 let isCommutable = Commutable;
349 let Inst{31-27} = 0b11101;
350 let Inst{26-25} = 0b01;
352 let Inst{23-21} = op23_21;
353 let Inst{20} = 0; // The S bit.
354 let Inst{14-12} = 0b000; // imm3
355 let Inst{7-6} = 0b00; // imm2
356 let Inst{5-4} = 0b00; // type
359 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
360 opc, ".w\t$dst, $lhs, $rhs",
361 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
362 let Inst{31-27} = 0b11101;
363 let Inst{26-25} = 0b01;
365 let Inst{23-21} = op23_21;
366 let Inst{20} = 0; // The S bit.
370 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
371 /// for a binary operation that produces a value and use the carry
372 /// bit. It's not predicable.
373 let Uses = [CPSR] in {
374 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
375 bit Commutable = 0> {
377 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
378 opc, "\t$dst, $lhs, $rhs",
379 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
380 Requires<[IsThumb2]> {
381 let Inst{31-27} = 0b11110;
383 let Inst{24-21} = opcod;
384 let Inst{20} = 0; // The S bit.
388 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
389 opc, ".w\t$dst, $lhs, $rhs",
390 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
391 Requires<[IsThumb2]> {
392 let isCommutable = Commutable;
393 let Inst{31-27} = 0b11101;
394 let Inst{26-25} = 0b01;
395 let Inst{24-21} = opcod;
396 let Inst{20} = 0; // The S bit.
397 let Inst{14-12} = 0b000; // imm3
398 let Inst{7-6} = 0b00; // imm2
399 let Inst{5-4} = 0b00; // type
402 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
403 opc, ".w\t$dst, $lhs, $rhs",
404 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
405 Requires<[IsThumb2]> {
406 let Inst{31-27} = 0b11101;
407 let Inst{26-25} = 0b01;
408 let Inst{24-21} = opcod;
409 let Inst{20} = 0; // The S bit.
413 // Carry setting variants
414 let Defs = [CPSR] in {
415 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
416 bit Commutable = 0> {
418 def Sri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
419 opc, "\t$dst, $lhs, $rhs",
420 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
421 Requires<[IsThumb2]> {
422 let Inst{31-27} = 0b11110;
424 let Inst{24-21} = opcod;
425 let Inst{20} = 1; // The S bit.
429 def Srr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
430 opc, ".w\t$dst, $lhs, $rhs",
431 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
432 Requires<[IsThumb2]> {
433 let isCommutable = Commutable;
434 let Inst{31-27} = 0b11101;
435 let Inst{26-25} = 0b01;
436 let Inst{24-21} = opcod;
437 let Inst{20} = 1; // The S bit.
438 let Inst{14-12} = 0b000; // imm3
439 let Inst{7-6} = 0b00; // imm2
440 let Inst{5-4} = 0b00; // type
443 def Srs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
444 opc, ".w\t$dst, $lhs, $rhs",
445 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
446 Requires<[IsThumb2]> {
447 let Inst{31-27} = 0b11101;
448 let Inst{26-25} = 0b01;
449 let Inst{24-21} = opcod;
450 let Inst{20} = 1; // The S bit.
456 /// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
457 let Defs = [CPSR] in {
458 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
460 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
462 !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"),
463 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
464 let Inst{31-27} = 0b11110;
466 let Inst{24-21} = opcod;
467 let Inst{20} = 1; // The S bit.
471 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
473 !strconcat(opc, "${s}\t$dst, $rhs, $lhs"),
474 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
475 let Inst{31-27} = 0b11101;
476 let Inst{26-25} = 0b01;
477 let Inst{24-21} = opcod;
478 let Inst{20} = 1; // The S bit.
483 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
484 // rotate operation that produces a value.
485 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
487 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
488 opc, ".w\t$dst, $lhs, $rhs",
489 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]> {
490 let Inst{31-27} = 0b11101;
491 let Inst{26-21} = 0b010010;
492 let Inst{19-16} = 0b1111; // Rn
493 let Inst{5-4} = opcod;
496 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr,
497 opc, ".w\t$dst, $lhs, $rhs",
498 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
499 let Inst{31-27} = 0b11111;
500 let Inst{26-23} = 0b0100;
501 let Inst{22-21} = opcod;
502 let Inst{15-12} = 0b1111;
503 let Inst{7-4} = 0b0000;
507 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
508 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
509 /// a explicit result, only implicitly set CPSR.
510 let Defs = [CPSR] in {
511 multiclass T2I_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
513 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
514 opc, ".w\t$lhs, $rhs",
515 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
516 let Inst{31-27} = 0b11110;
518 let Inst{24-21} = opcod;
519 let Inst{20} = 1; // The S bit.
521 let Inst{11-8} = 0b1111; // Rd
524 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
525 opc, ".w\t$lhs, $rhs",
526 [(opnode GPR:$lhs, GPR:$rhs)]> {
527 let Inst{31-27} = 0b11101;
528 let Inst{26-25} = 0b01;
529 let Inst{24-21} = opcod;
530 let Inst{20} = 1; // The S bit.
531 let Inst{14-12} = 0b000; // imm3
532 let Inst{11-8} = 0b1111; // Rd
533 let Inst{7-6} = 0b00; // imm2
534 let Inst{5-4} = 0b00; // type
537 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
538 opc, ".w\t$lhs, $rhs",
539 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
540 let Inst{31-27} = 0b11101;
541 let Inst{26-25} = 0b01;
542 let Inst{24-21} = opcod;
543 let Inst{20} = 1; // The S bit.
544 let Inst{11-8} = 0b1111; // Rd
549 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
550 multiclass T2I_ld<bit signed, bits<2> opcod, string opc, PatFrag opnode> {
551 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
552 opc, ".w\t$dst, $addr",
553 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
554 let Inst{31-27} = 0b11111;
555 let Inst{26-25} = 0b00;
556 let Inst{24} = signed;
558 let Inst{22-21} = opcod;
559 let Inst{20} = 1; // load
561 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
562 opc, "\t$dst, $addr",
563 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
564 let Inst{31-27} = 0b11111;
565 let Inst{26-25} = 0b00;
566 let Inst{24} = signed;
568 let Inst{22-21} = opcod;
569 let Inst{20} = 1; // load
571 // Offset: index==TRUE, wback==FALSE
572 let Inst{10} = 1; // The P bit.
573 let Inst{8} = 0; // The W bit.
575 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
576 opc, ".w\t$dst, $addr",
577 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
578 let Inst{31-27} = 0b11111;
579 let Inst{26-25} = 0b00;
580 let Inst{24} = signed;
582 let Inst{22-21} = opcod;
583 let Inst{20} = 1; // load
584 let Inst{11-6} = 0b000000;
586 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
587 opc, ".w\t$dst, $addr",
588 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
589 let isReMaterializable = 1;
590 let Inst{31-27} = 0b11111;
591 let Inst{26-25} = 0b00;
592 let Inst{24} = signed;
593 let Inst{23} = ?; // add = (U == '1')
594 let Inst{22-21} = opcod;
595 let Inst{20} = 1; // load
596 let Inst{19-16} = 0b1111; // Rn
600 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
601 multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
602 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
603 opc, ".w\t$src, $addr",
604 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
605 let Inst{31-27} = 0b11111;
606 let Inst{26-23} = 0b0001;
607 let Inst{22-21} = opcod;
608 let Inst{20} = 0; // !load
610 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
611 opc, "\t$src, $addr",
612 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
613 let Inst{31-27} = 0b11111;
614 let Inst{26-23} = 0b0000;
615 let Inst{22-21} = opcod;
616 let Inst{20} = 0; // !load
618 // Offset: index==TRUE, wback==FALSE
619 let Inst{10} = 1; // The P bit.
620 let Inst{8} = 0; // The W bit.
622 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
623 opc, ".w\t$src, $addr",
624 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
625 let Inst{31-27} = 0b11111;
626 let Inst{26-23} = 0b0000;
627 let Inst{22-21} = opcod;
628 let Inst{20} = 0; // !load
629 let Inst{11-6} = 0b000000;
633 /// T2I_picld - Defines the PIC load pattern.
634 class T2I_picld<string opc, PatFrag opnode> :
635 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi,
636 !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr",
637 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
639 /// T2I_picst - Defines the PIC store pattern.
640 class T2I_picst<string opc, PatFrag opnode> :
641 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer,
642 !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr",
643 [(opnode GPR:$src, addrmodepc:$addr)]>;
646 /// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
647 /// register and one whose operand is a register rotated by 8/16/24.
648 multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
649 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
650 opc, ".w\t$dst, $src",
651 [(set GPR:$dst, (opnode GPR:$src))]> {
652 let Inst{31-27} = 0b11111;
653 let Inst{26-23} = 0b0100;
654 let Inst{22-20} = opcod;
655 let Inst{19-16} = 0b1111; // Rn
656 let Inst{15-12} = 0b1111;
658 let Inst{5-4} = 0b00; // rotate
660 def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
661 opc, ".w\t$dst, $src, ror $rot",
662 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
663 let Inst{31-27} = 0b11111;
664 let Inst{26-23} = 0b0100;
665 let Inst{22-20} = opcod;
666 let Inst{19-16} = 0b1111; // Rn
667 let Inst{15-12} = 0b1111;
669 let Inst{5-4} = {?,?}; // rotate
673 /// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
674 /// register and one whose operand is a register rotated by 8/16/24.
675 multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
676 def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
677 opc, "\t$dst, $LHS, $RHS",
678 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]> {
679 let Inst{31-27} = 0b11111;
680 let Inst{26-23} = 0b0100;
681 let Inst{22-20} = opcod;
682 let Inst{15-12} = 0b1111;
684 let Inst{5-4} = 0b00; // rotate
686 def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
687 IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
688 [(set GPR:$dst, (opnode GPR:$LHS,
689 (rotr GPR:$RHS, rot_imm:$rot)))]> {
690 let Inst{31-27} = 0b11111;
691 let Inst{26-23} = 0b0100;
692 let Inst{22-20} = opcod;
693 let Inst{15-12} = 0b1111;
695 let Inst{5-4} = {?,?}; // rotate
699 //===----------------------------------------------------------------------===//
701 //===----------------------------------------------------------------------===//
703 //===----------------------------------------------------------------------===//
704 // Miscellaneous Instructions.
707 // LEApcrel - Load a pc-relative address into a register without offending the
709 def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
710 "adr$p.w\t$dst, #$label", []> {
711 let Inst{31-27} = 0b11110;
712 let Inst{25-24} = 0b10;
713 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
716 let Inst{19-16} = 0b1111; // Rn
719 def t2LEApcrelJT : T2XI<(outs GPR:$dst),
720 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
721 "adr$p.w\t$dst, #${label}_${id}", []> {
722 let Inst{31-27} = 0b11110;
723 let Inst{25-24} = 0b10;
724 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
727 let Inst{19-16} = 0b1111; // Rn
731 // ADD r, sp, {so_imm|i12}
732 def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
733 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
734 let Inst{31-27} = 0b11110;
736 let Inst{24-21} = 0b1000;
737 let Inst{20} = ?; // The S bit.
738 let Inst{19-16} = 0b1101; // Rn = sp
741 def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
742 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
743 let Inst{31-27} = 0b11110;
745 let Inst{24-21} = 0b0000;
746 let Inst{20} = 0; // The S bit.
747 let Inst{19-16} = 0b1101; // Rn = sp
752 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
753 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
754 let Inst{31-27} = 0b11101;
755 let Inst{26-25} = 0b01;
756 let Inst{24-21} = 0b1000;
757 let Inst{20} = ?; // The S bit.
758 let Inst{19-16} = 0b1101; // Rn = sp
762 // SUB r, sp, {so_imm|i12}
763 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
764 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
765 let Inst{31-27} = 0b11110;
767 let Inst{24-21} = 0b1101;
768 let Inst{20} = ?; // The S bit.
769 let Inst{19-16} = 0b1101; // Rn = sp
772 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
773 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
774 let Inst{31-27} = 0b11110;
776 let Inst{24-21} = 0b0101;
777 let Inst{20} = 0; // The S bit.
778 let Inst{19-16} = 0b1101; // Rn = sp
783 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
785 "sub", "\t$dst, $sp, $rhs", []> {
786 let Inst{31-27} = 0b11101;
787 let Inst{26-25} = 0b01;
788 let Inst{24-21} = 0b1101;
789 let Inst{20} = ?; // The S bit.
790 let Inst{19-16} = 0b1101; // Rn = sp
794 // Pseudo instruction that will expand into a t2SUBrSPi + a copy.
795 let usesCustomInserter = 1 in { // Expanded after instruction selection.
796 def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
797 NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
798 def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
799 NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
800 def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
801 NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
802 } // usesCustomInserter
805 //===----------------------------------------------------------------------===//
806 // Load / store Instructions.
810 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
811 defm t2LDR : T2I_ld<0, 0b10, "ldr", UnOpFrag<(load node:$Src)>>;
813 // Loads with zero extension
814 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
815 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
817 // Loads with sign extension
818 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
819 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
821 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
823 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
824 (ins t2addrmode_imm8s4:$addr),
825 IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
826 def t2LDRDpci : T2Ii8s4<?, ?, 1, (outs GPR:$dst1, GPR:$dst2),
827 (ins i32imm:$addr), IIC_iLoadi,
828 "ldrd", "\t$dst1, $addr", []> {
829 let Inst{19-16} = 0b1111; // Rn
833 // zextload i1 -> zextload i8
834 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
835 (t2LDRBi12 t2addrmode_imm12:$addr)>;
836 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
837 (t2LDRBi8 t2addrmode_imm8:$addr)>;
838 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
839 (t2LDRBs t2addrmode_so_reg:$addr)>;
840 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
841 (t2LDRBpci tconstpool:$addr)>;
843 // extload -> zextload
844 // FIXME: Reduce the number of patterns by legalizing extload to zextload
846 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
847 (t2LDRBi12 t2addrmode_imm12:$addr)>;
848 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
849 (t2LDRBi8 t2addrmode_imm8:$addr)>;
850 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
851 (t2LDRBs t2addrmode_so_reg:$addr)>;
852 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
853 (t2LDRBpci tconstpool:$addr)>;
855 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
856 (t2LDRBi12 t2addrmode_imm12:$addr)>;
857 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
858 (t2LDRBi8 t2addrmode_imm8:$addr)>;
859 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
860 (t2LDRBs t2addrmode_so_reg:$addr)>;
861 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
862 (t2LDRBpci tconstpool:$addr)>;
864 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
865 (t2LDRHi12 t2addrmode_imm12:$addr)>;
866 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
867 (t2LDRHi8 t2addrmode_imm8:$addr)>;
868 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
869 (t2LDRHs t2addrmode_so_reg:$addr)>;
870 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
871 (t2LDRHpci tconstpool:$addr)>;
875 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
876 (ins t2addrmode_imm8:$addr),
877 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
878 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
881 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
882 (ins GPR:$base, t2am_imm8_offset:$offset),
883 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
884 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
887 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
888 (ins t2addrmode_imm8:$addr),
889 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
890 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
892 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
893 (ins GPR:$base, t2am_imm8_offset:$offset),
894 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
895 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
898 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
899 (ins t2addrmode_imm8:$addr),
900 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
901 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
903 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
904 (ins GPR:$base, t2am_imm8_offset:$offset),
905 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
906 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
909 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
910 (ins t2addrmode_imm8:$addr),
911 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
912 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
914 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
915 (ins GPR:$base, t2am_imm8_offset:$offset),
916 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
917 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
920 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
921 (ins t2addrmode_imm8:$addr),
922 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
923 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
925 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
926 (ins GPR:$base, t2am_imm8_offset:$offset),
927 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
928 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
933 defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
934 defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
935 defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
938 let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
939 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
940 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
941 IIC_iStorer, "strd", "\t$src1, $addr", []>;
944 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
945 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
946 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
947 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
949 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
951 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
952 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
953 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
954 "str", "\t$src, [$base], $offset", "$base = $base_wb",
956 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
958 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
959 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
960 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
961 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
963 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
965 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
966 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
967 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
968 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
970 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
972 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
973 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
974 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
975 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
977 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
979 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
980 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
981 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
982 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
984 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
987 // FIXME: ldrd / strd pre / post variants
989 //===----------------------------------------------------------------------===//
990 // Load / store multiple Instructions.
993 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
994 def t2LDM : T2XI<(outs),
995 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
996 IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
997 let Inst{31-27} = 0b11101;
998 let Inst{26-25} = 0b00;
999 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1001 let Inst{21} = ?; // The W bit.
1002 let Inst{20} = 1; // Load
1005 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1006 def t2STM : T2XI<(outs),
1007 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1008 IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1009 let Inst{31-27} = 0b11101;
1010 let Inst{26-25} = 0b00;
1011 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1013 let Inst{21} = ?; // The W bit.
1014 let Inst{20} = 0; // Store
1017 //===----------------------------------------------------------------------===//
1018 // Move Instructions.
1021 let neverHasSideEffects = 1 in
1022 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1023 "mov", ".w\t$dst, $src", []> {
1024 let Inst{31-27} = 0b11101;
1025 let Inst{26-25} = 0b01;
1026 let Inst{24-21} = 0b0010;
1027 let Inst{20} = ?; // The S bit.
1028 let Inst{19-16} = 0b1111; // Rn
1029 let Inst{14-12} = 0b000;
1030 let Inst{7-4} = 0b0000;
1033 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1034 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1035 def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1036 "mov", ".w\t$dst, $src",
1037 [(set GPR:$dst, t2_so_imm:$src)]> {
1038 let Inst{31-27} = 0b11110;
1040 let Inst{24-21} = 0b0010;
1041 let Inst{20} = ?; // The S bit.
1042 let Inst{19-16} = 0b1111; // Rn
1046 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1047 def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1048 "movw", "\t$dst, $src",
1049 [(set GPR:$dst, imm0_65535:$src)]> {
1050 let Inst{31-27} = 0b11110;
1052 let Inst{24-21} = 0b0010;
1053 let Inst{20} = 0; // The S bit.
1057 let Constraints = "$src = $dst" in
1058 def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
1059 "movt", "\t$dst, $imm",
1061 (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]> {
1062 let Inst{31-27} = 0b11110;
1064 let Inst{24-21} = 0b0110;
1065 let Inst{20} = 0; // The S bit.
1069 def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
1071 //===----------------------------------------------------------------------===//
1072 // Extend Instructions.
1077 defm t2SXTB : T2I_unary_rrot<0b100, "sxtb",
1078 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1079 defm t2SXTH : T2I_unary_rrot<0b000, "sxth",
1080 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1082 defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
1083 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1084 defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
1085 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1087 // TODO: SXT(A){B|H}16
1091 let AddedComplexity = 16 in {
1092 defm t2UXTB : T2I_unary_rrot<0b101, "uxtb",
1093 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1094 defm t2UXTH : T2I_unary_rrot<0b001, "uxth",
1095 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1096 defm t2UXTB16 : T2I_unary_rrot<0b011, "uxtb16",
1097 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1099 def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1100 (t2UXTB16r_rot GPR:$Src, 24)>;
1101 def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1102 (t2UXTB16r_rot GPR:$Src, 8)>;
1104 defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
1105 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1106 defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
1107 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1110 //===----------------------------------------------------------------------===//
1111 // Arithmetic Instructions.
1114 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1115 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1116 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1117 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1119 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1120 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1121 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1122 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1123 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1125 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1126 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1127 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1128 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1129 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adcs",
1130 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1131 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbcs",
1132 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1135 defm t2RSB : T2I_rbin_is <0b1110, "rsb",
1136 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1137 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1138 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1140 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1141 let AddedComplexity = 1 in
1142 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1143 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1144 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1145 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1146 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1147 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1150 //===----------------------------------------------------------------------===//
1151 // Shift and rotate Instructions.
1154 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1155 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1156 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1157 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1159 let Uses = [CPSR] in {
1160 def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1161 "rrx", "\t$dst, $src",
1162 [(set GPR:$dst, (ARMrrx GPR:$src))]> {
1163 let Inst{31-27} = 0b11101;
1164 let Inst{26-25} = 0b01;
1165 let Inst{24-21} = 0b0010;
1166 let Inst{20} = ?; // The S bit.
1167 let Inst{19-16} = 0b1111; // Rn
1168 let Inst{14-12} = 0b000;
1169 let Inst{7-4} = 0b0011;
1173 let Defs = [CPSR] in {
1174 def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1175 "lsrs.w\t$dst, $src, #1",
1176 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]> {
1177 let Inst{31-27} = 0b11101;
1178 let Inst{26-25} = 0b01;
1179 let Inst{24-21} = 0b0010;
1180 let Inst{20} = 1; // The S bit.
1181 let Inst{19-16} = 0b1111; // Rn
1182 let Inst{5-4} = 0b01; // Shift type.
1183 // Shift amount = Inst{14-12:7-6} = 1.
1184 let Inst{14-12} = 0b000;
1185 let Inst{7-6} = 0b01;
1187 def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1188 "asrs.w\t$dst, $src, #1",
1189 [(set GPR:$dst, (ARMsra_flag GPR:$src))]> {
1190 let Inst{31-27} = 0b11101;
1191 let Inst{26-25} = 0b01;
1192 let Inst{24-21} = 0b0010;
1193 let Inst{20} = 1; // The S bit.
1194 let Inst{19-16} = 0b1111; // Rn
1195 let Inst{5-4} = 0b10; // Shift type.
1196 // Shift amount = Inst{14-12:7-6} = 1.
1197 let Inst{14-12} = 0b000;
1198 let Inst{7-6} = 0b01;
1202 //===----------------------------------------------------------------------===//
1203 // Bitwise Instructions.
1206 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1207 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1208 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1209 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1210 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1211 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1213 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1214 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1216 let Constraints = "$src = $dst" in
1217 def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1218 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1219 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]> {
1220 let Inst{31-27} = 0b11110;
1222 let Inst{24-20} = 0b10110;
1223 let Inst{19-16} = 0b1111; // Rn
1227 def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1228 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1229 let Inst{31-27} = 0b11110;
1231 let Inst{24-20} = 0b10100;
1235 def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1236 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1237 let Inst{31-27} = 0b11110;
1239 let Inst{24-20} = 0b11100;
1243 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1244 // Added for disassembler with the pattern field purposely left blank.
1245 // FIXME: Utilize this instruction in codgen.
1246 def t2BFI : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1247 IIC_iALUi, "bfi", "\t$dst, $src, $lsb, $width", []> {
1248 let Inst{31-27} = 0b11110;
1250 let Inst{24-20} = 0b10110;
1254 defm t2ORN : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or node:$LHS,
1257 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1258 let AddedComplexity = 1 in
1259 defm t2MVN : T2I_un_irs <0b0011, "mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
1262 def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
1263 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
1265 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1266 def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
1267 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
1268 Requires<[IsThumb2]>;
1270 def : T2Pat<(t2_so_imm_not:$src),
1271 (t2MVNi t2_so_imm_not:$src)>;
1273 //===----------------------------------------------------------------------===//
1274 // Multiply Instructions.
1276 let isCommutable = 1 in
1277 def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1278 "mul", "\t$dst, $a, $b",
1279 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]> {
1280 let Inst{31-27} = 0b11111;
1281 let Inst{26-23} = 0b0110;
1282 let Inst{22-20} = 0b000;
1283 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1284 let Inst{7-4} = 0b0000; // Multiply
1287 def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1288 "mla", "\t$dst, $a, $b, $c",
1289 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]> {
1290 let Inst{31-27} = 0b11111;
1291 let Inst{26-23} = 0b0110;
1292 let Inst{22-20} = 0b000;
1293 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1294 let Inst{7-4} = 0b0000; // Multiply
1297 def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1298 "mls", "\t$dst, $a, $b, $c",
1299 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]> {
1300 let Inst{31-27} = 0b11111;
1301 let Inst{26-23} = 0b0110;
1302 let Inst{22-20} = 0b000;
1303 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1304 let Inst{7-4} = 0b0001; // Multiply and Subtract
1307 // Extra precision multiplies with low / high results
1308 let neverHasSideEffects = 1 in {
1309 let isCommutable = 1 in {
1310 def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1311 "smull", "\t$ldst, $hdst, $a, $b", []> {
1312 let Inst{31-27} = 0b11111;
1313 let Inst{26-23} = 0b0111;
1314 let Inst{22-20} = 0b000;
1315 let Inst{7-4} = 0b0000;
1318 def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1319 "umull", "\t$ldst, $hdst, $a, $b", []> {
1320 let Inst{31-27} = 0b11111;
1321 let Inst{26-23} = 0b0111;
1322 let Inst{22-20} = 0b010;
1323 let Inst{7-4} = 0b0000;
1327 // Multiply + accumulate
1328 def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1329 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1330 let Inst{31-27} = 0b11111;
1331 let Inst{26-23} = 0b0111;
1332 let Inst{22-20} = 0b100;
1333 let Inst{7-4} = 0b0000;
1336 def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1337 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1338 let Inst{31-27} = 0b11111;
1339 let Inst{26-23} = 0b0111;
1340 let Inst{22-20} = 0b110;
1341 let Inst{7-4} = 0b0000;
1344 def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1345 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1346 let Inst{31-27} = 0b11111;
1347 let Inst{26-23} = 0b0111;
1348 let Inst{22-20} = 0b110;
1349 let Inst{7-4} = 0b0110;
1351 } // neverHasSideEffects
1353 // Most significant word multiply
1354 def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1355 "smmul", "\t$dst, $a, $b",
1356 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]> {
1357 let Inst{31-27} = 0b11111;
1358 let Inst{26-23} = 0b0110;
1359 let Inst{22-20} = 0b101;
1360 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1361 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1364 def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1365 "smmla", "\t$dst, $a, $b, $c",
1366 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]> {
1367 let Inst{31-27} = 0b11111;
1368 let Inst{26-23} = 0b0110;
1369 let Inst{22-20} = 0b101;
1370 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1371 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1375 def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1376 "smmls", "\t$dst, $a, $b, $c",
1377 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]> {
1378 let Inst{31-27} = 0b11111;
1379 let Inst{26-23} = 0b0110;
1380 let Inst{22-20} = 0b110;
1381 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1382 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1385 multiclass T2I_smul<string opc, PatFrag opnode> {
1386 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1387 !strconcat(opc, "bb"), "\t$dst, $a, $b",
1388 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1389 (sext_inreg GPR:$b, i16)))]> {
1390 let Inst{31-27} = 0b11111;
1391 let Inst{26-23} = 0b0110;
1392 let Inst{22-20} = 0b001;
1393 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1394 let Inst{7-6} = 0b00;
1395 let Inst{5-4} = 0b00;
1398 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1399 !strconcat(opc, "bt"), "\t$dst, $a, $b",
1400 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1401 (sra GPR:$b, (i32 16))))]> {
1402 let Inst{31-27} = 0b11111;
1403 let Inst{26-23} = 0b0110;
1404 let Inst{22-20} = 0b001;
1405 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1406 let Inst{7-6} = 0b00;
1407 let Inst{5-4} = 0b01;
1410 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1411 !strconcat(opc, "tb"), "\t$dst, $a, $b",
1412 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1413 (sext_inreg GPR:$b, i16)))]> {
1414 let Inst{31-27} = 0b11111;
1415 let Inst{26-23} = 0b0110;
1416 let Inst{22-20} = 0b001;
1417 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1418 let Inst{7-6} = 0b00;
1419 let Inst{5-4} = 0b10;
1422 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1423 !strconcat(opc, "tt"), "\t$dst, $a, $b",
1424 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1425 (sra GPR:$b, (i32 16))))]> {
1426 let Inst{31-27} = 0b11111;
1427 let Inst{26-23} = 0b0110;
1428 let Inst{22-20} = 0b001;
1429 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1430 let Inst{7-6} = 0b00;
1431 let Inst{5-4} = 0b11;
1434 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1435 !strconcat(opc, "wb"), "\t$dst, $a, $b",
1436 [(set GPR:$dst, (sra (opnode GPR:$a,
1437 (sext_inreg GPR:$b, i16)), (i32 16)))]> {
1438 let Inst{31-27} = 0b11111;
1439 let Inst{26-23} = 0b0110;
1440 let Inst{22-20} = 0b011;
1441 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1442 let Inst{7-6} = 0b00;
1443 let Inst{5-4} = 0b00;
1446 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1447 !strconcat(opc, "wt"), "\t$dst, $a, $b",
1448 [(set GPR:$dst, (sra (opnode GPR:$a,
1449 (sra GPR:$b, (i32 16))), (i32 16)))]> {
1450 let Inst{31-27} = 0b11111;
1451 let Inst{26-23} = 0b0110;
1452 let Inst{22-20} = 0b011;
1453 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1454 let Inst{7-6} = 0b00;
1455 let Inst{5-4} = 0b01;
1460 multiclass T2I_smla<string opc, PatFrag opnode> {
1461 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1462 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1463 [(set GPR:$dst, (add GPR:$acc,
1464 (opnode (sext_inreg GPR:$a, i16),
1465 (sext_inreg GPR:$b, i16))))]> {
1466 let Inst{31-27} = 0b11111;
1467 let Inst{26-23} = 0b0110;
1468 let Inst{22-20} = 0b001;
1469 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1470 let Inst{7-6} = 0b00;
1471 let Inst{5-4} = 0b00;
1474 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1475 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1476 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1477 (sra GPR:$b, (i32 16)))))]> {
1478 let Inst{31-27} = 0b11111;
1479 let Inst{26-23} = 0b0110;
1480 let Inst{22-20} = 0b001;
1481 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1482 let Inst{7-6} = 0b00;
1483 let Inst{5-4} = 0b01;
1486 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1487 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1488 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1489 (sext_inreg GPR:$b, i16))))]> {
1490 let Inst{31-27} = 0b11111;
1491 let Inst{26-23} = 0b0110;
1492 let Inst{22-20} = 0b001;
1493 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1494 let Inst{7-6} = 0b00;
1495 let Inst{5-4} = 0b10;
1498 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1499 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1500 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1501 (sra GPR:$b, (i32 16)))))]> {
1502 let Inst{31-27} = 0b11111;
1503 let Inst{26-23} = 0b0110;
1504 let Inst{22-20} = 0b001;
1505 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1506 let Inst{7-6} = 0b00;
1507 let Inst{5-4} = 0b11;
1510 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1511 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1512 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1513 (sext_inreg GPR:$b, i16)), (i32 16))))]> {
1514 let Inst{31-27} = 0b11111;
1515 let Inst{26-23} = 0b0110;
1516 let Inst{22-20} = 0b011;
1517 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1518 let Inst{7-6} = 0b00;
1519 let Inst{5-4} = 0b00;
1522 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1523 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1524 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1525 (sra GPR:$b, (i32 16))), (i32 16))))]> {
1526 let Inst{31-27} = 0b11111;
1527 let Inst{26-23} = 0b0110;
1528 let Inst{22-20} = 0b011;
1529 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1530 let Inst{7-6} = 0b00;
1531 let Inst{5-4} = 0b01;
1535 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1536 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1538 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1539 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1542 //===----------------------------------------------------------------------===//
1543 // Misc. Arithmetic Instructions.
1546 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
1547 InstrItinClass itin, string opc, string asm, list<dag> pattern>
1548 : T2I<oops, iops, itin, opc, asm, pattern> {
1549 let Inst{31-27} = 0b11111;
1550 let Inst{26-22} = 0b01010;
1551 let Inst{21-20} = op1;
1552 let Inst{15-12} = 0b1111;
1553 let Inst{7-6} = 0b10;
1554 let Inst{5-4} = op2;
1557 def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1558 "clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
1560 def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1561 "rbit", "\t$dst, $src",
1562 [(set GPR:$dst, (ARMrbit GPR:$src))]>;
1564 def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1565 "rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
1567 def t2REV16 : T2I_misc<0b01, 0b01, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1568 "rev16", ".w\t$dst, $src",
1570 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1571 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1572 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1573 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
1575 def t2REVSH : T2I_misc<0b01, 0b11, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1576 "revsh", ".w\t$dst, $src",
1579 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1580 (shl GPR:$src, (i32 8))), i16))]>;
1582 def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1583 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1584 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1585 (and (shl GPR:$src2, (i32 imm:$shamt)),
1587 let Inst{31-27} = 0b11101;
1588 let Inst{26-25} = 0b01;
1589 let Inst{24-20} = 0b01100;
1590 let Inst{5} = 0; // BT form
1594 // Alternate cases for PKHBT where identities eliminate some nodes.
1595 def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1596 (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
1597 def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1598 (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1600 def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1601 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1602 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1603 (and (sra GPR:$src2, imm16_31:$shamt),
1605 let Inst{31-27} = 0b11101;
1606 let Inst{26-25} = 0b01;
1607 let Inst{24-20} = 0b01100;
1608 let Inst{5} = 1; // TB form
1612 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
1613 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1614 def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1615 (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
1616 def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
1617 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1618 (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1620 //===----------------------------------------------------------------------===//
1621 // Comparison Instructions...
1624 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
1625 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1626 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
1627 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1629 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
1630 // Compare-to-zero still works out, just not the relationals
1631 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
1632 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1633 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
1634 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1636 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
1637 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
1639 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
1640 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
1642 defm t2TST : T2I_cmp_irs<0b0000, "tst",
1643 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1644 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
1645 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
1647 // A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
1648 // Short range conditional branch. Looks awesome for loops. Need to figure
1649 // out how to use this one.
1652 // Conditional moves
1653 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1654 // a two-value operand where a dag node expects two operands. :(
1655 def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
1656 "mov", ".w\t$dst, $true",
1657 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1658 RegConstraint<"$false = $dst"> {
1659 let Inst{31-27} = 0b11101;
1660 let Inst{26-25} = 0b01;
1661 let Inst{24-21} = 0b0010;
1662 let Inst{20} = 0; // The S bit.
1663 let Inst{19-16} = 0b1111; // Rn
1664 let Inst{14-12} = 0b000;
1665 let Inst{7-4} = 0b0000;
1668 def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
1669 IIC_iCMOVi, "mov", ".w\t$dst, $true",
1670 [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1671 RegConstraint<"$false = $dst"> {
1672 let Inst{31-27} = 0b11110;
1674 let Inst{24-21} = 0b0010;
1675 let Inst{20} = 0; // The S bit.
1676 let Inst{19-16} = 0b1111; // Rn
1680 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
1681 string opc, string asm, list<dag> pattern>
1682 : T2I<oops, iops, itin, opc, asm, pattern> {
1683 let Inst{31-27} = 0b11101;
1684 let Inst{26-25} = 0b01;
1685 let Inst{24-21} = 0b0010;
1686 let Inst{20} = 0; // The S bit.
1687 let Inst{19-16} = 0b1111; // Rn
1688 let Inst{5-4} = opcod; // Shift type.
1690 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs GPR:$dst),
1691 (ins GPR:$false, GPR:$true, i32imm:$rhs),
1692 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
1693 RegConstraint<"$false = $dst">;
1694 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs GPR:$dst),
1695 (ins GPR:$false, GPR:$true, i32imm:$rhs),
1696 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
1697 RegConstraint<"$false = $dst">;
1698 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs GPR:$dst),
1699 (ins GPR:$false, GPR:$true, i32imm:$rhs),
1700 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
1701 RegConstraint<"$false = $dst">;
1702 def t2MOVCCror : T2I_movcc_sh<0b11, (outs GPR:$dst),
1703 (ins GPR:$false, GPR:$true, i32imm:$rhs),
1704 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
1705 RegConstraint<"$false = $dst">;
1707 //===----------------------------------------------------------------------===//
1708 // Atomic operations intrinsics
1711 // memory barriers protect the atomic sequences
1712 let hasSideEffects = 1 in {
1713 def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
1714 Pseudo, NoItinerary,
1716 [(ARMMemBarrierV7)]>,
1717 Requires<[IsThumb2]> {
1718 let Inst{31-4} = 0xF3BF8F5;
1719 // FIXME: add support for options other than a full system DMB
1720 let Inst{3-0} = 0b1111;
1723 def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
1724 Pseudo, NoItinerary,
1726 [(ARMSyncBarrierV7)]>,
1727 Requires<[IsThumb2]> {
1728 let Inst{31-4} = 0xF3BF8F4;
1729 // FIXME: add support for options other than a full system DSB
1730 let Inst{3-0} = 0b1111;
1734 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1735 InstrItinClass itin, string opc, string asm, string cstr,
1736 list<dag> pattern, bits<4> rt2 = 0b1111>
1737 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
1738 let Inst{31-27} = 0b11101;
1739 let Inst{26-20} = 0b0001101;
1740 let Inst{11-8} = rt2;
1741 let Inst{7-6} = 0b01;
1742 let Inst{5-4} = opcod;
1743 let Inst{3-0} = 0b1111;
1745 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
1746 InstrItinClass itin, string opc, string asm, string cstr,
1747 list<dag> pattern, bits<4> rt2 = 0b1111>
1748 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
1749 let Inst{31-27} = 0b11101;
1750 let Inst{26-20} = 0b0001100;
1751 let Inst{11-8} = rt2;
1752 let Inst{7-6} = 0b01;
1753 let Inst{5-4} = opcod;
1756 let mayLoad = 1 in {
1757 def t2LDREXB : T2I_ldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1758 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
1760 def t2LDREXH : T2I_ldrex<0b01, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1761 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
1763 def t2LDREX : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1764 Size4Bytes, NoItinerary,
1765 "ldrex", "\t$dest, [$ptr]", "",
1767 let Inst{31-27} = 0b11101;
1768 let Inst{26-20} = 0b0000101;
1769 let Inst{11-8} = 0b1111;
1770 let Inst{7-0} = 0b00000000; // imm8 = 0
1772 def t2LDREXD : T2I_ldrex<0b11, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1773 AddrModeNone, Size4Bytes, NoItinerary,
1774 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
1778 let mayStore = 1, Constraints = "@earlyclobber $success" in {
1779 def t2STREXB : T2I_strex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1780 AddrModeNone, Size4Bytes, NoItinerary,
1781 "strexb", "\t$success, $src, [$ptr]", "", []>;
1782 def t2STREXH : T2I_strex<0b01, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1783 AddrModeNone, Size4Bytes, NoItinerary,
1784 "strexh", "\t$success, $src, [$ptr]", "", []>;
1785 def t2STREX : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1786 AddrModeNone, Size4Bytes, NoItinerary,
1787 "strex", "\t$success, $src, [$ptr]", "",
1789 let Inst{31-27} = 0b11101;
1790 let Inst{26-20} = 0b0000100;
1791 let Inst{7-0} = 0b00000000; // imm8 = 0
1793 def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
1794 (ins GPR:$src, GPR:$src2, GPR:$ptr),
1795 AddrModeNone, Size4Bytes, NoItinerary,
1796 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
1800 //===----------------------------------------------------------------------===//
1804 // __aeabi_read_tp preserves the registers r1-r3.
1806 Defs = [R0, R12, LR, CPSR] in {
1807 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
1808 "bl\t__aeabi_read_tp",
1809 [(set R0, ARMthread_pointer)]> {
1810 let Inst{31-27} = 0b11110;
1811 let Inst{15-14} = 0b11;
1816 //===----------------------------------------------------------------------===//
1817 // SJLJ Exception handling intrinsics
1818 // eh_sjlj_setjmp() is an instruction sequence to store the return
1819 // address and save #0 in R0 for the non-longjmp case.
1820 // Since by its nature we may be coming from some other function to get
1821 // here, and we're using the stack frame for the containing function to
1822 // save/restore registers, we can't keep anything live in regs across
1823 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1824 // when we get here from a longjmp(). We force everthing out of registers
1825 // except for our own input by listing the relevant registers in Defs. By
1826 // doing so, we also cause the prologue/epilogue code to actively preserve
1827 // all of the callee-saved resgisters, which is exactly what we want.
1828 // The current SP is passed in $val, and we reuse the reg as a scratch.
1830 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
1831 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1832 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1834 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
1835 AddrModeNone, SizeSpecial, NoItinerary,
1836 "str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
1838 "\tadds\t$val, #9\n"
1839 "\tstr\t$val, [$src, #4]\n"
1842 "\tmovs\tr0, #1\t@ end eh.setjmp\n"
1844 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
1849 //===----------------------------------------------------------------------===//
1850 // Control-Flow Instructions
1853 // FIXME: remove when we have a way to marking a MI with these properties.
1854 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
1856 // FIXME: Should pc be an implicit operand like PICADD, etc?
1857 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1858 hasExtraDefRegAllocReq = 1 in
1859 def t2LDM_RET : T2XI<(outs),
1860 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1861 IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
1863 let Inst{31-27} = 0b11101;
1864 let Inst{26-25} = 0b00;
1865 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1867 let Inst{21} = ?; // The W bit.
1868 let Inst{20} = 1; // Load
1871 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1872 let isPredicable = 1 in
1873 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
1875 [(br bb:$target)]> {
1876 let Inst{31-27} = 0b11110;
1877 let Inst{15-14} = 0b10;
1881 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1884 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
1885 IIC_Br, "mov\tpc, $target\n$jt",
1886 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
1887 let Inst{31-27} = 0b11101;
1888 let Inst{26-20} = 0b0100100;
1889 let Inst{19-16} = 0b1111;
1890 let Inst{14-12} = 0b000;
1891 let Inst{11-8} = 0b1111; // Rd = pc
1892 let Inst{7-4} = 0b0000;
1895 // FIXME: Add a non-pc based case that can be predicated.
1898 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
1899 IIC_Br, "tbb\t$index\n$jt", []> {
1900 let Inst{31-27} = 0b11101;
1901 let Inst{26-20} = 0b0001101;
1902 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
1903 let Inst{15-8} = 0b11110000;
1904 let Inst{7-4} = 0b0000; // B form
1909 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
1910 IIC_Br, "tbh\t$index\n$jt", []> {
1911 let Inst{31-27} = 0b11101;
1912 let Inst{26-20} = 0b0001101;
1913 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
1914 let Inst{15-8} = 0b11110000;
1915 let Inst{7-4} = 0b0001; // H form
1917 } // isNotDuplicable, isIndirectBranch
1919 } // isBranch, isTerminator, isBarrier
1921 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1922 // a two-value operand where a dag node expects two operands. :(
1923 let isBranch = 1, isTerminator = 1 in
1924 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
1926 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
1927 let Inst{31-27} = 0b11110;
1928 let Inst{15-14} = 0b10;
1934 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
1935 AddrModeNone, Size2Bytes, IIC_iALUx,
1936 "it$mask\t$cc", "", []> {
1937 // 16-bit instruction.
1938 let Inst{31-16} = 0x0000;
1939 let Inst{15-8} = 0b10111111;
1942 //===----------------------------------------------------------------------===//
1943 // Non-Instruction Patterns
1946 // Two piece so_imms.
1947 def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
1948 (t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1949 (t2_so_imm2part_2 imm:$RHS))>;
1950 def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
1951 (t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1952 (t2_so_imm2part_2 imm:$RHS))>;
1953 def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
1954 (t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1955 (t2_so_imm2part_2 imm:$RHS))>;
1956 def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
1957 (t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
1958 (t2_so_neg_imm2part_2 imm:$RHS))>;
1960 // 32-bit immediate using movw + movt.
1961 // This is a single pseudo instruction to make it re-materializable. Remove
1962 // when we can do generalized remat.
1963 let isReMaterializable = 1 in
1964 def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1965 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
1966 [(set GPR:$dst, (i32 imm:$src))]>;
1968 // ConstantPool, GlobalAddress, and JumpTable
1969 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
1970 Requires<[IsThumb2, DontUseMovt]>;
1971 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
1972 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
1973 Requires<[IsThumb2, UseMovt]>;
1975 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1976 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
1978 // Pseudo instruction that combines ldr from constpool and add pc. This should
1979 // be expanded into two instructions late to allow if-conversion and
1981 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
1982 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
1983 NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
1984 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
1986 Requires<[IsThumb2]>;