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 // Shifted operands. No register controlled shifts for Thumb2.
25 // Note: We do not support rrx shifted operands yet.
26 def t2_so_reg : Operand<i32>, // reg imm
27 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
29 let EncoderMethod = "getT2SORegOpValue";
30 let PrintMethod = "printT2SOOperand";
31 let MIOperandInfo = (ops rGPR, i32imm);
34 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
35 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
36 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
39 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
40 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
41 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
44 // t2_so_imm - Match a 32-bit immediate operand, which is an
45 // 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
46 // immediate splatted into multiple bytes of the word.
47 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
48 let EncoderMethod = "getT2SOImmOpValue";
51 // t2_so_imm_not - Match an immediate that is a complement
53 def t2_so_imm_not : Operand<i32>,
55 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
56 }], t2_so_imm_not_XFORM>;
58 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
59 def t2_so_imm_neg : Operand<i32>,
61 return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
62 }], t2_so_imm_neg_XFORM>;
64 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
65 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
66 // to get the first/second pieces.
67 def t2_so_imm2part : Operand<i32>,
69 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
73 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
74 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
75 return CurDAG->getTargetConstant(V, MVT::i32);
78 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
79 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
80 return CurDAG->getTargetConstant(V, MVT::i32);
83 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
84 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
88 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
89 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
90 return CurDAG->getTargetConstant(V, MVT::i32);
93 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
94 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
95 return CurDAG->getTargetConstant(V, MVT::i32);
98 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
99 def imm1_31 : PatLeaf<(i32 imm), [{
100 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
103 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
104 def imm0_4095 : Operand<i32>,
105 PatLeaf<(i32 imm), [{
106 return (uint32_t)N->getZExtValue() < 4096;
109 def imm0_4095_neg : PatLeaf<(i32 imm), [{
110 return (uint32_t)(-N->getZExtValue()) < 4096;
113 def imm0_255_neg : PatLeaf<(i32 imm), [{
114 return (uint32_t)(-N->getZExtValue()) < 255;
117 def imm0_255_not : PatLeaf<(i32 imm), [{
118 return (uint32_t)(~N->getZExtValue()) < 255;
121 // Define Thumb2 specific addressing modes.
123 // t2addrmode_imm12 := reg + imm12
124 def t2addrmode_imm12 : Operand<i32>,
125 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
126 let PrintMethod = "printAddrModeImm12Operand";
127 let EncoderMethod = "getAddrModeImm12OpValue";
128 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
129 let ParserMatchClass = MemMode5AsmOperand;
132 // ADR instruction labels.
133 def t2adrlabel : Operand<i32> {
134 let EncoderMethod = "getT2AdrLabelOpValue";
138 // t2addrmode_imm8 := reg +/- imm8
139 def t2addrmode_imm8 : Operand<i32>,
140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
141 let PrintMethod = "printT2AddrModeImm8Operand";
142 let EncoderMethod = "getT2AddrModeImm8OpValue";
143 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
144 let ParserMatchClass = MemMode5AsmOperand;
147 def t2am_imm8_offset : Operand<i32>,
148 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
149 [], [SDNPWantRoot]> {
150 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
151 let EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
152 let ParserMatchClass = MemMode5AsmOperand;
155 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
156 def t2addrmode_imm8s4 : Operand<i32> {
157 let PrintMethod = "printT2AddrModeImm8s4Operand";
158 let EncoderMethod = "getT2AddrModeImm8s4OpValue";
159 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
160 let ParserMatchClass = MemMode5AsmOperand;
163 def t2am_imm8s4_offset : Operand<i32> {
164 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
167 // t2addrmode_so_reg := reg + (reg << imm2)
168 def t2addrmode_so_reg : Operand<i32>,
169 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
170 let PrintMethod = "printT2AddrModeSoRegOperand";
171 let EncoderMethod = "getT2AddrModeSORegOpValue";
172 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
173 let ParserMatchClass = MemMode5AsmOperand;
177 //===----------------------------------------------------------------------===//
178 // Multiclass helpers...
182 class T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
183 string opc, string asm, list<dag> pattern>
184 : T2I<oops, iops, itin, opc, asm, pattern> {
189 let Inst{26} = imm{11};
190 let Inst{14-12} = imm{10-8};
191 let Inst{7-0} = imm{7-0};
195 class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
196 string opc, string asm, list<dag> pattern>
197 : T2sI<oops, iops, itin, opc, asm, pattern> {
203 let Inst{26} = imm{11};
204 let Inst{14-12} = imm{10-8};
205 let Inst{7-0} = imm{7-0};
208 class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin,
209 string opc, string asm, list<dag> pattern>
210 : T2I<oops, iops, itin, opc, asm, pattern> {
214 let Inst{19-16} = Rn;
215 let Inst{26} = imm{11};
216 let Inst{14-12} = imm{10-8};
217 let Inst{7-0} = imm{7-0};
221 class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
222 string opc, string asm, list<dag> pattern>
223 : T2I<oops, iops, itin, opc, asm, pattern> {
228 let Inst{3-0} = ShiftedRm{3-0};
229 let Inst{5-4} = ShiftedRm{6-5};
230 let Inst{14-12} = ShiftedRm{11-9};
231 let Inst{7-6} = ShiftedRm{8-7};
234 class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
235 string opc, string asm, list<dag> pattern>
236 : T2sI<oops, iops, itin, opc, asm, pattern> {
241 let Inst{3-0} = ShiftedRm{3-0};
242 let Inst{5-4} = ShiftedRm{6-5};
243 let Inst{14-12} = ShiftedRm{11-9};
244 let Inst{7-6} = ShiftedRm{8-7};
247 class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin,
248 string opc, string asm, list<dag> pattern>
249 : T2I<oops, iops, itin, opc, asm, pattern> {
253 let Inst{19-16} = Rn;
254 let Inst{3-0} = ShiftedRm{3-0};
255 let Inst{5-4} = ShiftedRm{6-5};
256 let Inst{14-12} = ShiftedRm{11-9};
257 let Inst{7-6} = ShiftedRm{8-7};
260 class T2TwoReg<dag oops, dag iops, InstrItinClass itin,
261 string opc, string asm, list<dag> pattern>
262 : T2I<oops, iops, itin, opc, asm, pattern> {
270 class T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
271 string opc, string asm, list<dag> pattern>
272 : T2sI<oops, iops, itin, opc, asm, pattern> {
280 class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin,
281 string opc, string asm, list<dag> pattern>
282 : T2I<oops, iops, itin, opc, asm, pattern> {
286 let Inst{19-16} = Rn;
291 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
292 string opc, string asm, list<dag> pattern>
293 : T2I<oops, iops, itin, opc, asm, pattern> {
299 let Inst{19-16} = Rn;
300 let Inst{26} = imm{11};
301 let Inst{14-12} = imm{10-8};
302 let Inst{7-0} = imm{7-0};
305 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
306 string opc, string asm, list<dag> pattern>
307 : T2sI<oops, iops, itin, opc, asm, pattern> {
313 let Inst{19-16} = Rn;
314 let Inst{26} = imm{11};
315 let Inst{14-12} = imm{10-8};
316 let Inst{7-0} = imm{7-0};
319 class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
320 string opc, string asm, list<dag> pattern>
321 : T2I<oops, iops, itin, opc, asm, pattern> {
328 let Inst{14-12} = imm{4-2};
329 let Inst{7-6} = imm{1-0};
332 class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
333 string opc, string asm, list<dag> pattern>
334 : T2sI<oops, iops, itin, opc, asm, pattern> {
341 let Inst{14-12} = imm{4-2};
342 let Inst{7-6} = imm{1-0};
345 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
346 string opc, string asm, list<dag> pattern>
347 : T2I<oops, iops, itin, opc, asm, pattern> {
353 let Inst{19-16} = Rn;
357 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
358 string opc, string asm, list<dag> pattern>
359 : T2sI<oops, iops, itin, opc, asm, pattern> {
365 let Inst{19-16} = Rn;
369 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
370 string opc, string asm, list<dag> pattern>
371 : T2I<oops, iops, itin, opc, asm, pattern> {
377 let Inst{19-16} = Rn;
378 let Inst{3-0} = ShiftedRm{3-0};
379 let Inst{5-4} = ShiftedRm{6-5};
380 let Inst{14-12} = ShiftedRm{11-9};
381 let Inst{7-6} = ShiftedRm{8-7};
384 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
385 string opc, string asm, list<dag> pattern>
386 : T2sI<oops, iops, itin, opc, asm, pattern> {
392 let Inst{19-16} = Rn;
393 let Inst{3-0} = ShiftedRm{3-0};
394 let Inst{5-4} = ShiftedRm{6-5};
395 let Inst{14-12} = ShiftedRm{11-9};
396 let Inst{7-6} = ShiftedRm{8-7};
399 class T2FourReg<dag oops, dag iops, InstrItinClass itin,
400 string opc, string asm, list<dag> pattern>
401 : T2I<oops, iops, itin, opc, asm, pattern> {
407 let Inst{19-16} = Rn;
408 let Inst{15-12} = Ra;
413 class T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
414 dag oops, dag iops, InstrItinClass itin,
415 string opc, string asm, list<dag> pattern>
416 : T2I<oops, iops, itin, opc, asm, pattern> {
422 let Inst{31-23} = 0b111110111;
423 let Inst{22-20} = opc22_20;
424 let Inst{19-16} = Rn;
425 let Inst{15-12} = RdLo;
426 let Inst{11-8} = RdHi;
427 let Inst{7-4} = opc7_4;
432 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
433 /// unary operation that produces a value. These are predicable and can be
434 /// changed to modify CPSR.
435 multiclass T2I_un_irs<bits<4> opcod, string opc,
436 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
437 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
439 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
441 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> {
442 let isAsCheapAsAMove = Cheap;
443 let isReMaterializable = ReMat;
444 let Inst{31-27} = 0b11110;
446 let Inst{24-21} = opcod;
447 let Inst{19-16} = 0b1111; // Rn
451 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
453 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
454 let Inst{31-27} = 0b11101;
455 let Inst{26-25} = 0b01;
456 let Inst{24-21} = opcod;
457 let Inst{19-16} = 0b1111; // Rn
458 let Inst{14-12} = 0b000; // imm3
459 let Inst{7-6} = 0b00; // imm2
460 let Inst{5-4} = 0b00; // type
463 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
464 opc, ".w\t$Rd, $ShiftedRm",
465 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> {
466 let Inst{31-27} = 0b11101;
467 let Inst{26-25} = 0b01;
468 let Inst{24-21} = opcod;
469 let Inst{19-16} = 0b1111; // Rn
473 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
474 /// binary operation that produces a value. These are predicable and can be
475 /// changed to modify CPSR.
476 multiclass T2I_bin_irs<bits<4> opcod, string opc,
477 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
478 PatFrag opnode, bit Commutable = 0, string wide = ""> {
480 def ri : T2sTwoRegImm<
481 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
482 opc, "\t$Rd, $Rn, $imm",
483 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
484 let Inst{31-27} = 0b11110;
486 let Inst{24-21} = opcod;
490 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
491 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
492 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
493 let isCommutable = Commutable;
494 let Inst{31-27} = 0b11101;
495 let Inst{26-25} = 0b01;
496 let Inst{24-21} = opcod;
497 let Inst{14-12} = 0b000; // imm3
498 let Inst{7-6} = 0b00; // imm2
499 let Inst{5-4} = 0b00; // type
502 def rs : T2sTwoRegShiftedReg<
503 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
504 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
505 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
506 let Inst{31-27} = 0b11101;
507 let Inst{26-25} = 0b01;
508 let Inst{24-21} = opcod;
512 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
513 // the ".w" prefix to indicate that they are wide.
514 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
515 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
516 PatFrag opnode, bit Commutable = 0> :
517 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
519 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
520 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
521 /// it is equivalent to the T2I_bin_irs counterpart.
522 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
524 def ri : T2sTwoRegImm<
525 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
526 opc, ".w\t$Rd, $Rn, $imm",
527 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
528 let Inst{31-27} = 0b11110;
530 let Inst{24-21} = opcod;
534 def rr : T2sThreeReg<
535 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
536 opc, "\t$Rd, $Rn, $Rm",
537 [/* For disassembly only; pattern left blank */]> {
538 let Inst{31-27} = 0b11101;
539 let Inst{26-25} = 0b01;
540 let Inst{24-21} = opcod;
541 let Inst{14-12} = 0b000; // imm3
542 let Inst{7-6} = 0b00; // imm2
543 let Inst{5-4} = 0b00; // type
546 def rs : T2sTwoRegShiftedReg<
547 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
548 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
549 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
550 let Inst{31-27} = 0b11101;
551 let Inst{26-25} = 0b01;
552 let Inst{24-21} = opcod;
556 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
557 /// instruction modifies the CPSR register.
558 let isCodeGenOnly = 1, Defs = [CPSR] in {
559 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
560 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
561 PatFrag opnode, bit Commutable = 0> {
563 def ri : T2TwoRegImm<
564 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
565 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
566 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
567 let Inst{31-27} = 0b11110;
569 let Inst{24-21} = opcod;
570 let Inst{20} = 1; // The S bit.
575 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
576 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
577 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
578 let isCommutable = Commutable;
579 let Inst{31-27} = 0b11101;
580 let Inst{26-25} = 0b01;
581 let Inst{24-21} = opcod;
582 let Inst{20} = 1; // The S bit.
583 let Inst{14-12} = 0b000; // imm3
584 let Inst{7-6} = 0b00; // imm2
585 let Inst{5-4} = 0b00; // type
588 def rs : T2TwoRegShiftedReg<
589 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
590 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
591 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
592 let Inst{31-27} = 0b11101;
593 let Inst{26-25} = 0b01;
594 let Inst{24-21} = opcod;
595 let Inst{20} = 1; // The S bit.
600 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
601 /// patterns for a binary operation that produces a value.
602 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
603 bit Commutable = 0> {
605 // The register-immediate version is re-materializable. This is useful
606 // in particular for taking the address of a local.
607 let isReMaterializable = 1 in {
608 def ri : T2sTwoRegImm<
609 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
610 opc, ".w\t$Rd, $Rn, $imm",
611 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
612 let Inst{31-27} = 0b11110;
615 let Inst{23-21} = op23_21;
621 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
622 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
623 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
627 let Inst{31-27} = 0b11110;
628 let Inst{26} = imm{11};
629 let Inst{25-24} = 0b10;
630 let Inst{23-21} = op23_21;
631 let Inst{20} = 0; // The S bit.
632 let Inst{19-16} = Rn;
634 let Inst{14-12} = imm{10-8};
636 let Inst{7-0} = imm{7-0};
639 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
640 opc, ".w\t$Rd, $Rn, $Rm",
641 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
642 let isCommutable = Commutable;
643 let Inst{31-27} = 0b11101;
644 let Inst{26-25} = 0b01;
646 let Inst{23-21} = op23_21;
647 let Inst{14-12} = 0b000; // imm3
648 let Inst{7-6} = 0b00; // imm2
649 let Inst{5-4} = 0b00; // type
652 def rs : T2sTwoRegShiftedReg<
653 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
654 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
655 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
656 let Inst{31-27} = 0b11101;
657 let Inst{26-25} = 0b01;
659 let Inst{23-21} = op23_21;
663 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
664 /// for a binary operation that produces a value and use the carry
665 /// bit. It's not predicable.
666 let Uses = [CPSR] in {
667 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
668 bit Commutable = 0> {
670 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
671 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
672 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
673 Requires<[IsThumb2]> {
674 let Inst{31-27} = 0b11110;
676 let Inst{24-21} = opcod;
680 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
681 opc, ".w\t$Rd, $Rn, $Rm",
682 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
683 Requires<[IsThumb2]> {
684 let isCommutable = Commutable;
685 let Inst{31-27} = 0b11101;
686 let Inst{26-25} = 0b01;
687 let Inst{24-21} = opcod;
688 let Inst{14-12} = 0b000; // imm3
689 let Inst{7-6} = 0b00; // imm2
690 let Inst{5-4} = 0b00; // type
693 def rs : T2sTwoRegShiftedReg<
694 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
695 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
696 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
697 Requires<[IsThumb2]> {
698 let Inst{31-27} = 0b11101;
699 let Inst{26-25} = 0b01;
700 let Inst{24-21} = opcod;
704 // Carry setting variants
705 let isCodeGenOnly = 1, Defs = [CPSR] in {
706 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
707 bit Commutable = 0> {
709 def ri : T2sTwoRegImm<
710 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
711 opc, "\t$Rd, $Rn, $imm",
712 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
713 Requires<[IsThumb2]> {
714 let Inst{31-27} = 0b11110;
716 let Inst{24-21} = opcod;
717 let Inst{20} = 1; // The S bit.
721 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
722 opc, ".w\t$Rd, $Rn, $Rm",
723 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
724 Requires<[IsThumb2]> {
725 let isCommutable = Commutable;
726 let Inst{31-27} = 0b11101;
727 let Inst{26-25} = 0b01;
728 let Inst{24-21} = opcod;
729 let Inst{20} = 1; // The S bit.
730 let Inst{14-12} = 0b000; // imm3
731 let Inst{7-6} = 0b00; // imm2
732 let Inst{5-4} = 0b00; // type
735 def rs : T2sTwoRegShiftedReg<
736 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
737 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
738 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
739 Requires<[IsThumb2]> {
740 let Inst{31-27} = 0b11101;
741 let Inst{26-25} = 0b01;
742 let Inst{24-21} = opcod;
743 let Inst{20} = 1; // The S bit.
749 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
750 /// version is not needed since this is only for codegen.
751 let isCodeGenOnly = 1, Defs = [CPSR] in {
752 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
754 def ri : T2TwoRegImm<
755 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
756 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
757 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
758 let Inst{31-27} = 0b11110;
760 let Inst{24-21} = opcod;
761 let Inst{20} = 1; // The S bit.
765 def rs : T2TwoRegShiftedReg<
766 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
767 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
768 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
769 let Inst{31-27} = 0b11101;
770 let Inst{26-25} = 0b01;
771 let Inst{24-21} = opcod;
772 let Inst{20} = 1; // The S bit.
777 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
778 // rotate operation that produces a value.
779 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
781 def ri : T2sTwoRegShiftImm<
782 (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi,
783 opc, ".w\t$Rd, $Rm, $imm",
784 [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> {
785 let Inst{31-27} = 0b11101;
786 let Inst{26-21} = 0b010010;
787 let Inst{19-16} = 0b1111; // Rn
788 let Inst{5-4} = opcod;
791 def rr : T2sThreeReg<
792 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr,
793 opc, ".w\t$Rd, $Rn, $Rm",
794 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
795 let Inst{31-27} = 0b11111;
796 let Inst{26-23} = 0b0100;
797 let Inst{22-21} = opcod;
798 let Inst{15-12} = 0b1111;
799 let Inst{7-4} = 0b0000;
803 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
804 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
805 /// a explicit result, only implicitly set CPSR.
806 let isCompare = 1, Defs = [CPSR] in {
807 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
808 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
811 def ri : T2OneRegCmpImm<
812 (outs), (ins GPR:$Rn, t2_so_imm:$imm), iii,
813 opc, ".w\t$Rn, $imm",
814 [(opnode GPR:$Rn, t2_so_imm:$imm)]> {
815 let Inst{31-27} = 0b11110;
817 let Inst{24-21} = opcod;
818 let Inst{20} = 1; // The S bit.
820 let Inst{11-8} = 0b1111; // Rd
823 def rr : T2TwoRegCmp<
824 (outs), (ins GPR:$lhs, rGPR:$rhs), iir,
825 opc, ".w\t$lhs, $rhs",
826 [(opnode GPR:$lhs, rGPR:$rhs)]> {
827 let Inst{31-27} = 0b11101;
828 let Inst{26-25} = 0b01;
829 let Inst{24-21} = opcod;
830 let Inst{20} = 1; // The S bit.
831 let Inst{14-12} = 0b000; // imm3
832 let Inst{11-8} = 0b1111; // Rd
833 let Inst{7-6} = 0b00; // imm2
834 let Inst{5-4} = 0b00; // type
837 def rs : T2OneRegCmpShiftedReg<
838 (outs), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
839 opc, ".w\t$Rn, $ShiftedRm",
840 [(opnode GPR:$Rn, t2_so_reg:$ShiftedRm)]> {
841 let Inst{31-27} = 0b11101;
842 let Inst{26-25} = 0b01;
843 let Inst{24-21} = opcod;
844 let Inst{20} = 1; // The S bit.
845 let Inst{11-8} = 0b1111; // Rd
850 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
851 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
852 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
853 def i12 : T2Ii12<(outs GPR:$Rt), (ins t2addrmode_imm12:$addr), iii,
854 opc, ".w\t$Rt, $addr",
855 [(set GPR:$Rt, (opnode t2addrmode_imm12:$addr))]> {
856 let Inst{31-27} = 0b11111;
857 let Inst{26-25} = 0b00;
858 let Inst{24} = signed;
860 let Inst{22-21} = opcod;
861 let Inst{20} = 1; // load
864 let Inst{15-12} = Rt;
867 let Inst{19-16} = addr{16-13}; // Rn
868 let Inst{23} = addr{12}; // U
869 let Inst{11-0} = addr{11-0}; // imm
871 def i8 : T2Ii8 <(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), iii,
873 [(set GPR:$Rt, (opnode t2addrmode_imm8:$addr))]> {
874 let Inst{31-27} = 0b11111;
875 let Inst{26-25} = 0b00;
876 let Inst{24} = signed;
878 let Inst{22-21} = opcod;
879 let Inst{20} = 1; // load
881 // Offset: index==TRUE, wback==FALSE
882 let Inst{10} = 1; // The P bit.
883 let Inst{8} = 0; // The W bit.
886 let Inst{15-12} = Rt;
889 let Inst{19-16} = addr{12-9}; // Rn
890 let Inst{9} = addr{8}; // U
891 let Inst{7-0} = addr{7-0}; // imm
893 def s : T2Iso <(outs GPR:$Rt), (ins t2addrmode_so_reg:$addr), iis,
894 opc, ".w\t$Rt, $addr",
895 [(set GPR:$Rt, (opnode t2addrmode_so_reg:$addr))]> {
896 let Inst{31-27} = 0b11111;
897 let Inst{26-25} = 0b00;
898 let Inst{24} = signed;
900 let Inst{22-21} = opcod;
901 let Inst{20} = 1; // load
902 let Inst{11-6} = 0b000000;
905 let Inst{15-12} = Rt;
908 let Inst{19-16} = addr{9-6}; // Rn
909 let Inst{3-0} = addr{5-2}; // Rm
910 let Inst{5-4} = addr{1-0}; // imm
913 // FIXME: Is the pci variant actually needed?
914 def pci : T2Ipc <(outs GPR:$Rt), (ins i32imm:$addr), iii,
915 opc, ".w\t$Rt, $addr",
916 [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
917 let isReMaterializable = 1;
918 let Inst{31-27} = 0b11111;
919 let Inst{26-25} = 0b00;
920 let Inst{24} = signed;
921 let Inst{23} = ?; // add = (U == '1')
922 let Inst{22-21} = opcod;
923 let Inst{20} = 1; // load
924 let Inst{19-16} = 0b1111; // Rn
927 let Inst{15-12} = Rt{3-0};
928 let Inst{11-0} = addr{11-0};
932 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
933 multiclass T2I_st<bits<2> opcod, string opc,
934 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
935 def i12 : T2Ii12<(outs), (ins GPR:$Rt, t2addrmode_imm12:$addr), iii,
936 opc, ".w\t$Rt, $addr",
937 [(opnode GPR:$Rt, t2addrmode_imm12:$addr)]> {
938 let Inst{31-27} = 0b11111;
939 let Inst{26-23} = 0b0001;
940 let Inst{22-21} = opcod;
941 let Inst{20} = 0; // !load
944 let Inst{15-12} = Rt;
947 let Inst{19-16} = addr{16-13}; // Rn
948 let Inst{23} = addr{12}; // U
949 let Inst{11-0} = addr{11-0}; // imm
951 def i8 : T2Ii8 <(outs), (ins GPR:$Rt, t2addrmode_imm8:$addr), iii,
953 [(opnode GPR:$Rt, t2addrmode_imm8:$addr)]> {
954 let Inst{31-27} = 0b11111;
955 let Inst{26-23} = 0b0000;
956 let Inst{22-21} = opcod;
957 let Inst{20} = 0; // !load
959 // Offset: index==TRUE, wback==FALSE
960 let Inst{10} = 1; // The P bit.
961 let Inst{8} = 0; // The W bit.
964 let Inst{15-12} = Rt;
967 let Inst{19-16} = addr{12-9}; // Rn
968 let Inst{9} = addr{8}; // U
969 let Inst{7-0} = addr{7-0}; // imm
971 def s : T2Iso <(outs), (ins GPR:$Rt, t2addrmode_so_reg:$addr), iis,
972 opc, ".w\t$Rt, $addr",
973 [(opnode GPR:$Rt, t2addrmode_so_reg:$addr)]> {
974 let Inst{31-27} = 0b11111;
975 let Inst{26-23} = 0b0000;
976 let Inst{22-21} = opcod;
977 let Inst{20} = 0; // !load
978 let Inst{11-6} = 0b000000;
981 let Inst{15-12} = Rt;
984 let Inst{19-16} = addr{9-6}; // Rn
985 let Inst{3-0} = addr{5-2}; // Rm
986 let Inst{5-4} = addr{1-0}; // imm
990 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
991 /// register and one whose operand is a register rotated by 8/16/24.
992 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
993 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
995 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
996 let Inst{31-27} = 0b11111;
997 let Inst{26-23} = 0b0100;
998 let Inst{22-20} = opcod;
999 let Inst{19-16} = 0b1111; // Rn
1000 let Inst{15-12} = 0b1111;
1002 let Inst{5-4} = 0b00; // rotate
1004 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
1005 opc, ".w\t$Rd, $Rm, ror $rot",
1006 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> {
1007 let Inst{31-27} = 0b11111;
1008 let Inst{26-23} = 0b0100;
1009 let Inst{22-20} = opcod;
1010 let Inst{19-16} = 0b1111; // Rn
1011 let Inst{15-12} = 0b1111;
1015 let Inst{5-4} = rot{1-0}; // rotate
1019 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
1020 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
1021 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
1023 [(set rGPR:$Rd, (opnode rGPR:$Rm))]>,
1024 Requires<[HasT2ExtractPack, IsThumb2]> {
1025 let Inst{31-27} = 0b11111;
1026 let Inst{26-23} = 0b0100;
1027 let Inst{22-20} = opcod;
1028 let Inst{19-16} = 0b1111; // Rn
1029 let Inst{15-12} = 0b1111;
1031 let Inst{5-4} = 0b00; // rotate
1033 def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot),
1034 IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot",
1035 [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1036 Requires<[HasT2ExtractPack, IsThumb2]> {
1037 let Inst{31-27} = 0b11111;
1038 let Inst{26-23} = 0b0100;
1039 let Inst{22-20} = opcod;
1040 let Inst{19-16} = 0b1111; // Rn
1041 let Inst{15-12} = 0b1111;
1045 let Inst{5-4} = rot{1-0}; // rotate
1049 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
1051 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
1052 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
1053 opc, "\t$Rd, $Rm", []> {
1054 let Inst{31-27} = 0b11111;
1055 let Inst{26-23} = 0b0100;
1056 let Inst{22-20} = opcod;
1057 let Inst{19-16} = 0b1111; // Rn
1058 let Inst{15-12} = 0b1111;
1060 let Inst{5-4} = 0b00; // rotate
1062 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
1063 opc, "\t$Rd, $Rm, ror $rot", []> {
1064 let Inst{31-27} = 0b11111;
1065 let Inst{26-23} = 0b0100;
1066 let Inst{22-20} = opcod;
1067 let Inst{19-16} = 0b1111; // Rn
1068 let Inst{15-12} = 0b1111;
1072 let Inst{5-4} = rot{1-0}; // rotate
1076 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
1077 /// register and one whose operand is a register rotated by 8/16/24.
1078 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
1079 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1080 opc, "\t$Rd, $Rn, $Rm",
1081 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
1082 Requires<[HasT2ExtractPack, IsThumb2]> {
1083 let Inst{31-27} = 0b11111;
1084 let Inst{26-23} = 0b0100;
1085 let Inst{22-20} = opcod;
1086 let Inst{15-12} = 0b1111;
1088 let Inst{5-4} = 0b00; // rotate
1090 def rr_rot : T2ThreeReg<(outs rGPR:$Rd),
1091 (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
1092 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
1093 [(set rGPR:$Rd, (opnode rGPR:$Rn,
1094 (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1095 Requires<[HasT2ExtractPack, IsThumb2]> {
1096 let Inst{31-27} = 0b11111;
1097 let Inst{26-23} = 0b0100;
1098 let Inst{22-20} = opcod;
1099 let Inst{15-12} = 0b1111;
1103 let Inst{5-4} = rot{1-0}; // rotate
1107 // DO variant - disassembly only, no pattern
1109 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
1110 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1111 opc, "\t$Rd, $Rn, $Rm", []> {
1112 let Inst{31-27} = 0b11111;
1113 let Inst{26-23} = 0b0100;
1114 let Inst{22-20} = opcod;
1115 let Inst{15-12} = 0b1111;
1117 let Inst{5-4} = 0b00; // rotate
1119 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
1120 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> {
1121 let Inst{31-27} = 0b11111;
1122 let Inst{26-23} = 0b0100;
1123 let Inst{22-20} = opcod;
1124 let Inst{15-12} = 0b1111;
1128 let Inst{5-4} = rot{1-0}; // rotate
1132 //===----------------------------------------------------------------------===//
1134 //===----------------------------------------------------------------------===//
1136 //===----------------------------------------------------------------------===//
1137 // Miscellaneous Instructions.
1140 class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
1141 string asm, list<dag> pattern>
1142 : T2XI<oops, iops, itin, asm, pattern> {
1146 let Inst{11-8} = Rd;
1147 let Inst{26} = label{11};
1148 let Inst{14-12} = label{10-8};
1149 let Inst{7-0} = label{7-0};
1152 // LEApcrel - Load a pc-relative address into a register without offending the
1154 def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
1155 (ins t2adrlabel:$addr, pred:$p),
1156 IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> {
1157 let Inst{31-27} = 0b11110;
1158 let Inst{25-24} = 0b10;
1159 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1162 let Inst{19-16} = 0b1111; // Rn
1167 let Inst{11-8} = Rd;
1168 let Inst{23} = addr{12};
1169 let Inst{21} = addr{12};
1170 let Inst{26} = addr{11};
1171 let Inst{14-12} = addr{10-8};
1172 let Inst{7-0} = addr{7-0};
1175 let neverHasSideEffects = 1, isReMaterializable = 1 in
1176 def t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
1177 Size4Bytes, IIC_iALUi, []>;
1178 def t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd),
1179 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1180 Size4Bytes, IIC_iALUi,
1184 // FIXME: None of these add/sub SP special instructions should be necessary
1185 // at all for thumb2 since they use the same encodings as the generic
1186 // add/sub instructions. In thumb1 we need them since they have dedicated
1187 // encodings. At the least, they should be pseudo instructions.
1188 // ADD r, sp, {so_imm|i12}
1189 let isCodeGenOnly = 1 in {
1190 def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1191 IIC_iALUi, "add", ".w\t$Rd, $Rn, $imm", []> {
1192 let Inst{31-27} = 0b11110;
1194 let Inst{24-21} = 0b1000;
1197 def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1198 IIC_iALUi, "addw", "\t$Rd, $Rn, $imm", []> {
1199 let Inst{31-27} = 0b11110;
1200 let Inst{25-20} = 0b100000;
1204 // ADD r, sp, so_reg
1205 def t2ADDrSPs : T2sTwoRegShiftedReg<
1206 (outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
1207 IIC_iALUsi, "add", ".w\t$Rd, $Rn, $ShiftedRm", []> {
1208 let Inst{31-27} = 0b11101;
1209 let Inst{26-25} = 0b01;
1210 let Inst{24-21} = 0b1000;
1214 // SUB r, sp, {so_imm|i12}
1215 def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1216 IIC_iALUi, "sub", ".w\t$Rd, $Rn, $imm", []> {
1217 let Inst{31-27} = 0b11110;
1219 let Inst{24-21} = 0b1101;
1222 def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1223 IIC_iALUi, "subw", "\t$Rd, $Rn, $imm", []> {
1224 let Inst{31-27} = 0b11110;
1225 let Inst{25-20} = 0b101010;
1229 // SUB r, sp, so_reg
1230 def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$imm),
1232 "sub", "\t$Rd, $Rn, $imm", []> {
1233 let Inst{31-27} = 0b11101;
1234 let Inst{26-25} = 0b01;
1235 let Inst{24-21} = 0b1101;
1236 let Inst{19-16} = 0b1101; // Rn = sp
1239 } // end isCodeGenOnly = 1
1241 // Signed and unsigned division on v7-M
1242 def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1243 "sdiv", "\t$Rd, $Rn, $Rm",
1244 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>,
1245 Requires<[HasDivide, IsThumb2]> {
1246 let Inst{31-27} = 0b11111;
1247 let Inst{26-21} = 0b011100;
1249 let Inst{15-12} = 0b1111;
1250 let Inst{7-4} = 0b1111;
1253 def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1254 "udiv", "\t$Rd, $Rn, $Rm",
1255 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>,
1256 Requires<[HasDivide, IsThumb2]> {
1257 let Inst{31-27} = 0b11111;
1258 let Inst{26-21} = 0b011101;
1260 let Inst{15-12} = 0b1111;
1261 let Inst{7-4} = 0b1111;
1264 //===----------------------------------------------------------------------===//
1265 // Load / store Instructions.
1269 let canFoldAsLoad = 1, isReMaterializable = 1 in
1270 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1271 UnOpFrag<(load node:$Src)>>;
1273 // Loads with zero extension
1274 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1275 UnOpFrag<(zextloadi16 node:$Src)>>;
1276 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1277 UnOpFrag<(zextloadi8 node:$Src)>>;
1279 // Loads with sign extension
1280 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1281 UnOpFrag<(sextloadi16 node:$Src)>>;
1282 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1283 UnOpFrag<(sextloadi8 node:$Src)>>;
1285 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1287 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1288 (ins t2addrmode_imm8s4:$addr),
1289 IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", []>;
1290 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1292 // zextload i1 -> zextload i8
1293 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1294 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1295 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1296 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1297 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1298 (t2LDRBs t2addrmode_so_reg:$addr)>;
1299 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1300 (t2LDRBpci tconstpool:$addr)>;
1302 // extload -> zextload
1303 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1305 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1306 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1307 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1308 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1309 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1310 (t2LDRBs t2addrmode_so_reg:$addr)>;
1311 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1312 (t2LDRBpci tconstpool:$addr)>;
1314 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1315 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1316 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1317 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1318 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1319 (t2LDRBs t2addrmode_so_reg:$addr)>;
1320 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1321 (t2LDRBpci tconstpool:$addr)>;
1323 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1324 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1325 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1326 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1327 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1328 (t2LDRHs t2addrmode_so_reg:$addr)>;
1329 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1330 (t2LDRHpci tconstpool:$addr)>;
1332 // FIXME: The destination register of the loads and stores can't be PC, but
1333 // can be SP. We need another regclass (similar to rGPR) to represent
1334 // that. Not a pressing issue since these are selected manually,
1339 let mayLoad = 1, neverHasSideEffects = 1 in {
1340 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1341 (ins t2addrmode_imm8:$addr),
1342 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1343 "ldr", "\t$Rt, $addr!", "$addr.base = $Rn",
1346 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1347 (ins GPR:$base, t2am_imm8_offset:$addr),
1348 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1349 "ldr", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1352 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1353 (ins t2addrmode_imm8:$addr),
1354 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1355 "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn",
1357 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1358 (ins GPR:$base, t2am_imm8_offset:$addr),
1359 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1360 "ldrb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1363 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1364 (ins t2addrmode_imm8:$addr),
1365 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1366 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn",
1368 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1369 (ins GPR:$base, t2am_imm8_offset:$addr),
1370 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1371 "ldrh", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1374 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1375 (ins t2addrmode_imm8:$addr),
1376 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1377 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn",
1379 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1380 (ins GPR:$base, t2am_imm8_offset:$addr),
1381 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1382 "ldrsb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1385 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1386 (ins t2addrmode_imm8:$addr),
1387 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1388 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn",
1390 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$Rn),
1391 (ins GPR:$base, t2am_imm8_offset:$addr),
1392 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1393 "ldrsh", "\t$dst, [$Rn], $addr", "$base = $Rn",
1395 } // mayLoad = 1, neverHasSideEffects = 1
1397 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1398 // for disassembly only.
1399 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1400 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1401 : T2Ii8<(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1402 "\t$Rt, $addr", []> {
1403 let Inst{31-27} = 0b11111;
1404 let Inst{26-25} = 0b00;
1405 let Inst{24} = signed;
1407 let Inst{22-21} = type;
1408 let Inst{20} = 1; // load
1410 let Inst{10-8} = 0b110; // PUW.
1414 let Inst{15-12} = Rt;
1415 let Inst{19-16} = addr{12-9};
1416 let Inst{7-0} = addr{7-0};
1419 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1420 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1421 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1422 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1423 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1426 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1427 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1428 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1429 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1430 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1431 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1434 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1435 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1436 (ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr),
1437 IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>;
1440 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1441 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1442 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1443 "str", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1445 (pre_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1447 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1448 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1449 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1450 "str", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1452 (post_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1454 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1455 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1456 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1457 "strh", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1459 (pre_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1461 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1462 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1463 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1464 "strh", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1466 (post_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1468 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1469 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1470 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1471 "strb", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1473 (pre_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1475 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1476 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1477 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1478 "strb", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1480 (post_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1482 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1484 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1485 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1486 : T2Ii8<(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1487 "\t$Rt, $addr", []> {
1488 let Inst{31-27} = 0b11111;
1489 let Inst{26-25} = 0b00;
1490 let Inst{24} = 0; // not signed
1492 let Inst{22-21} = type;
1493 let Inst{20} = 0; // store
1495 let Inst{10-8} = 0b110; // PUW
1499 let Inst{15-12} = Rt;
1500 let Inst{19-16} = addr{12-9};
1501 let Inst{7-0} = addr{7-0};
1504 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1505 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1506 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1508 // ldrd / strd pre / post variants
1509 // For disassembly only.
1511 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
1512 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1513 "ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1515 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
1516 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1517 "ldrd", "\t$Rt, $Rt2, [$base], $imm", []>;
1519 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1520 (ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1521 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1523 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1524 (ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1525 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>;
1527 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1528 // data/instruction access. These are for disassembly only.
1529 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1530 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1531 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1533 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1535 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1536 let Inst{31-25} = 0b1111100;
1537 let Inst{24} = instr;
1539 let Inst{21} = write;
1541 let Inst{15-12} = 0b1111;
1544 let Inst{19-16} = addr{16-13}; // Rn
1545 let Inst{23} = addr{12}; // U
1546 let Inst{11-0} = addr{11-0}; // imm12
1549 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1551 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1552 let Inst{31-25} = 0b1111100;
1553 let Inst{24} = instr;
1554 let Inst{23} = 0; // U = 0
1556 let Inst{21} = write;
1558 let Inst{15-12} = 0b1111;
1559 let Inst{11-8} = 0b1100;
1562 let Inst{19-16} = addr{12-9}; // Rn
1563 let Inst{7-0} = addr{7-0}; // imm8
1566 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1568 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1569 let Inst{31-25} = 0b1111100;
1570 let Inst{24} = instr;
1571 let Inst{23} = 0; // add = TRUE for T1
1573 let Inst{21} = write;
1575 let Inst{15-12} = 0b1111;
1576 let Inst{11-6} = 0000000;
1579 let Inst{19-16} = addr{9-6}; // Rn
1580 let Inst{3-0} = addr{5-2}; // Rm
1581 let Inst{5-4} = addr{1-0}; // imm2
1585 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1586 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1587 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1589 //===----------------------------------------------------------------------===//
1590 // Load / store multiple Instructions.
1593 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1594 InstrItinClass itin_upd, bit L_bit> {
1596 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1597 itin, !strconcat(asm, "ia${p}.w\t$Rn, $regs"), []> {
1601 let Inst{31-27} = 0b11101;
1602 let Inst{26-25} = 0b00;
1603 let Inst{24-23} = 0b01; // Increment After
1605 let Inst{21} = 0; // No writeback
1606 let Inst{20} = L_bit;
1607 let Inst{19-16} = Rn;
1608 let Inst{15-0} = regs;
1611 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1612 itin_upd, !strconcat(asm, "ia${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1616 let Inst{31-27} = 0b11101;
1617 let Inst{26-25} = 0b00;
1618 let Inst{24-23} = 0b01; // Increment After
1620 let Inst{21} = 1; // Writeback
1621 let Inst{20} = L_bit;
1622 let Inst{19-16} = Rn;
1623 let Inst{15-0} = regs;
1626 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1627 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1631 let Inst{31-27} = 0b11101;
1632 let Inst{26-25} = 0b00;
1633 let Inst{24-23} = 0b10; // Decrement Before
1635 let Inst{21} = 0; // No writeback
1636 let Inst{20} = L_bit;
1637 let Inst{19-16} = Rn;
1638 let Inst{15-0} = regs;
1641 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1642 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1646 let Inst{31-27} = 0b11101;
1647 let Inst{26-25} = 0b00;
1648 let Inst{24-23} = 0b10; // Decrement Before
1650 let Inst{21} = 1; // Writeback
1651 let Inst{20} = L_bit;
1652 let Inst{19-16} = Rn;
1653 let Inst{15-0} = regs;
1657 let neverHasSideEffects = 1 in {
1659 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1660 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1662 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1663 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1665 } // neverHasSideEffects
1668 //===----------------------------------------------------------------------===//
1669 // Move Instructions.
1672 let neverHasSideEffects = 1 in
1673 def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1674 "mov", ".w\t$Rd, $Rm", []> {
1675 let Inst{31-27} = 0b11101;
1676 let Inst{26-25} = 0b01;
1677 let Inst{24-21} = 0b0010;
1678 let Inst{19-16} = 0b1111; // Rn
1679 let Inst{14-12} = 0b000;
1680 let Inst{7-4} = 0b0000;
1683 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1684 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
1685 AddedComplexity = 1 in
1686 def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
1687 "mov", ".w\t$Rd, $imm",
1688 [(set rGPR:$Rd, t2_so_imm:$imm)]> {
1689 let Inst{31-27} = 0b11110;
1691 let Inst{24-21} = 0b0010;
1692 let Inst{19-16} = 0b1111; // Rn
1696 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1697 def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
1698 "movw", "\t$Rd, $imm",
1699 [(set rGPR:$Rd, imm0_65535:$imm)]> {
1700 let Inst{31-27} = 0b11110;
1702 let Inst{24-21} = 0b0010;
1703 let Inst{20} = 0; // The S bit.
1709 let Inst{11-8} = Rd;
1710 let Inst{19-16} = imm{15-12};
1711 let Inst{26} = imm{11};
1712 let Inst{14-12} = imm{10-8};
1713 let Inst{7-0} = imm{7-0};
1716 def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1717 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1719 let Constraints = "$src = $Rd" in {
1720 def t2MOVTi16 : T2I<(outs rGPR:$Rd),
1721 (ins rGPR:$src, i32imm_hilo16:$imm), IIC_iMOVi,
1722 "movt", "\t$Rd, $imm",
1724 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1725 let Inst{31-27} = 0b11110;
1727 let Inst{24-21} = 0b0110;
1728 let Inst{20} = 0; // The S bit.
1734 let Inst{11-8} = Rd;
1735 let Inst{19-16} = imm{15-12};
1736 let Inst{26} = imm{11};
1737 let Inst{14-12} = imm{10-8};
1738 let Inst{7-0} = imm{7-0};
1741 def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1742 (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1745 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1747 //===----------------------------------------------------------------------===//
1748 // Extend Instructions.
1753 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1754 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1755 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1756 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1757 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1759 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1760 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1761 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1762 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1763 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1765 // TODO: SXT(A){B|H}16 - done for disassembly only
1769 let AddedComplexity = 16 in {
1770 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1771 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1772 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1773 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1774 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1775 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1777 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1778 // The transformation should probably be done as a combiner action
1779 // instead so we can include a check for masking back in the upper
1780 // eight bits of the source into the lower eight bits of the result.
1781 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1782 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1783 // Requires<[HasT2ExtractPack, IsThumb2]>;
1784 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1785 (t2UXTB16r_rot rGPR:$Src, 8)>,
1786 Requires<[HasT2ExtractPack, IsThumb2]>;
1788 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1789 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1790 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1791 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1792 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1795 //===----------------------------------------------------------------------===//
1796 // Arithmetic Instructions.
1799 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1800 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1801 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1802 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1804 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1805 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1806 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1807 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1808 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1809 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1810 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1812 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1813 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1814 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1815 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1816 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1817 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1818 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1819 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1822 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1823 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1824 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1825 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1827 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1828 // The assume-no-carry-in form uses the negation of the input since add/sub
1829 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1830 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1832 // The AddedComplexity preferences the first variant over the others since
1833 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1834 let AddedComplexity = 1 in
1835 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1836 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1837 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1838 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1839 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1840 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1841 let AddedComplexity = 1 in
1842 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1843 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1844 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1845 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1846 // The with-carry-in form matches bitwise not instead of the negation.
1847 // Effectively, the inverse interpretation of the carry flag already accounts
1848 // for part of the negation.
1849 let AddedComplexity = 1 in
1850 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1851 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1852 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1853 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1855 // Select Bytes -- for disassembly only
1857 def t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1858 NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []> {
1859 let Inst{31-27} = 0b11111;
1860 let Inst{26-24} = 0b010;
1862 let Inst{22-20} = 0b010;
1863 let Inst{15-12} = 0b1111;
1865 let Inst{6-4} = 0b000;
1868 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1869 // And Miscellaneous operations -- for disassembly only
1870 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1871 list<dag> pat = [/* For disassembly only; pattern left blank */],
1872 dag iops = (ins rGPR:$Rn, rGPR:$Rm),
1873 string asm = "\t$Rd, $Rn, $Rm">
1874 : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat> {
1875 let Inst{31-27} = 0b11111;
1876 let Inst{26-23} = 0b0101;
1877 let Inst{22-20} = op22_20;
1878 let Inst{15-12} = 0b1111;
1879 let Inst{7-4} = op7_4;
1885 let Inst{11-8} = Rd;
1886 let Inst{19-16} = Rn;
1890 // Saturating add/subtract -- for disassembly only
1892 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1893 [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))],
1894 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1895 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1896 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1897 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1898 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd", [],
1899 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1900 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub", [],
1901 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1902 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1903 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1904 [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))],
1905 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1906 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1907 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1908 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1909 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1910 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1911 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1912 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1913 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1915 // Signed/Unsigned add/subtract -- for disassembly only
1917 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1918 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1919 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1920 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1921 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1922 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1923 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1924 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1925 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1926 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1927 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1928 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1930 // Signed/Unsigned halving add/subtract -- for disassembly only
1932 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1933 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1934 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1935 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1936 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1937 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1938 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1939 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1940 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1941 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1942 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1943 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1945 // Helper class for disassembly only
1946 // A6.3.16 & A6.3.17
1947 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1948 class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1949 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1950 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
1951 let Inst{31-27} = 0b11111;
1952 let Inst{26-24} = 0b011;
1953 let Inst{23} = long;
1954 let Inst{22-20} = op22_20;
1955 let Inst{7-4} = op7_4;
1958 class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1959 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1960 : T2FourReg<oops, iops, itin, opc, asm, pattern> {
1961 let Inst{31-27} = 0b11111;
1962 let Inst{26-24} = 0b011;
1963 let Inst{23} = long;
1964 let Inst{22-20} = op22_20;
1965 let Inst{7-4} = op7_4;
1968 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1970 def t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1971 (ins rGPR:$Rn, rGPR:$Rm),
1972 NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []> {
1973 let Inst{15-12} = 0b1111;
1975 def t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1976 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
1977 "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>;
1979 // Signed/Unsigned saturate -- for disassembly only
1981 class T2SatI<dag oops, dag iops, InstrItinClass itin,
1982 string opc, string asm, list<dag> pattern>
1983 : T2I<oops, iops, itin, opc, asm, pattern> {
1989 let Inst{11-8} = Rd;
1990 let Inst{19-16} = Rn;
1991 let Inst{4-0} = sat_imm{4-0};
1992 let Inst{21} = sh{6};
1993 let Inst{14-12} = sh{4-2};
1994 let Inst{7-6} = sh{1-0};
1998 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1999 NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
2000 [/* For disassembly only; pattern left blank */]> {
2001 let Inst{31-27} = 0b11110;
2002 let Inst{25-22} = 0b1100;
2007 def t2SSAT16: T2SatI<
2008 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
2009 "ssat16", "\t$Rd, $sat_imm, $Rn",
2010 [/* For disassembly only; pattern left blank */]> {
2011 let Inst{31-27} = 0b11110;
2012 let Inst{25-22} = 0b1100;
2015 let Inst{21} = 1; // sh = '1'
2016 let Inst{14-12} = 0b000; // imm3 = '000'
2017 let Inst{7-6} = 0b00; // imm2 = '00'
2021 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
2022 NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh",
2023 [/* For disassembly only; pattern left blank */]> {
2024 let Inst{31-27} = 0b11110;
2025 let Inst{25-22} = 0b1110;
2030 def t2USAT16: T2SatI<
2031 (outs rGPR:$dst), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
2032 "usat16", "\t$dst, $sat_imm, $Rn",
2033 [/* For disassembly only; pattern left blank */]> {
2034 let Inst{31-27} = 0b11110;
2035 let Inst{25-22} = 0b1110;
2038 let Inst{21} = 1; // sh = '1'
2039 let Inst{14-12} = 0b000; // imm3 = '000'
2040 let Inst{7-6} = 0b00; // imm2 = '00'
2043 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
2044 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
2046 //===----------------------------------------------------------------------===//
2047 // Shift and rotate Instructions.
2050 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
2051 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
2052 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
2053 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
2055 let Uses = [CPSR] in {
2056 def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2057 "rrx", "\t$Rd, $Rm",
2058 [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> {
2059 let Inst{31-27} = 0b11101;
2060 let Inst{26-25} = 0b01;
2061 let Inst{24-21} = 0b0010;
2062 let Inst{19-16} = 0b1111; // Rn
2063 let Inst{14-12} = 0b000;
2064 let Inst{7-4} = 0b0011;
2068 let isCodeGenOnly = 1, Defs = [CPSR] in {
2069 def t2MOVsrl_flag : T2TwoRegShiftImm<
2070 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2071 "lsrs", ".w\t$Rd, $Rm, #1",
2072 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> {
2073 let Inst{31-27} = 0b11101;
2074 let Inst{26-25} = 0b01;
2075 let Inst{24-21} = 0b0010;
2076 let Inst{20} = 1; // The S bit.
2077 let Inst{19-16} = 0b1111; // Rn
2078 let Inst{5-4} = 0b01; // Shift type.
2079 // Shift amount = Inst{14-12:7-6} = 1.
2080 let Inst{14-12} = 0b000;
2081 let Inst{7-6} = 0b01;
2083 def t2MOVsra_flag : T2TwoRegShiftImm<
2084 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2085 "asrs", ".w\t$Rd, $Rm, #1",
2086 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> {
2087 let Inst{31-27} = 0b11101;
2088 let Inst{26-25} = 0b01;
2089 let Inst{24-21} = 0b0010;
2090 let Inst{20} = 1; // The S bit.
2091 let Inst{19-16} = 0b1111; // Rn
2092 let Inst{5-4} = 0b10; // Shift type.
2093 // Shift amount = Inst{14-12:7-6} = 1.
2094 let Inst{14-12} = 0b000;
2095 let Inst{7-6} = 0b01;
2099 //===----------------------------------------------------------------------===//
2100 // Bitwise Instructions.
2103 defm t2AND : T2I_bin_w_irs<0b0000, "and",
2104 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2105 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2106 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
2107 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2108 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2109 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
2110 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2111 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2113 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
2114 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2115 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2117 class T2BitFI<dag oops, dag iops, InstrItinClass itin,
2118 string opc, string asm, list<dag> pattern>
2119 : T2I<oops, iops, itin, opc, asm, pattern> {
2124 let Inst{11-8} = Rd;
2125 let Inst{4-0} = msb{4-0};
2126 let Inst{14-12} = lsb{4-2};
2127 let Inst{7-6} = lsb{1-0};
2130 class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2131 string opc, string asm, list<dag> pattern>
2132 : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2135 let Inst{19-16} = Rn;
2138 let Constraints = "$src = $Rd" in
2139 def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2140 IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2141 [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2142 let Inst{31-27} = 0b11110;
2144 let Inst{24-20} = 0b10110;
2145 let Inst{19-16} = 0b1111; // Rn
2149 let msb{4-0} = imm{9-5};
2150 let lsb{4-0} = imm{4-0};
2153 def t2SBFX: T2TwoRegBitFI<
2154 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2155 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2156 let Inst{31-27} = 0b11110;
2158 let Inst{24-20} = 0b10100;
2162 def t2UBFX: T2TwoRegBitFI<
2163 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2164 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2165 let Inst{31-27} = 0b11110;
2167 let Inst{24-20} = 0b11100;
2171 // A8.6.18 BFI - Bitfield insert (Encoding T1)
2172 let Constraints = "$src = $Rd" in {
2173 def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2174 (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2175 IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2176 [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2177 bf_inv_mask_imm:$imm))]> {
2178 let Inst{31-27} = 0b11110;
2180 let Inst{24-20} = 0b10110;
2184 let msb{4-0} = imm{9-5};
2185 let lsb{4-0} = imm{4-0};
2188 // GNU as only supports this form of bfi (w/ 4 arguments)
2189 let isAsmParserOnly = 1 in
2190 def t2BFI4p : T2TwoRegBitFI<(outs rGPR:$Rd),
2191 (ins rGPR:$src, rGPR:$Rn, lsb_pos_imm:$lsbit,
2193 IIC_iBITi, "bfi", "\t$Rd, $Rn, $lsbit, $width",
2195 let Inst{31-27} = 0b11110;
2197 let Inst{24-20} = 0b10110;
2202 let msb{4-0} = width; // Custom encoder => lsb+width-1
2203 let lsb{4-0} = lsbit;
2207 defm t2ORN : T2I_bin_irs<0b0011, "orn",
2208 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2209 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
2211 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2212 let AddedComplexity = 1 in
2213 defm t2MVN : T2I_un_irs <0b0011, "mvn",
2214 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2215 UnOpFrag<(not node:$Src)>, 1, 1>;
2218 let AddedComplexity = 1 in
2219 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
2220 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2222 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2223 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
2224 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2225 Requires<[IsThumb2]>;
2227 def : T2Pat<(t2_so_imm_not:$src),
2228 (t2MVNi t2_so_imm_not:$src)>;
2230 //===----------------------------------------------------------------------===//
2231 // Multiply Instructions.
2233 let isCommutable = 1 in
2234 def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2235 "mul", "\t$Rd, $Rn, $Rm",
2236 [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2237 let Inst{31-27} = 0b11111;
2238 let Inst{26-23} = 0b0110;
2239 let Inst{22-20} = 0b000;
2240 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2241 let Inst{7-4} = 0b0000; // Multiply
2244 def t2MLA: T2FourReg<
2245 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2246 "mla", "\t$Rd, $Rn, $Rm, $Ra",
2247 [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> {
2248 let Inst{31-27} = 0b11111;
2249 let Inst{26-23} = 0b0110;
2250 let Inst{22-20} = 0b000;
2251 let Inst{7-4} = 0b0000; // Multiply
2254 def t2MLS: T2FourReg<
2255 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2256 "mls", "\t$Rd, $Rn, $Rm, $Ra",
2257 [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> {
2258 let Inst{31-27} = 0b11111;
2259 let Inst{26-23} = 0b0110;
2260 let Inst{22-20} = 0b000;
2261 let Inst{7-4} = 0b0001; // Multiply and Subtract
2264 // Extra precision multiplies with low / high results
2265 let neverHasSideEffects = 1 in {
2266 let isCommutable = 1 in {
2267 def t2SMULL : T2MulLong<0b000, 0b0000,
2268 (outs rGPR:$Rd, rGPR:$Ra),
2269 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2270 "smull", "\t$Rd, $Ra, $Rn, $Rm", []>;
2272 def t2UMULL : T2MulLong<0b010, 0b0000,
2273 (outs rGPR:$RdLo, rGPR:$RdHi),
2274 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2275 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2278 // Multiply + accumulate
2279 def t2SMLAL : T2MulLong<0b100, 0b0000,
2280 (outs rGPR:$RdLo, rGPR:$RdHi),
2281 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2282 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2284 def t2UMLAL : T2MulLong<0b110, 0b0000,
2285 (outs rGPR:$RdLo, rGPR:$RdHi),
2286 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2287 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2289 def t2UMAAL : T2MulLong<0b110, 0b0110,
2290 (outs rGPR:$RdLo, rGPR:$RdHi),
2291 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2292 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2293 } // neverHasSideEffects
2295 // Rounding variants of the below included for disassembly only
2297 // Most significant word multiply
2298 def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2299 "smmul", "\t$Rd, $Rn, $Rm",
2300 [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]> {
2301 let Inst{31-27} = 0b11111;
2302 let Inst{26-23} = 0b0110;
2303 let Inst{22-20} = 0b101;
2304 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2305 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2308 def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2309 "smmulr", "\t$Rd, $Rn, $Rm", []> {
2310 let Inst{31-27} = 0b11111;
2311 let Inst{26-23} = 0b0110;
2312 let Inst{22-20} = 0b101;
2313 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2314 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2317 def t2SMMLA : T2FourReg<
2318 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2319 "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2320 [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]> {
2321 let Inst{31-27} = 0b11111;
2322 let Inst{26-23} = 0b0110;
2323 let Inst{22-20} = 0b101;
2324 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2327 def t2SMMLAR: T2FourReg<
2328 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2329 "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []> {
2330 let Inst{31-27} = 0b11111;
2331 let Inst{26-23} = 0b0110;
2332 let Inst{22-20} = 0b101;
2333 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2336 def t2SMMLS: T2FourReg<
2337 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2338 "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2339 [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]> {
2340 let Inst{31-27} = 0b11111;
2341 let Inst{26-23} = 0b0110;
2342 let Inst{22-20} = 0b110;
2343 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2346 def t2SMMLSR:T2FourReg<
2347 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2348 "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []> {
2349 let Inst{31-27} = 0b11111;
2350 let Inst{26-23} = 0b0110;
2351 let Inst{22-20} = 0b110;
2352 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2355 multiclass T2I_smul<string opc, PatFrag opnode> {
2356 def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2357 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2358 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2359 (sext_inreg rGPR:$Rm, i16)))]> {
2360 let Inst{31-27} = 0b11111;
2361 let Inst{26-23} = 0b0110;
2362 let Inst{22-20} = 0b001;
2363 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2364 let Inst{7-6} = 0b00;
2365 let Inst{5-4} = 0b00;
2368 def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2369 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2370 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2371 (sra rGPR:$Rm, (i32 16))))]> {
2372 let Inst{31-27} = 0b11111;
2373 let Inst{26-23} = 0b0110;
2374 let Inst{22-20} = 0b001;
2375 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2376 let Inst{7-6} = 0b00;
2377 let Inst{5-4} = 0b01;
2380 def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2381 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2382 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2383 (sext_inreg rGPR:$Rm, i16)))]> {
2384 let Inst{31-27} = 0b11111;
2385 let Inst{26-23} = 0b0110;
2386 let Inst{22-20} = 0b001;
2387 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2388 let Inst{7-6} = 0b00;
2389 let Inst{5-4} = 0b10;
2392 def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2393 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2394 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2395 (sra rGPR:$Rm, (i32 16))))]> {
2396 let Inst{31-27} = 0b11111;
2397 let Inst{26-23} = 0b0110;
2398 let Inst{22-20} = 0b001;
2399 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2400 let Inst{7-6} = 0b00;
2401 let Inst{5-4} = 0b11;
2404 def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2405 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2406 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2407 (sext_inreg rGPR:$Rm, i16)), (i32 16)))]> {
2408 let Inst{31-27} = 0b11111;
2409 let Inst{26-23} = 0b0110;
2410 let Inst{22-20} = 0b011;
2411 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2412 let Inst{7-6} = 0b00;
2413 let Inst{5-4} = 0b00;
2416 def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2417 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2418 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2419 (sra rGPR:$Rm, (i32 16))), (i32 16)))]> {
2420 let Inst{31-27} = 0b11111;
2421 let Inst{26-23} = 0b0110;
2422 let Inst{22-20} = 0b011;
2423 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2424 let Inst{7-6} = 0b00;
2425 let Inst{5-4} = 0b01;
2430 multiclass T2I_smla<string opc, PatFrag opnode> {
2432 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2433 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2434 [(set rGPR:$Rd, (add rGPR:$Ra,
2435 (opnode (sext_inreg rGPR:$Rn, i16),
2436 (sext_inreg rGPR:$Rm, i16))))]> {
2437 let Inst{31-27} = 0b11111;
2438 let Inst{26-23} = 0b0110;
2439 let Inst{22-20} = 0b001;
2440 let Inst{7-6} = 0b00;
2441 let Inst{5-4} = 0b00;
2445 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2446 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2447 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
2448 (sra rGPR:$Rm, (i32 16)))))]> {
2449 let Inst{31-27} = 0b11111;
2450 let Inst{26-23} = 0b0110;
2451 let Inst{22-20} = 0b001;
2452 let Inst{7-6} = 0b00;
2453 let Inst{5-4} = 0b01;
2457 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2458 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2459 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2460 (sext_inreg rGPR:$Rm, i16))))]> {
2461 let Inst{31-27} = 0b11111;
2462 let Inst{26-23} = 0b0110;
2463 let Inst{22-20} = 0b001;
2464 let Inst{7-6} = 0b00;
2465 let Inst{5-4} = 0b10;
2469 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2470 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2471 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2472 (sra rGPR:$Rm, (i32 16)))))]> {
2473 let Inst{31-27} = 0b11111;
2474 let Inst{26-23} = 0b0110;
2475 let Inst{22-20} = 0b001;
2476 let Inst{7-6} = 0b00;
2477 let Inst{5-4} = 0b11;
2481 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2482 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2483 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2484 (sext_inreg rGPR:$Rm, i16)), (i32 16))))]> {
2485 let Inst{31-27} = 0b11111;
2486 let Inst{26-23} = 0b0110;
2487 let Inst{22-20} = 0b011;
2488 let Inst{7-6} = 0b00;
2489 let Inst{5-4} = 0b00;
2493 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2494 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2495 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2496 (sra rGPR:$Rm, (i32 16))), (i32 16))))]> {
2497 let Inst{31-27} = 0b11111;
2498 let Inst{26-23} = 0b0110;
2499 let Inst{22-20} = 0b011;
2500 let Inst{7-6} = 0b00;
2501 let Inst{5-4} = 0b01;
2505 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2506 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2508 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2509 def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
2510 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
2511 [/* For disassembly only; pattern left blank */]>;
2512 def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
2513 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
2514 [/* For disassembly only; pattern left blank */]>;
2515 def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
2516 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
2517 [/* For disassembly only; pattern left blank */]>;
2518 def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
2519 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
2520 [/* For disassembly only; pattern left blank */]>;
2522 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2523 // These are for disassembly only.
2525 def t2SMUAD: T2ThreeReg_mac<
2526 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2527 IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []> {
2528 let Inst{15-12} = 0b1111;
2530 def t2SMUADX:T2ThreeReg_mac<
2531 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2532 IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []> {
2533 let Inst{15-12} = 0b1111;
2535 def t2SMUSD: T2ThreeReg_mac<
2536 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2537 IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []> {
2538 let Inst{15-12} = 0b1111;
2540 def t2SMUSDX:T2ThreeReg_mac<
2541 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2542 IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []> {
2543 let Inst{15-12} = 0b1111;
2545 def t2SMLAD : T2ThreeReg_mac<
2546 0, 0b010, 0b0000, (outs rGPR:$Rd),
2547 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
2548 "\t$Rd, $Rn, $Rm, $Ra", []>;
2549 def t2SMLADX : T2FourReg_mac<
2550 0, 0b010, 0b0001, (outs rGPR:$Rd),
2551 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
2552 "\t$Rd, $Rn, $Rm, $Ra", []>;
2553 def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
2554 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
2555 "\t$Rd, $Rn, $Rm, $Ra", []>;
2556 def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
2557 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
2558 "\t$Rd, $Rn, $Rm, $Ra", []>;
2559 def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2560 (ins rGPR:$Rm, rGPR:$Rn), IIC_iMAC64, "smlald",
2561 "\t$Ra, $Rd, $Rm, $Rn", []>;
2562 def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2563 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlaldx",
2564 "\t$Ra, $Rd, $Rm, $Rn", []>;
2565 def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2566 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsld",
2567 "\t$Ra, $Rd, $Rm, $Rn", []>;
2568 def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2569 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
2570 "\t$Ra, $Rd, $Rm, $Rn", []>;
2572 //===----------------------------------------------------------------------===//
2573 // Misc. Arithmetic Instructions.
2576 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2577 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2578 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2579 let Inst{31-27} = 0b11111;
2580 let Inst{26-22} = 0b01010;
2581 let Inst{21-20} = op1;
2582 let Inst{15-12} = 0b1111;
2583 let Inst{7-6} = 0b10;
2584 let Inst{5-4} = op2;
2588 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2589 "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>;
2591 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2592 "rbit", "\t$Rd, $Rm",
2593 [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>;
2595 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2596 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>;
2598 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2599 "rev16", ".w\t$Rd, $Rm",
2601 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF),
2602 (or (and (shl rGPR:$Rm, (i32 8)), 0xFF00),
2603 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000),
2604 (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)))))]>;
2606 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2607 "revsh", ".w\t$Rd, $Rm",
2610 (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)),
2611 (shl rGPR:$Rm, (i32 8))), i16))]>;
2613 def t2PKHBT : T2ThreeReg<
2614 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2615 IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2616 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2617 (and (shl rGPR:$Rm, lsl_amt:$sh),
2619 Requires<[HasT2ExtractPack, IsThumb2]> {
2620 let Inst{31-27} = 0b11101;
2621 let Inst{26-25} = 0b01;
2622 let Inst{24-20} = 0b01100;
2623 let Inst{5} = 0; // BT form
2627 let Inst{14-12} = sh{7-5};
2628 let Inst{7-6} = sh{4-3};
2631 // Alternate cases for PKHBT where identities eliminate some nodes.
2632 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2633 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2634 Requires<[HasT2ExtractPack, IsThumb2]>;
2635 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2636 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2637 Requires<[HasT2ExtractPack, IsThumb2]>;
2639 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2640 // will match the pattern below.
2641 def t2PKHTB : T2ThreeReg<
2642 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2643 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2644 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
2645 (and (sra rGPR:$Rm, asr_amt:$sh),
2647 Requires<[HasT2ExtractPack, IsThumb2]> {
2648 let Inst{31-27} = 0b11101;
2649 let Inst{26-25} = 0b01;
2650 let Inst{24-20} = 0b01100;
2651 let Inst{5} = 1; // TB form
2655 let Inst{14-12} = sh{7-5};
2656 let Inst{7-6} = sh{4-3};
2659 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2660 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2661 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2662 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2663 Requires<[HasT2ExtractPack, IsThumb2]>;
2664 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2665 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2666 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2667 Requires<[HasT2ExtractPack, IsThumb2]>;
2669 //===----------------------------------------------------------------------===//
2670 // Comparison Instructions...
2672 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2673 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2674 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2676 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_imm:$imm),
2677 (t2CMPri GPR:$lhs, t2_so_imm:$imm)>;
2678 def : T2Pat<(ARMcmpZ GPR:$lhs, rGPR:$rhs),
2679 (t2CMPrr GPR:$lhs, rGPR:$rhs)>;
2680 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_reg:$rhs),
2681 (t2CMPrs GPR:$lhs, t2_so_reg:$rhs)>;
2683 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2684 // Compare-to-zero still works out, just not the relationals
2685 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2686 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2687 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2688 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2689 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2691 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2692 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2694 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2695 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2697 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2698 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2699 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
2700 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2701 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2702 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
2704 // Conditional moves
2705 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2706 // a two-value operand where a dag node expects two operands. :(
2707 let neverHasSideEffects = 1 in {
2708 def t2MOVCCr : T2TwoReg<
2709 (outs rGPR:$Rd), (ins rGPR:$false, rGPR:$Rm), IIC_iCMOVr,
2710 "mov", ".w\t$Rd, $Rm",
2711 [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2712 RegConstraint<"$false = $Rd"> {
2713 let Inst{31-27} = 0b11101;
2714 let Inst{26-25} = 0b01;
2715 let Inst{24-21} = 0b0010;
2716 let Inst{20} = 0; // The S bit.
2717 let Inst{19-16} = 0b1111; // Rn
2718 let Inst{14-12} = 0b000;
2719 let Inst{7-4} = 0b0000;
2722 let isMoveImm = 1 in
2723 def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2724 IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
2725 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2726 RegConstraint<"$false = $Rd"> {
2727 let Inst{31-27} = 0b11110;
2729 let Inst{24-21} = 0b0010;
2730 let Inst{20} = 0; // The S bit.
2731 let Inst{19-16} = 0b1111; // Rn
2735 let isMoveImm = 1 in
2736 def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm_hilo16:$imm),
2738 "movw", "\t$Rd, $imm", []>,
2739 RegConstraint<"$false = $Rd"> {
2740 let Inst{31-27} = 0b11110;
2742 let Inst{24-21} = 0b0010;
2743 let Inst{20} = 0; // The S bit.
2749 let Inst{11-8} = Rd;
2750 let Inst{19-16} = imm{15-12};
2751 let Inst{26} = imm{11};
2752 let Inst{14-12} = imm{10-8};
2753 let Inst{7-0} = imm{7-0};
2756 let isMoveImm = 1 in
2757 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2758 (ins rGPR:$false, i32imm:$src, pred:$p),
2759 IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">;
2761 let isMoveImm = 1 in
2762 def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2763 IIC_iCMOVi, "mvn", ".w\t$Rd, $imm",
2764 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm,
2765 imm:$cc, CCR:$ccr))*/]>,
2766 RegConstraint<"$false = $Rd"> {
2767 let Inst{31-27} = 0b11110;
2769 let Inst{24-21} = 0b0011;
2770 let Inst{20} = 0; // The S bit.
2771 let Inst{19-16} = 0b1111; // Rn
2775 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2776 string opc, string asm, list<dag> pattern>
2777 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> {
2778 let Inst{31-27} = 0b11101;
2779 let Inst{26-25} = 0b01;
2780 let Inst{24-21} = 0b0010;
2781 let Inst{20} = 0; // The S bit.
2782 let Inst{19-16} = 0b1111; // Rn
2783 let Inst{5-4} = opcod; // Shift type.
2785 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd),
2786 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2787 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>,
2788 RegConstraint<"$false = $Rd">;
2789 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd),
2790 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2791 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>,
2792 RegConstraint<"$false = $Rd">;
2793 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd),
2794 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2795 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>,
2796 RegConstraint<"$false = $Rd">;
2797 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
2798 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2799 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
2800 RegConstraint<"$false = $Rd">;
2801 } // neverHasSideEffects
2803 //===----------------------------------------------------------------------===//
2804 // Atomic operations intrinsics
2807 // memory barriers protect the atomic sequences
2808 let hasSideEffects = 1 in {
2809 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2810 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2811 Requires<[IsThumb, HasDB]> {
2813 let Inst{31-4} = 0xf3bf8f5;
2814 let Inst{3-0} = opt;
2818 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2820 [/* For disassembly only; pattern left blank */]>,
2821 Requires<[IsThumb, HasDB]> {
2823 let Inst{31-4} = 0xf3bf8f4;
2824 let Inst{3-0} = opt;
2827 // ISB has only full system option -- for disassembly only
2828 def t2ISB : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "isb", "",
2829 [/* For disassembly only; pattern left blank */]>,
2830 Requires<[IsThumb2, HasV7]> {
2831 let Inst{31-4} = 0xf3bf8f6;
2832 let Inst{3-0} = 0b1111;
2835 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2836 InstrItinClass itin, string opc, string asm, string cstr,
2837 list<dag> pattern, bits<4> rt2 = 0b1111>
2838 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2839 let Inst{31-27} = 0b11101;
2840 let Inst{26-20} = 0b0001101;
2841 let Inst{11-8} = rt2;
2842 let Inst{7-6} = 0b01;
2843 let Inst{5-4} = opcod;
2844 let Inst{3-0} = 0b1111;
2848 let Inst{19-16} = Rn;
2849 let Inst{15-12} = Rt;
2851 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2852 InstrItinClass itin, string opc, string asm, string cstr,
2853 list<dag> pattern, bits<4> rt2 = 0b1111>
2854 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2855 let Inst{31-27} = 0b11101;
2856 let Inst{26-20} = 0b0001100;
2857 let Inst{11-8} = rt2;
2858 let Inst{7-6} = 0b01;
2859 let Inst{5-4} = opcod;
2864 let Inst{11-8} = Rd;
2865 let Inst{19-16} = Rn;
2866 let Inst{15-12} = Rt;
2869 let mayLoad = 1 in {
2870 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2871 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
2873 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2874 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
2876 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2877 Size4Bytes, NoItinerary,
2878 "ldrex", "\t$Rt, [$Rn]", "",
2880 let Inst{31-27} = 0b11101;
2881 let Inst{26-20} = 0b0000101;
2882 let Inst{11-8} = 0b1111;
2883 let Inst{7-0} = 0b00000000; // imm8 = 0
2887 let Inst{19-16} = Rn;
2888 let Inst{15-12} = Rt;
2890 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
2891 AddrModeNone, Size4Bytes, NoItinerary,
2892 "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
2895 let Inst{11-8} = Rt2;
2899 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2900 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2901 AddrModeNone, Size4Bytes, NoItinerary,
2902 "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
2903 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2904 AddrModeNone, Size4Bytes, NoItinerary,
2905 "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
2906 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2907 AddrModeNone, Size4Bytes, NoItinerary,
2908 "strex", "\t$Rd, $Rt, [$Rn]", "",
2910 let Inst{31-27} = 0b11101;
2911 let Inst{26-20} = 0b0000100;
2912 let Inst{7-0} = 0b00000000; // imm8 = 0
2917 let Inst{11-8} = Rd;
2918 let Inst{19-16} = Rn;
2919 let Inst{15-12} = Rt;
2921 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2922 (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
2923 AddrModeNone, Size4Bytes, NoItinerary,
2924 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
2927 let Inst{11-8} = Rt2;
2931 // Clear-Exclusive is for disassembly only.
2932 def t2CLREX : T2XI<(outs), (ins), NoItinerary, "clrex",
2933 [/* For disassembly only; pattern left blank */]>,
2934 Requires<[IsThumb2, HasV7]> {
2935 let Inst{31-16} = 0xf3bf;
2936 let Inst{15-14} = 0b10;
2939 let Inst{11-8} = 0b1111;
2940 let Inst{7-4} = 0b0010;
2941 let Inst{3-0} = 0b1111;
2944 //===----------------------------------------------------------------------===//
2948 // __aeabi_read_tp preserves the registers r1-r3.
2950 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
2951 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2952 "bl\t__aeabi_read_tp",
2953 [(set R0, ARMthread_pointer)]> {
2954 let Inst{31-27} = 0b11110;
2955 let Inst{15-14} = 0b11;
2960 //===----------------------------------------------------------------------===//
2961 // SJLJ Exception handling intrinsics
2962 // eh_sjlj_setjmp() is an instruction sequence to store the return
2963 // address and save #0 in R0 for the non-longjmp case.
2964 // Since by its nature we may be coming from some other function to get
2965 // here, and we're using the stack frame for the containing function to
2966 // save/restore registers, we can't keep anything live in regs across
2967 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2968 // when we get here from a longjmp(). We force everthing out of registers
2969 // except for our own input by listing the relevant registers in Defs. By
2970 // doing so, we also cause the prologue/epilogue code to actively preserve
2971 // all of the callee-saved resgisters, which is exactly what we want.
2972 // $val is a scratch register for our use.
2974 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2975 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2976 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2977 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2978 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2979 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2980 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2981 Requires<[IsThumb2, HasVFP2]>;
2985 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2986 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2987 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2988 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2989 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2990 Requires<[IsThumb2, NoVFP]>;
2994 //===----------------------------------------------------------------------===//
2995 // Control-Flow Instructions
2998 // FIXME: remove when we have a way to marking a MI with these properties.
2999 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
3001 // FIXME: Should pc be an implicit operand like PICADD, etc?
3002 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
3003 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
3004 def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
3005 reglist:$regs, variable_ops),
3007 "ldmia${p}.w\t$Rn!, $regs",
3012 let Inst{31-27} = 0b11101;
3013 let Inst{26-25} = 0b00;
3014 let Inst{24-23} = 0b01; // Increment After
3016 let Inst{21} = 1; // Writeback
3018 let Inst{19-16} = Rn;
3019 let Inst{15-0} = regs;
3022 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
3023 let isPredicable = 1 in
3024 def t2B : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br,
3026 [(br bb:$target)]> {
3027 let Inst{31-27} = 0b11110;
3028 let Inst{15-14} = 0b10;
3032 let Inst{26} = target{19};
3033 let Inst{11} = target{18};
3034 let Inst{13} = target{17};
3035 let Inst{21-16} = target{16-11};
3036 let Inst{10-0} = target{10-0};
3039 let isNotDuplicable = 1, isIndirectBranch = 1 in {
3040 def t2BR_JT : t2PseudoInst<(outs),
3041 (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id),
3042 SizeSpecial, IIC_Br,
3043 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
3045 // FIXME: Add a non-pc based case that can be predicated.
3046 def t2TBB_JT : t2PseudoInst<(outs),
3047 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3048 SizeSpecial, IIC_Br, []>;
3050 def t2TBH_JT : t2PseudoInst<(outs),
3051 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3052 SizeSpecial, IIC_Br, []>;
3054 def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3055 "tbb", "\t[$Rn, $Rm]", []> {
3058 let Inst{31-20} = 0b111010001101;
3059 let Inst{19-16} = Rn;
3060 let Inst{15-5} = 0b11110000000;
3061 let Inst{4} = 0; // B form
3065 def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3066 "tbh", "\t[$Rn, $Rm, lsl #1]", []> {
3069 let Inst{31-20} = 0b111010001101;
3070 let Inst{19-16} = Rn;
3071 let Inst{15-5} = 0b11110000000;
3072 let Inst{4} = 1; // H form
3075 } // isNotDuplicable, isIndirectBranch
3077 } // isBranch, isTerminator, isBarrier
3079 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
3080 // a two-value operand where a dag node expects two operands. :(
3081 let isBranch = 1, isTerminator = 1 in
3082 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3084 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
3085 let Inst{31-27} = 0b11110;
3086 let Inst{15-14} = 0b10;
3090 let Inst{25-22} = p;
3093 let Inst{26} = target{20};
3094 let Inst{11} = target{19};
3095 let Inst{13} = target{18};
3096 let Inst{21-16} = target{17-12};
3097 let Inst{10-0} = target{11-1};
3102 let Defs = [ITSTATE] in
3103 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3104 AddrModeNone, Size2Bytes, IIC_iALUx,
3105 "it$mask\t$cc", "", []> {
3106 // 16-bit instruction.
3107 let Inst{31-16} = 0x0000;
3108 let Inst{15-8} = 0b10111111;
3113 let Inst{3-0} = mask;
3116 // Branch and Exchange Jazelle -- for disassembly only
3118 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
3119 [/* For disassembly only; pattern left blank */]> {
3120 let Inst{31-27} = 0b11110;
3122 let Inst{25-20} = 0b111100;
3123 let Inst{15-14} = 0b10;
3127 let Inst{19-16} = func;
3130 // Change Processor State is a system instruction -- for disassembly and
3132 // FIXME: Since the asm parser has currently no clean way to handle optional
3133 // operands, create 3 versions of the same instruction. Once there's a clean
3134 // framework to represent optional operands, change this behavior.
3135 class t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary,
3136 !strconcat("cps", asm_op),
3137 [/* For disassembly only; pattern left blank */]> {
3143 let Inst{31-27} = 0b11110;
3145 let Inst{25-20} = 0b111010;
3146 let Inst{19-16} = 0b1111;
3147 let Inst{15-14} = 0b10;
3149 let Inst{10-9} = imod;
3151 let Inst{7-5} = iflags;
3152 let Inst{4-0} = mode;
3156 def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
3157 "$imod.w\t$iflags, $mode">;
3158 let mode = 0, M = 0 in
3159 def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags),
3160 "$imod.w\t$iflags">;
3161 let imod = 0, iflags = 0, M = 1 in
3162 def t2CPS1p : t2CPS<(ins i32imm:$mode), "\t$mode">;
3164 // A6.3.4 Branches and miscellaneous control
3165 // Table A6-14 Change Processor State, and hint instructions
3166 // Helper class for disassembly only.
3167 class T2I_hint<bits<8> op7_0, string opc, string asm>
3168 : T2I<(outs), (ins), NoItinerary, opc, asm,
3169 [/* For disassembly only; pattern left blank */]> {
3170 let Inst{31-20} = 0xf3a;
3171 let Inst{19-16} = 0b1111;
3172 let Inst{15-14} = 0b10;
3174 let Inst{10-8} = 0b000;
3175 let Inst{7-0} = op7_0;
3178 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
3179 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
3180 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
3181 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
3182 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
3184 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
3185 [/* For disassembly only; pattern left blank */]> {
3186 let Inst{31-20} = 0xf3a;
3187 let Inst{15-14} = 0b10;
3189 let Inst{10-8} = 0b000;
3190 let Inst{7-4} = 0b1111;
3193 let Inst{3-0} = opt;
3196 // Secure Monitor Call is a system instruction -- for disassembly only
3197 // Option = Inst{19-16}
3198 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
3199 [/* For disassembly only; pattern left blank */]> {
3200 let Inst{31-27} = 0b11110;
3201 let Inst{26-20} = 0b1111111;
3202 let Inst{15-12} = 0b1000;
3205 let Inst{19-16} = opt;
3208 class T2SRS<bits<12> op31_20,
3209 dag oops, dag iops, InstrItinClass itin,
3210 string opc, string asm, list<dag> pattern>
3211 : T2I<oops, iops, itin, opc, asm, pattern> {
3212 let Inst{31-20} = op31_20{11-0};
3215 let Inst{4-0} = mode{4-0};
3218 // Store Return State is a system instruction -- for disassembly only
3219 def t2SRSDBW : T2SRS<0b111010000010,
3220 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
3221 [/* For disassembly only; pattern left blank */]>;
3222 def t2SRSDB : T2SRS<0b111010000000,
3223 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
3224 [/* For disassembly only; pattern left blank */]>;
3225 def t2SRSIAW : T2SRS<0b111010011010,
3226 (outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
3227 [/* For disassembly only; pattern left blank */]>;
3228 def t2SRSIA : T2SRS<0b111010011000,
3229 (outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
3230 [/* For disassembly only; pattern left blank */]>;
3232 // Return From Exception is a system instruction -- for disassembly only
3234 class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3235 string opc, string asm, list<dag> pattern>
3236 : T2I<oops, iops, itin, opc, asm, pattern> {
3237 let Inst{31-20} = op31_20{11-0};
3240 let Inst{19-16} = Rn;
3243 def t2RFEDBW : T2RFE<0b111010000011,
3244 (outs), (ins rGPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3245 [/* For disassembly only; pattern left blank */]>;
3246 def t2RFEDB : T2RFE<0b111010000001,
3247 (outs), (ins rGPR:$Rn), NoItinerary, "rfeab", "\t$Rn",
3248 [/* For disassembly only; pattern left blank */]>;
3249 def t2RFEIAW : T2RFE<0b111010011011,
3250 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3251 [/* For disassembly only; pattern left blank */]>;
3252 def t2RFEIA : T2RFE<0b111010011001,
3253 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3254 [/* For disassembly only; pattern left blank */]>;
3256 //===----------------------------------------------------------------------===//
3257 // Non-Instruction Patterns
3260 // 32-bit immediate using movw + movt.
3261 // This is a single pseudo instruction to make it re-materializable.
3262 // FIXME: Remove this when we can do generalized remat.
3263 let isReMaterializable = 1, isMoveImm = 1 in
3264 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3265 [(set rGPR:$dst, (i32 imm:$src))]>,
3266 Requires<[IsThumb, HasV6T2]>;
3268 // Pseudo instruction that combines movw + movt + add pc (if pic).
3269 // It also makes it possible to rematerialize the instructions.
3270 // FIXME: Remove this when we can do generalized remat and when machine licm
3271 // can properly the instructions.
3272 let isReMaterializable = 1 in {
3273 def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3275 [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3276 Requires<[IsThumb2, UseMovt]>;
3278 def t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3280 [(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3281 Requires<[IsThumb2, UseMovt]>;
3284 // ConstantPool, GlobalAddress, and JumpTable
3285 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
3286 Requires<[IsThumb2, DontUseMovt]>;
3287 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
3288 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3289 Requires<[IsThumb2, UseMovt]>;
3291 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3292 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
3294 // Pseudo instruction that combines ldr from constpool and add pc. This should
3295 // be expanded into two instructions late to allow if-conversion and
3297 let canFoldAsLoad = 1, isReMaterializable = 1 in
3298 def t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3300 [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3302 Requires<[IsThumb2]>;
3304 //===----------------------------------------------------------------------===//
3305 // Move between special register and ARM core register -- for disassembly only
3308 class T2SpecialReg<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3309 dag oops, dag iops, InstrItinClass itin,
3310 string opc, string asm, list<dag> pattern>
3311 : T2I<oops, iops, itin, opc, asm, pattern> {
3312 let Inst{31-20} = op31_20{11-0};
3313 let Inst{15-14} = op15_14{1-0};
3314 let Inst{12} = op12{0};
3317 class T2MRS<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3318 dag oops, dag iops, InstrItinClass itin,
3319 string opc, string asm, list<dag> pattern>
3320 : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3322 let Inst{11-8} = Rd;
3323 let Inst{19-16} = 0b1111;
3326 def t2MRS : T2MRS<0b111100111110, 0b10, 0,
3327 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3328 [/* For disassembly only; pattern left blank */]>;
3329 def t2MRSsys : T2MRS<0b111100111111, 0b10, 0,
3330 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
3331 [/* For disassembly only; pattern left blank */]>;
3333 // Move from ARM core register to Special Register
3335 // No need to have both system and application versions, the encodings are the
3336 // same and the assembly parser has no way to distinguish between them. The mask
3337 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3338 // the mask with the fields to be accessed in the special register.
3339 def t2MSR : T2SpecialReg<0b111100111000 /* op31-20 */, 0b10 /* op15-14 */,
3340 0 /* op12 */, (outs), (ins msr_mask:$mask, rGPR:$Rn),
3341 NoItinerary, "msr", "\t$mask, $Rn",
3342 [/* For disassembly only; pattern left blank */]> {
3345 let Inst{19-16} = Rn;
3346 let Inst{20} = mask{4}; // R Bit
3348 let Inst{11-8} = mask{3-0};
3351 //===----------------------------------------------------------------------===//
3352 // Move between coprocessor and ARM core register -- for disassembly only
3355 class t2MovRCopro<string opc, bit direction>
3356 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
3357 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3358 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3359 [/* For disassembly only; pattern left blank */]> {
3360 let Inst{27-24} = 0b1110;
3361 let Inst{20} = direction;
3371 let Inst{15-12} = Rt;
3372 let Inst{11-8} = cop;
3373 let Inst{23-21} = opc1;
3374 let Inst{7-5} = opc2;
3375 let Inst{3-0} = CRm;
3376 let Inst{19-16} = CRn;
3379 def t2MCR2 : t2MovRCopro<"mcr2", 0 /* from ARM core register to coprocessor */>;
3380 def t2MRC2 : t2MovRCopro<"mrc2", 1 /* from coprocessor to ARM core register */>;
3382 class t2MovRRCopro<string opc, bit direction>
3383 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3384 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3385 [/* For disassembly only; pattern left blank */]> {
3386 let Inst{27-24} = 0b1100;
3387 let Inst{23-21} = 0b010;
3388 let Inst{20} = direction;
3396 let Inst{15-12} = Rt;
3397 let Inst{19-16} = Rt2;
3398 let Inst{11-8} = cop;
3399 let Inst{7-4} = opc1;
3400 let Inst{3-0} = CRm;
3403 def t2MCRR2 : t2MovRRCopro<"mcrr2",
3404 0 /* from ARM core register to coprocessor */>;
3405 def t2MRRC2 : t2MovRRCopro<"mrrc2",
3406 1 /* from coprocessor to ARM core register */>;
3408 //===----------------------------------------------------------------------===//
3409 // Other Coprocessor Instructions. For disassembly only.
3412 def t2CDP2 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
3413 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3414 "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3415 [/* For disassembly only; pattern left blank */]> {
3416 let Inst{27-24} = 0b1110;
3425 let Inst{3-0} = CRm;
3427 let Inst{7-5} = opc2;
3428 let Inst{11-8} = cop;
3429 let Inst{15-12} = CRd;
3430 let Inst{19-16} = CRn;
3431 let Inst{23-20} = opc1;