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 : ImmLeaf<i32, [{
66 return (int32_t)Imm >= 1 && (int32_t)Imm < 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 Imm >= 0 && Imm < 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;
148 // t2addrmode_reg := reg
149 // Used by load/store exclusive instructions. Useful to enable right assembly
150 // parsing and printing. Not used for any codegen matching.
152 def t2addrmode_reg : Operand<i32> {
153 let PrintMethod = "printAddrMode7Operand";
154 let MIOperandInfo = (ops tGPR);
155 let ParserMatchClass = MemMode7AsmOperand;
158 //===----------------------------------------------------------------------===//
159 // Multiclass helpers...
163 class T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
164 string opc, string asm, list<dag> pattern>
165 : T2I<oops, iops, itin, opc, asm, pattern> {
170 let Inst{26} = imm{11};
171 let Inst{14-12} = imm{10-8};
172 let Inst{7-0} = imm{7-0};
176 class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
177 string opc, string asm, list<dag> pattern>
178 : T2sI<oops, iops, itin, opc, asm, pattern> {
184 let Inst{26} = imm{11};
185 let Inst{14-12} = imm{10-8};
186 let Inst{7-0} = imm{7-0};
189 class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin,
190 string opc, string asm, list<dag> pattern>
191 : T2I<oops, iops, itin, opc, asm, pattern> {
195 let Inst{19-16} = Rn;
196 let Inst{26} = imm{11};
197 let Inst{14-12} = imm{10-8};
198 let Inst{7-0} = imm{7-0};
202 class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
203 string opc, string asm, list<dag> pattern>
204 : T2I<oops, iops, itin, opc, asm, pattern> {
209 let Inst{3-0} = ShiftedRm{3-0};
210 let Inst{5-4} = ShiftedRm{6-5};
211 let Inst{14-12} = ShiftedRm{11-9};
212 let Inst{7-6} = ShiftedRm{8-7};
215 class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
216 string opc, string asm, list<dag> pattern>
217 : T2sI<oops, iops, itin, opc, asm, pattern> {
222 let Inst{3-0} = ShiftedRm{3-0};
223 let Inst{5-4} = ShiftedRm{6-5};
224 let Inst{14-12} = ShiftedRm{11-9};
225 let Inst{7-6} = ShiftedRm{8-7};
228 class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin,
229 string opc, string asm, list<dag> pattern>
230 : T2I<oops, iops, itin, opc, asm, pattern> {
234 let Inst{19-16} = Rn;
235 let Inst{3-0} = ShiftedRm{3-0};
236 let Inst{5-4} = ShiftedRm{6-5};
237 let Inst{14-12} = ShiftedRm{11-9};
238 let Inst{7-6} = ShiftedRm{8-7};
241 class T2TwoReg<dag oops, dag iops, InstrItinClass itin,
242 string opc, string asm, list<dag> pattern>
243 : T2I<oops, iops, itin, opc, asm, pattern> {
251 class T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
252 string opc, string asm, list<dag> pattern>
253 : T2sI<oops, iops, itin, opc, asm, pattern> {
261 class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin,
262 string opc, string asm, list<dag> pattern>
263 : T2I<oops, iops, itin, opc, asm, pattern> {
267 let Inst{19-16} = Rn;
272 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
273 string opc, string asm, list<dag> pattern>
274 : T2I<oops, iops, itin, opc, asm, pattern> {
280 let Inst{19-16} = Rn;
281 let Inst{26} = imm{11};
282 let Inst{14-12} = imm{10-8};
283 let Inst{7-0} = imm{7-0};
286 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
287 string opc, string asm, list<dag> pattern>
288 : T2sI<oops, iops, itin, opc, asm, pattern> {
294 let Inst{19-16} = Rn;
295 let Inst{26} = imm{11};
296 let Inst{14-12} = imm{10-8};
297 let Inst{7-0} = imm{7-0};
300 class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
301 string opc, string asm, list<dag> pattern>
302 : T2I<oops, iops, itin, opc, asm, pattern> {
309 let Inst{14-12} = imm{4-2};
310 let Inst{7-6} = imm{1-0};
313 class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
314 string opc, string asm, list<dag> pattern>
315 : T2sI<oops, iops, itin, opc, asm, pattern> {
322 let Inst{14-12} = imm{4-2};
323 let Inst{7-6} = imm{1-0};
326 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
327 string opc, string asm, list<dag> pattern>
328 : T2I<oops, iops, itin, opc, asm, pattern> {
334 let Inst{19-16} = Rn;
338 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
339 string opc, string asm, list<dag> pattern>
340 : T2sI<oops, iops, itin, opc, asm, pattern> {
346 let Inst{19-16} = Rn;
350 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
351 string opc, string asm, list<dag> pattern>
352 : T2I<oops, iops, itin, opc, asm, pattern> {
358 let Inst{19-16} = Rn;
359 let Inst{3-0} = ShiftedRm{3-0};
360 let Inst{5-4} = ShiftedRm{6-5};
361 let Inst{14-12} = ShiftedRm{11-9};
362 let Inst{7-6} = ShiftedRm{8-7};
365 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
366 string opc, string asm, list<dag> pattern>
367 : T2sI<oops, iops, itin, opc, asm, pattern> {
373 let Inst{19-16} = Rn;
374 let Inst{3-0} = ShiftedRm{3-0};
375 let Inst{5-4} = ShiftedRm{6-5};
376 let Inst{14-12} = ShiftedRm{11-9};
377 let Inst{7-6} = ShiftedRm{8-7};
380 class T2FourReg<dag oops, dag iops, InstrItinClass itin,
381 string opc, string asm, list<dag> pattern>
382 : T2I<oops, iops, itin, opc, asm, pattern> {
388 let Inst{19-16} = Rn;
389 let Inst{15-12} = Ra;
394 class T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
395 dag oops, dag iops, InstrItinClass itin,
396 string opc, string asm, list<dag> pattern>
397 : T2I<oops, iops, itin, opc, asm, pattern> {
403 let Inst{31-23} = 0b111110111;
404 let Inst{22-20} = opc22_20;
405 let Inst{19-16} = Rn;
406 let Inst{15-12} = RdLo;
407 let Inst{11-8} = RdHi;
408 let Inst{7-4} = opc7_4;
413 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
414 /// unary operation that produces a value. These are predicable and can be
415 /// changed to modify CPSR.
416 multiclass T2I_un_irs<bits<4> opcod, string opc,
417 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
418 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
420 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
422 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> {
423 let isAsCheapAsAMove = Cheap;
424 let isReMaterializable = ReMat;
425 let Inst{31-27} = 0b11110;
427 let Inst{24-21} = opcod;
428 let Inst{19-16} = 0b1111; // Rn
432 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
434 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
435 let Inst{31-27} = 0b11101;
436 let Inst{26-25} = 0b01;
437 let Inst{24-21} = opcod;
438 let Inst{19-16} = 0b1111; // Rn
439 let Inst{14-12} = 0b000; // imm3
440 let Inst{7-6} = 0b00; // imm2
441 let Inst{5-4} = 0b00; // type
444 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
445 opc, ".w\t$Rd, $ShiftedRm",
446 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> {
447 let Inst{31-27} = 0b11101;
448 let Inst{26-25} = 0b01;
449 let Inst{24-21} = opcod;
450 let Inst{19-16} = 0b1111; // Rn
454 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
455 /// binary operation that produces a value. These are predicable and can be
456 /// changed to modify CPSR.
457 multiclass T2I_bin_irs<bits<4> opcod, string opc,
458 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
459 PatFrag opnode, bit Commutable = 0, string wide = ""> {
461 def ri : T2sTwoRegImm<
462 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
463 opc, "\t$Rd, $Rn, $imm",
464 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
465 let Inst{31-27} = 0b11110;
467 let Inst{24-21} = opcod;
471 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
472 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
473 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
474 let isCommutable = Commutable;
475 let Inst{31-27} = 0b11101;
476 let Inst{26-25} = 0b01;
477 let Inst{24-21} = opcod;
478 let Inst{14-12} = 0b000; // imm3
479 let Inst{7-6} = 0b00; // imm2
480 let Inst{5-4} = 0b00; // type
483 def rs : T2sTwoRegShiftedReg<
484 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
485 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
486 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
487 let Inst{31-27} = 0b11101;
488 let Inst{26-25} = 0b01;
489 let Inst{24-21} = opcod;
493 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
494 // the ".w" prefix to indicate that they are wide.
495 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
496 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
497 PatFrag opnode, bit Commutable = 0> :
498 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
500 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
501 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
502 /// it is equivalent to the T2I_bin_irs counterpart.
503 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
505 def ri : T2sTwoRegImm<
506 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
507 opc, ".w\t$Rd, $Rn, $imm",
508 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
509 let Inst{31-27} = 0b11110;
511 let Inst{24-21} = opcod;
515 def rr : T2sThreeReg<
516 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
517 opc, "\t$Rd, $Rn, $Rm",
518 [/* For disassembly only; pattern left blank */]> {
519 let Inst{31-27} = 0b11101;
520 let Inst{26-25} = 0b01;
521 let Inst{24-21} = opcod;
522 let Inst{14-12} = 0b000; // imm3
523 let Inst{7-6} = 0b00; // imm2
524 let Inst{5-4} = 0b00; // type
527 def rs : T2sTwoRegShiftedReg<
528 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
529 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
530 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
531 let Inst{31-27} = 0b11101;
532 let Inst{26-25} = 0b01;
533 let Inst{24-21} = opcod;
537 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
538 /// instruction modifies the CPSR register.
539 let isCodeGenOnly = 1, Defs = [CPSR] in {
540 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
541 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
542 PatFrag opnode, bit Commutable = 0> {
544 def ri : T2TwoRegImm<
545 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
546 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
547 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
548 let Inst{31-27} = 0b11110;
550 let Inst{24-21} = opcod;
551 let Inst{20} = 1; // The S bit.
556 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
557 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
558 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
559 let isCommutable = Commutable;
560 let Inst{31-27} = 0b11101;
561 let Inst{26-25} = 0b01;
562 let Inst{24-21} = opcod;
563 let Inst{20} = 1; // The S bit.
564 let Inst{14-12} = 0b000; // imm3
565 let Inst{7-6} = 0b00; // imm2
566 let Inst{5-4} = 0b00; // type
569 def rs : T2TwoRegShiftedReg<
570 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
571 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
572 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
573 let Inst{31-27} = 0b11101;
574 let Inst{26-25} = 0b01;
575 let Inst{24-21} = opcod;
576 let Inst{20} = 1; // The S bit.
581 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
582 /// patterns for a binary operation that produces a value.
583 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
584 bit Commutable = 0> {
586 // The register-immediate version is re-materializable. This is useful
587 // in particular for taking the address of a local.
588 let isReMaterializable = 1 in {
589 def ri : T2sTwoRegImm<
590 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
591 opc, ".w\t$Rd, $Rn, $imm",
592 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
593 let Inst{31-27} = 0b11110;
596 let Inst{23-21} = op23_21;
602 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
603 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
604 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
608 let Inst{31-27} = 0b11110;
609 let Inst{26} = imm{11};
610 let Inst{25-24} = 0b10;
611 let Inst{23-21} = op23_21;
612 let Inst{20} = 0; // The S bit.
613 let Inst{19-16} = Rn;
615 let Inst{14-12} = imm{10-8};
617 let Inst{7-0} = imm{7-0};
620 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
621 opc, ".w\t$Rd, $Rn, $Rm",
622 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
623 let isCommutable = Commutable;
624 let Inst{31-27} = 0b11101;
625 let Inst{26-25} = 0b01;
627 let Inst{23-21} = op23_21;
628 let Inst{14-12} = 0b000; // imm3
629 let Inst{7-6} = 0b00; // imm2
630 let Inst{5-4} = 0b00; // type
633 def rs : T2sTwoRegShiftedReg<
634 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
635 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
636 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
637 let Inst{31-27} = 0b11101;
638 let Inst{26-25} = 0b01;
640 let Inst{23-21} = op23_21;
644 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
645 /// for a binary operation that produces a value and use the carry
646 /// bit. It's not predicable.
647 let Uses = [CPSR] in {
648 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
649 bit Commutable = 0> {
651 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
652 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
653 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
654 Requires<[IsThumb2]> {
655 let Inst{31-27} = 0b11110;
657 let Inst{24-21} = opcod;
661 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
662 opc, ".w\t$Rd, $Rn, $Rm",
663 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
664 Requires<[IsThumb2]> {
665 let isCommutable = Commutable;
666 let Inst{31-27} = 0b11101;
667 let Inst{26-25} = 0b01;
668 let Inst{24-21} = opcod;
669 let Inst{14-12} = 0b000; // imm3
670 let Inst{7-6} = 0b00; // imm2
671 let Inst{5-4} = 0b00; // type
674 def rs : T2sTwoRegShiftedReg<
675 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
676 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
677 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
678 Requires<[IsThumb2]> {
679 let Inst{31-27} = 0b11101;
680 let Inst{26-25} = 0b01;
681 let Inst{24-21} = opcod;
686 // Carry setting variants
687 // NOTE: CPSR def omitted because it will be handled by the custom inserter.
688 let usesCustomInserter = 1 in {
689 multiclass T2I_adde_sube_s_irs<PatFrag opnode, bit Commutable = 0> {
691 def ri : t2PseudoInst<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
692 Size4Bytes, IIC_iALUi,
693 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>;
695 def rr : t2PseudoInst<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
696 Size4Bytes, IIC_iALUr,
697 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
698 let isCommutable = Commutable;
701 def rs : t2PseudoInst<
702 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
703 Size4Bytes, IIC_iALUsi,
704 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>;
708 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
709 /// version is not needed since this is only for codegen.
710 let isCodeGenOnly = 1, Defs = [CPSR] in {
711 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
713 def ri : T2TwoRegImm<
714 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
715 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
716 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
717 let Inst{31-27} = 0b11110;
719 let Inst{24-21} = opcod;
720 let Inst{20} = 1; // The S bit.
724 def rs : T2TwoRegShiftedReg<
725 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
726 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
727 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
728 let Inst{31-27} = 0b11101;
729 let Inst{26-25} = 0b01;
730 let Inst{24-21} = opcod;
731 let Inst{20} = 1; // The S bit.
736 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
737 // rotate operation that produces a value.
738 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
740 def ri : T2sTwoRegShiftImm<
741 (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi,
742 opc, ".w\t$Rd, $Rm, $imm",
743 [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> {
744 let Inst{31-27} = 0b11101;
745 let Inst{26-21} = 0b010010;
746 let Inst{19-16} = 0b1111; // Rn
747 let Inst{5-4} = opcod;
750 def rr : T2sThreeReg<
751 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr,
752 opc, ".w\t$Rd, $Rn, $Rm",
753 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
754 let Inst{31-27} = 0b11111;
755 let Inst{26-23} = 0b0100;
756 let Inst{22-21} = opcod;
757 let Inst{15-12} = 0b1111;
758 let Inst{7-4} = 0b0000;
762 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
763 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
764 /// a explicit result, only implicitly set CPSR.
765 let isCompare = 1, Defs = [CPSR] in {
766 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
767 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
770 def ri : T2OneRegCmpImm<
771 (outs), (ins GPR:$Rn, t2_so_imm:$imm), iii,
772 opc, ".w\t$Rn, $imm",
773 [(opnode GPR:$Rn, t2_so_imm:$imm)]> {
774 let Inst{31-27} = 0b11110;
776 let Inst{24-21} = opcod;
777 let Inst{20} = 1; // The S bit.
779 let Inst{11-8} = 0b1111; // Rd
782 def rr : T2TwoRegCmp<
783 (outs), (ins GPR:$lhs, rGPR:$rhs), iir,
784 opc, ".w\t$lhs, $rhs",
785 [(opnode GPR:$lhs, rGPR:$rhs)]> {
786 let Inst{31-27} = 0b11101;
787 let Inst{26-25} = 0b01;
788 let Inst{24-21} = opcod;
789 let Inst{20} = 1; // The S bit.
790 let Inst{14-12} = 0b000; // imm3
791 let Inst{11-8} = 0b1111; // Rd
792 let Inst{7-6} = 0b00; // imm2
793 let Inst{5-4} = 0b00; // type
796 def rs : T2OneRegCmpShiftedReg<
797 (outs), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
798 opc, ".w\t$Rn, $ShiftedRm",
799 [(opnode GPR:$Rn, t2_so_reg:$ShiftedRm)]> {
800 let Inst{31-27} = 0b11101;
801 let Inst{26-25} = 0b01;
802 let Inst{24-21} = opcod;
803 let Inst{20} = 1; // The S bit.
804 let Inst{11-8} = 0b1111; // Rd
809 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
810 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
811 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
812 def i12 : T2Ii12<(outs GPR:$Rt), (ins t2addrmode_imm12:$addr), iii,
813 opc, ".w\t$Rt, $addr",
814 [(set GPR:$Rt, (opnode t2addrmode_imm12:$addr))]> {
815 let Inst{31-27} = 0b11111;
816 let Inst{26-25} = 0b00;
817 let Inst{24} = signed;
819 let Inst{22-21} = opcod;
820 let Inst{20} = 1; // load
823 let Inst{15-12} = Rt;
826 let addr{12} = 1; // add = TRUE
827 let Inst{19-16} = addr{16-13}; // Rn
828 let Inst{23} = addr{12}; // U
829 let Inst{11-0} = addr{11-0}; // imm
831 def i8 : T2Ii8 <(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), iii,
833 [(set GPR:$Rt, (opnode t2addrmode_imm8:$addr))]> {
834 let Inst{31-27} = 0b11111;
835 let Inst{26-25} = 0b00;
836 let Inst{24} = signed;
838 let Inst{22-21} = opcod;
839 let Inst{20} = 1; // load
841 // Offset: index==TRUE, wback==FALSE
842 let Inst{10} = 1; // The P bit.
843 let Inst{8} = 0; // The W bit.
846 let Inst{15-12} = Rt;
849 let Inst{19-16} = addr{12-9}; // Rn
850 let Inst{9} = addr{8}; // U
851 let Inst{7-0} = addr{7-0}; // imm
853 def s : T2Iso <(outs GPR:$Rt), (ins t2addrmode_so_reg:$addr), iis,
854 opc, ".w\t$Rt, $addr",
855 [(set GPR:$Rt, (opnode t2addrmode_so_reg:$addr))]> {
856 let Inst{31-27} = 0b11111;
857 let Inst{26-25} = 0b00;
858 let Inst{24} = signed;
860 let Inst{22-21} = opcod;
861 let Inst{20} = 1; // load
862 let Inst{11-6} = 0b000000;
865 let Inst{15-12} = Rt;
868 let Inst{19-16} = addr{9-6}; // Rn
869 let Inst{3-0} = addr{5-2}; // Rm
870 let Inst{5-4} = addr{1-0}; // imm
873 // FIXME: Is the pci variant actually needed?
874 def pci : T2Ipc <(outs GPR:$Rt), (ins t2ldrlabel:$addr), iii,
875 opc, ".w\t$Rt, $addr",
876 [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
877 let isReMaterializable = 1;
878 let Inst{31-27} = 0b11111;
879 let Inst{26-25} = 0b00;
880 let Inst{24} = signed;
881 let Inst{23} = ?; // add = (U == '1')
882 let Inst{22-21} = opcod;
883 let Inst{20} = 1; // load
884 let Inst{19-16} = 0b1111; // Rn
887 let Inst{15-12} = Rt{3-0};
888 let Inst{11-0} = addr{11-0};
892 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
893 multiclass T2I_st<bits<2> opcod, string opc,
894 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
895 def i12 : T2Ii12<(outs), (ins GPR:$Rt, t2addrmode_imm12:$addr), iii,
896 opc, ".w\t$Rt, $addr",
897 [(opnode GPR:$Rt, t2addrmode_imm12:$addr)]> {
898 let Inst{31-27} = 0b11111;
899 let Inst{26-23} = 0b0001;
900 let Inst{22-21} = opcod;
901 let Inst{20} = 0; // !load
904 let Inst{15-12} = Rt;
907 let addr{12} = 1; // add = TRUE
908 let Inst{19-16} = addr{16-13}; // Rn
909 let Inst{23} = addr{12}; // U
910 let Inst{11-0} = addr{11-0}; // imm
912 def i8 : T2Ii8 <(outs), (ins GPR:$Rt, t2addrmode_imm8:$addr), iii,
914 [(opnode GPR:$Rt, t2addrmode_imm8:$addr)]> {
915 let Inst{31-27} = 0b11111;
916 let Inst{26-23} = 0b0000;
917 let Inst{22-21} = opcod;
918 let Inst{20} = 0; // !load
920 // Offset: index==TRUE, wback==FALSE
921 let Inst{10} = 1; // The P bit.
922 let Inst{8} = 0; // The W bit.
925 let Inst{15-12} = Rt;
928 let Inst{19-16} = addr{12-9}; // Rn
929 let Inst{9} = addr{8}; // U
930 let Inst{7-0} = addr{7-0}; // imm
932 def s : T2Iso <(outs), (ins GPR:$Rt, t2addrmode_so_reg:$addr), iis,
933 opc, ".w\t$Rt, $addr",
934 [(opnode GPR:$Rt, t2addrmode_so_reg:$addr)]> {
935 let Inst{31-27} = 0b11111;
936 let Inst{26-23} = 0b0000;
937 let Inst{22-21} = opcod;
938 let Inst{20} = 0; // !load
939 let Inst{11-6} = 0b000000;
942 let Inst{15-12} = Rt;
945 let Inst{19-16} = addr{9-6}; // Rn
946 let Inst{3-0} = addr{5-2}; // Rm
947 let Inst{5-4} = addr{1-0}; // imm
951 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
952 /// register and one whose operand is a register rotated by 8/16/24.
953 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
954 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
956 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
957 let Inst{31-27} = 0b11111;
958 let Inst{26-23} = 0b0100;
959 let Inst{22-20} = opcod;
960 let Inst{19-16} = 0b1111; // Rn
961 let Inst{15-12} = 0b1111;
963 let Inst{5-4} = 0b00; // rotate
965 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
966 opc, ".w\t$Rd, $Rm, ror $rot",
967 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> {
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;
976 let Inst{5-4} = rot{1-0}; // rotate
980 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
981 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
982 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
984 [(set rGPR:$Rd, (opnode rGPR:$Rm))]>,
985 Requires<[HasT2ExtractPack, IsThumb2]> {
986 let Inst{31-27} = 0b11111;
987 let Inst{26-23} = 0b0100;
988 let Inst{22-20} = opcod;
989 let Inst{19-16} = 0b1111; // Rn
990 let Inst{15-12} = 0b1111;
992 let Inst{5-4} = 0b00; // rotate
994 def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot),
995 IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot",
996 [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
997 Requires<[HasT2ExtractPack, IsThumb2]> {
998 let Inst{31-27} = 0b11111;
999 let Inst{26-23} = 0b0100;
1000 let Inst{22-20} = opcod;
1001 let Inst{19-16} = 0b1111; // Rn
1002 let Inst{15-12} = 0b1111;
1006 let Inst{5-4} = rot{1-0}; // rotate
1010 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
1012 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
1013 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
1014 opc, "\t$Rd, $Rm", []> {
1015 let Inst{31-27} = 0b11111;
1016 let Inst{26-23} = 0b0100;
1017 let Inst{22-20} = opcod;
1018 let Inst{19-16} = 0b1111; // Rn
1019 let Inst{15-12} = 0b1111;
1021 let Inst{5-4} = 0b00; // rotate
1023 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
1024 opc, "\t$Rd, $Rm, ror $rot", []> {
1025 let Inst{31-27} = 0b11111;
1026 let Inst{26-23} = 0b0100;
1027 let Inst{22-20} = opcod;
1028 let Inst{19-16} = 0b1111; // Rn
1029 let Inst{15-12} = 0b1111;
1033 let Inst{5-4} = rot{1-0}; // rotate
1037 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
1038 /// register and one whose operand is a register rotated by 8/16/24.
1039 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
1040 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1041 opc, "\t$Rd, $Rn, $Rm",
1042 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
1043 Requires<[HasT2ExtractPack, IsThumb2]> {
1044 let Inst{31-27} = 0b11111;
1045 let Inst{26-23} = 0b0100;
1046 let Inst{22-20} = opcod;
1047 let Inst{15-12} = 0b1111;
1049 let Inst{5-4} = 0b00; // rotate
1051 def rr_rot : T2ThreeReg<(outs rGPR:$Rd),
1052 (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
1053 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
1054 [(set rGPR:$Rd, (opnode rGPR:$Rn,
1055 (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1056 Requires<[HasT2ExtractPack, IsThumb2]> {
1057 let Inst{31-27} = 0b11111;
1058 let Inst{26-23} = 0b0100;
1059 let Inst{22-20} = opcod;
1060 let Inst{15-12} = 0b1111;
1064 let Inst{5-4} = rot{1-0}; // rotate
1068 // DO variant - disassembly only, no pattern
1070 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
1071 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1072 opc, "\t$Rd, $Rn, $Rm", []> {
1073 let Inst{31-27} = 0b11111;
1074 let Inst{26-23} = 0b0100;
1075 let Inst{22-20} = opcod;
1076 let Inst{15-12} = 0b1111;
1078 let Inst{5-4} = 0b00; // rotate
1080 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
1081 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> {
1082 let Inst{31-27} = 0b11111;
1083 let Inst{26-23} = 0b0100;
1084 let Inst{22-20} = opcod;
1085 let Inst{15-12} = 0b1111;
1089 let Inst{5-4} = rot{1-0}; // rotate
1093 //===----------------------------------------------------------------------===//
1095 //===----------------------------------------------------------------------===//
1097 //===----------------------------------------------------------------------===//
1098 // Miscellaneous Instructions.
1101 class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
1102 string asm, list<dag> pattern>
1103 : T2XI<oops, iops, itin, asm, pattern> {
1107 let Inst{11-8} = Rd;
1108 let Inst{26} = label{11};
1109 let Inst{14-12} = label{10-8};
1110 let Inst{7-0} = label{7-0};
1113 // LEApcrel - Load a pc-relative address into a register without offending the
1115 def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
1116 (ins t2adrlabel:$addr, pred:$p),
1117 IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> {
1118 let Inst{31-27} = 0b11110;
1119 let Inst{25-24} = 0b10;
1120 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1123 let Inst{19-16} = 0b1111; // Rn
1128 let Inst{11-8} = Rd;
1129 let Inst{23} = addr{12};
1130 let Inst{21} = addr{12};
1131 let Inst{26} = addr{11};
1132 let Inst{14-12} = addr{10-8};
1133 let Inst{7-0} = addr{7-0};
1136 let neverHasSideEffects = 1, isReMaterializable = 1 in
1137 def t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
1138 Size4Bytes, IIC_iALUi, []>;
1139 def t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd),
1140 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1141 Size4Bytes, IIC_iALUi,
1145 // FIXME: None of these add/sub SP special instructions should be necessary
1146 // at all for thumb2 since they use the same encodings as the generic
1147 // add/sub instructions. In thumb1 we need them since they have dedicated
1148 // encodings. At the least, they should be pseudo instructions.
1149 // ADD r, sp, {so_imm|i12}
1150 let isCodeGenOnly = 1 in {
1151 def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1152 IIC_iALUi, "add", ".w\t$Rd, $Rn, $imm", []> {
1153 let Inst{31-27} = 0b11110;
1155 let Inst{24-21} = 0b1000;
1158 def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1159 IIC_iALUi, "addw", "\t$Rd, $Rn, $imm", []> {
1160 let Inst{31-27} = 0b11110;
1161 let Inst{25-20} = 0b100000;
1165 // ADD r, sp, so_reg
1166 def t2ADDrSPs : T2sTwoRegShiftedReg<
1167 (outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
1168 IIC_iALUsi, "add", ".w\t$Rd, $Rn, $ShiftedRm", []> {
1169 let Inst{31-27} = 0b11101;
1170 let Inst{26-25} = 0b01;
1171 let Inst{24-21} = 0b1000;
1175 // SUB r, sp, {so_imm|i12}
1176 def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
1177 IIC_iALUi, "sub", ".w\t$Rd, $Rn, $imm", []> {
1178 let Inst{31-27} = 0b11110;
1180 let Inst{24-21} = 0b1101;
1183 def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
1184 IIC_iALUi, "subw", "\t$Rd, $Rn, $imm", []> {
1185 let Inst{31-27} = 0b11110;
1186 let Inst{25-20} = 0b101010;
1190 // SUB r, sp, so_reg
1191 def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$imm),
1193 "sub", "\t$Rd, $Rn, $imm", []> {
1194 let Inst{31-27} = 0b11101;
1195 let Inst{26-25} = 0b01;
1196 let Inst{24-21} = 0b1101;
1197 let Inst{19-16} = 0b1101; // Rn = sp
1200 } // end isCodeGenOnly = 1
1202 // Signed and unsigned division on v7-M
1203 def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1204 "sdiv", "\t$Rd, $Rn, $Rm",
1205 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>,
1206 Requires<[HasDivide, IsThumb2]> {
1207 let Inst{31-27} = 0b11111;
1208 let Inst{26-21} = 0b011100;
1210 let Inst{15-12} = 0b1111;
1211 let Inst{7-4} = 0b1111;
1214 def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1215 "udiv", "\t$Rd, $Rn, $Rm",
1216 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>,
1217 Requires<[HasDivide, IsThumb2]> {
1218 let Inst{31-27} = 0b11111;
1219 let Inst{26-21} = 0b011101;
1221 let Inst{15-12} = 0b1111;
1222 let Inst{7-4} = 0b1111;
1225 //===----------------------------------------------------------------------===//
1226 // Load / store Instructions.
1230 let canFoldAsLoad = 1, isReMaterializable = 1 in
1231 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1232 UnOpFrag<(load node:$Src)>>;
1234 // Loads with zero extension
1235 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1236 UnOpFrag<(zextloadi16 node:$Src)>>;
1237 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1238 UnOpFrag<(zextloadi8 node:$Src)>>;
1240 // Loads with sign extension
1241 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1242 UnOpFrag<(sextloadi16 node:$Src)>>;
1243 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1244 UnOpFrag<(sextloadi8 node:$Src)>>;
1246 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1248 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1249 (ins t2addrmode_imm8s4:$addr),
1250 IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", []>;
1251 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1253 // zextload i1 -> zextload i8
1254 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1255 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1256 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1257 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1258 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1259 (t2LDRBs t2addrmode_so_reg:$addr)>;
1260 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1261 (t2LDRBpci tconstpool:$addr)>;
1263 // extload -> zextload
1264 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1266 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1267 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1268 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1269 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1270 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1271 (t2LDRBs t2addrmode_so_reg:$addr)>;
1272 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1273 (t2LDRBpci tconstpool:$addr)>;
1275 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1276 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1277 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1278 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1279 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1280 (t2LDRBs t2addrmode_so_reg:$addr)>;
1281 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1282 (t2LDRBpci tconstpool:$addr)>;
1284 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1285 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1286 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1287 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1288 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1289 (t2LDRHs t2addrmode_so_reg:$addr)>;
1290 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1291 (t2LDRHpci tconstpool:$addr)>;
1293 // FIXME: The destination register of the loads and stores can't be PC, but
1294 // can be SP. We need another regclass (similar to rGPR) to represent
1295 // that. Not a pressing issue since these are selected manually,
1300 let mayLoad = 1, neverHasSideEffects = 1 in {
1301 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1302 (ins t2addrmode_imm8:$addr),
1303 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1304 "ldr", "\t$Rt, $addr!", "$addr.base = $Rn",
1307 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1308 (ins GPR:$base, t2am_imm8_offset:$addr),
1309 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1310 "ldr", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1313 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1314 (ins t2addrmode_imm8:$addr),
1315 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1316 "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn",
1318 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1319 (ins GPR:$base, t2am_imm8_offset:$addr),
1320 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1321 "ldrb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1324 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1325 (ins t2addrmode_imm8:$addr),
1326 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1327 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn",
1329 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1330 (ins GPR:$base, t2am_imm8_offset:$addr),
1331 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1332 "ldrh", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1335 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1336 (ins t2addrmode_imm8:$addr),
1337 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1338 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn",
1340 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn),
1341 (ins GPR:$base, t2am_imm8_offset:$addr),
1342 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1343 "ldrsb", "\t$Rt, [$Rn], $addr", "$base = $Rn",
1346 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn),
1347 (ins t2addrmode_imm8:$addr),
1348 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1349 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn",
1351 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$Rn),
1352 (ins GPR:$base, t2am_imm8_offset:$addr),
1353 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1354 "ldrsh", "\t$dst, [$Rn], $addr", "$base = $Rn",
1356 } // mayLoad = 1, neverHasSideEffects = 1
1358 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1359 // for disassembly only.
1360 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1361 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1362 : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1363 "\t$Rt, $addr", []> {
1364 let Inst{31-27} = 0b11111;
1365 let Inst{26-25} = 0b00;
1366 let Inst{24} = signed;
1368 let Inst{22-21} = type;
1369 let Inst{20} = 1; // load
1371 let Inst{10-8} = 0b110; // PUW.
1375 let Inst{15-12} = Rt;
1376 let Inst{19-16} = addr{12-9};
1377 let Inst{7-0} = addr{7-0};
1380 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1381 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1382 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1383 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1384 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1387 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1388 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1389 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1390 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1391 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1392 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1395 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1396 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1397 (ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr),
1398 IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>;
1401 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1402 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1403 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1404 "str", "\t$Rt, [$Rn, $addr]!",
1405 "$Rn = $base_wb,@earlyclobber $base_wb",
1407 (pre_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1409 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1410 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1411 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1412 "str", "\t$Rt, [$Rn], $addr",
1413 "$Rn = $base_wb,@earlyclobber $base_wb",
1415 (post_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1417 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1418 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1419 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1420 "strh", "\t$Rt, [$Rn, $addr]!",
1421 "$Rn = $base_wb,@earlyclobber $base_wb",
1423 (pre_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1425 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1426 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1427 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1428 "strh", "\t$Rt, [$Rn], $addr",
1429 "$Rn = $base_wb,@earlyclobber $base_wb",
1431 (post_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1433 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1434 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1435 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1436 "strb", "\t$Rt, [$Rn, $addr]!",
1437 "$Rn = $base_wb,@earlyclobber $base_wb",
1439 (pre_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1441 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1442 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1443 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1444 "strb", "\t$Rt, [$Rn], $addr",
1445 "$Rn = $base_wb,@earlyclobber $base_wb",
1447 (post_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1449 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1451 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1452 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1453 : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1454 "\t$Rt, $addr", []> {
1455 let Inst{31-27} = 0b11111;
1456 let Inst{26-25} = 0b00;
1457 let Inst{24} = 0; // not signed
1459 let Inst{22-21} = type;
1460 let Inst{20} = 0; // store
1462 let Inst{10-8} = 0b110; // PUW
1466 let Inst{15-12} = Rt;
1467 let Inst{19-16} = addr{12-9};
1468 let Inst{7-0} = addr{7-0};
1471 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1472 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1473 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1475 // ldrd / strd pre / post variants
1476 // For disassembly only.
1478 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1479 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1480 "ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1482 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1483 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1484 "ldrd", "\t$Rt, $Rt2, [$base], $imm", []>;
1486 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1487 (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1488 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
1490 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1491 (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
1492 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>;
1494 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1495 // data/instruction access. These are for disassembly only.
1496 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1497 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1498 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1500 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1502 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1503 let Inst{31-25} = 0b1111100;
1504 let Inst{24} = instr;
1506 let Inst{21} = write;
1508 let Inst{15-12} = 0b1111;
1511 let addr{12} = 1; // add = TRUE
1512 let Inst{19-16} = addr{16-13}; // Rn
1513 let Inst{23} = addr{12}; // U
1514 let Inst{11-0} = addr{11-0}; // imm12
1517 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1519 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1520 let Inst{31-25} = 0b1111100;
1521 let Inst{24} = instr;
1522 let Inst{23} = 0; // U = 0
1524 let Inst{21} = write;
1526 let Inst{15-12} = 0b1111;
1527 let Inst{11-8} = 0b1100;
1530 let Inst{19-16} = addr{12-9}; // Rn
1531 let Inst{7-0} = addr{7-0}; // imm8
1534 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1536 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1537 let Inst{31-25} = 0b1111100;
1538 let Inst{24} = instr;
1539 let Inst{23} = 0; // add = TRUE for T1
1541 let Inst{21} = write;
1543 let Inst{15-12} = 0b1111;
1544 let Inst{11-6} = 0000000;
1547 let Inst{19-16} = addr{9-6}; // Rn
1548 let Inst{3-0} = addr{5-2}; // Rm
1549 let Inst{5-4} = addr{1-0}; // imm2
1553 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1554 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1555 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1557 //===----------------------------------------------------------------------===//
1558 // Load / store multiple Instructions.
1561 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1562 InstrItinClass itin_upd, bit L_bit> {
1564 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1565 itin, !strconcat(asm, "ia${p}.w\t$Rn, $regs"), []> {
1569 let Inst{31-27} = 0b11101;
1570 let Inst{26-25} = 0b00;
1571 let Inst{24-23} = 0b01; // Increment After
1573 let Inst{21} = 0; // No writeback
1574 let Inst{20} = L_bit;
1575 let Inst{19-16} = Rn;
1576 let Inst{15-0} = regs;
1579 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1580 itin_upd, !strconcat(asm, "ia${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1584 let Inst{31-27} = 0b11101;
1585 let Inst{26-25} = 0b00;
1586 let Inst{24-23} = 0b01; // Increment After
1588 let Inst{21} = 1; // Writeback
1589 let Inst{20} = L_bit;
1590 let Inst{19-16} = Rn;
1591 let Inst{15-0} = regs;
1594 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1595 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1599 let Inst{31-27} = 0b11101;
1600 let Inst{26-25} = 0b00;
1601 let Inst{24-23} = 0b10; // Decrement Before
1603 let Inst{21} = 0; // No writeback
1604 let Inst{20} = L_bit;
1605 let Inst{19-16} = Rn;
1606 let Inst{15-0} = regs;
1609 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1610 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1614 let Inst{31-27} = 0b11101;
1615 let Inst{26-25} = 0b00;
1616 let Inst{24-23} = 0b10; // Decrement Before
1618 let Inst{21} = 1; // Writeback
1619 let Inst{20} = L_bit;
1620 let Inst{19-16} = Rn;
1621 let Inst{15-0} = regs;
1625 let neverHasSideEffects = 1 in {
1627 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1628 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1630 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1631 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1633 } // neverHasSideEffects
1636 //===----------------------------------------------------------------------===//
1637 // Move Instructions.
1640 let neverHasSideEffects = 1 in
1641 def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1642 "mov", ".w\t$Rd, $Rm", []> {
1643 let Inst{31-27} = 0b11101;
1644 let Inst{26-25} = 0b01;
1645 let Inst{24-21} = 0b0010;
1646 let Inst{19-16} = 0b1111; // Rn
1647 let Inst{14-12} = 0b000;
1648 let Inst{7-4} = 0b0000;
1651 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1652 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
1653 AddedComplexity = 1 in
1654 def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
1655 "mov", ".w\t$Rd, $imm",
1656 [(set rGPR:$Rd, t2_so_imm:$imm)]> {
1657 let Inst{31-27} = 0b11110;
1659 let Inst{24-21} = 0b0010;
1660 let Inst{19-16} = 0b1111; // Rn
1664 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1665 def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
1666 "movw", "\t$Rd, $imm",
1667 [(set rGPR:$Rd, imm0_65535:$imm)]> {
1668 let Inst{31-27} = 0b11110;
1670 let Inst{24-21} = 0b0010;
1671 let Inst{20} = 0; // The S bit.
1677 let Inst{11-8} = Rd;
1678 let Inst{19-16} = imm{15-12};
1679 let Inst{26} = imm{11};
1680 let Inst{14-12} = imm{10-8};
1681 let Inst{7-0} = imm{7-0};
1684 def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1685 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1687 let Constraints = "$src = $Rd" in {
1688 def t2MOVTi16 : T2I<(outs rGPR:$Rd),
1689 (ins rGPR:$src, i32imm_hilo16:$imm), IIC_iMOVi,
1690 "movt", "\t$Rd, $imm",
1692 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1693 let Inst{31-27} = 0b11110;
1695 let Inst{24-21} = 0b0110;
1696 let Inst{20} = 0; // The S bit.
1702 let Inst{11-8} = Rd;
1703 let Inst{19-16} = imm{15-12};
1704 let Inst{26} = imm{11};
1705 let Inst{14-12} = imm{10-8};
1706 let Inst{7-0} = imm{7-0};
1709 def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1710 (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1713 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1715 //===----------------------------------------------------------------------===//
1716 // Extend Instructions.
1721 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1722 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1723 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1724 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1725 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1727 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1728 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1729 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1730 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1731 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1733 // TODO: SXT(A){B|H}16 - done for disassembly only
1737 let AddedComplexity = 16 in {
1738 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1739 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1740 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1741 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1742 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1743 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1745 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1746 // The transformation should probably be done as a combiner action
1747 // instead so we can include a check for masking back in the upper
1748 // eight bits of the source into the lower eight bits of the result.
1749 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1750 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1751 // Requires<[HasT2ExtractPack, IsThumb2]>;
1752 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1753 (t2UXTB16r_rot rGPR:$Src, 8)>,
1754 Requires<[HasT2ExtractPack, IsThumb2]>;
1756 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1757 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1758 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1759 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1760 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1763 //===----------------------------------------------------------------------===//
1764 // Arithmetic Instructions.
1767 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1768 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1769 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1770 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1772 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1773 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1774 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1775 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1776 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1777 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1778 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1780 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1781 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1782 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1783 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1784 defm t2ADCS : T2I_adde_sube_s_irs<BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1785 defm t2SBCS : T2I_adde_sube_s_irs<BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1788 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1789 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1790 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1791 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1793 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1794 // The assume-no-carry-in form uses the negation of the input since add/sub
1795 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1796 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1798 // The AddedComplexity preferences the first variant over the others since
1799 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1800 let AddedComplexity = 1 in
1801 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1802 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1803 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1804 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1805 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1806 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1807 let AddedComplexity = 1 in
1808 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1809 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1810 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1811 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1812 // The with-carry-in form matches bitwise not instead of the negation.
1813 // Effectively, the inverse interpretation of the carry flag already accounts
1814 // for part of the negation.
1815 let AddedComplexity = 1 in
1816 def : T2Pat<(adde_dead_carry rGPR:$src, imm0_255_not:$imm),
1817 (t2SBCri rGPR:$src, imm0_255_not:$imm)>;
1818 def : T2Pat<(adde_dead_carry rGPR:$src, t2_so_imm_not:$imm),
1819 (t2SBCri rGPR:$src, t2_so_imm_not:$imm)>;
1820 let AddedComplexity = 1 in
1821 def : T2Pat<(adde_live_carry rGPR:$src, imm0_255_not:$imm),
1822 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1823 def : T2Pat<(adde_live_carry rGPR:$src, t2_so_imm_not:$imm),
1824 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1826 // Select Bytes -- for disassembly only
1828 def t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1829 NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []> {
1830 let Inst{31-27} = 0b11111;
1831 let Inst{26-24} = 0b010;
1833 let Inst{22-20} = 0b010;
1834 let Inst{15-12} = 0b1111;
1836 let Inst{6-4} = 0b000;
1839 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1840 // And Miscellaneous operations -- for disassembly only
1841 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1842 list<dag> pat = [/* For disassembly only; pattern left blank */],
1843 dag iops = (ins rGPR:$Rn, rGPR:$Rm),
1844 string asm = "\t$Rd, $Rn, $Rm">
1845 : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat> {
1846 let Inst{31-27} = 0b11111;
1847 let Inst{26-23} = 0b0101;
1848 let Inst{22-20} = op22_20;
1849 let Inst{15-12} = 0b1111;
1850 let Inst{7-4} = op7_4;
1856 let Inst{11-8} = Rd;
1857 let Inst{19-16} = Rn;
1861 // Saturating add/subtract -- for disassembly only
1863 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1864 [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))],
1865 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1866 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1867 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1868 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1869 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd", [],
1870 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1871 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub", [],
1872 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1873 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1874 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1875 [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))],
1876 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
1877 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1878 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1879 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1880 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1881 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1882 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1883 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1884 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1886 // Signed/Unsigned add/subtract -- for disassembly only
1888 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1889 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1890 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1891 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1892 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1893 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1894 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1895 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1896 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1897 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1898 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1899 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1901 // Signed/Unsigned halving add/subtract -- for disassembly only
1903 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1904 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1905 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1906 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1907 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1908 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1909 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1910 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1911 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1912 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1913 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1914 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1916 // Helper class for disassembly only
1917 // A6.3.16 & A6.3.17
1918 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1919 class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1920 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1921 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
1922 let Inst{31-27} = 0b11111;
1923 let Inst{26-24} = 0b011;
1924 let Inst{23} = long;
1925 let Inst{22-20} = op22_20;
1926 let Inst{7-4} = op7_4;
1929 class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1930 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1931 : T2FourReg<oops, iops, itin, opc, asm, pattern> {
1932 let Inst{31-27} = 0b11111;
1933 let Inst{26-24} = 0b011;
1934 let Inst{23} = long;
1935 let Inst{22-20} = op22_20;
1936 let Inst{7-4} = op7_4;
1939 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1941 def t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1942 (ins rGPR:$Rn, rGPR:$Rm),
1943 NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []> {
1944 let Inst{15-12} = 0b1111;
1946 def t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1947 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
1948 "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>;
1950 // Signed/Unsigned saturate -- for disassembly only
1952 class T2SatI<dag oops, dag iops, InstrItinClass itin,
1953 string opc, string asm, list<dag> pattern>
1954 : T2I<oops, iops, itin, opc, asm, pattern> {
1960 let Inst{11-8} = Rd;
1961 let Inst{19-16} = Rn;
1962 let Inst{4-0} = sat_imm{4-0};
1963 let Inst{21} = sh{6};
1964 let Inst{14-12} = sh{4-2};
1965 let Inst{7-6} = sh{1-0};
1969 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1970 NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
1971 [/* For disassembly only; pattern left blank */]> {
1972 let Inst{31-27} = 0b11110;
1973 let Inst{25-22} = 0b1100;
1978 def t2SSAT16: T2SatI<
1979 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
1980 "ssat16", "\t$Rd, $sat_imm, $Rn",
1981 [/* For disassembly only; pattern left blank */]> {
1982 let Inst{31-27} = 0b11110;
1983 let Inst{25-22} = 0b1100;
1986 let Inst{21} = 1; // sh = '1'
1987 let Inst{14-12} = 0b000; // imm3 = '000'
1988 let Inst{7-6} = 0b00; // imm2 = '00'
1992 (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1993 NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh",
1994 [/* For disassembly only; pattern left blank */]> {
1995 let Inst{31-27} = 0b11110;
1996 let Inst{25-22} = 0b1110;
2001 def t2USAT16: T2SatI<
2002 (outs rGPR:$dst), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
2003 "usat16", "\t$dst, $sat_imm, $Rn",
2004 [/* For disassembly only; pattern left blank */]> {
2005 let Inst{31-27} = 0b11110;
2006 let Inst{25-22} = 0b1110;
2009 let Inst{21} = 1; // sh = '1'
2010 let Inst{14-12} = 0b000; // imm3 = '000'
2011 let Inst{7-6} = 0b00; // imm2 = '00'
2014 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
2015 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
2017 //===----------------------------------------------------------------------===//
2018 // Shift and rotate Instructions.
2021 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
2022 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
2023 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
2024 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
2026 let Uses = [CPSR] in {
2027 def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2028 "rrx", "\t$Rd, $Rm",
2029 [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> {
2030 let Inst{31-27} = 0b11101;
2031 let Inst{26-25} = 0b01;
2032 let Inst{24-21} = 0b0010;
2033 let Inst{19-16} = 0b1111; // Rn
2034 let Inst{14-12} = 0b000;
2035 let Inst{7-4} = 0b0011;
2039 let isCodeGenOnly = 1, Defs = [CPSR] in {
2040 def t2MOVsrl_flag : T2TwoRegShiftImm<
2041 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2042 "lsrs", ".w\t$Rd, $Rm, #1",
2043 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> {
2044 let Inst{31-27} = 0b11101;
2045 let Inst{26-25} = 0b01;
2046 let Inst{24-21} = 0b0010;
2047 let Inst{20} = 1; // The S bit.
2048 let Inst{19-16} = 0b1111; // Rn
2049 let Inst{5-4} = 0b01; // Shift type.
2050 // Shift amount = Inst{14-12:7-6} = 1.
2051 let Inst{14-12} = 0b000;
2052 let Inst{7-6} = 0b01;
2054 def t2MOVsra_flag : T2TwoRegShiftImm<
2055 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2056 "asrs", ".w\t$Rd, $Rm, #1",
2057 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> {
2058 let Inst{31-27} = 0b11101;
2059 let Inst{26-25} = 0b01;
2060 let Inst{24-21} = 0b0010;
2061 let Inst{20} = 1; // The S bit.
2062 let Inst{19-16} = 0b1111; // Rn
2063 let Inst{5-4} = 0b10; // Shift type.
2064 // Shift amount = Inst{14-12:7-6} = 1.
2065 let Inst{14-12} = 0b000;
2066 let Inst{7-6} = 0b01;
2070 //===----------------------------------------------------------------------===//
2071 // Bitwise Instructions.
2074 defm t2AND : T2I_bin_w_irs<0b0000, "and",
2075 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2076 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2077 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
2078 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2079 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2080 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
2081 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2082 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2084 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
2085 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2086 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2088 class T2BitFI<dag oops, dag iops, InstrItinClass itin,
2089 string opc, string asm, list<dag> pattern>
2090 : T2I<oops, iops, itin, opc, asm, pattern> {
2095 let Inst{11-8} = Rd;
2096 let Inst{4-0} = msb{4-0};
2097 let Inst{14-12} = lsb{4-2};
2098 let Inst{7-6} = lsb{1-0};
2101 class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2102 string opc, string asm, list<dag> pattern>
2103 : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2106 let Inst{19-16} = Rn;
2109 let Constraints = "$src = $Rd" in
2110 def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2111 IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2112 [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2113 let Inst{31-27} = 0b11110;
2114 let Inst{26} = 0; // should be 0.
2116 let Inst{24-20} = 0b10110;
2117 let Inst{19-16} = 0b1111; // Rn
2119 let Inst{5} = 0; // should be 0.
2122 let msb{4-0} = imm{9-5};
2123 let lsb{4-0} = imm{4-0};
2126 def t2SBFX: T2TwoRegBitFI<
2127 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2128 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2129 let Inst{31-27} = 0b11110;
2131 let Inst{24-20} = 0b10100;
2135 def t2UBFX: T2TwoRegBitFI<
2136 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2137 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2138 let Inst{31-27} = 0b11110;
2140 let Inst{24-20} = 0b11100;
2144 // A8.6.18 BFI - Bitfield insert (Encoding T1)
2145 let Constraints = "$src = $Rd" in {
2146 def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2147 (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2148 IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2149 [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2150 bf_inv_mask_imm:$imm))]> {
2151 let Inst{31-27} = 0b11110;
2152 let Inst{26} = 0; // should be 0.
2154 let Inst{24-20} = 0b10110;
2156 let Inst{5} = 0; // should be 0.
2159 let msb{4-0} = imm{9-5};
2160 let lsb{4-0} = imm{4-0};
2163 // GNU as only supports this form of bfi (w/ 4 arguments)
2164 let isAsmParserOnly = 1 in
2165 def t2BFI4p : T2TwoRegBitFI<(outs rGPR:$Rd),
2166 (ins rGPR:$src, rGPR:$Rn, lsb_pos_imm:$lsbit,
2168 IIC_iBITi, "bfi", "\t$Rd, $Rn, $lsbit, $width",
2170 let Inst{31-27} = 0b11110;
2171 let Inst{26} = 0; // should be 0.
2173 let Inst{24-20} = 0b10110;
2175 let Inst{5} = 0; // should be 0.
2179 let msb{4-0} = width; // Custom encoder => lsb+width-1
2180 let lsb{4-0} = lsbit;
2184 defm t2ORN : T2I_bin_irs<0b0011, "orn",
2185 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2186 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
2188 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2189 let AddedComplexity = 1 in
2190 defm t2MVN : T2I_un_irs <0b0011, "mvn",
2191 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2192 UnOpFrag<(not node:$Src)>, 1, 1>;
2195 let AddedComplexity = 1 in
2196 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
2197 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2199 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2200 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
2201 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2202 Requires<[IsThumb2]>;
2204 def : T2Pat<(t2_so_imm_not:$src),
2205 (t2MVNi t2_so_imm_not:$src)>;
2207 //===----------------------------------------------------------------------===//
2208 // Multiply Instructions.
2210 let isCommutable = 1 in
2211 def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2212 "mul", "\t$Rd, $Rn, $Rm",
2213 [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2214 let Inst{31-27} = 0b11111;
2215 let Inst{26-23} = 0b0110;
2216 let Inst{22-20} = 0b000;
2217 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2218 let Inst{7-4} = 0b0000; // Multiply
2221 def t2MLA: T2FourReg<
2222 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2223 "mla", "\t$Rd, $Rn, $Rm, $Ra",
2224 [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> {
2225 let Inst{31-27} = 0b11111;
2226 let Inst{26-23} = 0b0110;
2227 let Inst{22-20} = 0b000;
2228 let Inst{7-4} = 0b0000; // Multiply
2231 def t2MLS: T2FourReg<
2232 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2233 "mls", "\t$Rd, $Rn, $Rm, $Ra",
2234 [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> {
2235 let Inst{31-27} = 0b11111;
2236 let Inst{26-23} = 0b0110;
2237 let Inst{22-20} = 0b000;
2238 let Inst{7-4} = 0b0001; // Multiply and Subtract
2241 // Extra precision multiplies with low / high results
2242 let neverHasSideEffects = 1 in {
2243 let isCommutable = 1 in {
2244 def t2SMULL : T2MulLong<0b000, 0b0000,
2245 (outs rGPR:$Rd, rGPR:$Ra),
2246 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2247 "smull", "\t$Rd, $Ra, $Rn, $Rm", []>;
2249 def t2UMULL : T2MulLong<0b010, 0b0000,
2250 (outs rGPR:$RdLo, rGPR:$RdHi),
2251 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2252 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2255 // Multiply + accumulate
2256 def t2SMLAL : T2MulLong<0b100, 0b0000,
2257 (outs rGPR:$RdLo, rGPR:$RdHi),
2258 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2259 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2261 def t2UMLAL : T2MulLong<0b110, 0b0000,
2262 (outs rGPR:$RdLo, rGPR:$RdHi),
2263 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2264 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2266 def t2UMAAL : T2MulLong<0b110, 0b0110,
2267 (outs rGPR:$RdLo, rGPR:$RdHi),
2268 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2269 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2270 } // neverHasSideEffects
2272 // Rounding variants of the below included for disassembly only
2274 // Most significant word multiply
2275 def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2276 "smmul", "\t$Rd, $Rn, $Rm",
2277 [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]> {
2278 let Inst{31-27} = 0b11111;
2279 let Inst{26-23} = 0b0110;
2280 let Inst{22-20} = 0b101;
2281 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2282 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2285 def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2286 "smmulr", "\t$Rd, $Rn, $Rm", []> {
2287 let Inst{31-27} = 0b11111;
2288 let Inst{26-23} = 0b0110;
2289 let Inst{22-20} = 0b101;
2290 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2291 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2294 def t2SMMLA : T2FourReg<
2295 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2296 "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2297 [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]> {
2298 let Inst{31-27} = 0b11111;
2299 let Inst{26-23} = 0b0110;
2300 let Inst{22-20} = 0b101;
2301 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2304 def t2SMMLAR: T2FourReg<
2305 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2306 "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []> {
2307 let Inst{31-27} = 0b11111;
2308 let Inst{26-23} = 0b0110;
2309 let Inst{22-20} = 0b101;
2310 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2313 def t2SMMLS: T2FourReg<
2314 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2315 "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2316 [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]> {
2317 let Inst{31-27} = 0b11111;
2318 let Inst{26-23} = 0b0110;
2319 let Inst{22-20} = 0b110;
2320 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2323 def t2SMMLSR:T2FourReg<
2324 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2325 "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []> {
2326 let Inst{31-27} = 0b11111;
2327 let Inst{26-23} = 0b0110;
2328 let Inst{22-20} = 0b110;
2329 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2332 multiclass T2I_smul<string opc, PatFrag opnode> {
2333 def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2334 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2335 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2336 (sext_inreg rGPR:$Rm, i16)))]> {
2337 let Inst{31-27} = 0b11111;
2338 let Inst{26-23} = 0b0110;
2339 let Inst{22-20} = 0b001;
2340 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2341 let Inst{7-6} = 0b00;
2342 let Inst{5-4} = 0b00;
2345 def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2346 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2347 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2348 (sra rGPR:$Rm, (i32 16))))]> {
2349 let Inst{31-27} = 0b11111;
2350 let Inst{26-23} = 0b0110;
2351 let Inst{22-20} = 0b001;
2352 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2353 let Inst{7-6} = 0b00;
2354 let Inst{5-4} = 0b01;
2357 def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2358 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2359 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2360 (sext_inreg rGPR:$Rm, i16)))]> {
2361 let Inst{31-27} = 0b11111;
2362 let Inst{26-23} = 0b0110;
2363 let Inst{22-20} = 0b001;
2364 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2365 let Inst{7-6} = 0b00;
2366 let Inst{5-4} = 0b10;
2369 def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2370 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2371 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2372 (sra rGPR:$Rm, (i32 16))))]> {
2373 let Inst{31-27} = 0b11111;
2374 let Inst{26-23} = 0b0110;
2375 let Inst{22-20} = 0b001;
2376 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2377 let Inst{7-6} = 0b00;
2378 let Inst{5-4} = 0b11;
2381 def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2382 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2383 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2384 (sext_inreg rGPR:$Rm, i16)), (i32 16)))]> {
2385 let Inst{31-27} = 0b11111;
2386 let Inst{26-23} = 0b0110;
2387 let Inst{22-20} = 0b011;
2388 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2389 let Inst{7-6} = 0b00;
2390 let Inst{5-4} = 0b00;
2393 def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2394 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2395 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn,
2396 (sra rGPR:$Rm, (i32 16))), (i32 16)))]> {
2397 let Inst{31-27} = 0b11111;
2398 let Inst{26-23} = 0b0110;
2399 let Inst{22-20} = 0b011;
2400 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2401 let Inst{7-6} = 0b00;
2402 let Inst{5-4} = 0b01;
2407 multiclass T2I_smla<string opc, PatFrag opnode> {
2409 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2410 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2411 [(set rGPR:$Rd, (add rGPR:$Ra,
2412 (opnode (sext_inreg rGPR:$Rn, i16),
2413 (sext_inreg rGPR:$Rm, i16))))]> {
2414 let Inst{31-27} = 0b11111;
2415 let Inst{26-23} = 0b0110;
2416 let Inst{22-20} = 0b001;
2417 let Inst{7-6} = 0b00;
2418 let Inst{5-4} = 0b00;
2422 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2423 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2424 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
2425 (sra rGPR:$Rm, (i32 16)))))]> {
2426 let Inst{31-27} = 0b11111;
2427 let Inst{26-23} = 0b0110;
2428 let Inst{22-20} = 0b001;
2429 let Inst{7-6} = 0b00;
2430 let Inst{5-4} = 0b01;
2434 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2435 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2436 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2437 (sext_inreg rGPR:$Rm, i16))))]> {
2438 let Inst{31-27} = 0b11111;
2439 let Inst{26-23} = 0b0110;
2440 let Inst{22-20} = 0b001;
2441 let Inst{7-6} = 0b00;
2442 let Inst{5-4} = 0b10;
2446 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2447 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2448 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2449 (sra rGPR:$Rm, (i32 16)))))]> {
2450 let Inst{31-27} = 0b11111;
2451 let Inst{26-23} = 0b0110;
2452 let Inst{22-20} = 0b001;
2453 let Inst{7-6} = 0b00;
2454 let Inst{5-4} = 0b11;
2458 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2459 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2460 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2461 (sext_inreg rGPR:$Rm, i16)), (i32 16))))]> {
2462 let Inst{31-27} = 0b11111;
2463 let Inst{26-23} = 0b0110;
2464 let Inst{22-20} = 0b011;
2465 let Inst{7-6} = 0b00;
2466 let Inst{5-4} = 0b00;
2470 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2471 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2472 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn,
2473 (sra rGPR:$Rm, (i32 16))), (i32 16))))]> {
2474 let Inst{31-27} = 0b11111;
2475 let Inst{26-23} = 0b0110;
2476 let Inst{22-20} = 0b011;
2477 let Inst{7-6} = 0b00;
2478 let Inst{5-4} = 0b01;
2482 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2483 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2485 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2486 def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
2487 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
2488 [/* For disassembly only; pattern left blank */]>;
2489 def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
2490 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
2491 [/* For disassembly only; pattern left blank */]>;
2492 def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
2493 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
2494 [/* For disassembly only; pattern left blank */]>;
2495 def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
2496 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
2497 [/* For disassembly only; pattern left blank */]>;
2499 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2500 // These are for disassembly only.
2502 def t2SMUAD: T2ThreeReg_mac<
2503 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2504 IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []> {
2505 let Inst{15-12} = 0b1111;
2507 def t2SMUADX:T2ThreeReg_mac<
2508 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2509 IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []> {
2510 let Inst{15-12} = 0b1111;
2512 def t2SMUSD: T2ThreeReg_mac<
2513 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2514 IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []> {
2515 let Inst{15-12} = 0b1111;
2517 def t2SMUSDX:T2ThreeReg_mac<
2518 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2519 IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []> {
2520 let Inst{15-12} = 0b1111;
2522 def t2SMLAD : T2ThreeReg_mac<
2523 0, 0b010, 0b0000, (outs rGPR:$Rd),
2524 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
2525 "\t$Rd, $Rn, $Rm, $Ra", []>;
2526 def t2SMLADX : T2FourReg_mac<
2527 0, 0b010, 0b0001, (outs rGPR:$Rd),
2528 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
2529 "\t$Rd, $Rn, $Rm, $Ra", []>;
2530 def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
2531 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
2532 "\t$Rd, $Rn, $Rm, $Ra", []>;
2533 def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
2534 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
2535 "\t$Rd, $Rn, $Rm, $Ra", []>;
2536 def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2537 (ins rGPR:$Rm, rGPR:$Rn), IIC_iMAC64, "smlald",
2538 "\t$Ra, $Rd, $Rm, $Rn", []>;
2539 def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2540 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlaldx",
2541 "\t$Ra, $Rd, $Rm, $Rn", []>;
2542 def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2543 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsld",
2544 "\t$Ra, $Rd, $Rm, $Rn", []>;
2545 def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2546 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
2547 "\t$Ra, $Rd, $Rm, $Rn", []>;
2549 //===----------------------------------------------------------------------===//
2550 // Misc. Arithmetic Instructions.
2553 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2554 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2555 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2556 let Inst{31-27} = 0b11111;
2557 let Inst{26-22} = 0b01010;
2558 let Inst{21-20} = op1;
2559 let Inst{15-12} = 0b1111;
2560 let Inst{7-6} = 0b10;
2561 let Inst{5-4} = op2;
2565 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2566 "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>;
2568 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2569 "rbit", "\t$Rd, $Rm",
2570 [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>;
2572 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2573 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>;
2575 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2576 "rev16", ".w\t$Rd, $Rm",
2578 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF),
2579 (or (and (shl rGPR:$Rm, (i32 8)), 0xFF00),
2580 (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000),
2581 (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)))))]>;
2583 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2584 "revsh", ".w\t$Rd, $Rm",
2587 (or (srl rGPR:$Rm, (i32 8)),
2588 (shl rGPR:$Rm, (i32 8))), i16))]>;
2590 def : T2Pat<(sext_inreg (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)),
2591 (shl rGPR:$Rm, (i32 8))), i16),
2592 (t2REVSH rGPR:$Rm)>;
2594 def : T2Pat<(sra (bswap rGPR:$Rm), (i32 16)), (t2REVSH rGPR:$Rm)>;
2596 def t2PKHBT : T2ThreeReg<
2597 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2598 IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2599 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2600 (and (shl rGPR:$Rm, lsl_amt:$sh),
2602 Requires<[HasT2ExtractPack, IsThumb2]> {
2603 let Inst{31-27} = 0b11101;
2604 let Inst{26-25} = 0b01;
2605 let Inst{24-20} = 0b01100;
2606 let Inst{5} = 0; // BT form
2610 let Inst{14-12} = sh{7-5};
2611 let Inst{7-6} = sh{4-3};
2614 // Alternate cases for PKHBT where identities eliminate some nodes.
2615 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2616 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2617 Requires<[HasT2ExtractPack, IsThumb2]>;
2618 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2619 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2620 Requires<[HasT2ExtractPack, IsThumb2]>;
2622 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2623 // will match the pattern below.
2624 def t2PKHTB : T2ThreeReg<
2625 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2626 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2627 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
2628 (and (sra rGPR:$Rm, asr_amt:$sh),
2630 Requires<[HasT2ExtractPack, IsThumb2]> {
2631 let Inst{31-27} = 0b11101;
2632 let Inst{26-25} = 0b01;
2633 let Inst{24-20} = 0b01100;
2634 let Inst{5} = 1; // TB form
2638 let Inst{14-12} = sh{7-5};
2639 let Inst{7-6} = sh{4-3};
2642 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2643 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2644 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2645 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2646 Requires<[HasT2ExtractPack, IsThumb2]>;
2647 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2648 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2649 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2650 Requires<[HasT2ExtractPack, IsThumb2]>;
2652 //===----------------------------------------------------------------------===//
2653 // Comparison Instructions...
2655 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2656 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2657 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2659 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_imm:$imm),
2660 (t2CMPri GPR:$lhs, t2_so_imm:$imm)>;
2661 def : T2Pat<(ARMcmpZ GPR:$lhs, rGPR:$rhs),
2662 (t2CMPrr GPR:$lhs, rGPR:$rhs)>;
2663 def : T2Pat<(ARMcmpZ GPR:$lhs, t2_so_reg:$rhs),
2664 (t2CMPrs GPR:$lhs, t2_so_reg:$rhs)>;
2666 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2667 // Compare-to-zero still works out, just not the relationals
2668 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2669 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2670 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2671 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2672 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2674 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2675 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2677 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2678 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2680 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2681 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2682 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
2683 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2684 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2685 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
2687 // Conditional moves
2688 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2689 // a two-value operand where a dag node expects two operands. :(
2690 let neverHasSideEffects = 1 in {
2691 def t2MOVCCr : T2TwoReg<
2692 (outs rGPR:$Rd), (ins rGPR:$false, rGPR:$Rm), IIC_iCMOVr,
2693 "mov", ".w\t$Rd, $Rm",
2694 [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2695 RegConstraint<"$false = $Rd"> {
2696 let Inst{31-27} = 0b11101;
2697 let Inst{26-25} = 0b01;
2698 let Inst{24-21} = 0b0010;
2699 let Inst{20} = 0; // The S bit.
2700 let Inst{19-16} = 0b1111; // Rn
2701 let Inst{14-12} = 0b000;
2702 let Inst{7-4} = 0b0000;
2705 let isMoveImm = 1 in
2706 def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2707 IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
2708 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2709 RegConstraint<"$false = $Rd"> {
2710 let Inst{31-27} = 0b11110;
2712 let Inst{24-21} = 0b0010;
2713 let Inst{20} = 0; // The S bit.
2714 let Inst{19-16} = 0b1111; // Rn
2718 let isMoveImm = 1 in
2719 def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm_hilo16:$imm),
2721 "movw", "\t$Rd, $imm", []>,
2722 RegConstraint<"$false = $Rd"> {
2723 let Inst{31-27} = 0b11110;
2725 let Inst{24-21} = 0b0010;
2726 let Inst{20} = 0; // The S bit.
2732 let Inst{11-8} = Rd;
2733 let Inst{19-16} = imm{15-12};
2734 let Inst{26} = imm{11};
2735 let Inst{14-12} = imm{10-8};
2736 let Inst{7-0} = imm{7-0};
2739 let isMoveImm = 1 in
2740 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2741 (ins rGPR:$false, i32imm:$src, pred:$p),
2742 IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">;
2744 let isMoveImm = 1 in
2745 def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2746 IIC_iCMOVi, "mvn", ".w\t$Rd, $imm",
2747 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm,
2748 imm:$cc, CCR:$ccr))*/]>,
2749 RegConstraint<"$false = $Rd"> {
2750 let Inst{31-27} = 0b11110;
2752 let Inst{24-21} = 0b0011;
2753 let Inst{20} = 0; // The S bit.
2754 let Inst{19-16} = 0b1111; // Rn
2758 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2759 string opc, string asm, list<dag> pattern>
2760 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> {
2761 let Inst{31-27} = 0b11101;
2762 let Inst{26-25} = 0b01;
2763 let Inst{24-21} = 0b0010;
2764 let Inst{20} = 0; // The S bit.
2765 let Inst{19-16} = 0b1111; // Rn
2766 let Inst{5-4} = opcod; // Shift type.
2768 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd),
2769 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2770 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>,
2771 RegConstraint<"$false = $Rd">;
2772 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd),
2773 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2774 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>,
2775 RegConstraint<"$false = $Rd">;
2776 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd),
2777 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2778 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>,
2779 RegConstraint<"$false = $Rd">;
2780 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
2781 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2782 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
2783 RegConstraint<"$false = $Rd">;
2784 } // neverHasSideEffects
2786 //===----------------------------------------------------------------------===//
2787 // Atomic operations intrinsics
2790 // memory barriers protect the atomic sequences
2791 let hasSideEffects = 1 in {
2792 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2793 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2794 Requires<[IsThumb, HasDB]> {
2796 let Inst{31-4} = 0xf3bf8f5;
2797 let Inst{3-0} = opt;
2801 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2803 [/* For disassembly only; pattern left blank */]>,
2804 Requires<[IsThumb, HasDB]> {
2806 let Inst{31-4} = 0xf3bf8f4;
2807 let Inst{3-0} = opt;
2810 // ISB has only full system option -- for disassembly only
2811 def t2ISB : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "isb", "",
2812 [/* For disassembly only; pattern left blank */]>,
2813 Requires<[IsThumb2, HasV7]> {
2814 let Inst{31-4} = 0xf3bf8f6;
2815 let Inst{3-0} = 0b1111;
2818 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2819 InstrItinClass itin, string opc, string asm, string cstr,
2820 list<dag> pattern, bits<4> rt2 = 0b1111>
2821 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2822 let Inst{31-27} = 0b11101;
2823 let Inst{26-20} = 0b0001101;
2824 let Inst{11-8} = rt2;
2825 let Inst{7-6} = 0b01;
2826 let Inst{5-4} = opcod;
2827 let Inst{3-0} = 0b1111;
2831 let Inst{19-16} = addr;
2832 let Inst{15-12} = Rt;
2834 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2835 InstrItinClass itin, string opc, string asm, string cstr,
2836 list<dag> pattern, bits<4> rt2 = 0b1111>
2837 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2838 let Inst{31-27} = 0b11101;
2839 let Inst{26-20} = 0b0001100;
2840 let Inst{11-8} = rt2;
2841 let Inst{7-6} = 0b01;
2842 let Inst{5-4} = opcod;
2848 let Inst{19-16} = addr;
2849 let Inst{15-12} = Rt;
2852 let mayLoad = 1 in {
2853 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
2854 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, $addr",
2856 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
2857 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, $addr",
2859 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
2860 Size4Bytes, NoItinerary,
2861 "ldrex", "\t$Rt, $addr", "",
2863 let Inst{31-27} = 0b11101;
2864 let Inst{26-20} = 0b0000101;
2865 let Inst{11-8} = 0b1111;
2866 let Inst{7-0} = 0b00000000; // imm8 = 0
2870 let Inst{19-16} = addr;
2871 let Inst{15-12} = Rt;
2873 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins t2addrmode_reg:$addr),
2874 AddrModeNone, Size4Bytes, NoItinerary,
2875 "ldrexd", "\t$Rt, $Rt2, $addr", "",
2878 let Inst{11-8} = Rt2;
2882 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2883 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2884 AddrModeNone, Size4Bytes, NoItinerary,
2885 "strexb", "\t$Rd, $Rt, $addr", "", []>;
2886 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2887 AddrModeNone, Size4Bytes, NoItinerary,
2888 "strexh", "\t$Rd, $Rt, $addr", "", []>;
2889 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2890 AddrModeNone, Size4Bytes, NoItinerary,
2891 "strex", "\t$Rd, $Rt, $addr", "",
2893 let Inst{31-27} = 0b11101;
2894 let Inst{26-20} = 0b0000100;
2895 let Inst{7-0} = 0b00000000; // imm8 = 0
2900 let Inst{11-8} = Rd;
2901 let Inst{19-16} = addr;
2902 let Inst{15-12} = Rt;
2904 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2905 (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_reg:$addr),
2906 AddrModeNone, Size4Bytes, NoItinerary,
2907 "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
2910 let Inst{11-8} = Rt2;
2914 // Clear-Exclusive is for disassembly only.
2915 def t2CLREX : T2XI<(outs), (ins), NoItinerary, "clrex",
2916 [/* For disassembly only; pattern left blank */]>,
2917 Requires<[IsThumb2, HasV7]> {
2918 let Inst{31-16} = 0xf3bf;
2919 let Inst{15-14} = 0b10;
2922 let Inst{11-8} = 0b1111;
2923 let Inst{7-4} = 0b0010;
2924 let Inst{3-0} = 0b1111;
2927 //===----------------------------------------------------------------------===//
2931 // __aeabi_read_tp preserves the registers r1-r3.
2933 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
2934 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2935 "bl\t__aeabi_read_tp",
2936 [(set R0, ARMthread_pointer)]> {
2937 let Inst{31-27} = 0b11110;
2938 let Inst{15-14} = 0b11;
2943 //===----------------------------------------------------------------------===//
2944 // SJLJ Exception handling intrinsics
2945 // eh_sjlj_setjmp() is an instruction sequence to store the return
2946 // address and save #0 in R0 for the non-longjmp case.
2947 // Since by its nature we may be coming from some other function to get
2948 // here, and we're using the stack frame for the containing function to
2949 // save/restore registers, we can't keep anything live in regs across
2950 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2951 // when we get here from a longjmp(). We force everything out of registers
2952 // except for our own input by listing the relevant registers in Defs. By
2953 // doing so, we also cause the prologue/epilogue code to actively preserve
2954 // all of the callee-saved resgisters, which is exactly what we want.
2955 // $val is a scratch register for our use.
2957 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2958 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2959 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2960 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2961 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2962 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2963 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2964 Requires<[IsThumb2, HasVFP2]>;
2968 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2969 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2970 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2971 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2972 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2973 Requires<[IsThumb2, NoVFP]>;
2977 //===----------------------------------------------------------------------===//
2978 // Control-Flow Instructions
2981 // FIXME: remove when we have a way to marking a MI with these properties.
2982 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2984 // FIXME: Should pc be an implicit operand like PICADD, etc?
2985 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2986 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2987 def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2988 reglist:$regs, variable_ops),
2990 "ldmia${p}.w\t$Rn!, $regs",
2995 let Inst{31-27} = 0b11101;
2996 let Inst{26-25} = 0b00;
2997 let Inst{24-23} = 0b01; // Increment After
2999 let Inst{21} = 1; // Writeback
3001 let Inst{19-16} = Rn;
3002 let Inst{15-0} = regs;
3005 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
3006 let isPredicable = 1 in
3007 def t2B : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br,
3009 [(br bb:$target)]> {
3010 let Inst{31-27} = 0b11110;
3011 let Inst{15-14} = 0b10;
3015 let Inst{26} = target{19};
3016 let Inst{11} = target{18};
3017 let Inst{13} = target{17};
3018 let Inst{21-16} = target{16-11};
3019 let Inst{10-0} = target{10-0};
3022 let isNotDuplicable = 1, isIndirectBranch = 1 in {
3023 def t2BR_JT : t2PseudoInst<(outs),
3024 (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id),
3025 SizeSpecial, IIC_Br,
3026 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
3028 // FIXME: Add a non-pc based case that can be predicated.
3029 def t2TBB_JT : t2PseudoInst<(outs),
3030 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3031 SizeSpecial, IIC_Br, []>;
3033 def t2TBH_JT : t2PseudoInst<(outs),
3034 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3035 SizeSpecial, IIC_Br, []>;
3037 def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3038 "tbb", "\t[$Rn, $Rm]", []> {
3041 let Inst{31-20} = 0b111010001101;
3042 let Inst{19-16} = Rn;
3043 let Inst{15-5} = 0b11110000000;
3044 let Inst{4} = 0; // B form
3048 def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3049 "tbh", "\t[$Rn, $Rm, lsl #1]", []> {
3052 let Inst{31-20} = 0b111010001101;
3053 let Inst{19-16} = Rn;
3054 let Inst{15-5} = 0b11110000000;
3055 let Inst{4} = 1; // H form
3058 } // isNotDuplicable, isIndirectBranch
3060 } // isBranch, isTerminator, isBarrier
3062 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
3063 // a two-value operand where a dag node expects two operands. :(
3064 let isBranch = 1, isTerminator = 1 in
3065 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3067 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
3068 let Inst{31-27} = 0b11110;
3069 let Inst{15-14} = 0b10;
3073 let Inst{25-22} = p;
3076 let Inst{26} = target{20};
3077 let Inst{11} = target{19};
3078 let Inst{13} = target{18};
3079 let Inst{21-16} = target{17-12};
3080 let Inst{10-0} = target{11-1};
3085 let Defs = [ITSTATE] in
3086 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3087 AddrModeNone, Size2Bytes, IIC_iALUx,
3088 "it$mask\t$cc", "", []> {
3089 // 16-bit instruction.
3090 let Inst{31-16} = 0x0000;
3091 let Inst{15-8} = 0b10111111;
3096 let Inst{3-0} = mask;
3099 // Branch and Exchange Jazelle -- for disassembly only
3101 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
3102 [/* For disassembly only; pattern left blank */]> {
3103 let Inst{31-27} = 0b11110;
3105 let Inst{25-20} = 0b111100;
3106 let Inst{15-14} = 0b10;
3110 let Inst{19-16} = func;
3113 // Change Processor State is a system instruction -- for disassembly and
3115 // FIXME: Since the asm parser has currently no clean way to handle optional
3116 // operands, create 3 versions of the same instruction. Once there's a clean
3117 // framework to represent optional operands, change this behavior.
3118 class t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary,
3119 !strconcat("cps", asm_op),
3120 [/* For disassembly only; pattern left blank */]> {
3126 let Inst{31-27} = 0b11110;
3128 let Inst{25-20} = 0b111010;
3129 let Inst{19-16} = 0b1111;
3130 let Inst{15-14} = 0b10;
3132 let Inst{10-9} = imod;
3134 let Inst{7-5} = iflags;
3135 let Inst{4-0} = mode;
3139 def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
3140 "$imod.w\t$iflags, $mode">;
3141 let mode = 0, M = 0 in
3142 def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags),
3143 "$imod.w\t$iflags">;
3144 let imod = 0, iflags = 0, M = 1 in
3145 def t2CPS1p : t2CPS<(ins i32imm:$mode), "\t$mode">;
3147 // A6.3.4 Branches and miscellaneous control
3148 // Table A6-14 Change Processor State, and hint instructions
3149 // Helper class for disassembly only.
3150 class T2I_hint<bits<8> op7_0, string opc, string asm>
3151 : T2I<(outs), (ins), NoItinerary, opc, asm,
3152 [/* For disassembly only; pattern left blank */]> {
3153 let Inst{31-20} = 0xf3a;
3154 let Inst{19-16} = 0b1111;
3155 let Inst{15-14} = 0b10;
3157 let Inst{10-8} = 0b000;
3158 let Inst{7-0} = op7_0;
3161 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
3162 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
3163 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
3164 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
3165 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
3167 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
3168 [/* For disassembly only; pattern left blank */]> {
3169 let Inst{31-20} = 0xf3a;
3170 let Inst{15-14} = 0b10;
3172 let Inst{10-8} = 0b000;
3173 let Inst{7-4} = 0b1111;
3176 let Inst{3-0} = opt;
3179 // Secure Monitor Call is a system instruction -- for disassembly only
3180 // Option = Inst{19-16}
3181 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
3182 [/* For disassembly only; pattern left blank */]> {
3183 let Inst{31-27} = 0b11110;
3184 let Inst{26-20} = 0b1111111;
3185 let Inst{15-12} = 0b1000;
3188 let Inst{19-16} = opt;
3191 class T2SRS<bits<12> op31_20,
3192 dag oops, dag iops, InstrItinClass itin,
3193 string opc, string asm, list<dag> pattern>
3194 : T2I<oops, iops, itin, opc, asm, pattern> {
3195 let Inst{31-20} = op31_20{11-0};
3198 let Inst{4-0} = mode{4-0};
3201 // Store Return State is a system instruction -- for disassembly only
3202 def t2SRSDBW : T2SRS<0b111010000010,
3203 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
3204 [/* For disassembly only; pattern left blank */]>;
3205 def t2SRSDB : T2SRS<0b111010000000,
3206 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
3207 [/* For disassembly only; pattern left blank */]>;
3208 def t2SRSIAW : T2SRS<0b111010011010,
3209 (outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
3210 [/* For disassembly only; pattern left blank */]>;
3211 def t2SRSIA : T2SRS<0b111010011000,
3212 (outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
3213 [/* For disassembly only; pattern left blank */]>;
3215 // Return From Exception is a system instruction -- for disassembly only
3217 class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3218 string opc, string asm, list<dag> pattern>
3219 : T2I<oops, iops, itin, opc, asm, pattern> {
3220 let Inst{31-20} = op31_20{11-0};
3223 let Inst{19-16} = Rn;
3224 let Inst{15-0} = 0xc000;
3227 def t2RFEDBW : T2RFE<0b111010000011,
3228 (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3229 [/* For disassembly only; pattern left blank */]>;
3230 def t2RFEDB : T2RFE<0b111010000001,
3231 (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn",
3232 [/* For disassembly only; pattern left blank */]>;
3233 def t2RFEIAW : T2RFE<0b111010011011,
3234 (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3235 [/* For disassembly only; pattern left blank */]>;
3236 def t2RFEIA : T2RFE<0b111010011001,
3237 (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3238 [/* For disassembly only; pattern left blank */]>;
3240 //===----------------------------------------------------------------------===//
3241 // Non-Instruction Patterns
3244 // 32-bit immediate using movw + movt.
3245 // This is a single pseudo instruction to make it re-materializable.
3246 // FIXME: Remove this when we can do generalized remat.
3247 let isReMaterializable = 1, isMoveImm = 1 in
3248 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3249 [(set rGPR:$dst, (i32 imm:$src))]>,
3250 Requires<[IsThumb, HasV6T2]>;
3252 // Pseudo instruction that combines movw + movt + add pc (if pic).
3253 // It also makes it possible to rematerialize the instructions.
3254 // FIXME: Remove this when we can do generalized remat and when machine licm
3255 // can properly the instructions.
3256 let isReMaterializable = 1 in {
3257 def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3259 [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3260 Requires<[IsThumb2, UseMovt]>;
3262 def t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3264 [(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3265 Requires<[IsThumb2, UseMovt]>;
3268 // ConstantPool, GlobalAddress, and JumpTable
3269 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
3270 Requires<[IsThumb2, DontUseMovt]>;
3271 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
3272 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3273 Requires<[IsThumb2, UseMovt]>;
3275 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3276 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
3278 // Pseudo instruction that combines ldr from constpool and add pc. This should
3279 // be expanded into two instructions late to allow if-conversion and
3281 let canFoldAsLoad = 1, isReMaterializable = 1 in
3282 def t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3284 [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3286 Requires<[IsThumb2]>;
3288 //===----------------------------------------------------------------------===//
3289 // Move between special register and ARM core register -- for disassembly only
3292 class T2SpecialReg<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3293 dag oops, dag iops, InstrItinClass itin,
3294 string opc, string asm, list<dag> pattern>
3295 : T2I<oops, iops, itin, opc, asm, pattern> {
3296 let Inst{31-20} = op31_20{11-0};
3297 let Inst{15-14} = op15_14{1-0};
3298 let Inst{12} = op12{0};
3301 class T2MRS<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3302 dag oops, dag iops, InstrItinClass itin,
3303 string opc, string asm, list<dag> pattern>
3304 : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3306 let Inst{11-8} = Rd;
3307 let Inst{19-16} = 0b1111;
3310 def t2MRS : T2MRS<0b111100111110, 0b10, 0,
3311 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3312 [/* For disassembly only; pattern left blank */]>;
3313 def t2MRSsys : T2MRS<0b111100111111, 0b10, 0,
3314 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
3315 [/* For disassembly only; pattern left blank */]>;
3317 // Move from ARM core register to Special Register
3319 // No need to have both system and application versions, the encodings are the
3320 // same and the assembly parser has no way to distinguish between them. The mask
3321 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3322 // the mask with the fields to be accessed in the special register.
3323 def t2MSR : T2SpecialReg<0b111100111000 /* op31-20 */, 0b10 /* op15-14 */,
3324 0 /* op12 */, (outs), (ins msr_mask:$mask, rGPR:$Rn),
3325 NoItinerary, "msr", "\t$mask, $Rn",
3326 [/* For disassembly only; pattern left blank */]> {
3329 let Inst{19-16} = Rn;
3330 let Inst{20} = mask{4}; // R Bit
3332 let Inst{11-8} = mask{3-0};
3335 //===----------------------------------------------------------------------===//
3336 // Move between coprocessor and ARM core register -- for disassembly only
3339 class t2MovRCopro<string opc, bit direction, dag oops, dag iops>
3340 : T2Cop<oops, iops, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3341 [/* For disassembly only; pattern left blank */]> {
3342 let Inst{27-24} = 0b1110;
3343 let Inst{20} = direction;
3353 let Inst{15-12} = Rt;
3354 let Inst{11-8} = cop;
3355 let Inst{23-21} = opc1;
3356 let Inst{7-5} = opc2;
3357 let Inst{3-0} = CRm;
3358 let Inst{19-16} = CRn;
3361 def t2MCR2 : t2MovRCopro<"mcr2", 0 /* from ARM core register to coprocessor */,
3362 (outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, c_imm:$CRn,
3363 c_imm:$CRm, i32imm:$opc2)>;
3364 def t2MRC2 : t2MovRCopro<"mrc2", 1 /* from coprocessor to ARM core register */,
3365 (outs GPR:$Rt), (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn,
3366 c_imm:$CRm, i32imm:$opc2)>;
3368 class t2MovRRCopro<string opc, bit direction>
3369 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3370 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3371 [/* For disassembly only; pattern left blank */]> {
3372 let Inst{27-24} = 0b1100;
3373 let Inst{23-21} = 0b010;
3374 let Inst{20} = direction;
3382 let Inst{15-12} = Rt;
3383 let Inst{19-16} = Rt2;
3384 let Inst{11-8} = cop;
3385 let Inst{7-4} = opc1;
3386 let Inst{3-0} = CRm;
3389 def t2MCRR2 : t2MovRRCopro<"mcrr2",
3390 0 /* from ARM core register to coprocessor */>;
3391 def t2MRRC2 : t2MovRRCopro<"mrrc2",
3392 1 /* from coprocessor to ARM core register */>;
3394 //===----------------------------------------------------------------------===//
3395 // Other Coprocessor Instructions. For disassembly only.
3398 def t2CDP2 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
3399 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3400 "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3401 [/* For disassembly only; pattern left blank */]> {
3402 let Inst{27-24} = 0b1110;
3411 let Inst{3-0} = CRm;
3413 let Inst{7-5} = opc2;
3414 let Inst{11-8} = cop;
3415 let Inst{15-12} = CRd;
3416 let Inst{19-16} = CRn;
3417 let Inst{23-20} = opc1;