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 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
65 def imm1_31 : PatLeaf<(i32 imm), [{
66 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
69 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
70 def imm0_4095 : Operand<i32>,
72 return (uint32_t)N->getZExtValue() < 4096;
75 def imm0_4095_neg : PatLeaf<(i32 imm), [{
76 return (uint32_t)(-N->getZExtValue()) < 4096;
79 def imm0_255_neg : PatLeaf<(i32 imm), [{
80 return (uint32_t)(-N->getZExtValue()) < 255;
83 def imm0_255_not : PatLeaf<(i32 imm), [{
84 return (uint32_t)(~N->getZExtValue()) < 255;
87 // Define Thumb2 specific addressing modes.
89 // t2addrmode_imm12 := reg + imm12
90 def t2addrmode_imm12 : Operand<i32>,
91 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
92 let PrintMethod = "printAddrModeImm12Operand";
93 let EncoderMethod = "getAddrModeImm12OpValue";
94 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
95 let ParserMatchClass = MemMode5AsmOperand;
98 // t2ldrlabel := imm12
99 def t2ldrlabel : Operand<i32> {
100 let EncoderMethod = "getAddrModeImm12OpValue";
104 // ADR instruction labels.
105 def t2adrlabel : Operand<i32> {
106 let EncoderMethod = "getT2AdrLabelOpValue";
110 // t2addrmode_imm8 := reg +/- imm8
111 def t2addrmode_imm8 : Operand<i32>,
112 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
113 let PrintMethod = "printT2AddrModeImm8Operand";
114 let EncoderMethod = "getT2AddrModeImm8OpValue";
115 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
116 let ParserMatchClass = MemMode5AsmOperand;
119 def t2am_imm8_offset : Operand<i32>,
120 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
121 [], [SDNPWantRoot]> {
122 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
123 let EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
124 let ParserMatchClass = MemMode5AsmOperand;
127 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
128 def t2addrmode_imm8s4 : Operand<i32> {
129 let PrintMethod = "printT2AddrModeImm8s4Operand";
130 let EncoderMethod = "getT2AddrModeImm8s4OpValue";
131 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
132 let ParserMatchClass = MemMode5AsmOperand;
135 def t2am_imm8s4_offset : Operand<i32> {
136 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
139 // t2addrmode_so_reg := reg + (reg << imm2)
140 def t2addrmode_so_reg : Operand<i32>,
141 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
142 let PrintMethod = "printT2AddrModeSoRegOperand";
143 let EncoderMethod = "getT2AddrModeSORegOpValue";
144 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
145 let ParserMatchClass = MemMode5AsmOperand;
149 //===----------------------------------------------------------------------===//
150 // Multiclass helpers...
154 class T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
155 string opc, string asm, list<dag> pattern>
156 : T2I<oops, iops, itin, opc, asm, pattern> {
161 let Inst{26} = imm{11};
162 let Inst{14-12} = imm{10-8};
163 let Inst{7-0} = imm{7-0};
167 class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
168 string opc, string asm, list<dag> pattern>
169 : T2sI<oops, iops, itin, opc, asm, pattern> {
175 let Inst{26} = imm{11};
176 let Inst{14-12} = imm{10-8};
177 let Inst{7-0} = imm{7-0};
180 class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin,
181 string opc, string asm, list<dag> pattern>
182 : T2I<oops, iops, itin, opc, asm, pattern> {
186 let Inst{19-16} = Rn;
187 let Inst{26} = imm{11};
188 let Inst{14-12} = imm{10-8};
189 let Inst{7-0} = imm{7-0};
193 class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
194 string opc, string asm, list<dag> pattern>
195 : T2I<oops, iops, itin, opc, asm, pattern> {
200 let Inst{3-0} = ShiftedRm{3-0};
201 let Inst{5-4} = ShiftedRm{6-5};
202 let Inst{14-12} = ShiftedRm{11-9};
203 let Inst{7-6} = ShiftedRm{8-7};
206 class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
207 string opc, string asm, list<dag> pattern>
208 : T2sI<oops, iops, itin, opc, asm, pattern> {
213 let Inst{3-0} = ShiftedRm{3-0};
214 let Inst{5-4} = ShiftedRm{6-5};
215 let Inst{14-12} = ShiftedRm{11-9};
216 let Inst{7-6} = ShiftedRm{8-7};
219 class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin,
220 string opc, string asm, list<dag> pattern>
221 : T2I<oops, iops, itin, opc, asm, pattern> {
225 let Inst{19-16} = Rn;
226 let Inst{3-0} = ShiftedRm{3-0};
227 let Inst{5-4} = ShiftedRm{6-5};
228 let Inst{14-12} = ShiftedRm{11-9};
229 let Inst{7-6} = ShiftedRm{8-7};
232 class T2TwoReg<dag oops, dag iops, InstrItinClass itin,
233 string opc, string asm, list<dag> pattern>
234 : T2I<oops, iops, itin, opc, asm, pattern> {
242 class T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
243 string opc, string asm, list<dag> pattern>
244 : T2sI<oops, iops, itin, opc, asm, pattern> {
252 class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin,
253 string opc, string asm, list<dag> pattern>
254 : T2I<oops, iops, itin, opc, asm, pattern> {
258 let Inst{19-16} = Rn;
263 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
264 string opc, string asm, list<dag> pattern>
265 : T2I<oops, iops, itin, opc, asm, pattern> {
271 let Inst{19-16} = Rn;
272 let Inst{26} = imm{11};
273 let Inst{14-12} = imm{10-8};
274 let Inst{7-0} = imm{7-0};
277 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
278 string opc, string asm, list<dag> pattern>
279 : T2sI<oops, iops, itin, opc, asm, pattern> {
285 let Inst{19-16} = Rn;
286 let Inst{26} = imm{11};
287 let Inst{14-12} = imm{10-8};
288 let Inst{7-0} = imm{7-0};
291 class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
292 string opc, string asm, list<dag> pattern>
293 : T2I<oops, iops, itin, opc, asm, pattern> {
300 let Inst{14-12} = imm{4-2};
301 let Inst{7-6} = imm{1-0};
304 class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
305 string opc, string asm, list<dag> pattern>
306 : T2sI<oops, iops, itin, opc, asm, pattern> {
313 let Inst{14-12} = imm{4-2};
314 let Inst{7-6} = imm{1-0};
317 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
318 string opc, string asm, list<dag> pattern>
319 : T2I<oops, iops, itin, opc, asm, pattern> {
325 let Inst{19-16} = Rn;
329 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
330 string opc, string asm, list<dag> pattern>
331 : T2sI<oops, iops, itin, opc, asm, pattern> {
337 let Inst{19-16} = Rn;
341 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
342 string opc, string asm, list<dag> pattern>
343 : T2I<oops, iops, itin, opc, asm, pattern> {
349 let Inst{19-16} = Rn;
350 let Inst{3-0} = ShiftedRm{3-0};
351 let Inst{5-4} = ShiftedRm{6-5};
352 let Inst{14-12} = ShiftedRm{11-9};
353 let Inst{7-6} = ShiftedRm{8-7};
356 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
357 string opc, string asm, list<dag> pattern>
358 : T2sI<oops, iops, itin, opc, asm, pattern> {
364 let Inst{19-16} = Rn;
365 let Inst{3-0} = ShiftedRm{3-0};
366 let Inst{5-4} = ShiftedRm{6-5};
367 let Inst{14-12} = ShiftedRm{11-9};
368 let Inst{7-6} = ShiftedRm{8-7};
371 class T2FourReg<dag oops, dag iops, InstrItinClass itin,
372 string opc, string asm, list<dag> pattern>
373 : T2I<oops, iops, itin, opc, asm, pattern> {
379 let Inst{19-16} = Rn;
380 let Inst{15-12} = Ra;
385 class T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
386 dag oops, dag iops, InstrItinClass itin,
387 string opc, string asm, list<dag> pattern>
388 : T2I<oops, iops, itin, opc, asm, pattern> {
394 let Inst{31-23} = 0b111110111;
395 let Inst{22-20} = opc22_20;
396 let Inst{19-16} = Rn;
397 let Inst{15-12} = RdLo;
398 let Inst{11-8} = RdHi;
399 let Inst{7-4} = opc7_4;
404 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
405 /// unary operation that produces a value. These are predicable and can be
406 /// changed to modify CPSR.
407 multiclass T2I_un_irs<bits<4> opcod, string opc,
408 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
409 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
411 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
413 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> {
414 let isAsCheapAsAMove = Cheap;
415 let isReMaterializable = ReMat;
416 let Inst{31-27} = 0b11110;
418 let Inst{24-21} = opcod;
419 let Inst{19-16} = 0b1111; // Rn
423 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
425 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
426 let Inst{31-27} = 0b11101;
427 let Inst{26-25} = 0b01;
428 let Inst{24-21} = opcod;
429 let Inst{19-16} = 0b1111; // Rn
430 let Inst{14-12} = 0b000; // imm3
431 let Inst{7-6} = 0b00; // imm2
432 let Inst{5-4} = 0b00; // type
435 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
436 opc, ".w\t$Rd, $ShiftedRm",
437 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> {
438 let Inst{31-27} = 0b11101;
439 let Inst{26-25} = 0b01;
440 let Inst{24-21} = opcod;
441 let Inst{19-16} = 0b1111; // Rn
445 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
446 /// binary operation that produces a value. These are predicable and can be
447 /// changed to modify CPSR.
448 multiclass T2I_bin_irs<bits<4> opcod, string opc,
449 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
450 PatFrag opnode, bit Commutable = 0, string wide = ""> {
452 def ri : T2sTwoRegImm<
453 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
454 opc, "\t$Rd, $Rn, $imm",
455 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
456 let Inst{31-27} = 0b11110;
458 let Inst{24-21} = opcod;
462 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
463 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
464 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
465 let isCommutable = Commutable;
466 let Inst{31-27} = 0b11101;
467 let Inst{26-25} = 0b01;
468 let Inst{24-21} = opcod;
469 let Inst{14-12} = 0b000; // imm3
470 let Inst{7-6} = 0b00; // imm2
471 let Inst{5-4} = 0b00; // type
474 def rs : T2sTwoRegShiftedReg<
475 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
476 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
477 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
478 let Inst{31-27} = 0b11101;
479 let Inst{26-25} = 0b01;
480 let Inst{24-21} = opcod;
484 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
485 // the ".w" prefix to indicate that they are wide.
486 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
487 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
488 PatFrag opnode, bit Commutable = 0> :
489 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
491 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
492 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
493 /// it is equivalent to the T2I_bin_irs counterpart.
494 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
496 def ri : T2sTwoRegImm<
497 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
498 opc, ".w\t$Rd, $Rn, $imm",
499 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
500 let Inst{31-27} = 0b11110;
502 let Inst{24-21} = opcod;
506 def rr : T2sThreeReg<
507 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
508 opc, "\t$Rd, $Rn, $Rm",
509 [/* For disassembly only; pattern left blank */]> {
510 let Inst{31-27} = 0b11101;
511 let Inst{26-25} = 0b01;
512 let Inst{24-21} = opcod;
513 let Inst{14-12} = 0b000; // imm3
514 let Inst{7-6} = 0b00; // imm2
515 let Inst{5-4} = 0b00; // type
518 def rs : T2sTwoRegShiftedReg<
519 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
520 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
521 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
522 let Inst{31-27} = 0b11101;
523 let Inst{26-25} = 0b01;
524 let Inst{24-21} = opcod;
528 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
529 /// instruction modifies the CPSR register.
530 let isCodeGenOnly = 1, Defs = [CPSR] in {
531 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
532 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
533 PatFrag opnode, bit Commutable = 0> {
535 def ri : T2TwoRegImm<
536 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
537 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
538 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
539 let Inst{31-27} = 0b11110;
541 let Inst{24-21} = opcod;
542 let Inst{20} = 1; // The S bit.
547 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
548 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
549 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
550 let isCommutable = Commutable;
551 let Inst{31-27} = 0b11101;
552 let Inst{26-25} = 0b01;
553 let Inst{24-21} = opcod;
554 let Inst{20} = 1; // The S bit.
555 let Inst{14-12} = 0b000; // imm3
556 let Inst{7-6} = 0b00; // imm2
557 let Inst{5-4} = 0b00; // type
560 def rs : T2TwoRegShiftedReg<
561 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
562 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
563 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
564 let Inst{31-27} = 0b11101;
565 let Inst{26-25} = 0b01;
566 let Inst{24-21} = opcod;
567 let Inst{20} = 1; // The S bit.
572 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
573 /// patterns for a binary operation that produces a value.
574 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
575 bit Commutable = 0> {
577 // The register-immediate version is re-materializable. This is useful
578 // in particular for taking the address of a local.
579 let isReMaterializable = 1 in {
580 def ri : T2sTwoRegImm<
581 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
582 opc, ".w\t$Rd, $Rn, $imm",
583 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
584 let Inst{31-27} = 0b11110;
587 let Inst{23-21} = op23_21;
593 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
594 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
595 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
599 let Inst{31-27} = 0b11110;
600 let Inst{26} = imm{11};
601 let Inst{25-24} = 0b10;
602 let Inst{23-21} = op23_21;
603 let Inst{20} = 0; // The S bit.
604 let Inst{19-16} = Rn;
606 let Inst{14-12} = imm{10-8};
608 let Inst{7-0} = imm{7-0};
611 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
612 opc, ".w\t$Rd, $Rn, $Rm",
613 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
614 let isCommutable = Commutable;
615 let Inst{31-27} = 0b11101;
616 let Inst{26-25} = 0b01;
618 let Inst{23-21} = op23_21;
619 let Inst{14-12} = 0b000; // imm3
620 let Inst{7-6} = 0b00; // imm2
621 let Inst{5-4} = 0b00; // type
624 def rs : T2sTwoRegShiftedReg<
625 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
626 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
627 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
628 let Inst{31-27} = 0b11101;
629 let Inst{26-25} = 0b01;
631 let Inst{23-21} = op23_21;
635 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
636 /// for a binary operation that produces a value and use the carry
637 /// bit. It's not predicable.
638 let Uses = [CPSR] in {
639 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
640 bit Commutable = 0> {
642 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
643 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
644 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
645 Requires<[IsThumb2]> {
646 let Inst{31-27} = 0b11110;
648 let Inst{24-21} = opcod;
652 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
653 opc, ".w\t$Rd, $Rn, $Rm",
654 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
655 Requires<[IsThumb2]> {
656 let isCommutable = Commutable;
657 let Inst{31-27} = 0b11101;
658 let Inst{26-25} = 0b01;
659 let Inst{24-21} = opcod;
660 let Inst{14-12} = 0b000; // imm3
661 let Inst{7-6} = 0b00; // imm2
662 let Inst{5-4} = 0b00; // type
665 def rs : T2sTwoRegShiftedReg<
666 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
667 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
668 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
669 Requires<[IsThumb2]> {
670 let Inst{31-27} = 0b11101;
671 let Inst{26-25} = 0b01;
672 let Inst{24-21} = opcod;
676 // Carry setting variants
677 let isCodeGenOnly = 1, Defs = [CPSR] in {
678 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
679 bit Commutable = 0> {
681 def ri : T2sTwoRegImm<
682 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
683 opc, "\t$Rd, $Rn, $imm",
684 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
685 Requires<[IsThumb2]> {
686 let Inst{31-27} = 0b11110;
688 let Inst{24-21} = opcod;
689 let Inst{20} = 1; // The S bit.
693 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
694 opc, ".w\t$Rd, $Rn, $Rm",
695 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
696 Requires<[IsThumb2]> {
697 let isCommutable = Commutable;
698 let Inst{31-27} = 0b11101;
699 let Inst{26-25} = 0b01;
700 let Inst{24-21} = opcod;
701 let Inst{20} = 1; // The S bit.
702 let Inst{14-12} = 0b000; // imm3
703 let Inst{7-6} = 0b00; // imm2
704 let Inst{5-4} = 0b00; // type
707 def rs : T2sTwoRegShiftedReg<
708 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
709 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
710 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
711 Requires<[IsThumb2]> {
712 let Inst{31-27} = 0b11101;
713 let Inst{26-25} = 0b01;
714 let Inst{24-21} = opcod;
715 let Inst{20} = 1; // The S bit.
721 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
722 /// version is not needed since this is only for codegen.
723 let isCodeGenOnly = 1, Defs = [CPSR] in {
724 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
726 def ri : T2TwoRegImm<
727 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
728 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
729 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
730 let Inst{31-27} = 0b11110;
732 let Inst{24-21} = opcod;
733 let Inst{20} = 1; // The S bit.
737 def rs : T2TwoRegShiftedReg<
738 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
739 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
740 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
741 let Inst{31-27} = 0b11101;
742 let Inst{26-25} = 0b01;
743 let Inst{24-21} = opcod;
744 let Inst{20} = 1; // The S bit.
749 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
750 // rotate operation that produces a value.
751 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
753 def ri : T2sTwoRegShiftImm<
754 (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi,
755 opc, ".w\t$Rd, $Rm, $imm",
756 [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> {
757 let Inst{31-27} = 0b11101;
758 let Inst{26-21} = 0b010010;
759 let Inst{19-16} = 0b1111; // Rn
760 let Inst{5-4} = opcod;
763 def rr : T2sThreeReg<
764 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr,
765 opc, ".w\t$Rd, $Rn, $Rm",
766 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
767 let Inst{31-27} = 0b11111;
768 let Inst{26-23} = 0b0100;
769 let Inst{22-21} = opcod;
770 let Inst{15-12} = 0b1111;
771 let Inst{7-4} = 0b0000;
775 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
776 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
777 /// a explicit result, only implicitly set CPSR.
778 let isCompare = 1, Defs = [CPSR] in {
779 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
780 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
783 def ri : T2OneRegCmpImm<
784 (outs), (ins GPR:$Rn, t2_so_imm:$imm), iii,
785 opc, ".w\t$Rn, $imm",
786 [(opnode GPR:$Rn, t2_so_imm:$imm)]> {
787 let Inst{31-27} = 0b11110;
789 let Inst{24-21} = opcod;
790 let Inst{20} = 1; // The S bit.
792 let Inst{11-8} = 0b1111; // Rd
795 def rr : T2TwoRegCmp<
796 (outs), (ins GPR:$lhs, rGPR:$rhs), iir,
797 opc, ".w\t$lhs, $rhs",
798 [(opnode GPR:$lhs, rGPR:$rhs)]> {
799 let Inst{31-27} = 0b11101;
800 let Inst{26-25} = 0b01;
801 let Inst{24-21} = opcod;
802 let Inst{20} = 1; // The S bit.
803 let Inst{14-12} = 0b000; // imm3
804 let Inst{11-8} = 0b1111; // Rd
805 let Inst{7-6} = 0b00; // imm2
806 let Inst{5-4} = 0b00; // type
809 def rs : T2OneRegCmpShiftedReg<
810 (outs), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
811 opc, ".w\t$Rn, $ShiftedRm",
812 [(opnode GPR:$Rn, t2_so_reg:$ShiftedRm)]> {
813 let Inst{31-27} = 0b11101;
814 let Inst{26-25} = 0b01;
815 let Inst{24-21} = opcod;
816 let Inst{20} = 1; // The S bit.
817 let Inst{11-8} = 0b1111; // Rd
822 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
823 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
824 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
825 def i12 : T2Ii12<(outs GPR:$Rt), (ins t2addrmode_imm12:$addr), iii,
826 opc, ".w\t$Rt, $addr",
827 [(set GPR:$Rt, (opnode t2addrmode_imm12:$addr))]> {
828 let Inst{31-27} = 0b11111;
829 let Inst{26-25} = 0b00;
830 let Inst{24} = signed;
832 let Inst{22-21} = opcod;
833 let Inst{20} = 1; // load
836 let Inst{15-12} = Rt;
839 let Inst{19-16} = addr{16-13}; // Rn
840 let Inst{23} = addr{12}; // U
841 let Inst{11-0} = addr{11-0}; // imm
843 def i8 : T2Ii8 <(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), iii,
845 [(set GPR:$Rt, (opnode t2addrmode_imm8:$addr))]> {
846 let Inst{31-27} = 0b11111;
847 let Inst{26-25} = 0b00;
848 let Inst{24} = signed;
850 let Inst{22-21} = opcod;
851 let Inst{20} = 1; // load
853 // Offset: index==TRUE, wback==FALSE
854 let Inst{10} = 1; // The P bit.
855 let Inst{8} = 0; // The W bit.
858 let Inst{15-12} = Rt;
861 let Inst{19-16} = addr{12-9}; // Rn
862 let Inst{9} = addr{8}; // U
863 let Inst{7-0} = addr{7-0}; // imm
865 def s : T2Iso <(outs GPR:$Rt), (ins t2addrmode_so_reg:$addr), iis,
866 opc, ".w\t$Rt, $addr",
867 [(set GPR:$Rt, (opnode t2addrmode_so_reg:$addr))]> {
868 let Inst{31-27} = 0b11111;
869 let Inst{26-25} = 0b00;
870 let Inst{24} = signed;
872 let Inst{22-21} = opcod;
873 let Inst{20} = 1; // load
874 let Inst{11-6} = 0b000000;
877 let Inst{15-12} = Rt;
880 let Inst{19-16} = addr{9-6}; // Rn
881 let Inst{3-0} = addr{5-2}; // Rm
882 let Inst{5-4} = addr{1-0}; // imm
885 // FIXME: Is the pci variant actually needed?
886 def pci : T2Ipc <(outs GPR:$Rt), (ins t2ldrlabel:$addr), iii,
887 opc, ".w\t$Rt, $addr",
888 [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
889 let isReMaterializable = 1;
890 let Inst{31-27} = 0b11111;
891 let Inst{26-25} = 0b00;
892 let Inst{24} = signed;
893 let Inst{23} = ?; // add = (U == '1')
894 let Inst{22-21} = opcod;
895 let Inst{20} = 1; // load
896 let Inst{19-16} = 0b1111; // Rn
899 let Inst{15-12} = Rt{3-0};
900 let Inst{11-0} = addr{11-0};
904 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
905 multiclass T2I_st<bits<2> opcod, string opc,
906 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
907 def i12 : T2Ii12<(outs), (ins GPR:$Rt, t2addrmode_imm12:$addr), iii,
908 opc, ".w\t$Rt, $addr",
909 [(opnode GPR:$Rt, t2addrmode_imm12:$addr)]> {
910 let Inst{31-27} = 0b11111;
911 let Inst{26-23} = 0b0001;
912 let Inst{22-21} = opcod;
913 let Inst{20} = 0; // !load
916 let Inst{15-12} = Rt;
919 let Inst{19-16} = addr{16-13}; // Rn
920 let Inst{23} = addr{12}; // U
921 let Inst{11-0} = addr{11-0}; // imm
923 def i8 : T2Ii8 <(outs), (ins GPR:$Rt, t2addrmode_imm8:$addr), iii,
925 [(opnode GPR:$Rt, t2addrmode_imm8:$addr)]> {
926 let Inst{31-27} = 0b11111;
927 let Inst{26-23} = 0b0000;
928 let Inst{22-21} = opcod;
929 let Inst{20} = 0; // !load
931 // Offset: index==TRUE, wback==FALSE
932 let Inst{10} = 1; // The P bit.
933 let Inst{8} = 0; // The W bit.
936 let Inst{15-12} = Rt;
939 let Inst{19-16} = addr{12-9}; // Rn
940 let Inst{9} = addr{8}; // U
941 let Inst{7-0} = addr{7-0}; // imm
943 def s : T2Iso <(outs), (ins GPR:$Rt, t2addrmode_so_reg:$addr), iis,
944 opc, ".w\t$Rt, $addr",
945 [(opnode GPR:$Rt, t2addrmode_so_reg:$addr)]> {
946 let Inst{31-27} = 0b11111;
947 let Inst{26-23} = 0b0000;
948 let Inst{22-21} = opcod;
949 let Inst{20} = 0; // !load
950 let Inst{11-6} = 0b000000;
953 let Inst{15-12} = Rt;
956 let Inst{19-16} = addr{9-6}; // Rn
957 let Inst{3-0} = addr{5-2}; // Rm
958 let Inst{5-4} = addr{1-0}; // imm
962 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
963 /// register and one whose operand is a register rotated by 8/16/24.
964 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
965 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
967 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
968 let Inst{31-27} = 0b11111;
969 let Inst{26-23} = 0b0100;
970 let Inst{22-20} = opcod;
971 let Inst{19-16} = 0b1111; // Rn
972 let Inst{15-12} = 0b1111;
974 let Inst{5-4} = 0b00; // rotate
976 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
977 opc, ".w\t$Rd, $Rm, ror $rot",
978 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> {
979 let Inst{31-27} = 0b11111;
980 let Inst{26-23} = 0b0100;
981 let Inst{22-20} = opcod;
982 let Inst{19-16} = 0b1111; // Rn
983 let Inst{15-12} = 0b1111;
987 let Inst{5-4} = rot{1-0}; // rotate
991 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
992 multiclass T2I_ext_rrot_uxtb16<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 Requires<[HasT2ExtractPack, IsThumb2]> {
997 let Inst{31-27} = 0b11111;
998 let Inst{26-23} = 0b0100;
999 let Inst{22-20} = opcod;
1000 let Inst{19-16} = 0b1111; // Rn
1001 let Inst{15-12} = 0b1111;
1003 let Inst{5-4} = 0b00; // rotate
1005 def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot),
1006 IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot",
1007 [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1008 Requires<[HasT2ExtractPack, IsThumb2]> {
1009 let Inst{31-27} = 0b11111;
1010 let Inst{26-23} = 0b0100;
1011 let Inst{22-20} = opcod;
1012 let Inst{19-16} = 0b1111; // Rn
1013 let Inst{15-12} = 0b1111;
1017 let Inst{5-4} = rot{1-0}; // rotate
1021 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
1023 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
1024 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
1025 opc, "\t$Rd, $Rm", []> {
1026 let Inst{31-27} = 0b11111;
1027 let Inst{26-23} = 0b0100;
1028 let Inst{22-20} = opcod;
1029 let Inst{19-16} = 0b1111; // Rn
1030 let Inst{15-12} = 0b1111;
1032 let Inst{5-4} = 0b00; // rotate
1034 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
1035 opc, "\t$Rd, $Rm, ror $rot", []> {
1036 let Inst{31-27} = 0b11111;
1037 let Inst{26-23} = 0b0100;
1038 let Inst{22-20} = opcod;
1039 let Inst{19-16} = 0b1111; // Rn
1040 let Inst{15-12} = 0b1111;
1044 let Inst{5-4} = rot{1-0}; // rotate
1048 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
1049 /// register and one whose operand is a register rotated by 8/16/24.
1050 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
1051 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1052 opc, "\t$Rd, $Rn, $Rm",
1053 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
1054 Requires<[HasT2ExtractPack, IsThumb2]> {
1055 let Inst{31-27} = 0b11111;
1056 let Inst{26-23} = 0b0100;
1057 let Inst{22-20} = opcod;
1058 let Inst{15-12} = 0b1111;
1060 let Inst{5-4} = 0b00; // rotate
1062 def rr_rot : T2ThreeReg<(outs rGPR:$Rd),
1063 (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
1064 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
1065 [(set rGPR:$Rd, (opnode rGPR:$Rn,
1066 (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1067 Requires<[HasT2ExtractPack, IsThumb2]> {
1068 let Inst{31-27} = 0b11111;
1069 let Inst{26-23} = 0b0100;
1070 let Inst{22-20} = opcod;
1071 let Inst{15-12} = 0b1111;
1075 let Inst{5-4} = rot{1-0}; // rotate
1079 // DO variant - disassembly only, no pattern
1081 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
1082 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1083 opc, "\t$Rd, $Rn, $Rm", []> {
1084 let Inst{31-27} = 0b11111;
1085 let Inst{26-23} = 0b0100;
1086 let Inst{22-20} = opcod;
1087 let Inst{15-12} = 0b1111;
1089 let Inst{5-4} = 0b00; // rotate
1091 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
1092 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> {
1093 let Inst{31-27} = 0b11111;
1094 let Inst{26-23} = 0b0100;
1095 let Inst{22-20} = opcod;
1096 let Inst{15-12} = 0b1111;
1100 let Inst{5-4} = rot{1-0}; // rotate
1104 //===----------------------------------------------------------------------===//
1106 //===----------------------------------------------------------------------===//
1108 //===----------------------------------------------------------------------===//
1109 // Miscellaneous Instructions.
1112 class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
1113 string asm, list<dag> pattern>
1114 : T2XI<oops, iops, itin, asm, pattern> {
1118 let Inst{11-8} = Rd;
1119 let Inst{26} = label{11};
1120 let Inst{14-12} = label{10-8};
1121 let Inst{7-0} = label{7-0};
1124 // LEApcrel - Load a pc-relative address into a register without offending the
1126 def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
1127 (ins t2adrlabel:$addr, pred:$p),
1128 IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> {
1129 let Inst{31-27} = 0b11110;
1130 let Inst{25-24} = 0b10;
1131 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1134 let Inst{19-16} = 0b1111; // Rn
1139 let Inst{11-8} = Rd;
1140 let Inst{23} = addr{12};
1141 let Inst{21} = addr{12};
1142 let Inst{26} = addr{11};
1143 let Inst{14-12} = addr{10-8};
1144 let Inst{7-0} = addr{7-0};
1147 let neverHasSideEffects = 1, isReMaterializable = 1 in
1148 def t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
1149 Size4Bytes, IIC_iALUi, []>;
1150 def t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd),
1151 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1152 Size4Bytes, IIC_iALUi,
1156 // FIXME: None of these add/sub SP special instructions should be necessary
1157 // at all for thumb2 since they use the same encodings as the generic
1158 // add/sub instructions. In thumb1 we need them since they have dedicated
1159 // encodings. At the least, they should be pseudo instructions.
1160 // ADD r, sp, {so_imm|i12}
1161 let isCodeGenOnly = 1 in {
1162 def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1163 IIC_iALUi, "add", ".w\t$Rd, $Rn, $imm", []> {
1164 let Inst{31-27} = 0b11110;
1166 let Inst{24-21} = 0b1000;
1169 def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1170 IIC_iALUi, "addw", "\t$Rd, $Rn, $imm", []> {
1171 let Inst{31-27} = 0b11110;
1172 let Inst{25-20} = 0b100000;
1176 // ADD r, sp, so_reg
1177 def t2ADDrSPs : T2sTwoRegShiftedReg<
1178 (outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
1179 IIC_iALUsi, "add", ".w\t$Rd, $Rn, $ShiftedRm", []> {
1180 let Inst{31-27} = 0b11101;
1181 let Inst{26-25} = 0b01;
1182 let Inst{24-21} = 0b1000;
1186 // SUB r, sp, {so_imm|i12}
1187 def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1188 IIC_iALUi, "sub", ".w\t$Rd, $Rn, $imm", []> {
1189 let Inst{31-27} = 0b11110;
1191 let Inst{24-21} = 0b1101;
1194 def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1195 IIC_iALUi, "subw", "\t$Rd, $Rn, $imm", []> {
1196 let Inst{31-27} = 0b11110;
1197 let Inst{25-20} = 0b101010;
1201 // SUB r, sp, so_reg
1202 def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$imm),
1204 "sub", "\t$Rd, $Rn, $imm", []> {
1205 let Inst{31-27} = 0b11101;
1206 let Inst{26-25} = 0b01;
1207 let Inst{24-21} = 0b1101;
1208 let Inst{19-16} = 0b1101; // Rn = sp
1211 } // end isCodeGenOnly = 1
1213 // Signed and unsigned division on v7-M
1214 def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1215 "sdiv", "\t$Rd, $Rn, $Rm",
1216 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>,
1217 Requires<[HasDivide, IsThumb2]> {
1218 let Inst{31-27} = 0b11111;
1219 let Inst{26-21} = 0b011100;
1221 let Inst{15-12} = 0b1111;
1222 let Inst{7-4} = 0b1111;
1225 def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1226 "udiv", "\t$Rd, $Rn, $Rm",
1227 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>,
1228 Requires<[HasDivide, IsThumb2]> {
1229 let Inst{31-27} = 0b11111;
1230 let Inst{26-21} = 0b011101;
1232 let Inst{15-12} = 0b1111;
1233 let Inst{7-4} = 0b1111;
1236 //===----------------------------------------------------------------------===//
1237 // Load / store Instructions.
1241 let canFoldAsLoad = 1, isReMaterializable = 1 in
1242 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1243 UnOpFrag<(load node:$Src)>>;
1245 // Loads with zero extension
1246 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1247 UnOpFrag<(zextloadi16 node:$Src)>>;
1248 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1249 UnOpFrag<(zextloadi8 node:$Src)>>;
1251 // Loads with sign extension
1252 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1253 UnOpFrag<(sextloadi16 node:$Src)>>;
1254 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1255 UnOpFrag<(sextloadi8 node:$Src)>>;
1257 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1259 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1260 (ins t2addrmode_imm8s4:$addr),
1261 IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", []>;
1262 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1264 // zextload i1 -> zextload i8
1265 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1266 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1267 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1268 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1269 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1270 (t2LDRBs t2addrmode_so_reg:$addr)>;
1271 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1272 (t2LDRBpci tconstpool:$addr)>;
1274 // extload -> zextload
1275 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1277 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1278 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1279 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1280 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1281 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1282 (t2LDRBs t2addrmode_so_reg:$addr)>;
1283 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1284 (t2LDRBpci tconstpool:$addr)>;
1286 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1287 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1288 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1289 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1290 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1291 (t2LDRBs t2addrmode_so_reg:$addr)>;
1292 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1293 (t2LDRBpci tconstpool:$addr)>;
1295 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1296 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1297 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1298 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1299 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1300 (t2LDRHs t2addrmode_so_reg:$addr)>;
1301 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1302 (t2LDRHpci tconstpool:$addr)>;
1304 // FIXME: The destination register of the loads and stores can't be PC, but
1305 // can be SP. We need another regclass (similar to rGPR) to represent
1306 // that. Not a pressing issue since these are selected manually,
1311 let mayLoad = 1, neverHasSideEffects = 1 in {
1312 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1313 (ins t2addrmode_imm8:$addr),
1314 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1315 "ldr", "\t$Rt, $addr!", "$addr.base = $Rn",
1318 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1319 (ins GPR:$base, t2am_imm8_offset:$addr),
1320 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1321 "ldr", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1324 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1325 (ins t2addrmode_imm8:$addr),
1326 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1327 "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn",
1329 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1330 (ins GPR:$base, t2am_imm8_offset:$addr),
1331 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1332 "ldrb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1335 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1336 (ins t2addrmode_imm8:$addr),
1337 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1338 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn",
1340 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1341 (ins GPR:$base, t2am_imm8_offset:$addr),
1342 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1343 "ldrh", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1346 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1347 (ins t2addrmode_imm8:$addr),
1348 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1349 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn",
1351 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1352 (ins GPR:$base, t2am_imm8_offset:$addr),
1353 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1354 "ldrsb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1357 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1358 (ins t2addrmode_imm8:$addr),
1359 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1360 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn",
1362 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$Rn),
1363 (ins GPR:$base, t2am_imm8_offset:$addr),
1364 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1365 "ldrsh", "\t$dst, [$Rn], $addr", "$base = $Rn",
1367 } // mayLoad = 1, neverHasSideEffects = 1
1369 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1370 // for disassembly only.
1371 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1372 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1373 : T2Ii8<(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1374 "\t$Rt, $addr", []> {
1375 let Inst{31-27} = 0b11111;
1376 let Inst{26-25} = 0b00;
1377 let Inst{24} = signed;
1379 let Inst{22-21} = type;
1380 let Inst{20} = 1; // load
1382 let Inst{10-8} = 0b110; // PUW.
1386 let Inst{15-12} = Rt;
1387 let Inst{19-16} = addr{12-9};
1388 let Inst{7-0} = addr{7-0};
1391 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1392 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1393 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1394 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1395 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1398 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1399 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1400 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1401 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1402 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1403 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1406 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1407 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1408 (ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr),
1409 IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>;
1412 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1413 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1414 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1415 "str", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1417 (pre_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1419 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1420 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1421 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1422 "str", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1424 (post_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1426 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1427 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1428 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1429 "strh", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1431 (pre_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1433 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1434 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1435 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1436 "strh", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1438 (post_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1440 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1441 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1442 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1443 "strb", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1445 (pre_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1447 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1448 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1449 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1450 "strb", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1452 (post_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1454 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1456 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1457 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1458 : T2Ii8<(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1459 "\t$Rt, $addr", []> {
1460 let Inst{31-27} = 0b11111;
1461 let Inst{26-25} = 0b00;
1462 let Inst{24} = 0; // not signed
1464 let Inst{22-21} = type;
1465 let Inst{20} = 0; // store
1467 let Inst{10-8} = 0b110; // PUW
1471 let Inst{15-12} = Rt;
1472 let Inst{19-16} = addr{12-9};
1473 let Inst{7-0} = addr{7-0};
1476 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1477 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1478 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1480 // ldrd / strd pre / post variants
1481 // For disassembly only.
1483 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
1484 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1485 "ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1487 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
1488 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1489 "ldrd", "\t$Rt, $Rt2, [$base], $imm", []>;
1491 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1492 (ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1493 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1495 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1496 (ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1497 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>;
1499 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1500 // data/instruction access. These are for disassembly only.
1501 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1502 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1503 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1505 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1507 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1508 let Inst{31-25} = 0b1111100;
1509 let Inst{24} = instr;
1511 let Inst{21} = write;
1513 let Inst{15-12} = 0b1111;
1516 let Inst{19-16} = addr{16-13}; // Rn
1517 let Inst{23} = addr{12}; // U
1518 let Inst{11-0} = addr{11-0}; // imm12
1521 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1523 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1524 let Inst{31-25} = 0b1111100;
1525 let Inst{24} = instr;
1526 let Inst{23} = 0; // U = 0
1528 let Inst{21} = write;
1530 let Inst{15-12} = 0b1111;
1531 let Inst{11-8} = 0b1100;
1534 let Inst{19-16} = addr{12-9}; // Rn
1535 let Inst{7-0} = addr{7-0}; // imm8
1538 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1540 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1541 let Inst{31-25} = 0b1111100;
1542 let Inst{24} = instr;
1543 let Inst{23} = 0; // add = TRUE for T1
1545 let Inst{21} = write;
1547 let Inst{15-12} = 0b1111;
1548 let Inst{11-6} = 0000000;
1551 let Inst{19-16} = addr{9-6}; // Rn
1552 let Inst{3-0} = addr{5-2}; // Rm
1553 let Inst{5-4} = addr{1-0}; // imm2
1557 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1558 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1559 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1561 //===----------------------------------------------------------------------===//
1562 // Load / store multiple Instructions.
1565 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1566 InstrItinClass itin_upd, bit L_bit> {
1568 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1569 itin, !strconcat(asm, "ia${p}.w\t$Rn, $regs"), []> {
1573 let Inst{31-27} = 0b11101;
1574 let Inst{26-25} = 0b00;
1575 let Inst{24-23} = 0b01; // Increment After
1577 let Inst{21} = 0; // No writeback
1578 let Inst{20} = L_bit;
1579 let Inst{19-16} = Rn;
1580 let Inst{15-0} = regs;
1583 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1584 itin_upd, !strconcat(asm, "ia${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1588 let Inst{31-27} = 0b11101;
1589 let Inst{26-25} = 0b00;
1590 let Inst{24-23} = 0b01; // Increment After
1592 let Inst{21} = 1; // Writeback
1593 let Inst{20} = L_bit;
1594 let Inst{19-16} = Rn;
1595 let Inst{15-0} = regs;
1598 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1599 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1603 let Inst{31-27} = 0b11101;
1604 let Inst{26-25} = 0b00;
1605 let Inst{24-23} = 0b10; // Decrement Before
1607 let Inst{21} = 0; // No writeback
1608 let Inst{20} = L_bit;
1609 let Inst{19-16} = Rn;
1610 let Inst{15-0} = regs;
1613 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1614 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1618 let Inst{31-27} = 0b11101;
1619 let Inst{26-25} = 0b00;
1620 let Inst{24-23} = 0b10; // Decrement Before
1622 let Inst{21} = 1; // Writeback
1623 let Inst{20} = L_bit;
1624 let Inst{19-16} = Rn;
1625 let Inst{15-0} = regs;
1629 let neverHasSideEffects = 1 in {
1631 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1632 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1634 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1635 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1637 } // neverHasSideEffects
1640 //===----------------------------------------------------------------------===//
1641 // Move Instructions.
1644 let neverHasSideEffects = 1 in
1645 def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1646 "mov", ".w\t$Rd, $Rm", []> {
1647 let Inst{31-27} = 0b11101;
1648 let Inst{26-25} = 0b01;
1649 let Inst{24-21} = 0b0010;
1650 let Inst{19-16} = 0b1111; // Rn
1651 let Inst{14-12} = 0b000;
1652 let Inst{7-4} = 0b0000;
1655 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1656 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
1657 AddedComplexity = 1 in
1658 def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
1659 "mov", ".w\t$Rd, $imm",
1660 [(set rGPR:$Rd, t2_so_imm:$imm)]> {
1661 let Inst{31-27} = 0b11110;
1663 let Inst{24-21} = 0b0010;
1664 let Inst{19-16} = 0b1111; // Rn
1668 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1669 def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
1670 "movw", "\t$Rd, $imm",
1671 [(set rGPR:$Rd, imm0_65535:$imm)]> {
1672 let Inst{31-27} = 0b11110;
1674 let Inst{24-21} = 0b0010;
1675 let Inst{20} = 0; // The S bit.
1681 let Inst{11-8} = Rd;
1682 let Inst{19-16} = imm{15-12};
1683 let Inst{26} = imm{11};
1684 let Inst{14-12} = imm{10-8};
1685 let Inst{7-0} = imm{7-0};
1688 def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1689 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1691 let Constraints = "$src = $Rd" in {
1692 def t2MOVTi16 : T2I<(outs rGPR:$Rd),
1693 (ins rGPR:$src, i32imm_hilo16:$imm), IIC_iMOVi,
1694 "movt", "\t$Rd, $imm",
1696 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1697 let Inst{31-27} = 0b11110;
1699 let Inst{24-21} = 0b0110;
1700 let Inst{20} = 0; // The S bit.
1706 let Inst{11-8} = Rd;
1707 let Inst{19-16} = imm{15-12};
1708 let Inst{26} = imm{11};
1709 let Inst{14-12} = imm{10-8};
1710 let Inst{7-0} = imm{7-0};
1713 def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1714 (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1717 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1719 //===----------------------------------------------------------------------===//
1720 // Extend Instructions.
1725 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1726 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1727 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1728 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1729 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1731 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1732 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1733 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1734 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1735 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1737 // TODO: SXT(A){B|H}16 - done for disassembly only
1741 let AddedComplexity = 16 in {
1742 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1743 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1744 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1745 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1746 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1747 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1749 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1750 // The transformation should probably be done as a combiner action
1751 // instead so we can include a check for masking back in the upper
1752 // eight bits of the source into the lower eight bits of the result.
1753 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1754 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1755 // Requires<[HasT2ExtractPack, IsThumb2]>;
1756 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1757 (t2UXTB16r_rot rGPR:$Src, 8)>,
1758 Requires<[HasT2ExtractPack, IsThumb2]>;
1760 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1761 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1762 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1763 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1764 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1767 //===----------------------------------------------------------------------===//
1768 // Arithmetic Instructions.
1771 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1772 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1773 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1774 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1776 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1777 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1778 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1779 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1780 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1781 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1782 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1784 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1785 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1786 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1787 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1788 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1789 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1790 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1791 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1794 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1795 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1796 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1797 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1799 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1800 // The assume-no-carry-in form uses the negation of the input since add/sub
1801 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1802 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1804 // The AddedComplexity preferences the first variant over the others since
1805 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1806 let AddedComplexity = 1 in
1807 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1808 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1809 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1810 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1811 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1812 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1813 let AddedComplexity = 1 in
1814 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1815 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1816 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1817 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1818 // The with-carry-in form matches bitwise not instead of the negation.
1819 // Effectively, the inverse interpretation of the carry flag already accounts
1820 // for part of the negation.
1821 let AddedComplexity = 1 in
1822 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1823 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1824 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1825 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1827 // Select Bytes -- for disassembly only
1829 def t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1830 NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []> {
1831 let Inst{31-27} = 0b11111;
1832 let Inst{26-24} = 0b010;
1834 let Inst{22-20} = 0b010;
1835 let Inst{15-12} = 0b1111;
1837 let Inst{6-4} = 0b000;
1840 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1841 // And Miscellaneous operations -- for disassembly only
1842 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1843 list<dag> pat = [/* For disassembly only; pattern left blank */],
1844 dag iops = (ins rGPR:$Rn, rGPR:$Rm),
1845 string asm = "\t$Rd, $Rn, $Rm">
1846 : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat> {
1847 let Inst{31-27} = 0b11111;
1848 let Inst{26-23} = 0b0101;
1849 let Inst{22-20} = op22_20;
1850 let Inst{15-12} = 0b1111;
1851 let Inst{7-4} = op7_4;
1857 let Inst{11-8} = Rd;
1858 let Inst{19-16} = Rn;
1862 // Saturating add/subtract -- for disassembly only
1864 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1865 [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))],
1866 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1867 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1868 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1869 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1870 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd", [],
1871 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1872 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub", [],
1873 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1874 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1875 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1876 [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))],
1877 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1878 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1879 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1880 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1881 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1882 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1883 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1884 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1885 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1887 // Signed/Unsigned add/subtract -- for disassembly only
1889 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1890 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1891 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1892 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1893 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1894 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1895 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1896 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1897 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1898 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1899 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1900 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1902 // Signed/Unsigned halving add/subtract -- for disassembly only
1904 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1905 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1906 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1907 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1908 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1909 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1910 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1911 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1912 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1913 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1914 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1915 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1917 // Helper class for disassembly only
1918 // A6.3.16 & A6.3.17
1919 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1920 class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1921 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1922 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
1923 let Inst{31-27} = 0b11111;
1924 let Inst{26-24} = 0b011;
1925 let Inst{23} = long;
1926 let Inst{22-20} = op22_20;
1927 let Inst{7-4} = op7_4;
1930 class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1931 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1932 : T2FourReg<oops, iops, itin, opc, asm, pattern> {
1933 let Inst{31-27} = 0b11111;
1934 let Inst{26-24} = 0b011;
1935 let Inst{23} = long;
1936 let Inst{22-20} = op22_20;
1937 let Inst{7-4} = op7_4;
1940 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1942 def t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1943 (ins rGPR:$Rn, rGPR:$Rm),
1944 NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []> {
1945 let Inst{15-12} = 0b1111;
1947 def t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1948 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
1949 "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>;
1951 // Signed/Unsigned saturate -- for disassembly only
1953 class T2SatI<dag oops, dag iops, InstrItinClass itin,
1954 string opc, string asm, list<dag> pattern>
1955 : T2I<oops, iops, itin, opc, asm, pattern> {
1961 let Inst{11-8} = Rd;
1962 let Inst{19-16} = Rn;
1963 let Inst{4-0} = sat_imm{4-0};
1964 let Inst{21} = sh{6};
1965 let Inst{14-12} = sh{4-2};
1966 let Inst{7-6} = sh{1-0};
1970 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1971 NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
1972 [/* For disassembly only; pattern left blank */]> {
1973 let Inst{31-27} = 0b11110;
1974 let Inst{25-22} = 0b1100;
1979 def t2SSAT16: T2SatI<
1980 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
1981 "ssat16", "\t$Rd, $sat_imm, $Rn",
1982 [/* For disassembly only; pattern left blank */]> {
1983 let Inst{31-27} = 0b11110;
1984 let Inst{25-22} = 0b1100;
1987 let Inst{21} = 1; // sh = '1'
1988 let Inst{14-12} = 0b000; // imm3 = '000'
1989 let Inst{7-6} = 0b00; // imm2 = '00'
1993 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1994 NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh",
1995 [/* For disassembly only; pattern left blank */]> {
1996 let Inst{31-27} = 0b11110;
1997 let Inst{25-22} = 0b1110;
2002 def t2USAT16: T2SatI<
2003 (outs rGPR:$dst), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
2004 "usat16", "\t$dst, $sat_imm, $Rn",
2005 [/* For disassembly only; pattern left blank */]> {
2006 let Inst{31-27} = 0b11110;
2007 let Inst{25-22} = 0b1110;
2010 let Inst{21} = 1; // sh = '1'
2011 let Inst{14-12} = 0b000; // imm3 = '000'
2012 let Inst{7-6} = 0b00; // imm2 = '00'
2015 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
2016 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
2018 //===----------------------------------------------------------------------===//
2019 // Shift and rotate Instructions.
2022 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
2023 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
2024 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
2025 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
2027 let Uses = [CPSR] in {
2028 def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2029 "rrx", "\t$Rd, $Rm",
2030 [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> {
2031 let Inst{31-27} = 0b11101;
2032 let Inst{26-25} = 0b01;
2033 let Inst{24-21} = 0b0010;
2034 let Inst{19-16} = 0b1111; // Rn
2035 let Inst{14-12} = 0b000;
2036 let Inst{7-4} = 0b0011;
2040 let isCodeGenOnly = 1, Defs = [CPSR] in {
2041 def t2MOVsrl_flag : T2TwoRegShiftImm<
2042 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2043 "lsrs", ".w\t$Rd, $Rm, #1",
2044 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> {
2045 let Inst{31-27} = 0b11101;
2046 let Inst{26-25} = 0b01;
2047 let Inst{24-21} = 0b0010;
2048 let Inst{20} = 1; // The S bit.
2049 let Inst{19-16} = 0b1111; // Rn
2050 let Inst{5-4} = 0b01; // Shift type.
2051 // Shift amount = Inst{14-12:7-6} = 1.
2052 let Inst{14-12} = 0b000;
2053 let Inst{7-6} = 0b01;
2055 def t2MOVsra_flag : T2TwoRegShiftImm<
2056 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2057 "asrs", ".w\t$Rd, $Rm, #1",
2058 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> {
2059 let Inst{31-27} = 0b11101;
2060 let Inst{26-25} = 0b01;
2061 let Inst{24-21} = 0b0010;
2062 let Inst{20} = 1; // The S bit.
2063 let Inst{19-16} = 0b1111; // Rn
2064 let Inst{5-4} = 0b10; // Shift type.
2065 // Shift amount = Inst{14-12:7-6} = 1.
2066 let Inst{14-12} = 0b000;
2067 let Inst{7-6} = 0b01;
2071 //===----------------------------------------------------------------------===//
2072 // Bitwise Instructions.
2075 defm t2AND : T2I_bin_w_irs<0b0000, "and",
2076 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2077 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2078 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
2079 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2080 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2081 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
2082 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2083 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2085 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
2086 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2087 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2089 class T2BitFI<dag oops, dag iops, InstrItinClass itin,
2090 string opc, string asm, list<dag> pattern>
2091 : T2I<oops, iops, itin, opc, asm, pattern> {
2096 let Inst{11-8} = Rd;
2097 let Inst{4-0} = msb{4-0};
2098 let Inst{14-12} = lsb{4-2};
2099 let Inst{7-6} = lsb{1-0};
2102 class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2103 string opc, string asm, list<dag> pattern>
2104 : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2107 let Inst{19-16} = Rn;
2110 let Constraints = "$src = $Rd" in
2111 def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2112 IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2113 [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2114 let Inst{31-27} = 0b11110;
2116 let Inst{24-20} = 0b10110;
2117 let Inst{19-16} = 0b1111; // Rn
2121 let msb{4-0} = imm{9-5};
2122 let lsb{4-0} = imm{4-0};
2125 def t2SBFX: T2TwoRegBitFI<
2126 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2127 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2128 let Inst{31-27} = 0b11110;
2130 let Inst{24-20} = 0b10100;
2134 def t2UBFX: T2TwoRegBitFI<
2135 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2136 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2137 let Inst{31-27} = 0b11110;
2139 let Inst{24-20} = 0b11100;
2143 // A8.6.18 BFI - Bitfield insert (Encoding T1)
2144 let Constraints = "$src = $Rd" in {
2145 def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2146 (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2147 IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2148 [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2149 bf_inv_mask_imm:$imm))]> {
2150 let Inst{31-27} = 0b11110;
2152 let Inst{24-20} = 0b10110;
2156 let msb{4-0} = imm{9-5};
2157 let lsb{4-0} = imm{4-0};
2160 // GNU as only supports this form of bfi (w/ 4 arguments)
2161 let isAsmParserOnly = 1 in
2162 def t2BFI4p : T2TwoRegBitFI<(outs rGPR:$Rd),
2163 (ins rGPR:$src, rGPR:$Rn, lsb_pos_imm:$lsbit,
2165 IIC_iBITi, "bfi", "\t$Rd, $Rn, $lsbit, $width",
2167 let Inst{31-27} = 0b11110;
2169 let Inst{24-20} = 0b10110;
2174 let msb{4-0} = width; // Custom encoder => lsb+width-1
2175 let lsb{4-0} = lsbit;
2179 defm t2ORN : T2I_bin_irs<0b0011, "orn",
2180 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2181 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
2183 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2184 let AddedComplexity = 1 in
2185 defm t2MVN : T2I_un_irs <0b0011, "mvn",
2186 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2187 UnOpFrag<(not node:$Src)>, 1, 1>;
2190 let AddedComplexity = 1 in
2191 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
2192 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2194 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2195 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
2196 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2197 Requires<[IsThumb2]>;
2199 def : T2Pat<(t2_so_imm_not:$src),
2200 (t2MVNi t2_so_imm_not:$src)>;
2202 //===----------------------------------------------------------------------===//
2203 // Multiply Instructions.
2205 let isCommutable = 1 in
2206 def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2207 "mul", "\t$Rd, $Rn, $Rm",
2208 [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2209 let Inst{31-27} = 0b11111;
2210 let Inst{26-23} = 0b0110;
2211 let Inst{22-20} = 0b000;
2212 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2213 let Inst{7-4} = 0b0000; // Multiply
2216 def t2MLA: T2FourReg<
2217 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2218 "mla", "\t$Rd, $Rn, $Rm, $Ra",
2219 [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> {
2220 let Inst{31-27} = 0b11111;
2221 let Inst{26-23} = 0b0110;
2222 let Inst{22-20} = 0b000;
2223 let Inst{7-4} = 0b0000; // Multiply
2226 def t2MLS: T2FourReg<
2227 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2228 "mls", "\t$Rd, $Rn, $Rm, $Ra",
2229 [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> {
2230 let Inst{31-27} = 0b11111;
2231 let Inst{26-23} = 0b0110;
2232 let Inst{22-20} = 0b000;
2233 let Inst{7-4} = 0b0001; // Multiply and Subtract
2236 // Extra precision multiplies with low / high results
2237 let neverHasSideEffects = 1 in {
2238 let isCommutable = 1 in {
2239 def t2SMULL : T2MulLong<0b000, 0b0000,
2240 (outs rGPR:$Rd, rGPR:$Ra),
2241 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2242 "smull", "\t$Rd, $Ra, $Rn, $Rm", []>;
2244 def t2UMULL : T2MulLong<0b010, 0b0000,
2245 (outs rGPR:$RdLo, rGPR:$RdHi),
2246 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2247 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2250 // Multiply + accumulate
2251 def t2SMLAL : T2MulLong<0b100, 0b0000,
2252 (outs rGPR:$RdLo, rGPR:$RdHi),
2253 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2254 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2256 def t2UMLAL : T2MulLong<0b110, 0b0000,
2257 (outs rGPR:$RdLo, rGPR:$RdHi),
2258 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2259 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2261 def t2UMAAL : T2MulLong<0b110, 0b0110,
2262 (outs rGPR:$RdLo, rGPR:$RdHi),
2263 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2264 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2265 } // neverHasSideEffects
2267 // Rounding variants of the below included for disassembly only
2269 // Most significant word multiply
2270 def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2271 "smmul", "\t$Rd, $Rn, $Rm",
2272 [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]> {
2273 let Inst{31-27} = 0b11111;
2274 let Inst{26-23} = 0b0110;
2275 let Inst{22-20} = 0b101;
2276 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2277 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2280 def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2281 "smmulr", "\t$Rd, $Rn, $Rm", []> {
2282 let Inst{31-27} = 0b11111;
2283 let Inst{26-23} = 0b0110;
2284 let Inst{22-20} = 0b101;
2285 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2286 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2289 def t2SMMLA : T2FourReg<
2290 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2291 "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2292 [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]> {
2293 let Inst{31-27} = 0b11111;
2294 let Inst{26-23} = 0b0110;
2295 let Inst{22-20} = 0b101;
2296 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2299 def t2SMMLAR: T2FourReg<
2300 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2301 "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []> {
2302 let Inst{31-27} = 0b11111;
2303 let Inst{26-23} = 0b0110;
2304 let Inst{22-20} = 0b101;
2305 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2308 def t2SMMLS: T2FourReg<
2309 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2310 "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2311 [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]> {
2312 let Inst{31-27} = 0b11111;
2313 let Inst{26-23} = 0b0110;
2314 let Inst{22-20} = 0b110;
2315 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2318 def t2SMMLSR:T2FourReg<
2319 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2320 "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []> {
2321 let Inst{31-27} = 0b11111;
2322 let Inst{26-23} = 0b0110;
2323 let Inst{22-20} = 0b110;
2324 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2327 multiclass T2I_smul<string opc, PatFrag opnode> {
2328 def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2329 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2330 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2331 (sext_inreg rGPR:$Rm, i16)))]> {
2332 let Inst{31-27} = 0b11111;
2333 let Inst{26-23} = 0b0110;
2334 let Inst{22-20} = 0b001;
2335 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2336 let Inst{7-6} = 0b00;
2337 let Inst{5-4} = 0b00;
2340 def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2341 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2342 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2343 (sra rGPR:$Rm, (i32 16))))]> {
2344 let Inst{31-27} = 0b11111;
2345 let Inst{26-23} = 0b0110;
2346 let Inst{22-20} = 0b001;
2347 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2348 let Inst{7-6} = 0b00;
2349 let Inst{5-4} = 0b01;
2352 def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2353 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2354 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2355 (sext_inreg rGPR:$Rm, i16)))]> {
2356 let Inst{31-27} = 0b11111;
2357 let Inst{26-23} = 0b0110;
2358 let Inst{22-20} = 0b001;
2359 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2360 let Inst{7-6} = 0b00;
2361 let Inst{5-4} = 0b10;
2364 def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2365 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2366 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2367 (sra rGPR:$Rm, (i32 16))))]> {
2368 let Inst{31-27} = 0b11111;
2369 let Inst{26-23} = 0b0110;
2370 let Inst{22-20} = 0b001;
2371 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2372 let Inst{7-6} = 0b00;
2373 let Inst{5-4} = 0b11;
2376 def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2377 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2378 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2379 (sext_inreg rGPR:$Rm, i16)), (i32 16)))]> {
2380 let Inst{31-27} = 0b11111;
2381 let Inst{26-23} = 0b0110;
2382 let Inst{22-20} = 0b011;
2383 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2384 let Inst{7-6} = 0b00;
2385 let Inst{5-4} = 0b00;
2388 def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2389 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2390 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2391 (sra rGPR:$Rm, (i32 16))), (i32 16)))]> {
2392 let Inst{31-27} = 0b11111;
2393 let Inst{26-23} = 0b0110;
2394 let Inst{22-20} = 0b011;
2395 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2396 let Inst{7-6} = 0b00;
2397 let Inst{5-4} = 0b01;
2402 multiclass T2I_smla<string opc, PatFrag opnode> {
2404 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2405 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2406 [(set rGPR:$Rd, (add rGPR:$Ra,
2407 (opnode (sext_inreg rGPR:$Rn, i16),
2408 (sext_inreg rGPR:$Rm, i16))))]> {
2409 let Inst{31-27} = 0b11111;
2410 let Inst{26-23} = 0b0110;
2411 let Inst{22-20} = 0b001;
2412 let Inst{7-6} = 0b00;
2413 let Inst{5-4} = 0b00;
2417 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2418 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2419 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
2420 (sra rGPR:$Rm, (i32 16)))))]> {
2421 let Inst{31-27} = 0b11111;
2422 let Inst{26-23} = 0b0110;
2423 let Inst{22-20} = 0b001;
2424 let Inst{7-6} = 0b00;
2425 let Inst{5-4} = 0b01;
2429 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2430 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2431 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2432 (sext_inreg rGPR:$Rm, i16))))]> {
2433 let Inst{31-27} = 0b11111;
2434 let Inst{26-23} = 0b0110;
2435 let Inst{22-20} = 0b001;
2436 let Inst{7-6} = 0b00;
2437 let Inst{5-4} = 0b10;
2441 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2442 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2443 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2444 (sra rGPR:$Rm, (i32 16)))))]> {
2445 let Inst{31-27} = 0b11111;
2446 let Inst{26-23} = 0b0110;
2447 let Inst{22-20} = 0b001;
2448 let Inst{7-6} = 0b00;
2449 let Inst{5-4} = 0b11;
2453 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2454 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2455 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2456 (sext_inreg rGPR:$Rm, i16)), (i32 16))))]> {
2457 let Inst{31-27} = 0b11111;
2458 let Inst{26-23} = 0b0110;
2459 let Inst{22-20} = 0b011;
2460 let Inst{7-6} = 0b00;
2461 let Inst{5-4} = 0b00;
2465 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2466 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2467 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2468 (sra rGPR:$Rm, (i32 16))), (i32 16))))]> {
2469 let Inst{31-27} = 0b11111;
2470 let Inst{26-23} = 0b0110;
2471 let Inst{22-20} = 0b011;
2472 let Inst{7-6} = 0b00;
2473 let Inst{5-4} = 0b01;
2477 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2478 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2480 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2481 def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
2482 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
2483 [/* For disassembly only; pattern left blank */]>;
2484 def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
2485 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
2486 [/* For disassembly only; pattern left blank */]>;
2487 def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
2488 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
2489 [/* For disassembly only; pattern left blank */]>;
2490 def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
2491 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
2492 [/* For disassembly only; pattern left blank */]>;
2494 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2495 // These are for disassembly only.
2497 def t2SMUAD: T2ThreeReg_mac<
2498 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2499 IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []> {
2500 let Inst{15-12} = 0b1111;
2502 def t2SMUADX:T2ThreeReg_mac<
2503 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2504 IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []> {
2505 let Inst{15-12} = 0b1111;
2507 def t2SMUSD: T2ThreeReg_mac<
2508 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2509 IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []> {
2510 let Inst{15-12} = 0b1111;
2512 def t2SMUSDX:T2ThreeReg_mac<
2513 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2514 IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []> {
2515 let Inst{15-12} = 0b1111;
2517 def t2SMLAD : T2ThreeReg_mac<
2518 0, 0b010, 0b0000, (outs rGPR:$Rd),
2519 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
2520 "\t$Rd, $Rn, $Rm, $Ra", []>;
2521 def t2SMLADX : T2FourReg_mac<
2522 0, 0b010, 0b0001, (outs rGPR:$Rd),
2523 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
2524 "\t$Rd, $Rn, $Rm, $Ra", []>;
2525 def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
2526 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
2527 "\t$Rd, $Rn, $Rm, $Ra", []>;
2528 def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
2529 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
2530 "\t$Rd, $Rn, $Rm, $Ra", []>;
2531 def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2532 (ins rGPR:$Rm, rGPR:$Rn), IIC_iMAC64, "smlald",
2533 "\t$Ra, $Rd, $Rm, $Rn", []>;
2534 def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2535 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlaldx",
2536 "\t$Ra, $Rd, $Rm, $Rn", []>;
2537 def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2538 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsld",
2539 "\t$Ra, $Rd, $Rm, $Rn", []>;
2540 def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2541 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
2542 "\t$Ra, $Rd, $Rm, $Rn", []>;
2544 //===----------------------------------------------------------------------===//
2545 // Misc. Arithmetic Instructions.
2548 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2549 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2550 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2551 let Inst{31-27} = 0b11111;
2552 let Inst{26-22} = 0b01010;
2553 let Inst{21-20} = op1;
2554 let Inst{15-12} = 0b1111;
2555 let Inst{7-6} = 0b10;
2556 let Inst{5-4} = op2;
2560 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2561 "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>;
2563 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2564 "rbit", "\t$Rd, $Rm",
2565 [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>;
2567 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2568 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>;
2570 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2571 "rev16", ".w\t$Rd, $Rm",
2573 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF),
2574 (or (and (shl rGPR:$Rm, (i32 8)), 0xFF00),
2575 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000),
2576 (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)))))]>;
2578 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2579 "revsh", ".w\t$Rd, $Rm",
2582 (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)),
2583 (shl rGPR:$Rm, (i32 8))), i16))]>;
2585 def t2PKHBT : T2ThreeReg<
2586 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2587 IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2588 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2589 (and (shl rGPR:$Rm, lsl_amt:$sh),
2591 Requires<[HasT2ExtractPack, IsThumb2]> {
2592 let Inst{31-27} = 0b11101;
2593 let Inst{26-25} = 0b01;
2594 let Inst{24-20} = 0b01100;
2595 let Inst{5} = 0; // BT form
2599 let Inst{14-12} = sh{7-5};
2600 let Inst{7-6} = sh{4-3};
2603 // Alternate cases for PKHBT where identities eliminate some nodes.
2604 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2605 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2606 Requires<[HasT2ExtractPack, IsThumb2]>;
2607 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2608 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2609 Requires<[HasT2ExtractPack, IsThumb2]>;
2611 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2612 // will match the pattern below.
2613 def t2PKHTB : T2ThreeReg<
2614 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2615 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2616 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
2617 (and (sra rGPR:$Rm, asr_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} = 1; // TB form
2627 let Inst{14-12} = sh{7-5};
2628 let Inst{7-6} = sh{4-3};
2631 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2632 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2633 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2634 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2635 Requires<[HasT2ExtractPack, IsThumb2]>;
2636 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2637 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2638 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2639 Requires<[HasT2ExtractPack, IsThumb2]>;
2641 //===----------------------------------------------------------------------===//
2642 // Comparison Instructions...
2644 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2645 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2646 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2648 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_imm:$imm),
2649 (t2CMPri GPR:$lhs, t2_so_imm:$imm)>;
2650 def : T2Pat<(ARMcmpZ GPR:$lhs, rGPR:$rhs),
2651 (t2CMPrr GPR:$lhs, rGPR:$rhs)>;
2652 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_reg:$rhs),
2653 (t2CMPrs GPR:$lhs, t2_so_reg:$rhs)>;
2655 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2656 // Compare-to-zero still works out, just not the relationals
2657 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2658 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2659 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2660 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2661 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2663 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2664 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2666 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2667 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2669 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2670 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2671 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
2672 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2673 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2674 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
2676 // Conditional moves
2677 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2678 // a two-value operand where a dag node expects two operands. :(
2679 let neverHasSideEffects = 1 in {
2680 def t2MOVCCr : T2TwoReg<
2681 (outs rGPR:$Rd), (ins rGPR:$false, rGPR:$Rm), IIC_iCMOVr,
2682 "mov", ".w\t$Rd, $Rm",
2683 [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2684 RegConstraint<"$false = $Rd"> {
2685 let Inst{31-27} = 0b11101;
2686 let Inst{26-25} = 0b01;
2687 let Inst{24-21} = 0b0010;
2688 let Inst{20} = 0; // The S bit.
2689 let Inst{19-16} = 0b1111; // Rn
2690 let Inst{14-12} = 0b000;
2691 let Inst{7-4} = 0b0000;
2694 let isMoveImm = 1 in
2695 def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2696 IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
2697 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2698 RegConstraint<"$false = $Rd"> {
2699 let Inst{31-27} = 0b11110;
2701 let Inst{24-21} = 0b0010;
2702 let Inst{20} = 0; // The S bit.
2703 let Inst{19-16} = 0b1111; // Rn
2707 let isMoveImm = 1 in
2708 def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm_hilo16:$imm),
2710 "movw", "\t$Rd, $imm", []>,
2711 RegConstraint<"$false = $Rd"> {
2712 let Inst{31-27} = 0b11110;
2714 let Inst{24-21} = 0b0010;
2715 let Inst{20} = 0; // The S bit.
2721 let Inst{11-8} = Rd;
2722 let Inst{19-16} = imm{15-12};
2723 let Inst{26} = imm{11};
2724 let Inst{14-12} = imm{10-8};
2725 let Inst{7-0} = imm{7-0};
2728 let isMoveImm = 1 in
2729 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2730 (ins rGPR:$false, i32imm:$src, pred:$p),
2731 IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">;
2733 let isMoveImm = 1 in
2734 def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2735 IIC_iCMOVi, "mvn", ".w\t$Rd, $imm",
2736 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm,
2737 imm:$cc, CCR:$ccr))*/]>,
2738 RegConstraint<"$false = $Rd"> {
2739 let Inst{31-27} = 0b11110;
2741 let Inst{24-21} = 0b0011;
2742 let Inst{20} = 0; // The S bit.
2743 let Inst{19-16} = 0b1111; // Rn
2747 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2748 string opc, string asm, list<dag> pattern>
2749 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> {
2750 let Inst{31-27} = 0b11101;
2751 let Inst{26-25} = 0b01;
2752 let Inst{24-21} = 0b0010;
2753 let Inst{20} = 0; // The S bit.
2754 let Inst{19-16} = 0b1111; // Rn
2755 let Inst{5-4} = opcod; // Shift type.
2757 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd),
2758 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2759 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>,
2760 RegConstraint<"$false = $Rd">;
2761 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd),
2762 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2763 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>,
2764 RegConstraint<"$false = $Rd">;
2765 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd),
2766 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2767 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>,
2768 RegConstraint<"$false = $Rd">;
2769 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
2770 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2771 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
2772 RegConstraint<"$false = $Rd">;
2773 } // neverHasSideEffects
2775 //===----------------------------------------------------------------------===//
2776 // Atomic operations intrinsics
2779 // memory barriers protect the atomic sequences
2780 let hasSideEffects = 1 in {
2781 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2782 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2783 Requires<[IsThumb, HasDB]> {
2785 let Inst{31-4} = 0xf3bf8f5;
2786 let Inst{3-0} = opt;
2790 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2792 [/* For disassembly only; pattern left blank */]>,
2793 Requires<[IsThumb, HasDB]> {
2795 let Inst{31-4} = 0xf3bf8f4;
2796 let Inst{3-0} = opt;
2799 // ISB has only full system option -- for disassembly only
2800 def t2ISB : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "isb", "",
2801 [/* For disassembly only; pattern left blank */]>,
2802 Requires<[IsThumb2, HasV7]> {
2803 let Inst{31-4} = 0xf3bf8f6;
2804 let Inst{3-0} = 0b1111;
2807 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2808 InstrItinClass itin, string opc, string asm, string cstr,
2809 list<dag> pattern, bits<4> rt2 = 0b1111>
2810 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2811 let Inst{31-27} = 0b11101;
2812 let Inst{26-20} = 0b0001101;
2813 let Inst{11-8} = rt2;
2814 let Inst{7-6} = 0b01;
2815 let Inst{5-4} = opcod;
2816 let Inst{3-0} = 0b1111;
2820 let Inst{19-16} = Rn;
2821 let Inst{15-12} = Rt;
2823 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2824 InstrItinClass itin, string opc, string asm, string cstr,
2825 list<dag> pattern, bits<4> rt2 = 0b1111>
2826 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2827 let Inst{31-27} = 0b11101;
2828 let Inst{26-20} = 0b0001100;
2829 let Inst{11-8} = rt2;
2830 let Inst{7-6} = 0b01;
2831 let Inst{5-4} = opcod;
2836 let Inst{11-8} = Rd;
2837 let Inst{19-16} = Rn;
2838 let Inst{15-12} = Rt;
2841 let mayLoad = 1 in {
2842 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2843 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
2845 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2846 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
2848 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2849 Size4Bytes, NoItinerary,
2850 "ldrex", "\t$Rt, [$Rn]", "",
2852 let Inst{31-27} = 0b11101;
2853 let Inst{26-20} = 0b0000101;
2854 let Inst{11-8} = 0b1111;
2855 let Inst{7-0} = 0b00000000; // imm8 = 0
2859 let Inst{19-16} = Rn;
2860 let Inst{15-12} = Rt;
2862 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
2863 AddrModeNone, Size4Bytes, NoItinerary,
2864 "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
2867 let Inst{11-8} = Rt2;
2871 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2872 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2873 AddrModeNone, Size4Bytes, NoItinerary,
2874 "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
2875 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2876 AddrModeNone, Size4Bytes, NoItinerary,
2877 "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
2878 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2879 AddrModeNone, Size4Bytes, NoItinerary,
2880 "strex", "\t$Rd, $Rt, [$Rn]", "",
2882 let Inst{31-27} = 0b11101;
2883 let Inst{26-20} = 0b0000100;
2884 let Inst{7-0} = 0b00000000; // imm8 = 0
2889 let Inst{11-8} = Rd;
2890 let Inst{19-16} = Rn;
2891 let Inst{15-12} = Rt;
2893 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2894 (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
2895 AddrModeNone, Size4Bytes, NoItinerary,
2896 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
2899 let Inst{11-8} = Rt2;
2903 // Clear-Exclusive is for disassembly only.
2904 def t2CLREX : T2XI<(outs), (ins), NoItinerary, "clrex",
2905 [/* For disassembly only; pattern left blank */]>,
2906 Requires<[IsThumb2, HasV7]> {
2907 let Inst{31-16} = 0xf3bf;
2908 let Inst{15-14} = 0b10;
2911 let Inst{11-8} = 0b1111;
2912 let Inst{7-4} = 0b0010;
2913 let Inst{3-0} = 0b1111;
2916 //===----------------------------------------------------------------------===//
2920 // __aeabi_read_tp preserves the registers r1-r3.
2922 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
2923 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2924 "bl\t__aeabi_read_tp",
2925 [(set R0, ARMthread_pointer)]> {
2926 let Inst{31-27} = 0b11110;
2927 let Inst{15-14} = 0b11;
2932 //===----------------------------------------------------------------------===//
2933 // SJLJ Exception handling intrinsics
2934 // eh_sjlj_setjmp() is an instruction sequence to store the return
2935 // address and save #0 in R0 for the non-longjmp case.
2936 // Since by its nature we may be coming from some other function to get
2937 // here, and we're using the stack frame for the containing function to
2938 // save/restore registers, we can't keep anything live in regs across
2939 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2940 // when we get here from a longjmp(). We force everthing out of registers
2941 // except for our own input by listing the relevant registers in Defs. By
2942 // doing so, we also cause the prologue/epilogue code to actively preserve
2943 // all of the callee-saved resgisters, which is exactly what we want.
2944 // $val is a scratch register for our use.
2946 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2947 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2948 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2949 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2950 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2951 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2952 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2953 Requires<[IsThumb2, HasVFP2]>;
2957 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2958 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2959 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2960 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2961 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2962 Requires<[IsThumb2, NoVFP]>;
2966 //===----------------------------------------------------------------------===//
2967 // Control-Flow Instructions
2970 // FIXME: remove when we have a way to marking a MI with these properties.
2971 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2973 // FIXME: Should pc be an implicit operand like PICADD, etc?
2974 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2975 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2976 def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2977 reglist:$regs, variable_ops),
2979 "ldmia${p}.w\t$Rn!, $regs",
2984 let Inst{31-27} = 0b11101;
2985 let Inst{26-25} = 0b00;
2986 let Inst{24-23} = 0b01; // Increment After
2988 let Inst{21} = 1; // Writeback
2990 let Inst{19-16} = Rn;
2991 let Inst{15-0} = regs;
2994 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2995 let isPredicable = 1 in
2996 def t2B : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br,
2998 [(br bb:$target)]> {
2999 let Inst{31-27} = 0b11110;
3000 let Inst{15-14} = 0b10;
3004 let Inst{26} = target{19};
3005 let Inst{11} = target{18};
3006 let Inst{13} = target{17};
3007 let Inst{21-16} = target{16-11};
3008 let Inst{10-0} = target{10-0};
3011 let isNotDuplicable = 1, isIndirectBranch = 1 in {
3012 def t2BR_JT : t2PseudoInst<(outs),
3013 (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id),
3014 SizeSpecial, IIC_Br,
3015 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
3017 // FIXME: Add a non-pc based case that can be predicated.
3018 def t2TBB_JT : t2PseudoInst<(outs),
3019 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3020 SizeSpecial, IIC_Br, []>;
3022 def t2TBH_JT : t2PseudoInst<(outs),
3023 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3024 SizeSpecial, IIC_Br, []>;
3026 def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3027 "tbb", "\t[$Rn, $Rm]", []> {
3030 let Inst{31-20} = 0b111010001101;
3031 let Inst{19-16} = Rn;
3032 let Inst{15-5} = 0b11110000000;
3033 let Inst{4} = 0; // B form
3037 def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3038 "tbh", "\t[$Rn, $Rm, lsl #1]", []> {
3041 let Inst{31-20} = 0b111010001101;
3042 let Inst{19-16} = Rn;
3043 let Inst{15-5} = 0b11110000000;
3044 let Inst{4} = 1; // H form
3047 } // isNotDuplicable, isIndirectBranch
3049 } // isBranch, isTerminator, isBarrier
3051 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
3052 // a two-value operand where a dag node expects two operands. :(
3053 let isBranch = 1, isTerminator = 1 in
3054 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3056 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
3057 let Inst{31-27} = 0b11110;
3058 let Inst{15-14} = 0b10;
3062 let Inst{25-22} = p;
3065 let Inst{26} = target{20};
3066 let Inst{11} = target{19};
3067 let Inst{13} = target{18};
3068 let Inst{21-16} = target{17-12};
3069 let Inst{10-0} = target{11-1};
3074 let Defs = [ITSTATE] in
3075 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3076 AddrModeNone, Size2Bytes, IIC_iALUx,
3077 "it$mask\t$cc", "", []> {
3078 // 16-bit instruction.
3079 let Inst{31-16} = 0x0000;
3080 let Inst{15-8} = 0b10111111;
3085 let Inst{3-0} = mask;
3088 // Branch and Exchange Jazelle -- for disassembly only
3090 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
3091 [/* For disassembly only; pattern left blank */]> {
3092 let Inst{31-27} = 0b11110;
3094 let Inst{25-20} = 0b111100;
3095 let Inst{15-14} = 0b10;
3099 let Inst{19-16} = func;
3102 // Change Processor State is a system instruction -- for disassembly and
3104 // FIXME: Since the asm parser has currently no clean way to handle optional
3105 // operands, create 3 versions of the same instruction. Once there's a clean
3106 // framework to represent optional operands, change this behavior.
3107 class t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary,
3108 !strconcat("cps", asm_op),
3109 [/* For disassembly only; pattern left blank */]> {
3115 let Inst{31-27} = 0b11110;
3117 let Inst{25-20} = 0b111010;
3118 let Inst{19-16} = 0b1111;
3119 let Inst{15-14} = 0b10;
3121 let Inst{10-9} = imod;
3123 let Inst{7-5} = iflags;
3124 let Inst{4-0} = mode;
3128 def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
3129 "$imod.w\t$iflags, $mode">;
3130 let mode = 0, M = 0 in
3131 def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags),
3132 "$imod.w\t$iflags">;
3133 let imod = 0, iflags = 0, M = 1 in
3134 def t2CPS1p : t2CPS<(ins i32imm:$mode), "\t$mode">;
3136 // A6.3.4 Branches and miscellaneous control
3137 // Table A6-14 Change Processor State, and hint instructions
3138 // Helper class for disassembly only.
3139 class T2I_hint<bits<8> op7_0, string opc, string asm>
3140 : T2I<(outs), (ins), NoItinerary, opc, asm,
3141 [/* For disassembly only; pattern left blank */]> {
3142 let Inst{31-20} = 0xf3a;
3143 let Inst{19-16} = 0b1111;
3144 let Inst{15-14} = 0b10;
3146 let Inst{10-8} = 0b000;
3147 let Inst{7-0} = op7_0;
3150 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
3151 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
3152 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
3153 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
3154 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
3156 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
3157 [/* For disassembly only; pattern left blank */]> {
3158 let Inst{31-20} = 0xf3a;
3159 let Inst{15-14} = 0b10;
3161 let Inst{10-8} = 0b000;
3162 let Inst{7-4} = 0b1111;
3165 let Inst{3-0} = opt;
3168 // Secure Monitor Call is a system instruction -- for disassembly only
3169 // Option = Inst{19-16}
3170 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
3171 [/* For disassembly only; pattern left blank */]> {
3172 let Inst{31-27} = 0b11110;
3173 let Inst{26-20} = 0b1111111;
3174 let Inst{15-12} = 0b1000;
3177 let Inst{19-16} = opt;
3180 class T2SRS<bits<12> op31_20,
3181 dag oops, dag iops, InstrItinClass itin,
3182 string opc, string asm, list<dag> pattern>
3183 : T2I<oops, iops, itin, opc, asm, pattern> {
3184 let Inst{31-20} = op31_20{11-0};
3187 let Inst{4-0} = mode{4-0};
3190 // Store Return State is a system instruction -- for disassembly only
3191 def t2SRSDBW : T2SRS<0b111010000010,
3192 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
3193 [/* For disassembly only; pattern left blank */]>;
3194 def t2SRSDB : T2SRS<0b111010000000,
3195 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
3196 [/* For disassembly only; pattern left blank */]>;
3197 def t2SRSIAW : T2SRS<0b111010011010,
3198 (outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
3199 [/* For disassembly only; pattern left blank */]>;
3200 def t2SRSIA : T2SRS<0b111010011000,
3201 (outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
3202 [/* For disassembly only; pattern left blank */]>;
3204 // Return From Exception is a system instruction -- for disassembly only
3206 class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3207 string opc, string asm, list<dag> pattern>
3208 : T2I<oops, iops, itin, opc, asm, pattern> {
3209 let Inst{31-20} = op31_20{11-0};
3212 let Inst{19-16} = Rn;
3215 def t2RFEDBW : T2RFE<0b111010000011,
3216 (outs), (ins rGPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3217 [/* For disassembly only; pattern left blank */]>;
3218 def t2RFEDB : T2RFE<0b111010000001,
3219 (outs), (ins rGPR:$Rn), NoItinerary, "rfeab", "\t$Rn",
3220 [/* For disassembly only; pattern left blank */]>;
3221 def t2RFEIAW : T2RFE<0b111010011011,
3222 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3223 [/* For disassembly only; pattern left blank */]>;
3224 def t2RFEIA : T2RFE<0b111010011001,
3225 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3226 [/* For disassembly only; pattern left blank */]>;
3228 //===----------------------------------------------------------------------===//
3229 // Non-Instruction Patterns
3232 // 32-bit immediate using movw + movt.
3233 // This is a single pseudo instruction to make it re-materializable.
3234 // FIXME: Remove this when we can do generalized remat.
3235 let isReMaterializable = 1, isMoveImm = 1 in
3236 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3237 [(set rGPR:$dst, (i32 imm:$src))]>,
3238 Requires<[IsThumb, HasV6T2]>;
3240 // Pseudo instruction that combines movw + movt + add pc (if pic).
3241 // It also makes it possible to rematerialize the instructions.
3242 // FIXME: Remove this when we can do generalized remat and when machine licm
3243 // can properly the instructions.
3244 let isReMaterializable = 1 in {
3245 def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3247 [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3248 Requires<[IsThumb2, UseMovt]>;
3250 def t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3252 [(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3253 Requires<[IsThumb2, UseMovt]>;
3256 // ConstantPool, GlobalAddress, and JumpTable
3257 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
3258 Requires<[IsThumb2, DontUseMovt]>;
3259 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
3260 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3261 Requires<[IsThumb2, UseMovt]>;
3263 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3264 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
3266 // Pseudo instruction that combines ldr from constpool and add pc. This should
3267 // be expanded into two instructions late to allow if-conversion and
3269 let canFoldAsLoad = 1, isReMaterializable = 1 in
3270 def t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3272 [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3274 Requires<[IsThumb2]>;
3276 //===----------------------------------------------------------------------===//
3277 // Move between special register and ARM core register -- for disassembly only
3280 class T2SpecialReg<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3281 dag oops, dag iops, InstrItinClass itin,
3282 string opc, string asm, list<dag> pattern>
3283 : T2I<oops, iops, itin, opc, asm, pattern> {
3284 let Inst{31-20} = op31_20{11-0};
3285 let Inst{15-14} = op15_14{1-0};
3286 let Inst{12} = op12{0};
3289 class T2MRS<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3290 dag oops, dag iops, InstrItinClass itin,
3291 string opc, string asm, list<dag> pattern>
3292 : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3294 let Inst{11-8} = Rd;
3295 let Inst{19-16} = 0b1111;
3298 def t2MRS : T2MRS<0b111100111110, 0b10, 0,
3299 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3300 [/* For disassembly only; pattern left blank */]>;
3301 def t2MRSsys : T2MRS<0b111100111111, 0b10, 0,
3302 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
3303 [/* For disassembly only; pattern left blank */]>;
3305 // Move from ARM core register to Special Register
3307 // No need to have both system and application versions, the encodings are the
3308 // same and the assembly parser has no way to distinguish between them. The mask
3309 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3310 // the mask with the fields to be accessed in the special register.
3311 def t2MSR : T2SpecialReg<0b111100111000 /* op31-20 */, 0b10 /* op15-14 */,
3312 0 /* op12 */, (outs), (ins msr_mask:$mask, rGPR:$Rn),
3313 NoItinerary, "msr", "\t$mask, $Rn",
3314 [/* For disassembly only; pattern left blank */]> {
3317 let Inst{19-16} = Rn;
3318 let Inst{20} = mask{4}; // R Bit
3320 let Inst{11-8} = mask{3-0};
3323 //===----------------------------------------------------------------------===//
3324 // Move between coprocessor and ARM core register -- for disassembly only
3327 class t2MovRCopro<string opc, bit direction>
3328 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
3329 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3330 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3331 [/* For disassembly only; pattern left blank */]> {
3332 let Inst{27-24} = 0b1110;
3333 let Inst{20} = direction;
3343 let Inst{15-12} = Rt;
3344 let Inst{11-8} = cop;
3345 let Inst{23-21} = opc1;
3346 let Inst{7-5} = opc2;
3347 let Inst{3-0} = CRm;
3348 let Inst{19-16} = CRn;
3351 def t2MCR2 : t2MovRCopro<"mcr2", 0 /* from ARM core register to coprocessor */>;
3352 def t2MRC2 : t2MovRCopro<"mrc2", 1 /* from coprocessor to ARM core register */>;
3354 class t2MovRRCopro<string opc, bit direction>
3355 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3356 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3357 [/* For disassembly only; pattern left blank */]> {
3358 let Inst{27-24} = 0b1100;
3359 let Inst{23-21} = 0b010;
3360 let Inst{20} = direction;
3368 let Inst{15-12} = Rt;
3369 let Inst{19-16} = Rt2;
3370 let Inst{11-8} = cop;
3371 let Inst{7-4} = opc1;
3372 let Inst{3-0} = CRm;
3375 def t2MCRR2 : t2MovRRCopro<"mcrr2",
3376 0 /* from ARM core register to coprocessor */>;
3377 def t2MRRC2 : t2MovRRCopro<"mrrc2",
3378 1 /* from coprocessor to ARM core register */>;
3380 //===----------------------------------------------------------------------===//
3381 // Other Coprocessor Instructions. For disassembly only.
3384 def t2CDP2 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
3385 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3386 "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3387 [/* For disassembly only; pattern left blank */]> {
3388 let Inst{27-24} = 0b1110;
3397 let Inst{3-0} = CRm;
3399 let Inst{7-5} = opc2;
3400 let Inst{11-8} = cop;
3401 let Inst{15-12} = CRd;
3402 let Inst{19-16} = CRn;
3403 let Inst{23-20} = opc1;