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 = "printMandatoryPredicateOperand";
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 EncoderMethod = "getT2SORegOpValue";
35 let PrintMethod = "printT2SOOperand";
36 let MIOperandInfo = (ops rGPR, i32imm);
39 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
40 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
41 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
44 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
45 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
46 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
49 // t2_so_imm - Match a 32-bit immediate operand, which is an
50 // 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
51 // immediate splatted into multiple bytes of the word. t2_so_imm values are
52 // represented in the imm field in the same 12-bit form that they are encoded
53 // into t2_so_imm instructions: the 8-bit immediate is the least significant
54 // bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
55 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
56 let EncoderMethod = "getT2SOImmOpValue";
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(-((uint32_t)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 def imm0_255_not : PatLeaf<(i32 imm), [{
126 return (uint32_t)(~N->getZExtValue()) < 255;
129 // Define Thumb2 specific addressing modes.
131 // t2addrmode_imm12 := reg + imm12
132 def t2addrmode_imm12 : Operand<i32>,
133 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
134 let PrintMethod = "printAddrModeImm12Operand";
135 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
138 // t2addrmode_imm8 := reg +/- imm8
139 def t2addrmode_imm8 : Operand<i32>,
140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
141 let PrintMethod = "printT2AddrModeImm8Operand";
142 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
145 def t2am_imm8_offset : Operand<i32>,
146 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
147 [], [SDNPWantRoot]> {
148 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
151 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
152 def t2addrmode_imm8s4 : Operand<i32> {
153 let PrintMethod = "printT2AddrModeImm8s4Operand";
154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
157 def t2am_imm8s4_offset : Operand<i32> {
158 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
161 // t2addrmode_so_reg := reg + (reg << imm2)
162 def t2addrmode_so_reg : Operand<i32>,
163 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
164 let PrintMethod = "printT2AddrModeSoRegOperand";
165 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
169 //===----------------------------------------------------------------------===//
170 // Multiclass helpers...
174 class T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
175 string opc, string asm, list<dag> pattern>
176 : T2I<oops, iops, itin, opc, asm, pattern> {
180 let Inst{11-8} = Rd{3-0};
181 let Inst{26} = imm{11};
182 let Inst{14-12} = imm{10-8};
183 let Inst{7-0} = imm{7-0};
186 class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
187 string opc, string asm, list<dag> pattern>
188 : T2sI<oops, iops, itin, opc, asm, pattern> {
193 let Inst{11-8} = Rd{3-0};
194 let Inst{26} = imm{11};
195 let Inst{14-12} = imm{10-8};
196 let Inst{7-0} = imm{7-0};
199 class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
200 string opc, string asm, list<dag> pattern>
201 : T2I<oops, iops, itin, opc, asm, pattern> {
205 let Inst{11-8} = Rd{3-0};
206 let Inst{3-0} = ShiftedRm{3-0};
207 let Inst{5-4} = ShiftedRm{6-5};
208 let Inst{14-12} = ShiftedRm{11-9};
209 let Inst{7-6} = ShiftedRm{8-7};
212 class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
213 string opc, string asm, list<dag> pattern>
214 : T2I<oops, iops, itin, opc, asm, pattern> {
218 let Inst{11-8} = Rd{3-0};
219 let Inst{3-0} = ShiftedRm{3-0};
220 let Inst{5-4} = ShiftedRm{6-5};
221 let Inst{14-12} = ShiftedRm{11-9};
222 let Inst{7-6} = ShiftedRm{8-7};
225 class T2TwoReg<dag oops, dag iops, InstrItinClass itin,
226 string opc, string asm, list<dag> pattern>
227 : T2I<oops, iops, itin, opc, asm, pattern> {
231 let Inst{11-8} = Rd{3-0};
232 let Inst{3-0} = Rm{3-0};
235 class T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
236 string opc, string asm, list<dag> pattern>
237 : T2sI<oops, iops, itin, opc, asm, pattern> {
241 let Inst{11-8} = Rd{3-0};
242 let Inst{3-0} = Rm{3-0};
246 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
247 string opc, string asm, list<dag> pattern>
248 : T2I<oops, iops, itin, opc, asm, pattern> {
252 let Inst{11-8} = Rd{3-0};
253 let Inst{3-0} = Rm{3-0};
256 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
257 string opc, string asm, list<dag> pattern>
258 : T2sI<oops, iops, itin, opc, asm, pattern> {
263 let Inst{11-8} = Rd{3-0};
264 let Inst{19-16} = Rn{3-0};
265 let Inst{26} = imm{11};
266 let Inst{14-12} = imm{10-8};
267 let Inst{7-0} = imm{7-0};
270 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
271 string opc, string asm, list<dag> pattern>
272 : T2I<oops, iops, itin, opc, asm, pattern> {
277 let Inst{11-8} = Rd{3-0};
278 let Inst{19-16} = Rn{3-0};
279 let Inst{3-0} = Rm{3-0};
282 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
283 string opc, string asm, list<dag> pattern>
284 : T2sI<oops, iops, itin, opc, asm, pattern> {
289 let Inst{11-8} = Rd{3-0};
290 let Inst{19-16} = Rn{3-0};
291 let Inst{3-0} = Rm{3-0};
294 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
295 string opc, string asm, list<dag> pattern>
296 : T2I<oops, iops, itin, opc, asm, pattern> {
301 let Inst{11-8} = Rd{3-0};
302 let Inst{19-16} = Rn{3-0};
303 let Inst{3-0} = ShiftedRm{3-0};
304 let Inst{5-4} = ShiftedRm{6-5};
305 let Inst{14-12} = ShiftedRm{11-9};
306 let Inst{7-6} = ShiftedRm{8-7};
309 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
310 string opc, string asm, list<dag> pattern>
311 : T2sI<oops, iops, itin, opc, asm, pattern> {
316 let Inst{11-8} = Rd{3-0};
317 let Inst{19-16} = Rn{3-0};
318 let Inst{3-0} = ShiftedRm{3-0};
319 let Inst{5-4} = ShiftedRm{6-5};
320 let Inst{14-12} = ShiftedRm{11-9};
321 let Inst{7-6} = ShiftedRm{8-7};
324 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
325 /// unary operation that produces a value. These are predicable and can be
326 /// changed to modify CPSR.
327 multiclass T2I_un_irs<bits<4> opcod, string opc,
328 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
329 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
331 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
333 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> {
334 let isAsCheapAsAMove = Cheap;
335 let isReMaterializable = ReMat;
336 let Inst{31-27} = 0b11110;
338 let Inst{24-21} = opcod;
339 let Inst{20} = ?; // The S bit.
340 let Inst{19-16} = 0b1111; // Rn
344 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
346 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
347 let Inst{31-27} = 0b11101;
348 let Inst{26-25} = 0b01;
349 let Inst{24-21} = opcod;
350 let Inst{20} = ?; // The S bit.
351 let Inst{19-16} = 0b1111; // Rn
352 let Inst{14-12} = 0b000; // imm3
353 let Inst{7-6} = 0b00; // imm2
354 let Inst{5-4} = 0b00; // type
357 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
358 opc, ".w\t$Rd, $ShiftedRm",
359 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> {
360 let Inst{31-27} = 0b11101;
361 let Inst{26-25} = 0b01;
362 let Inst{24-21} = opcod;
363 let Inst{20} = ?; // The S bit.
364 let Inst{19-16} = 0b1111; // Rn
368 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
369 /// binary operation that produces a value. These are predicable and can be
370 /// changed to modify CPSR.
371 multiclass T2I_bin_irs<bits<4> opcod, string opc,
372 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
373 PatFrag opnode, bit Commutable = 0, string wide = ""> {
375 def ri : T2sTwoRegImm<
376 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
377 opc, "\t$Rd, $Rn, $imm",
378 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
379 let Inst{31-27} = 0b11110;
381 let Inst{24-21} = opcod;
382 let Inst{20} = ?; // The S bit.
386 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
387 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
388 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
389 let isCommutable = Commutable;
390 let Inst{31-27} = 0b11101;
391 let Inst{26-25} = 0b01;
392 let Inst{24-21} = opcod;
393 let Inst{20} = ?; // The S bit.
394 let Inst{14-12} = 0b000; // imm3
395 let Inst{7-6} = 0b00; // imm2
396 let Inst{5-4} = 0b00; // type
399 def rs : T2sTwoRegShiftedReg<
400 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
401 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
402 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
403 let Inst{31-27} = 0b11101;
404 let Inst{26-25} = 0b01;
405 let Inst{24-21} = opcod;
406 let Inst{20} = ?; // The S bit.
410 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
411 // the ".w" prefix to indicate that they are wide.
412 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
413 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
414 PatFrag opnode, bit Commutable = 0> :
415 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
417 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
418 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
419 /// it is equivalent to the T2I_bin_irs counterpart.
420 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
422 def ri : T2sTwoRegImm<
423 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
424 opc, ".w\t$Rd, $Rn, $imm",
425 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
426 let Inst{31-27} = 0b11110;
428 let Inst{24-21} = opcod;
429 let Inst{20} = ?; // The S bit.
433 def rr : T2sThreeReg<
434 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
435 opc, "\t$Rd, $Rn, $Rm",
436 [/* For disassembly only; pattern left blank */]> {
437 let Inst{31-27} = 0b11101;
438 let Inst{26-25} = 0b01;
439 let Inst{24-21} = opcod;
440 let Inst{20} = ?; // The S bit.
441 let Inst{14-12} = 0b000; // imm3
442 let Inst{7-6} = 0b00; // imm2
443 let Inst{5-4} = 0b00; // type
446 def rs : T2sTwoRegShiftedReg<
447 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
448 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
449 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
450 let Inst{31-27} = 0b11101;
451 let Inst{26-25} = 0b01;
452 let Inst{24-21} = opcod;
453 let Inst{20} = ?; // The S bit.
457 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
458 /// instruction modifies the CPSR register.
459 let Defs = [CPSR] in {
460 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
461 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
462 PatFrag opnode, bit Commutable = 0> {
464 def ri : T2TwoRegImm<
465 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
466 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
467 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
468 let Inst{31-27} = 0b11110;
470 let Inst{24-21} = opcod;
471 let Inst{20} = 1; // The S bit.
476 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
477 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
478 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
479 let isCommutable = Commutable;
480 let Inst{31-27} = 0b11101;
481 let Inst{26-25} = 0b01;
482 let Inst{24-21} = opcod;
483 let Inst{20} = 1; // The S bit.
484 let Inst{14-12} = 0b000; // imm3
485 let Inst{7-6} = 0b00; // imm2
486 let Inst{5-4} = 0b00; // type
489 def rs : T2TwoRegShiftedReg<
490 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
491 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
492 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
493 let Inst{31-27} = 0b11101;
494 let Inst{26-25} = 0b01;
495 let Inst{24-21} = opcod;
496 let Inst{20} = 1; // The S bit.
501 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
502 /// patterns for a binary operation that produces a value.
503 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
504 bit Commutable = 0> {
506 // The register-immediate version is re-materializable. This is useful
507 // in particular for taking the address of a local.
508 let isReMaterializable = 1 in {
509 def ri : T2sTwoRegImm<
510 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
511 opc, ".w\t$Rd, $Rn, $imm",
512 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
513 let Inst{31-27} = 0b11110;
516 let Inst{23-21} = op23_21;
517 let Inst{20} = 0; // The S bit.
522 def ri12 : T2TwoRegImm<
523 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
524 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
525 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
526 let Inst{31-27} = 0b11110;
529 let Inst{23-21} = op23_21;
530 let Inst{20} = 0; // The S bit.
534 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
535 opc, ".w\t$Rd, $Rn, $Rm",
536 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
537 let isCommutable = Commutable;
538 let Inst{31-27} = 0b11101;
539 let Inst{26-25} = 0b01;
541 let Inst{23-21} = op23_21;
542 let Inst{20} = 0; // The S bit.
543 let Inst{14-12} = 0b000; // imm3
544 let Inst{7-6} = 0b00; // imm2
545 let Inst{5-4} = 0b00; // type
548 def rs : T2sTwoRegShiftedReg<
549 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
550 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
551 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
552 let Inst{31-27} = 0b11101;
553 let Inst{26-25} = 0b01;
555 let Inst{23-21} = op23_21;
556 let Inst{20} = 0; // The S bit.
560 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
561 /// for a binary operation that produces a value and use the carry
562 /// bit. It's not predicable.
563 let Uses = [CPSR] in {
564 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
565 bit Commutable = 0> {
567 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
568 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
569 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
570 Requires<[IsThumb2]> {
571 let Inst{31-27} = 0b11110;
573 let Inst{24-21} = opcod;
574 let Inst{20} = 0; // The S bit.
578 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
579 opc, ".w\t$Rd, $Rn, $Rm",
580 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
581 Requires<[IsThumb2]> {
582 let isCommutable = Commutable;
583 let Inst{31-27} = 0b11101;
584 let Inst{26-25} = 0b01;
585 let Inst{24-21} = opcod;
586 let Inst{20} = 0; // The S bit.
587 let Inst{14-12} = 0b000; // imm3
588 let Inst{7-6} = 0b00; // imm2
589 let Inst{5-4} = 0b00; // type
592 def rs : T2sTwoRegShiftedReg<
593 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
594 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
595 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
596 Requires<[IsThumb2]> {
597 let Inst{31-27} = 0b11101;
598 let Inst{26-25} = 0b01;
599 let Inst{24-21} = opcod;
600 let Inst{20} = 0; // The S bit.
604 // Carry setting variants
605 let Defs = [CPSR] in {
606 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
607 bit Commutable = 0> {
609 def ri : T2sTwoRegImm<
610 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
611 opc, "\t$Rd, $Rn, $imm",
612 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
613 Requires<[IsThumb2]> {
614 let Inst{31-27} = 0b11110;
616 let Inst{24-21} = opcod;
617 let Inst{20} = 1; // The S bit.
621 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
622 opc, ".w\t$Rd, $Rn, $Rm",
623 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
624 Requires<[IsThumb2]> {
625 let isCommutable = Commutable;
626 let Inst{31-27} = 0b11101;
627 let Inst{26-25} = 0b01;
628 let Inst{24-21} = opcod;
629 let Inst{20} = 1; // The S bit.
630 let Inst{14-12} = 0b000; // imm3
631 let Inst{7-6} = 0b00; // imm2
632 let Inst{5-4} = 0b00; // type
635 def rs : T2sTwoRegShiftedReg<
636 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
637 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
638 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
639 Requires<[IsThumb2]> {
640 let Inst{31-27} = 0b11101;
641 let Inst{26-25} = 0b01;
642 let Inst{24-21} = opcod;
643 let Inst{20} = 1; // The S bit.
649 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
650 /// version is not needed since this is only for codegen.
651 let Defs = [CPSR] in {
652 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
654 def ri : T2TwoRegImm<
655 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
656 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
657 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
658 let Inst{31-27} = 0b11110;
660 let Inst{24-21} = opcod;
661 let Inst{20} = 1; // The S bit.
665 def rs : T2TwoRegShiftedReg<
666 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
667 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
668 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
669 let Inst{31-27} = 0b11101;
670 let Inst{26-25} = 0b01;
671 let Inst{24-21} = opcod;
672 let Inst{20} = 1; // The S bit.
677 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
678 // rotate operation that produces a value.
679 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
681 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
682 opc, ".w\t$dst, $lhs, $rhs",
683 [(set rGPR:$dst, (opnode rGPR:$lhs, imm1_31:$rhs))]> {
684 let Inst{31-27} = 0b11101;
685 let Inst{26-21} = 0b010010;
686 let Inst{19-16} = 0b1111; // Rn
687 let Inst{5-4} = opcod;
690 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iMOVsr,
691 opc, ".w\t$dst, $lhs, $rhs",
692 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
693 let Inst{31-27} = 0b11111;
694 let Inst{26-23} = 0b0100;
695 let Inst{22-21} = opcod;
696 let Inst{15-12} = 0b1111;
697 let Inst{7-4} = 0b0000;
701 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
702 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
703 /// a explicit result, only implicitly set CPSR.
704 let isCompare = 1, Defs = [CPSR] in {
705 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
706 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
709 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), iii,
710 opc, ".w\t$lhs, $rhs",
711 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
712 let Inst{31-27} = 0b11110;
714 let Inst{24-21} = opcod;
715 let Inst{20} = 1; // The S bit.
717 let Inst{11-8} = 0b1111; // Rd
720 def rr : T2I<(outs), (ins GPR:$lhs, rGPR:$rhs), iir,
721 opc, ".w\t$lhs, $rhs",
722 [(opnode GPR:$lhs, rGPR:$rhs)]> {
723 let Inst{31-27} = 0b11101;
724 let Inst{26-25} = 0b01;
725 let Inst{24-21} = opcod;
726 let Inst{20} = 1; // The S bit.
727 let Inst{14-12} = 0b000; // imm3
728 let Inst{11-8} = 0b1111; // Rd
729 let Inst{7-6} = 0b00; // imm2
730 let Inst{5-4} = 0b00; // type
733 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), iis,
734 opc, ".w\t$lhs, $rhs",
735 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
736 let Inst{31-27} = 0b11101;
737 let Inst{26-25} = 0b01;
738 let Inst{24-21} = opcod;
739 let Inst{20} = 1; // The S bit.
740 let Inst{11-8} = 0b1111; // Rd
745 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
746 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
747 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
748 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii,
749 opc, ".w\t$dst, $addr",
750 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
751 let Inst{31-27} = 0b11111;
752 let Inst{26-25} = 0b00;
753 let Inst{24} = signed;
755 let Inst{22-21} = opcod;
756 let Inst{20} = 1; // load
758 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii,
759 opc, "\t$dst, $addr",
760 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
761 let Inst{31-27} = 0b11111;
762 let Inst{26-25} = 0b00;
763 let Inst{24} = signed;
765 let Inst{22-21} = opcod;
766 let Inst{20} = 1; // load
768 // Offset: index==TRUE, wback==FALSE
769 let Inst{10} = 1; // The P bit.
770 let Inst{8} = 0; // The W bit.
772 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis,
773 opc, ".w\t$dst, $addr",
774 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
775 let Inst{31-27} = 0b11111;
776 let Inst{26-25} = 0b00;
777 let Inst{24} = signed;
779 let Inst{22-21} = opcod;
780 let Inst{20} = 1; // load
781 let Inst{11-6} = 0b000000;
784 // FIXME: Is the pci variant actually needed?
785 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii,
786 opc, ".w\t$dst, $addr",
787 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
788 let isReMaterializable = 1;
789 let Inst{31-27} = 0b11111;
790 let Inst{26-25} = 0b00;
791 let Inst{24} = signed;
792 let Inst{23} = ?; // add = (U == '1')
793 let Inst{22-21} = opcod;
794 let Inst{20} = 1; // load
795 let Inst{19-16} = 0b1111; // Rn
799 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
800 multiclass T2I_st<bits<2> opcod, string opc,
801 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
802 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii,
803 opc, ".w\t$src, $addr",
804 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
805 let Inst{31-27} = 0b11111;
806 let Inst{26-23} = 0b0001;
807 let Inst{22-21} = opcod;
808 let Inst{20} = 0; // !load
810 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii,
811 opc, "\t$src, $addr",
812 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
813 let Inst{31-27} = 0b11111;
814 let Inst{26-23} = 0b0000;
815 let Inst{22-21} = opcod;
816 let Inst{20} = 0; // !load
818 // Offset: index==TRUE, wback==FALSE
819 let Inst{10} = 1; // The P bit.
820 let Inst{8} = 0; // The W bit.
822 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis,
823 opc, ".w\t$src, $addr",
824 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
825 let Inst{31-27} = 0b11111;
826 let Inst{26-23} = 0b0000;
827 let Inst{22-21} = opcod;
828 let Inst{20} = 0; // !load
829 let Inst{11-6} = 0b000000;
833 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
834 /// register and one whose operand is a register rotated by 8/16/24.
835 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
836 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
837 opc, ".w\t$dst, $src",
838 [(set rGPR:$dst, (opnode rGPR:$src))]> {
839 let Inst{31-27} = 0b11111;
840 let Inst{26-23} = 0b0100;
841 let Inst{22-20} = opcod;
842 let Inst{19-16} = 0b1111; // Rn
843 let Inst{15-12} = 0b1111;
845 let Inst{5-4} = 0b00; // rotate
847 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
848 opc, ".w\t$dst, $src, ror $rot",
849 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]> {
850 let Inst{31-27} = 0b11111;
851 let Inst{26-23} = 0b0100;
852 let Inst{22-20} = opcod;
853 let Inst{19-16} = 0b1111; // Rn
854 let Inst{15-12} = 0b1111;
856 let Inst{5-4} = {?,?}; // rotate
860 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
861 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
862 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
864 [(set rGPR:$dst, (opnode rGPR:$src))]>,
865 Requires<[HasT2ExtractPack, IsThumb2]> {
866 let Inst{31-27} = 0b11111;
867 let Inst{26-23} = 0b0100;
868 let Inst{22-20} = opcod;
869 let Inst{19-16} = 0b1111; // Rn
870 let Inst{15-12} = 0b1111;
872 let Inst{5-4} = 0b00; // rotate
874 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
875 opc, "\t$dst, $src, ror $rot",
876 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]>,
877 Requires<[HasT2ExtractPack, IsThumb2]> {
878 let Inst{31-27} = 0b11111;
879 let Inst{26-23} = 0b0100;
880 let Inst{22-20} = opcod;
881 let Inst{19-16} = 0b1111; // Rn
882 let Inst{15-12} = 0b1111;
884 let Inst{5-4} = {?,?}; // rotate
888 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
890 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
891 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
892 opc, "\t$dst, $src", []> {
893 let Inst{31-27} = 0b11111;
894 let Inst{26-23} = 0b0100;
895 let Inst{22-20} = opcod;
896 let Inst{19-16} = 0b1111; // Rn
897 let Inst{15-12} = 0b1111;
899 let Inst{5-4} = 0b00; // rotate
901 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
902 opc, "\t$dst, $src, ror $rot", []> {
903 let Inst{31-27} = 0b11111;
904 let Inst{26-23} = 0b0100;
905 let Inst{22-20} = opcod;
906 let Inst{19-16} = 0b1111; // Rn
907 let Inst{15-12} = 0b1111;
909 let Inst{5-4} = {?,?}; // rotate
913 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
914 /// register and one whose operand is a register rotated by 8/16/24.
915 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
916 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
917 opc, "\t$dst, $LHS, $RHS",
918 [(set rGPR:$dst, (opnode rGPR:$LHS, rGPR:$RHS))]>,
919 Requires<[HasT2ExtractPack, IsThumb2]> {
920 let Inst{31-27} = 0b11111;
921 let Inst{26-23} = 0b0100;
922 let Inst{22-20} = opcod;
923 let Inst{15-12} = 0b1111;
925 let Inst{5-4} = 0b00; // rotate
927 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
928 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
929 [(set rGPR:$dst, (opnode rGPR:$LHS,
930 (rotr rGPR:$RHS, rot_imm:$rot)))]>,
931 Requires<[HasT2ExtractPack, IsThumb2]> {
932 let Inst{31-27} = 0b11111;
933 let Inst{26-23} = 0b0100;
934 let Inst{22-20} = opcod;
935 let Inst{15-12} = 0b1111;
937 let Inst{5-4} = {?,?}; // rotate
941 // DO variant - disassembly only, no pattern
943 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
944 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
945 opc, "\t$dst, $LHS, $RHS", []> {
946 let Inst{31-27} = 0b11111;
947 let Inst{26-23} = 0b0100;
948 let Inst{22-20} = opcod;
949 let Inst{15-12} = 0b1111;
951 let Inst{5-4} = 0b00; // rotate
953 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
954 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
955 let Inst{31-27} = 0b11111;
956 let Inst{26-23} = 0b0100;
957 let Inst{22-20} = opcod;
958 let Inst{15-12} = 0b1111;
960 let Inst{5-4} = {?,?}; // rotate
964 //===----------------------------------------------------------------------===//
966 //===----------------------------------------------------------------------===//
968 //===----------------------------------------------------------------------===//
969 // Miscellaneous Instructions.
972 // LEApcrel - Load a pc-relative address into a register without offending the
974 let neverHasSideEffects = 1 in {
975 let isReMaterializable = 1 in
976 def t2LEApcrel : T2XI<(outs rGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
977 "adr${p}.w\t$dst, #$label", []> {
978 let Inst{31-27} = 0b11110;
979 let Inst{25-24} = 0b10;
980 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
983 let Inst{19-16} = 0b1111; // Rn
986 } // neverHasSideEffects
987 def t2LEApcrelJT : T2XI<(outs rGPR:$dst),
988 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
989 "adr${p}.w\t$dst, #${label}_${id}", []> {
990 let Inst{31-27} = 0b11110;
991 let Inst{25-24} = 0b10;
992 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
995 let Inst{19-16} = 0b1111; // Rn
999 // ADD r, sp, {so_imm|i12}
1000 def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
1001 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
1002 let Inst{31-27} = 0b11110;
1004 let Inst{24-21} = 0b1000;
1005 let Inst{20} = ?; // The S bit.
1006 let Inst{19-16} = 0b1101; // Rn = sp
1009 def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
1010 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
1011 let Inst{31-27} = 0b11110;
1013 let Inst{24-21} = 0b0000;
1014 let Inst{20} = 0; // The S bit.
1015 let Inst{19-16} = 0b1101; // Rn = sp
1019 // ADD r, sp, so_reg
1020 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
1021 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
1022 let Inst{31-27} = 0b11101;
1023 let Inst{26-25} = 0b01;
1024 let Inst{24-21} = 0b1000;
1025 let Inst{20} = ?; // The S bit.
1026 let Inst{19-16} = 0b1101; // Rn = sp
1030 // SUB r, sp, {so_imm|i12}
1031 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
1032 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
1033 let Inst{31-27} = 0b11110;
1035 let Inst{24-21} = 0b1101;
1036 let Inst{20} = ?; // The S bit.
1037 let Inst{19-16} = 0b1101; // Rn = sp
1040 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
1041 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
1042 let Inst{31-27} = 0b11110;
1044 let Inst{24-21} = 0b0101;
1045 let Inst{20} = 0; // The S bit.
1046 let Inst{19-16} = 0b1101; // Rn = sp
1050 // SUB r, sp, so_reg
1051 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
1053 "sub", "\t$dst, $sp, $rhs", []> {
1054 let Inst{31-27} = 0b11101;
1055 let Inst{26-25} = 0b01;
1056 let Inst{24-21} = 0b1101;
1057 let Inst{20} = ?; // The S bit.
1058 let Inst{19-16} = 0b1101; // Rn = sp
1062 // Signed and unsigned division on v7-M
1063 def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
1064 "sdiv", "\t$dst, $a, $b",
1065 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>,
1066 Requires<[HasDivide]> {
1067 let Inst{31-27} = 0b11111;
1068 let Inst{26-21} = 0b011100;
1070 let Inst{15-12} = 0b1111;
1071 let Inst{7-4} = 0b1111;
1074 def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
1075 "udiv", "\t$dst, $a, $b",
1076 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>,
1077 Requires<[HasDivide]> {
1078 let Inst{31-27} = 0b11111;
1079 let Inst{26-21} = 0b011101;
1081 let Inst{15-12} = 0b1111;
1082 let Inst{7-4} = 0b1111;
1085 //===----------------------------------------------------------------------===//
1086 // Load / store Instructions.
1090 let canFoldAsLoad = 1, isReMaterializable = 1 in
1091 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1092 UnOpFrag<(load node:$Src)>>;
1094 // Loads with zero extension
1095 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1096 UnOpFrag<(zextloadi16 node:$Src)>>;
1097 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1098 UnOpFrag<(zextloadi8 node:$Src)>>;
1100 // Loads with sign extension
1101 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1102 UnOpFrag<(sextloadi16 node:$Src)>>;
1103 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1104 UnOpFrag<(sextloadi8 node:$Src)>>;
1106 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1107 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
1109 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1110 (ins t2addrmode_imm8s4:$addr),
1111 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
1112 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1113 (ins i32imm:$addr), IIC_iLoad_d_i,
1114 "ldrd", "\t$dst1, $addr", []> {
1115 let Inst{19-16} = 0b1111; // Rn
1117 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1119 // zextload i1 -> zextload i8
1120 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1121 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1122 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1123 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1124 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1125 (t2LDRBs t2addrmode_so_reg:$addr)>;
1126 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1127 (t2LDRBpci tconstpool:$addr)>;
1129 // extload -> zextload
1130 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1132 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1133 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1134 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1135 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1136 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1137 (t2LDRBs t2addrmode_so_reg:$addr)>;
1138 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1139 (t2LDRBpci tconstpool:$addr)>;
1141 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1142 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1143 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1144 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1145 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1146 (t2LDRBs t2addrmode_so_reg:$addr)>;
1147 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1148 (t2LDRBpci tconstpool:$addr)>;
1150 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1151 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1152 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1153 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1154 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1155 (t2LDRHs t2addrmode_so_reg:$addr)>;
1156 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1157 (t2LDRHpci tconstpool:$addr)>;
1159 // FIXME: The destination register of the loads and stores can't be PC, but
1160 // can be SP. We need another regclass (similar to rGPR) to represent
1161 // that. Not a pressing issue since these are selected manually,
1165 let mayLoad = 1, neverHasSideEffects = 1 in {
1166 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1167 (ins t2addrmode_imm8:$addr),
1168 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1169 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
1172 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1173 (ins GPR:$base, t2am_imm8_offset:$offset),
1174 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1175 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
1178 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1179 (ins t2addrmode_imm8:$addr),
1180 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1181 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
1183 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1184 (ins GPR:$base, t2am_imm8_offset:$offset),
1185 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1186 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
1189 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1190 (ins t2addrmode_imm8:$addr),
1191 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1192 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
1194 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1195 (ins GPR:$base, t2am_imm8_offset:$offset),
1196 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1197 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
1200 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1201 (ins t2addrmode_imm8:$addr),
1202 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1203 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
1205 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1206 (ins GPR:$base, t2am_imm8_offset:$offset),
1207 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1208 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1211 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1212 (ins t2addrmode_imm8:$addr),
1213 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1214 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1216 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1217 (ins GPR:$base, t2am_imm8_offset:$offset),
1218 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1219 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1221 } // mayLoad = 1, neverHasSideEffects = 1
1223 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1224 // for disassembly only.
1225 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1226 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1227 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc,
1228 "\t$dst, $addr", []> {
1229 let Inst{31-27} = 0b11111;
1230 let Inst{26-25} = 0b00;
1231 let Inst{24} = signed;
1233 let Inst{22-21} = type;
1234 let Inst{20} = 1; // load
1236 let Inst{10-8} = 0b110; // PUW.
1239 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1240 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1241 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1242 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1243 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1246 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1247 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1248 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1249 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1250 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1251 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1254 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1255 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1256 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1257 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1258 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
1261 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1262 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1263 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1264 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1266 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1268 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1269 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1270 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1271 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1273 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1275 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1276 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1277 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1278 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1280 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1282 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1283 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1284 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1285 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1287 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1289 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1290 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1291 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1292 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1294 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1296 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1297 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1298 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1299 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1301 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1303 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1305 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1306 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1307 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc,
1308 "\t$src, $addr", []> {
1309 let Inst{31-27} = 0b11111;
1310 let Inst{26-25} = 0b00;
1311 let Inst{24} = 0; // not signed
1313 let Inst{22-21} = type;
1314 let Inst{20} = 0; // store
1316 let Inst{10-8} = 0b110; // PUW
1319 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1320 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1321 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1323 // ldrd / strd pre / post variants
1324 // For disassembly only.
1326 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1327 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1328 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1330 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1331 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1332 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1334 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1335 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1336 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1338 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1339 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1340 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
1342 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1343 // data/instruction access. These are for disassembly only.
1344 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1345 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1346 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1348 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1350 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1351 let Inst{31-25} = 0b1111100;
1352 let Inst{24} = instr;
1353 let Inst{23} = 1; // U = 1
1355 let Inst{21} = write;
1357 let Inst{15-12} = 0b1111;
1360 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1362 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1363 let Inst{31-25} = 0b1111100;
1364 let Inst{24} = instr;
1365 let Inst{23} = 0; // U = 0
1367 let Inst{21} = write;
1369 let Inst{15-12} = 0b1111;
1370 let Inst{11-8} = 0b1100;
1373 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1375 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1376 let Inst{31-25} = 0b1111100;
1377 let Inst{24} = instr;
1378 let Inst{23} = 0; // add = TRUE for T1
1380 let Inst{21} = write;
1382 let Inst{15-12} = 0b1111;
1383 let Inst{11-6} = 0000000;
1386 let isCodeGenOnly = 1 in
1387 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc,
1390 let Inst{31-25} = 0b1111100;
1391 let Inst{24} = write;
1392 let Inst{23} = ?; // add = (U == 1)
1394 let Inst{21} = instr;
1396 let Inst{19-16} = 0b1111; // Rn = 0b1111
1397 let Inst{15-12} = 0b1111;
1401 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1402 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1403 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1405 //===----------------------------------------------------------------------===//
1406 // Load / store multiple Instructions.
1409 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1410 InstrItinClass itin_upd, bit L_bit> {
1412 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1413 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
1417 let Inst{31-27} = 0b11101;
1418 let Inst{26-25} = 0b00;
1419 let Inst{24-23} = 0b01; // Increment After
1421 let Inst{21} = 0; // No writeback
1422 let Inst{20} = L_bit;
1423 let Inst{19-16} = Rn;
1424 let Inst{15-0} = regs;
1427 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1428 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1432 let Inst{31-27} = 0b11101;
1433 let Inst{26-25} = 0b00;
1434 let Inst{24-23} = 0b01; // Increment After
1436 let Inst{21} = 1; // Writeback
1437 let Inst{20} = L_bit;
1438 let Inst{19-16} = Rn;
1439 let Inst{15-0} = regs;
1442 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1443 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1447 let Inst{31-27} = 0b11101;
1448 let Inst{26-25} = 0b00;
1449 let Inst{24-23} = 0b10; // Decrement Before
1451 let Inst{21} = 0; // No writeback
1452 let Inst{20} = L_bit;
1453 let Inst{19-16} = Rn;
1454 let Inst{15-0} = regs;
1457 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1458 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1462 let Inst{31-27} = 0b11101;
1463 let Inst{26-25} = 0b00;
1464 let Inst{24-23} = 0b10; // Decrement Before
1466 let Inst{21} = 1; // Writeback
1467 let Inst{20} = L_bit;
1468 let Inst{19-16} = Rn;
1469 let Inst{15-0} = regs;
1474 let neverHasSideEffects = 1 in {
1476 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1477 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1479 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1480 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1482 } // neverHasSideEffects
1485 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1486 isCodeGenOnly = 1 in {
1487 def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1488 reglist:$dsts, variable_ops), IIC_iLoad_m,
1489 "ldm${amode}${p}.w\t$Rn, $dsts", []> {
1490 let Inst{31-27} = 0b11101;
1491 let Inst{26-25} = 0b00;
1492 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1494 let Inst{21} = 0; // The W bit.
1495 let Inst{20} = 1; // Load
1498 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1499 reglist:$dsts, variable_ops),
1501 "ldm${amode}${p}.w\t$Rn!, $dsts",
1503 let Inst{31-27} = 0b11101;
1504 let Inst{26-25} = 0b00;
1505 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1507 let Inst{21} = 1; // The W bit.
1508 let Inst{20} = 1; // Load
1510 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1512 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1513 isCodeGenOnly = 1 in {
1514 def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1515 reglist:$srcs, variable_ops), IIC_iStore_m,
1516 "stm${amode}${p}.w\t$Rn, $srcs", []> {
1517 let Inst{31-27} = 0b11101;
1518 let Inst{26-25} = 0b00;
1519 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1521 let Inst{21} = 0; // The W bit.
1522 let Inst{20} = 0; // Store
1525 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1526 reglist:$srcs, variable_ops),
1528 "stm${amode}${p}.w\t$Rn!, $srcs",
1530 let Inst{31-27} = 0b11101;
1531 let Inst{26-25} = 0b00;
1532 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1534 let Inst{21} = 1; // The W bit.
1535 let Inst{20} = 0; // Store
1537 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1539 //===----------------------------------------------------------------------===//
1540 // Move Instructions.
1543 let neverHasSideEffects = 1 in
1544 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1545 "mov", ".w\t$dst, $src", []> {
1546 let Inst{31-27} = 0b11101;
1547 let Inst{26-25} = 0b01;
1548 let Inst{24-21} = 0b0010;
1549 let Inst{20} = ?; // The S bit.
1550 let Inst{19-16} = 0b1111; // Rn
1551 let Inst{14-12} = 0b000;
1552 let Inst{7-4} = 0b0000;
1555 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1556 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1557 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1558 "mov", ".w\t$dst, $src",
1559 [(set rGPR:$dst, t2_so_imm:$src)]> {
1560 let Inst{31-27} = 0b11110;
1562 let Inst{24-21} = 0b0010;
1563 let Inst{20} = ?; // The S bit.
1564 let Inst{19-16} = 0b1111; // Rn
1568 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1569 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1570 "movw", "\t$dst, $src",
1571 [(set rGPR:$dst, imm0_65535:$src)]> {
1572 let Inst{31-27} = 0b11110;
1574 let Inst{24-21} = 0b0010;
1575 let Inst{20} = 0; // The S bit.
1579 let Constraints = "$src = $dst" in
1580 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1581 "movt", "\t$dst, $imm",
1583 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1584 let Inst{31-27} = 0b11110;
1586 let Inst{24-21} = 0b0110;
1587 let Inst{20} = 0; // The S bit.
1591 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1593 //===----------------------------------------------------------------------===//
1594 // Extend Instructions.
1599 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1600 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1601 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1602 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1603 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1605 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1606 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1607 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1608 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1609 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1611 // TODO: SXT(A){B|H}16 - done for disassembly only
1615 let AddedComplexity = 16 in {
1616 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1617 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1618 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1619 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1620 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1621 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1623 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1624 // The transformation should probably be done as a combiner action
1625 // instead so we can include a check for masking back in the upper
1626 // eight bits of the source into the lower eight bits of the result.
1627 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1628 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1629 // Requires<[HasT2ExtractPack, IsThumb2]>;
1630 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1631 (t2UXTB16r_rot rGPR:$Src, 8)>,
1632 Requires<[HasT2ExtractPack, IsThumb2]>;
1634 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1635 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1636 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1637 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1638 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1641 //===----------------------------------------------------------------------===//
1642 // Arithmetic Instructions.
1645 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1646 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1647 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1648 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1650 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1651 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1652 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1653 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1654 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1655 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1656 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1658 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1659 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1660 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1661 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1662 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1663 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1664 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1665 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1668 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1669 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1670 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1671 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1673 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1674 // The assume-no-carry-in form uses the negation of the input since add/sub
1675 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1676 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1678 // The AddedComplexity preferences the first variant over the others since
1679 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1680 let AddedComplexity = 1 in
1681 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1682 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1683 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1684 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1685 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1686 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1687 let AddedComplexity = 1 in
1688 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1689 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1690 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1691 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1692 // The with-carry-in form matches bitwise not instead of the negation.
1693 // Effectively, the inverse interpretation of the carry flag already accounts
1694 // for part of the negation.
1695 let AddedComplexity = 1 in
1696 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1697 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1698 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1699 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1701 // Select Bytes -- for disassembly only
1703 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1704 "\t$dst, $a, $b", []> {
1705 let Inst{31-27} = 0b11111;
1706 let Inst{26-24} = 0b010;
1708 let Inst{22-20} = 0b010;
1709 let Inst{15-12} = 0b1111;
1711 let Inst{6-4} = 0b000;
1714 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1715 // And Miscellaneous operations -- for disassembly only
1716 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1717 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1718 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1719 "\t$dst, $a, $b", pat> {
1720 let Inst{31-27} = 0b11111;
1721 let Inst{26-23} = 0b0101;
1722 let Inst{22-20} = op22_20;
1723 let Inst{15-12} = 0b1111;
1724 let Inst{7-4} = op7_4;
1727 // Saturating add/subtract -- for disassembly only
1729 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1730 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1731 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1732 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1733 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1734 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1735 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1736 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1737 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1738 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1739 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1740 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1741 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1742 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1743 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1744 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1745 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1746 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1748 // Signed/Unsigned add/subtract -- for disassembly only
1750 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1751 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1752 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1753 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1754 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1755 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1756 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1757 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1758 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1759 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1760 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1761 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1763 // Signed/Unsigned halving add/subtract -- for disassembly only
1765 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1766 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1767 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1768 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1769 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1770 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1771 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1772 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1773 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1774 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1775 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1776 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1778 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1780 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1781 (ins rGPR:$a, rGPR:$b),
1782 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1783 let Inst{15-12} = 0b1111;
1785 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1786 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1787 "\t$dst, $a, $b, $acc", []>;
1789 // Signed/Unsigned saturate -- for disassembly only
1791 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1792 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1793 [/* For disassembly only; pattern left blank */]> {
1794 let Inst{31-27} = 0b11110;
1795 let Inst{25-22} = 0b1100;
1800 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1801 "ssat16", "\t$dst, $bit_pos, $a",
1802 [/* For disassembly only; pattern left blank */]> {
1803 let Inst{31-27} = 0b11110;
1804 let Inst{25-22} = 0b1100;
1807 let Inst{21} = 1; // sh = '1'
1808 let Inst{14-12} = 0b000; // imm3 = '000'
1809 let Inst{7-6} = 0b00; // imm2 = '00'
1812 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1813 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1814 [/* For disassembly only; pattern left blank */]> {
1815 let Inst{31-27} = 0b11110;
1816 let Inst{25-22} = 0b1110;
1821 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1822 "usat16", "\t$dst, $bit_pos, $a",
1823 [/* For disassembly only; pattern left blank */]> {
1824 let Inst{31-27} = 0b11110;
1825 let Inst{25-22} = 0b1110;
1828 let Inst{21} = 1; // sh = '1'
1829 let Inst{14-12} = 0b000; // imm3 = '000'
1830 let Inst{7-6} = 0b00; // imm2 = '00'
1833 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1834 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1836 //===----------------------------------------------------------------------===//
1837 // Shift and rotate Instructions.
1840 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1841 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1842 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1843 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1845 let Uses = [CPSR] in {
1846 def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1847 "rrx", "\t$dst, $src",
1848 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1849 let Inst{31-27} = 0b11101;
1850 let Inst{26-25} = 0b01;
1851 let Inst{24-21} = 0b0010;
1852 let Inst{20} = ?; // The S bit.
1853 let Inst{19-16} = 0b1111; // Rn
1854 let Inst{14-12} = 0b000;
1855 let Inst{7-4} = 0b0011;
1859 let Defs = [CPSR] in {
1860 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1861 "lsrs", ".w\t$dst, $src, #1",
1862 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1863 let Inst{31-27} = 0b11101;
1864 let Inst{26-25} = 0b01;
1865 let Inst{24-21} = 0b0010;
1866 let Inst{20} = 1; // The S bit.
1867 let Inst{19-16} = 0b1111; // Rn
1868 let Inst{5-4} = 0b01; // Shift type.
1869 // Shift amount = Inst{14-12:7-6} = 1.
1870 let Inst{14-12} = 0b000;
1871 let Inst{7-6} = 0b01;
1873 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1874 "asrs", ".w\t$dst, $src, #1",
1875 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1876 let Inst{31-27} = 0b11101;
1877 let Inst{26-25} = 0b01;
1878 let Inst{24-21} = 0b0010;
1879 let Inst{20} = 1; // The S bit.
1880 let Inst{19-16} = 0b1111; // Rn
1881 let Inst{5-4} = 0b10; // Shift type.
1882 // Shift amount = Inst{14-12:7-6} = 1.
1883 let Inst{14-12} = 0b000;
1884 let Inst{7-6} = 0b01;
1888 //===----------------------------------------------------------------------===//
1889 // Bitwise Instructions.
1892 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1893 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1894 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1895 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1896 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1897 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1898 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1899 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1900 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1902 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1903 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1904 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1906 let Constraints = "$src = $dst" in
1907 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1908 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1909 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1910 let Inst{31-27} = 0b11110;
1912 let Inst{24-20} = 0b10110;
1913 let Inst{19-16} = 0b1111; // Rn
1917 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1918 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1919 let Inst{31-27} = 0b11110;
1921 let Inst{24-20} = 0b10100;
1925 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1926 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1927 let Inst{31-27} = 0b11110;
1929 let Inst{24-20} = 0b11100;
1933 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1934 let Constraints = "$src = $dst" in
1935 def t2BFI : T2I<(outs rGPR:$dst),
1936 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1937 IIC_iBITi, "bfi", "\t$dst, $val, $imm",
1938 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1939 bf_inv_mask_imm:$imm))]> {
1940 let Inst{31-27} = 0b11110;
1942 let Inst{24-20} = 0b10110;
1946 defm t2ORN : T2I_bin_irs<0b0011, "orn",
1947 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1948 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
1950 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1951 let AddedComplexity = 1 in
1952 defm t2MVN : T2I_un_irs <0b0011, "mvn",
1953 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
1954 UnOpFrag<(not node:$Src)>, 1, 1>;
1957 let AddedComplexity = 1 in
1958 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1959 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1961 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1962 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1963 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1964 Requires<[IsThumb2]>;
1966 def : T2Pat<(t2_so_imm_not:$src),
1967 (t2MVNi t2_so_imm_not:$src)>;
1969 //===----------------------------------------------------------------------===//
1970 // Multiply Instructions.
1972 let isCommutable = 1 in
1973 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1974 "mul", "\t$dst, $a, $b",
1975 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1976 let Inst{31-27} = 0b11111;
1977 let Inst{26-23} = 0b0110;
1978 let Inst{22-20} = 0b000;
1979 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1980 let Inst{7-4} = 0b0000; // Multiply
1983 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1984 "mla", "\t$dst, $a, $b, $c",
1985 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1986 let Inst{31-27} = 0b11111;
1987 let Inst{26-23} = 0b0110;
1988 let Inst{22-20} = 0b000;
1989 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1990 let Inst{7-4} = 0b0000; // Multiply
1993 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1994 "mls", "\t$dst, $a, $b, $c",
1995 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1996 let Inst{31-27} = 0b11111;
1997 let Inst{26-23} = 0b0110;
1998 let Inst{22-20} = 0b000;
1999 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2000 let Inst{7-4} = 0b0001; // Multiply and Subtract
2003 // Extra precision multiplies with low / high results
2004 let neverHasSideEffects = 1 in {
2005 let isCommutable = 1 in {
2006 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
2007 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
2008 "smull", "\t$ldst, $hdst, $a, $b", []> {
2009 let Inst{31-27} = 0b11111;
2010 let Inst{26-23} = 0b0111;
2011 let Inst{22-20} = 0b000;
2012 let Inst{7-4} = 0b0000;
2015 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
2016 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
2017 "umull", "\t$ldst, $hdst, $a, $b", []> {
2018 let Inst{31-27} = 0b11111;
2019 let Inst{26-23} = 0b0111;
2020 let Inst{22-20} = 0b010;
2021 let Inst{7-4} = 0b0000;
2025 // Multiply + accumulate
2026 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
2027 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
2028 "smlal", "\t$ldst, $hdst, $a, $b", []>{
2029 let Inst{31-27} = 0b11111;
2030 let Inst{26-23} = 0b0111;
2031 let Inst{22-20} = 0b100;
2032 let Inst{7-4} = 0b0000;
2035 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
2036 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
2037 "umlal", "\t$ldst, $hdst, $a, $b", []>{
2038 let Inst{31-27} = 0b11111;
2039 let Inst{26-23} = 0b0111;
2040 let Inst{22-20} = 0b110;
2041 let Inst{7-4} = 0b0000;
2044 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
2045 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
2046 "umaal", "\t$ldst, $hdst, $a, $b", []>{
2047 let Inst{31-27} = 0b11111;
2048 let Inst{26-23} = 0b0111;
2049 let Inst{22-20} = 0b110;
2050 let Inst{7-4} = 0b0110;
2052 } // neverHasSideEffects
2054 // Rounding variants of the below included for disassembly only
2056 // Most significant word multiply
2057 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
2058 "smmul", "\t$dst, $a, $b",
2059 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
2060 let Inst{31-27} = 0b11111;
2061 let Inst{26-23} = 0b0110;
2062 let Inst{22-20} = 0b101;
2063 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2064 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2067 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
2068 "smmulr", "\t$dst, $a, $b", []> {
2069 let Inst{31-27} = 0b11111;
2070 let Inst{26-23} = 0b0110;
2071 let Inst{22-20} = 0b101;
2072 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2073 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2076 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2077 "smmla", "\t$dst, $a, $b, $c",
2078 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
2079 let Inst{31-27} = 0b11111;
2080 let Inst{26-23} = 0b0110;
2081 let Inst{22-20} = 0b101;
2082 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2083 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2086 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2087 "smmlar", "\t$dst, $a, $b, $c", []> {
2088 let Inst{31-27} = 0b11111;
2089 let Inst{26-23} = 0b0110;
2090 let Inst{22-20} = 0b101;
2091 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2092 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2095 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2096 "smmls", "\t$dst, $a, $b, $c",
2097 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
2098 let Inst{31-27} = 0b11111;
2099 let Inst{26-23} = 0b0110;
2100 let Inst{22-20} = 0b110;
2101 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2102 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2105 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2106 "smmlsr", "\t$dst, $a, $b, $c", []> {
2107 let Inst{31-27} = 0b11111;
2108 let Inst{26-23} = 0b0110;
2109 let Inst{22-20} = 0b110;
2110 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2111 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2114 multiclass T2I_smul<string opc, PatFrag opnode> {
2115 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2116 !strconcat(opc, "bb"), "\t$dst, $a, $b",
2117 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
2118 (sext_inreg rGPR:$b, i16)))]> {
2119 let Inst{31-27} = 0b11111;
2120 let Inst{26-23} = 0b0110;
2121 let Inst{22-20} = 0b001;
2122 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2123 let Inst{7-6} = 0b00;
2124 let Inst{5-4} = 0b00;
2127 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2128 !strconcat(opc, "bt"), "\t$dst, $a, $b",
2129 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
2130 (sra rGPR:$b, (i32 16))))]> {
2131 let Inst{31-27} = 0b11111;
2132 let Inst{26-23} = 0b0110;
2133 let Inst{22-20} = 0b001;
2134 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2135 let Inst{7-6} = 0b00;
2136 let Inst{5-4} = 0b01;
2139 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2140 !strconcat(opc, "tb"), "\t$dst, $a, $b",
2141 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
2142 (sext_inreg rGPR:$b, i16)))]> {
2143 let Inst{31-27} = 0b11111;
2144 let Inst{26-23} = 0b0110;
2145 let Inst{22-20} = 0b001;
2146 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2147 let Inst{7-6} = 0b00;
2148 let Inst{5-4} = 0b10;
2151 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2152 !strconcat(opc, "tt"), "\t$dst, $a, $b",
2153 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
2154 (sra rGPR:$b, (i32 16))))]> {
2155 let Inst{31-27} = 0b11111;
2156 let Inst{26-23} = 0b0110;
2157 let Inst{22-20} = 0b001;
2158 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2159 let Inst{7-6} = 0b00;
2160 let Inst{5-4} = 0b11;
2163 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2164 !strconcat(opc, "wb"), "\t$dst, $a, $b",
2165 [(set rGPR:$dst, (sra (opnode rGPR:$a,
2166 (sext_inreg rGPR:$b, i16)), (i32 16)))]> {
2167 let Inst{31-27} = 0b11111;
2168 let Inst{26-23} = 0b0110;
2169 let Inst{22-20} = 0b011;
2170 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2171 let Inst{7-6} = 0b00;
2172 let Inst{5-4} = 0b00;
2175 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2176 !strconcat(opc, "wt"), "\t$dst, $a, $b",
2177 [(set rGPR:$dst, (sra (opnode rGPR:$a,
2178 (sra rGPR:$b, (i32 16))), (i32 16)))]> {
2179 let Inst{31-27} = 0b11111;
2180 let Inst{26-23} = 0b0110;
2181 let Inst{22-20} = 0b011;
2182 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2183 let Inst{7-6} = 0b00;
2184 let Inst{5-4} = 0b01;
2189 multiclass T2I_smla<string opc, PatFrag opnode> {
2190 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2191 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2192 [(set rGPR:$dst, (add rGPR:$acc,
2193 (opnode (sext_inreg rGPR:$a, i16),
2194 (sext_inreg rGPR:$b, i16))))]> {
2195 let Inst{31-27} = 0b11111;
2196 let Inst{26-23} = 0b0110;
2197 let Inst{22-20} = 0b001;
2198 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2199 let Inst{7-6} = 0b00;
2200 let Inst{5-4} = 0b00;
2203 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2204 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2205 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
2206 (sra rGPR:$b, (i32 16)))))]> {
2207 let Inst{31-27} = 0b11111;
2208 let Inst{26-23} = 0b0110;
2209 let Inst{22-20} = 0b001;
2210 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2211 let Inst{7-6} = 0b00;
2212 let Inst{5-4} = 0b01;
2215 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2216 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2217 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2218 (sext_inreg rGPR:$b, i16))))]> {
2219 let Inst{31-27} = 0b11111;
2220 let Inst{26-23} = 0b0110;
2221 let Inst{22-20} = 0b001;
2222 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2223 let Inst{7-6} = 0b00;
2224 let Inst{5-4} = 0b10;
2227 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2228 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2229 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2230 (sra rGPR:$b, (i32 16)))))]> {
2231 let Inst{31-27} = 0b11111;
2232 let Inst{26-23} = 0b0110;
2233 let Inst{22-20} = 0b001;
2234 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2235 let Inst{7-6} = 0b00;
2236 let Inst{5-4} = 0b11;
2239 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2240 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2241 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2242 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2243 let Inst{31-27} = 0b11111;
2244 let Inst{26-23} = 0b0110;
2245 let Inst{22-20} = 0b011;
2246 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2247 let Inst{7-6} = 0b00;
2248 let Inst{5-4} = 0b00;
2251 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2252 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2253 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2254 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2255 let Inst{31-27} = 0b11111;
2256 let Inst{26-23} = 0b0110;
2257 let Inst{22-20} = 0b011;
2258 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2259 let Inst{7-6} = 0b00;
2260 let Inst{5-4} = 0b01;
2264 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2265 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2267 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2268 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2269 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2270 [/* For disassembly only; pattern left blank */]>;
2271 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2272 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2273 [/* For disassembly only; pattern left blank */]>;
2274 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2275 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2276 [/* For disassembly only; pattern left blank */]>;
2277 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2278 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2279 [/* For disassembly only; pattern left blank */]>;
2281 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2282 // These are for disassembly only.
2284 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2285 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2286 let Inst{15-12} = 0b1111;
2288 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2289 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2290 let Inst{15-12} = 0b1111;
2292 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2293 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2294 let Inst{15-12} = 0b1111;
2296 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2297 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2298 let Inst{15-12} = 0b1111;
2300 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2301 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2302 "\t$dst, $a, $b, $acc", []>;
2303 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2304 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2305 "\t$dst, $a, $b, $acc", []>;
2306 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2307 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2308 "\t$dst, $a, $b, $acc", []>;
2309 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2310 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2311 "\t$dst, $a, $b, $acc", []>;
2312 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2313 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2314 "\t$ldst, $hdst, $a, $b", []>;
2315 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2316 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2317 "\t$ldst, $hdst, $a, $b", []>;
2318 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2319 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2320 "\t$ldst, $hdst, $a, $b", []>;
2321 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2322 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2323 "\t$ldst, $hdst, $a, $b", []>;
2325 //===----------------------------------------------------------------------===//
2326 // Misc. Arithmetic Instructions.
2329 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2330 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2331 : T2I<oops, iops, itin, opc, asm, pattern> {
2332 let Inst{31-27} = 0b11111;
2333 let Inst{26-22} = 0b01010;
2334 let Inst{21-20} = op1;
2335 let Inst{15-12} = 0b1111;
2336 let Inst{7-6} = 0b10;
2337 let Inst{5-4} = op2;
2340 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2341 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2343 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2344 "rbit", "\t$dst, $src",
2345 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2347 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2348 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2350 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2351 "rev16", ".w\t$dst, $src",
2353 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2354 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2355 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2356 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2358 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2359 "revsh", ".w\t$dst, $src",
2362 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2363 (shl rGPR:$src, (i32 8))), i16))]>;
2365 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2366 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2367 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2368 (and (shl rGPR:$src2, lsl_amt:$sh),
2370 Requires<[HasT2ExtractPack, IsThumb2]> {
2371 let Inst{31-27} = 0b11101;
2372 let Inst{26-25} = 0b01;
2373 let Inst{24-20} = 0b01100;
2374 let Inst{5} = 0; // BT form
2378 // Alternate cases for PKHBT where identities eliminate some nodes.
2379 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2380 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2381 Requires<[HasT2ExtractPack, IsThumb2]>;
2382 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2383 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2384 Requires<[HasT2ExtractPack, IsThumb2]>;
2386 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2387 // will match the pattern below.
2388 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2389 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2390 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2391 (and (sra rGPR:$src2, asr_amt:$sh),
2393 Requires<[HasT2ExtractPack, IsThumb2]> {
2394 let Inst{31-27} = 0b11101;
2395 let Inst{26-25} = 0b01;
2396 let Inst{24-20} = 0b01100;
2397 let Inst{5} = 1; // TB form
2401 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2402 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2403 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2404 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2405 Requires<[HasT2ExtractPack, IsThumb2]>;
2406 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2407 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2408 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2409 Requires<[HasT2ExtractPack, IsThumb2]>;
2411 //===----------------------------------------------------------------------===//
2412 // Comparison Instructions...
2414 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2415 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2416 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2417 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2418 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2419 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2421 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2422 // Compare-to-zero still works out, just not the relationals
2423 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2424 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2425 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2426 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2427 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2429 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2430 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2432 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2433 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2435 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2436 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2437 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2438 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2439 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2440 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2442 // Conditional moves
2443 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2444 // a two-value operand where a dag node expects two operands. :(
2445 let neverHasSideEffects = 1 in {
2446 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2447 "mov", ".w\t$dst, $true",
2448 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2449 RegConstraint<"$false = $dst"> {
2450 let Inst{31-27} = 0b11101;
2451 let Inst{26-25} = 0b01;
2452 let Inst{24-21} = 0b0010;
2453 let Inst{20} = 0; // The S bit.
2454 let Inst{19-16} = 0b1111; // Rn
2455 let Inst{14-12} = 0b000;
2456 let Inst{7-4} = 0b0000;
2459 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2460 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2461 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2462 RegConstraint<"$false = $dst"> {
2463 let Inst{31-27} = 0b11110;
2465 let Inst{24-21} = 0b0010;
2466 let Inst{20} = 0; // The S bit.
2467 let Inst{19-16} = 0b1111; // Rn
2471 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
2473 "movw", "\t$dst, $src", []>,
2474 RegConstraint<"$false = $dst"> {
2475 let Inst{31-27} = 0b11110;
2477 let Inst{24-21} = 0b0010;
2478 let Inst{20} = 0; // The S bit.
2482 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2483 (ins rGPR:$false, i32imm:$src, pred:$p),
2484 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">;
2486 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2487 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2488 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
2489 imm:$cc, CCR:$ccr))*/]>,
2490 RegConstraint<"$false = $dst"> {
2491 let Inst{31-27} = 0b11110;
2493 let Inst{24-21} = 0b0011;
2494 let Inst{20} = 0; // The S bit.
2495 let Inst{19-16} = 0b1111; // Rn
2499 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2500 string opc, string asm, list<dag> pattern>
2501 : T2I<oops, iops, itin, opc, asm, pattern> {
2502 let Inst{31-27} = 0b11101;
2503 let Inst{26-25} = 0b01;
2504 let Inst{24-21} = 0b0010;
2505 let Inst{20} = 0; // The S bit.
2506 let Inst{19-16} = 0b1111; // Rn
2507 let Inst{5-4} = opcod; // Shift type.
2509 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2510 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2511 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2512 RegConstraint<"$false = $dst">;
2513 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2514 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2515 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2516 RegConstraint<"$false = $dst">;
2517 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2518 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2519 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2520 RegConstraint<"$false = $dst">;
2521 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2522 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2523 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2524 RegConstraint<"$false = $dst">;
2525 } // neverHasSideEffects
2527 //===----------------------------------------------------------------------===//
2528 // Atomic operations intrinsics
2531 // memory barriers protect the atomic sequences
2532 let hasSideEffects = 1 in {
2533 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2534 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2535 Requires<[IsThumb, HasDB]> {
2537 let Inst{31-4} = 0xf3bf8f5;
2538 let Inst{3-0} = opt;
2542 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2544 [/* For disassembly only; pattern left blank */]>,
2545 Requires<[IsThumb, HasDB]> {
2547 let Inst{31-4} = 0xf3bf8f4;
2548 let Inst{3-0} = opt;
2551 // ISB has only full system option -- for disassembly only
2552 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2553 [/* For disassembly only; pattern left blank */]>,
2554 Requires<[IsThumb2, HasV7]> {
2555 let Inst{31-4} = 0xf3bf8f6;
2556 let Inst{3-0} = 0b1111;
2559 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2560 InstrItinClass itin, string opc, string asm, string cstr,
2561 list<dag> pattern, bits<4> rt2 = 0b1111>
2562 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2563 let Inst{31-27} = 0b11101;
2564 let Inst{26-20} = 0b0001101;
2565 let Inst{11-8} = rt2;
2566 let Inst{7-6} = 0b01;
2567 let Inst{5-4} = opcod;
2568 let Inst{3-0} = 0b1111;
2570 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2571 InstrItinClass itin, string opc, string asm, string cstr,
2572 list<dag> pattern, bits<4> rt2 = 0b1111>
2573 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2574 let Inst{31-27} = 0b11101;
2575 let Inst{26-20} = 0b0001100;
2576 let Inst{11-8} = rt2;
2577 let Inst{7-6} = 0b01;
2578 let Inst{5-4} = opcod;
2581 let mayLoad = 1 in {
2582 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2583 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2585 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2586 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2588 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2589 Size4Bytes, NoItinerary,
2590 "ldrex", "\t$dest, [$ptr]", "",
2592 let Inst{31-27} = 0b11101;
2593 let Inst{26-20} = 0b0000101;
2594 let Inst{11-8} = 0b1111;
2595 let Inst{7-0} = 0b00000000; // imm8 = 0
2597 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2598 AddrModeNone, Size4Bytes, NoItinerary,
2599 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2603 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2604 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2605 AddrModeNone, Size4Bytes, NoItinerary,
2606 "strexb", "\t$success, $src, [$ptr]", "", []>;
2607 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2608 AddrModeNone, Size4Bytes, NoItinerary,
2609 "strexh", "\t$success, $src, [$ptr]", "", []>;
2610 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2611 AddrModeNone, Size4Bytes, NoItinerary,
2612 "strex", "\t$success, $src, [$ptr]", "",
2614 let Inst{31-27} = 0b11101;
2615 let Inst{26-20} = 0b0000100;
2616 let Inst{7-0} = 0b00000000; // imm8 = 0
2618 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2619 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2620 AddrModeNone, Size4Bytes, NoItinerary,
2621 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2625 // Clear-Exclusive is for disassembly only.
2626 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2627 [/* For disassembly only; pattern left blank */]>,
2628 Requires<[IsARM, HasV7]> {
2629 let Inst{31-20} = 0xf3b;
2630 let Inst{15-14} = 0b10;
2632 let Inst{7-4} = 0b0010;
2635 //===----------------------------------------------------------------------===//
2639 // __aeabi_read_tp preserves the registers r1-r3.
2641 Defs = [R0, R12, LR, CPSR] in {
2642 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2643 "bl\t__aeabi_read_tp",
2644 [(set R0, ARMthread_pointer)]> {
2645 let Inst{31-27} = 0b11110;
2646 let Inst{15-14} = 0b11;
2651 //===----------------------------------------------------------------------===//
2652 // SJLJ Exception handling intrinsics
2653 // eh_sjlj_setjmp() is an instruction sequence to store the return
2654 // address and save #0 in R0 for the non-longjmp case.
2655 // Since by its nature we may be coming from some other function to get
2656 // here, and we're using the stack frame for the containing function to
2657 // save/restore registers, we can't keep anything live in regs across
2658 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2659 // when we get here from a longjmp(). We force everthing out of registers
2660 // except for our own input by listing the relevant registers in Defs. By
2661 // doing so, we also cause the prologue/epilogue code to actively preserve
2662 // all of the callee-saved resgisters, which is exactly what we want.
2663 // $val is a scratch register for our use.
2665 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2666 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2667 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2668 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2669 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2670 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2671 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2672 Requires<[IsThumb2, HasVFP2]>;
2676 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2677 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2678 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2679 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2680 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2681 Requires<[IsThumb2, NoVFP]>;
2685 //===----------------------------------------------------------------------===//
2686 // Control-Flow Instructions
2689 // FIXME: remove when we have a way to marking a MI with these properties.
2690 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2692 // FIXME: Should pc be an implicit operand like PICADD, etc?
2693 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2694 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2695 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
2696 reglist:$dsts, variable_ops),
2698 "ldm${amode}${p}.w\t$Rn!, $dsts",
2700 let Inst{31-27} = 0b11101;
2701 let Inst{26-25} = 0b00;
2702 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2704 let Inst{21} = 1; // The W bit.
2705 let Inst{20} = 1; // Load
2708 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2709 let isPredicable = 1 in
2710 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2712 [(br bb:$target)]> {
2713 let Inst{31-27} = 0b11110;
2714 let Inst{15-14} = 0b10;
2718 let isNotDuplicable = 1, isIndirectBranch = 1,
2719 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
2722 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2723 IIC_Br, "mov\tpc, $target$jt",
2724 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2725 let Inst{31-27} = 0b11101;
2726 let Inst{26-20} = 0b0100100;
2727 let Inst{19-16} = 0b1111;
2728 let Inst{14-12} = 0b000;
2729 let Inst{11-8} = 0b1111; // Rd = pc
2730 let Inst{7-4} = 0b0000;
2733 // FIXME: Add a non-pc based case that can be predicated.
2734 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2737 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2738 IIC_Br, "tbb\t$index$jt", []> {
2739 let Inst{31-27} = 0b11101;
2740 let Inst{26-20} = 0b0001101;
2741 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2742 let Inst{15-8} = 0b11110000;
2743 let Inst{7-4} = 0b0000; // B form
2746 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2749 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2750 IIC_Br, "tbh\t$index$jt", []> {
2751 let Inst{31-27} = 0b11101;
2752 let Inst{26-20} = 0b0001101;
2753 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2754 let Inst{15-8} = 0b11110000;
2755 let Inst{7-4} = 0b0001; // H form
2758 // Generic versions of the above two instructions, for disassembly only
2760 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2761 "tbb", "\t[$a, $b]", []>{
2762 let Inst{31-27} = 0b11101;
2763 let Inst{26-20} = 0b0001101;
2764 let Inst{15-8} = 0b11110000;
2765 let Inst{7-4} = 0b0000; // B form
2768 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2769 "tbh", "\t[$a, $b, lsl #1]", []> {
2770 let Inst{31-27} = 0b11101;
2771 let Inst{26-20} = 0b0001101;
2772 let Inst{15-8} = 0b11110000;
2773 let Inst{7-4} = 0b0001; // H form
2775 } // isNotDuplicable, isIndirectBranch
2777 } // isBranch, isTerminator, isBarrier
2779 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2780 // a two-value operand where a dag node expects two operands. :(
2781 let isBranch = 1, isTerminator = 1 in
2782 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2784 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2785 let Inst{31-27} = 0b11110;
2786 let Inst{15-14} = 0b10;
2792 let Defs = [ITSTATE] in
2793 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2794 AddrModeNone, Size2Bytes, IIC_iALUx,
2795 "it$mask\t$cc", "", []> {
2796 // 16-bit instruction.
2797 let Inst{31-16} = 0x0000;
2798 let Inst{15-8} = 0b10111111;
2801 // Branch and Exchange Jazelle -- for disassembly only
2803 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2804 [/* For disassembly only; pattern left blank */]> {
2805 let Inst{31-27} = 0b11110;
2807 let Inst{25-20} = 0b111100;
2808 let Inst{15-14} = 0b10;
2812 // Change Processor State is a system instruction -- for disassembly only.
2813 // The singleton $opt operand contains the following information:
2814 // opt{4-0} = mode from Inst{4-0}
2815 // opt{5} = changemode from Inst{17}
2816 // opt{8-6} = AIF from Inst{8-6}
2817 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2818 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2819 [/* For disassembly only; pattern left blank */]> {
2820 let Inst{31-27} = 0b11110;
2822 let Inst{25-20} = 0b111010;
2823 let Inst{15-14} = 0b10;
2827 // A6.3.4 Branches and miscellaneous control
2828 // Table A6-14 Change Processor State, and hint instructions
2829 // Helper class for disassembly only.
2830 class T2I_hint<bits<8> op7_0, string opc, string asm>
2831 : T2I<(outs), (ins), NoItinerary, opc, asm,
2832 [/* For disassembly only; pattern left blank */]> {
2833 let Inst{31-20} = 0xf3a;
2834 let Inst{15-14} = 0b10;
2836 let Inst{10-8} = 0b000;
2837 let Inst{7-0} = op7_0;
2840 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2841 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2842 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2843 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2844 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2846 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2847 [/* For disassembly only; pattern left blank */]> {
2848 let Inst{31-20} = 0xf3a;
2849 let Inst{15-14} = 0b10;
2851 let Inst{10-8} = 0b000;
2852 let Inst{7-4} = 0b1111;
2855 // Secure Monitor Call is a system instruction -- for disassembly only
2856 // Option = Inst{19-16}
2857 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2858 [/* For disassembly only; pattern left blank */]> {
2859 let Inst{31-27} = 0b11110;
2860 let Inst{26-20} = 0b1111111;
2861 let Inst{15-12} = 0b1000;
2864 // Store Return State is a system instruction -- for disassembly only
2865 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2866 [/* For disassembly only; pattern left blank */]> {
2867 let Inst{31-27} = 0b11101;
2868 let Inst{26-20} = 0b0000010; // W = 1
2871 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2872 [/* For disassembly only; pattern left blank */]> {
2873 let Inst{31-27} = 0b11101;
2874 let Inst{26-20} = 0b0000000; // W = 0
2877 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2878 [/* For disassembly only; pattern left blank */]> {
2879 let Inst{31-27} = 0b11101;
2880 let Inst{26-20} = 0b0011010; // W = 1
2883 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2884 [/* For disassembly only; pattern left blank */]> {
2885 let Inst{31-27} = 0b11101;
2886 let Inst{26-20} = 0b0011000; // W = 0
2889 // Return From Exception is a system instruction -- for disassembly only
2890 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2891 [/* For disassembly only; pattern left blank */]> {
2892 let Inst{31-27} = 0b11101;
2893 let Inst{26-20} = 0b0000011; // W = 1
2896 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2897 [/* For disassembly only; pattern left blank */]> {
2898 let Inst{31-27} = 0b11101;
2899 let Inst{26-20} = 0b0000001; // W = 0
2902 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2903 [/* For disassembly only; pattern left blank */]> {
2904 let Inst{31-27} = 0b11101;
2905 let Inst{26-20} = 0b0011011; // W = 1
2908 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2909 [/* For disassembly only; pattern left blank */]> {
2910 let Inst{31-27} = 0b11101;
2911 let Inst{26-20} = 0b0011001; // W = 0
2914 //===----------------------------------------------------------------------===//
2915 // Non-Instruction Patterns
2918 // Two piece so_imms.
2919 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2920 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2921 (t2_so_imm2part_2 imm:$RHS))>;
2922 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2923 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2924 (t2_so_imm2part_2 imm:$RHS))>;
2925 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2926 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2927 (t2_so_imm2part_2 imm:$RHS))>;
2928 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2929 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2930 (t2_so_neg_imm2part_2 imm:$RHS))>;
2932 // 32-bit immediate using movw + movt.
2933 // This is a single pseudo instruction to make it re-materializable.
2934 // FIXME: Remove this when we can do generalized remat.
2935 let isReMaterializable = 1 in
2936 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
2937 "", [(set rGPR:$dst, (i32 imm:$src))]>,
2938 Requires<[IsThumb, HasV6T2]>;
2940 // ConstantPool, GlobalAddress, and JumpTable
2941 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2942 Requires<[IsThumb2, DontUseMovt]>;
2943 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2944 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2945 Requires<[IsThumb2, UseMovt]>;
2947 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2948 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2950 // Pseudo instruction that combines ldr from constpool and add pc. This should
2951 // be expanded into two instructions late to allow if-conversion and
2953 let canFoldAsLoad = 1, isReMaterializable = 1 in
2954 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2956 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2958 Requires<[IsThumb2]>;
2960 //===----------------------------------------------------------------------===//
2961 // Move between special register and ARM core register -- for disassembly only
2965 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2966 [/* For disassembly only; pattern left blank */]> {
2967 let Inst{31-27} = 0b11110;
2969 let Inst{25-21} = 0b11111;
2970 let Inst{20} = 0; // The R bit.
2971 let Inst{15-14} = 0b10;
2976 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2977 [/* For disassembly only; pattern left blank */]> {
2978 let Inst{31-27} = 0b11110;
2980 let Inst{25-21} = 0b11111;
2981 let Inst{20} = 1; // The R bit.
2982 let Inst{15-14} = 0b10;
2987 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2988 "\tcpsr$mask, $src",
2989 [/* For disassembly only; pattern left blank */]> {
2990 let Inst{31-27} = 0b11110;
2992 let Inst{25-21} = 0b11100;
2993 let Inst{20} = 0; // The R bit.
2994 let Inst{15-14} = 0b10;
2999 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
3000 "\tspsr$mask, $src",
3001 [/* For disassembly only; pattern left blank */]> {
3002 let Inst{31-27} = 0b11110;
3004 let Inst{25-21} = 0b11100;
3005 let Inst{20} = 1; // The R bit.
3006 let Inst{15-14} = 0b10;