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. t2_so_imm values are
47 // represented in the imm field in the same 12-bit form that they are encoded
48 // into t2_so_imm instructions: the 8-bit immediate is the least significant
49 // bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
50 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
51 let EncoderMethod = "getT2SOImmOpValue";
54 // t2_so_imm_not - Match an immediate that is a complement
56 def t2_so_imm_not : Operand<i32>,
58 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
59 }], t2_so_imm_not_XFORM>;
61 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
62 def t2_so_imm_neg : Operand<i32>,
64 return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
65 }], t2_so_imm_neg_XFORM>;
67 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
68 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
69 // to get the first/second pieces.
70 def t2_so_imm2part : Operand<i32>,
72 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
76 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
77 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
78 return CurDAG->getTargetConstant(V, MVT::i32);
81 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
82 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
83 return CurDAG->getTargetConstant(V, MVT::i32);
86 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
87 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
91 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
92 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
93 return CurDAG->getTargetConstant(V, MVT::i32);
96 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
97 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
98 return CurDAG->getTargetConstant(V, MVT::i32);
101 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
102 def imm1_31 : PatLeaf<(i32 imm), [{
103 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
106 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
107 def imm0_4095 : Operand<i32>,
108 PatLeaf<(i32 imm), [{
109 return (uint32_t)N->getZExtValue() < 4096;
112 def imm0_4095_neg : PatLeaf<(i32 imm), [{
113 return (uint32_t)(-N->getZExtValue()) < 4096;
116 def imm0_255_neg : PatLeaf<(i32 imm), [{
117 return (uint32_t)(-N->getZExtValue()) < 255;
120 def imm0_255_not : PatLeaf<(i32 imm), [{
121 return (uint32_t)(~N->getZExtValue()) < 255;
124 // Define Thumb2 specific addressing modes.
126 // t2addrmode_imm12 := reg + imm12
127 def t2addrmode_imm12 : Operand<i32>,
128 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
129 let PrintMethod = "printAddrModeImm12Operand";
130 string EncoderMethod = "getT2AddrModeImm12OpValue";
131 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
134 // t2addrmode_imm8 := reg +/- imm8
135 def t2addrmode_imm8 : Operand<i32>,
136 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
137 let PrintMethod = "printT2AddrModeImm8Operand";
138 string EncoderMethod = "getT2AddrModeImm8OpValue";
139 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
142 def t2am_imm8_offset : Operand<i32>,
143 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
144 [], [SDNPWantRoot]> {
145 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
146 string EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
149 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
150 def t2addrmode_imm8s4 : Operand<i32> {
151 let PrintMethod = "printT2AddrModeImm8s4Operand";
152 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
155 def t2am_imm8s4_offset : Operand<i32> {
156 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
159 // t2addrmode_so_reg := reg + (reg << imm2)
160 def t2addrmode_so_reg : Operand<i32>,
161 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
162 let PrintMethod = "printT2AddrModeSoRegOperand";
163 string EncoderMethod = "getT2AddrModeSORegOpValue";
164 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
168 //===----------------------------------------------------------------------===//
169 // Multiclass helpers...
173 class T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
174 string opc, string asm, list<dag> pattern>
175 : T2I<oops, iops, itin, opc, asm, pattern> {
179 let Inst{11-8} = Rd{3-0};
180 let Inst{26} = imm{11};
181 let Inst{14-12} = imm{10-8};
182 let Inst{7-0} = imm{7-0};
186 class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
187 string opc, string asm, list<dag> pattern>
188 : T2sI<oops, iops, itin, opc, asm, pattern> {
193 let Inst{11-8} = Rd{3-0};
194 let Inst{26} = imm{11};
195 let Inst{14-12} = imm{10-8};
196 let Inst{7-0} = imm{7-0};
199 class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin,
200 string opc, string asm, list<dag> pattern>
201 : T2I<oops, iops, itin, opc, asm, pattern> {
205 let Inst{19-16} = Rn{3-0};
206 let Inst{26} = imm{11};
207 let Inst{14-12} = imm{10-8};
208 let Inst{7-0} = imm{7-0};
212 class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
213 string opc, string asm, list<dag> pattern>
214 : T2I<oops, iops, itin, opc, asm, pattern> {
218 let Inst{11-8} = Rd{3-0};
219 let Inst{3-0} = ShiftedRm{3-0};
220 let Inst{5-4} = ShiftedRm{6-5};
221 let Inst{14-12} = ShiftedRm{11-9};
222 let Inst{7-6} = ShiftedRm{8-7};
225 class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
226 string opc, string asm, list<dag> pattern>
227 : T2I<oops, iops, itin, opc, asm, pattern> {
231 let Inst{11-8} = Rd{3-0};
232 let Inst{3-0} = ShiftedRm{3-0};
233 let Inst{5-4} = ShiftedRm{6-5};
234 let Inst{14-12} = ShiftedRm{11-9};
235 let Inst{7-6} = ShiftedRm{8-7};
238 class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin,
239 string opc, string asm, list<dag> pattern>
240 : T2I<oops, iops, itin, opc, asm, pattern> {
244 let Inst{19-16} = Rn{3-0};
245 let Inst{3-0} = ShiftedRm{3-0};
246 let Inst{5-4} = ShiftedRm{6-5};
247 let Inst{14-12} = ShiftedRm{11-9};
248 let Inst{7-6} = ShiftedRm{8-7};
251 class T2TwoReg<dag oops, dag iops, InstrItinClass itin,
252 string opc, string asm, list<dag> pattern>
253 : T2I<oops, iops, itin, opc, asm, pattern> {
257 let Inst{11-8} = Rd{3-0};
258 let Inst{3-0} = Rm{3-0};
261 class T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
262 string opc, string asm, list<dag> pattern>
263 : T2sI<oops, iops, itin, opc, asm, pattern> {
267 let Inst{11-8} = Rd{3-0};
268 let Inst{3-0} = Rm{3-0};
271 class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin,
272 string opc, string asm, list<dag> pattern>
273 : T2I<oops, iops, itin, opc, asm, pattern> {
277 let Inst{19-16} = Rn{3-0};
278 let Inst{3-0} = Rm{3-0};
282 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
283 string opc, string asm, list<dag> pattern>
284 : T2I<oops, iops, itin, opc, asm, pattern> {
288 let Inst{11-8} = Rd{3-0};
289 let Inst{3-0} = Rm{3-0};
292 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
293 string opc, string asm, list<dag> pattern>
294 : T2sI<oops, iops, itin, opc, asm, pattern> {
299 let Inst{11-8} = Rd{3-0};
300 let Inst{19-16} = Rn{3-0};
301 let Inst{26} = imm{11};
302 let Inst{14-12} = imm{10-8};
303 let Inst{7-0} = imm{7-0};
306 class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
307 string opc, string asm, list<dag> pattern>
308 : T2I<oops, iops, itin, opc, asm, pattern> {
313 let Inst{11-8} = Rd{3-0};
314 let Inst{3-0} = Rm{3-0};
315 let Inst{14-12} = imm{4-2};
316 let Inst{7-6} = imm{1-0};
319 class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
320 string opc, string asm, list<dag> pattern>
321 : T2sI<oops, iops, itin, opc, asm, pattern> {
326 let Inst{11-8} = Rd{3-0};
327 let Inst{3-0} = Rm{3-0};
328 let Inst{14-12} = imm{4-2};
329 let Inst{7-6} = imm{1-0};
332 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
333 string opc, string asm, list<dag> pattern>
334 : T2I<oops, iops, itin, opc, asm, pattern> {
339 let Inst{11-8} = Rd{3-0};
340 let Inst{19-16} = Rn{3-0};
341 let Inst{3-0} = Rm{3-0};
344 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
345 string opc, string asm, list<dag> pattern>
346 : T2sI<oops, iops, itin, opc, asm, pattern> {
351 let Inst{11-8} = Rd{3-0};
352 let Inst{19-16} = Rn{3-0};
353 let Inst{3-0} = Rm{3-0};
356 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
357 string opc, string asm, list<dag> pattern>
358 : T2I<oops, iops, itin, opc, asm, pattern> {
363 let Inst{11-8} = Rd{3-0};
364 let Inst{19-16} = Rn{3-0};
365 let Inst{3-0} = ShiftedRm{3-0};
366 let Inst{5-4} = ShiftedRm{6-5};
367 let Inst{14-12} = ShiftedRm{11-9};
368 let Inst{7-6} = ShiftedRm{8-7};
371 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
372 string opc, string asm, list<dag> pattern>
373 : T2sI<oops, iops, itin, opc, asm, pattern> {
378 let Inst{11-8} = Rd{3-0};
379 let Inst{19-16} = Rn{3-0};
380 let Inst{3-0} = ShiftedRm{3-0};
381 let Inst{5-4} = ShiftedRm{6-5};
382 let Inst{14-12} = ShiftedRm{11-9};
383 let Inst{7-6} = ShiftedRm{8-7};
386 class T2FourReg<dag oops, dag iops, InstrItinClass itin,
387 string opc, string asm, list<dag> pattern>
388 : T2I<oops, iops, itin, opc, asm, pattern> {
394 let Inst{11-8} = Rd{3-0};
395 let Inst{19-16} = Rn{3-0};
396 let Inst{3-0} = Rm{3-0};
397 let Inst{15-12} = Ra{3-0};
401 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
402 /// unary operation that produces a value. These are predicable and can be
403 /// changed to modify CPSR.
404 multiclass T2I_un_irs<bits<4> opcod, string opc,
405 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
406 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
408 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
410 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> {
411 let isAsCheapAsAMove = Cheap;
412 let isReMaterializable = ReMat;
413 let Inst{31-27} = 0b11110;
415 let Inst{24-21} = opcod;
416 let Inst{20} = ?; // The S bit.
417 let Inst{19-16} = 0b1111; // Rn
421 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
423 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
424 let Inst{31-27} = 0b11101;
425 let Inst{26-25} = 0b01;
426 let Inst{24-21} = opcod;
427 let Inst{20} = ?; // The S bit.
428 let Inst{19-16} = 0b1111; // Rn
429 let Inst{14-12} = 0b000; // imm3
430 let Inst{7-6} = 0b00; // imm2
431 let Inst{5-4} = 0b00; // type
434 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
435 opc, ".w\t$Rd, $ShiftedRm",
436 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> {
437 let Inst{31-27} = 0b11101;
438 let Inst{26-25} = 0b01;
439 let Inst{24-21} = opcod;
440 let Inst{20} = ?; // The S bit.
441 let Inst{19-16} = 0b1111; // Rn
445 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
446 /// binary operation that produces a value. These are predicable and can be
447 /// changed to modify CPSR.
448 multiclass T2I_bin_irs<bits<4> opcod, string opc,
449 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
450 PatFrag opnode, bit Commutable = 0, string wide = ""> {
452 def ri : T2sTwoRegImm<
453 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
454 opc, "\t$Rd, $Rn, $imm",
455 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
456 let Inst{31-27} = 0b11110;
458 let Inst{24-21} = opcod;
459 let Inst{20} = ?; // The S bit.
463 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
464 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
465 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
466 let isCommutable = Commutable;
467 let Inst{31-27} = 0b11101;
468 let Inst{26-25} = 0b01;
469 let Inst{24-21} = opcod;
470 let Inst{20} = ?; // The S bit.
471 let Inst{14-12} = 0b000; // imm3
472 let Inst{7-6} = 0b00; // imm2
473 let Inst{5-4} = 0b00; // type
476 def rs : T2sTwoRegShiftedReg<
477 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
478 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
479 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
480 let Inst{31-27} = 0b11101;
481 let Inst{26-25} = 0b01;
482 let Inst{24-21} = opcod;
483 let Inst{20} = ?; // The S bit.
487 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
488 // the ".w" prefix to indicate that they are wide.
489 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
490 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
491 PatFrag opnode, bit Commutable = 0> :
492 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
494 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
495 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
496 /// it is equivalent to the T2I_bin_irs counterpart.
497 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
499 def ri : T2sTwoRegImm<
500 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
501 opc, ".w\t$Rd, $Rn, $imm",
502 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
503 let Inst{31-27} = 0b11110;
505 let Inst{24-21} = opcod;
506 let Inst{20} = ?; // The S bit.
510 def rr : T2sThreeReg<
511 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
512 opc, "\t$Rd, $Rn, $Rm",
513 [/* For disassembly only; pattern left blank */]> {
514 let Inst{31-27} = 0b11101;
515 let Inst{26-25} = 0b01;
516 let Inst{24-21} = opcod;
517 let Inst{20} = ?; // The S bit.
518 let Inst{14-12} = 0b000; // imm3
519 let Inst{7-6} = 0b00; // imm2
520 let Inst{5-4} = 0b00; // type
523 def rs : T2sTwoRegShiftedReg<
524 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
525 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
526 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
527 let Inst{31-27} = 0b11101;
528 let Inst{26-25} = 0b01;
529 let Inst{24-21} = opcod;
530 let Inst{20} = ?; // The S bit.
534 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
535 /// instruction modifies the CPSR register.
536 let Defs = [CPSR] in {
537 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
538 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
539 PatFrag opnode, bit Commutable = 0> {
541 def ri : T2TwoRegImm<
542 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
543 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
544 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
545 let Inst{31-27} = 0b11110;
547 let Inst{24-21} = opcod;
548 let Inst{20} = 1; // The S bit.
553 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
554 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
555 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
556 let isCommutable = Commutable;
557 let Inst{31-27} = 0b11101;
558 let Inst{26-25} = 0b01;
559 let Inst{24-21} = opcod;
560 let Inst{20} = 1; // The S bit.
561 let Inst{14-12} = 0b000; // imm3
562 let Inst{7-6} = 0b00; // imm2
563 let Inst{5-4} = 0b00; // type
566 def rs : T2TwoRegShiftedReg<
567 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
568 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
569 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
570 let Inst{31-27} = 0b11101;
571 let Inst{26-25} = 0b01;
572 let Inst{24-21} = opcod;
573 let Inst{20} = 1; // The S bit.
578 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
579 /// patterns for a binary operation that produces a value.
580 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
581 bit Commutable = 0> {
583 // The register-immediate version is re-materializable. This is useful
584 // in particular for taking the address of a local.
585 let isReMaterializable = 1 in {
586 def ri : T2sTwoRegImm<
587 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
588 opc, ".w\t$Rd, $Rn, $imm",
589 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
590 let Inst{31-27} = 0b11110;
593 let Inst{23-21} = op23_21;
594 let Inst{20} = 0; // The S bit.
599 def ri12 : T2TwoRegImm<
600 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
601 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
602 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
603 let Inst{31-27} = 0b11110;
606 let Inst{23-21} = op23_21;
607 let Inst{20} = 0; // The S bit.
611 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
612 opc, ".w\t$Rd, $Rn, $Rm",
613 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
614 let isCommutable = Commutable;
615 let Inst{31-27} = 0b11101;
616 let Inst{26-25} = 0b01;
618 let Inst{23-21} = op23_21;
619 let Inst{20} = 0; // The S bit.
620 let Inst{14-12} = 0b000; // imm3
621 let Inst{7-6} = 0b00; // imm2
622 let Inst{5-4} = 0b00; // type
625 def rs : T2sTwoRegShiftedReg<
626 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
627 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
628 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
629 let Inst{31-27} = 0b11101;
630 let Inst{26-25} = 0b01;
632 let Inst{23-21} = op23_21;
633 let Inst{20} = 0; // The S bit.
637 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
638 /// for a binary operation that produces a value and use the carry
639 /// bit. It's not predicable.
640 let Uses = [CPSR] in {
641 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
642 bit Commutable = 0> {
644 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
645 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
646 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
647 Requires<[IsThumb2]> {
648 let Inst{31-27} = 0b11110;
650 let Inst{24-21} = opcod;
651 let Inst{20} = 0; // The S bit.
655 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
656 opc, ".w\t$Rd, $Rn, $Rm",
657 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
658 Requires<[IsThumb2]> {
659 let isCommutable = Commutable;
660 let Inst{31-27} = 0b11101;
661 let Inst{26-25} = 0b01;
662 let Inst{24-21} = opcod;
663 let Inst{20} = 0; // The S bit.
664 let Inst{14-12} = 0b000; // imm3
665 let Inst{7-6} = 0b00; // imm2
666 let Inst{5-4} = 0b00; // type
669 def rs : T2sTwoRegShiftedReg<
670 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
671 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
672 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
673 Requires<[IsThumb2]> {
674 let Inst{31-27} = 0b11101;
675 let Inst{26-25} = 0b01;
676 let Inst{24-21} = opcod;
677 let Inst{20} = 0; // The S bit.
681 // Carry setting variants
682 let Defs = [CPSR] in {
683 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
684 bit Commutable = 0> {
686 def ri : T2sTwoRegImm<
687 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
688 opc, "\t$Rd, $Rn, $imm",
689 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
690 Requires<[IsThumb2]> {
691 let Inst{31-27} = 0b11110;
693 let Inst{24-21} = opcod;
694 let Inst{20} = 1; // The S bit.
698 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
699 opc, ".w\t$Rd, $Rn, $Rm",
700 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
701 Requires<[IsThumb2]> {
702 let isCommutable = Commutable;
703 let Inst{31-27} = 0b11101;
704 let Inst{26-25} = 0b01;
705 let Inst{24-21} = opcod;
706 let Inst{20} = 1; // The S bit.
707 let Inst{14-12} = 0b000; // imm3
708 let Inst{7-6} = 0b00; // imm2
709 let Inst{5-4} = 0b00; // type
712 def rs : T2sTwoRegShiftedReg<
713 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
714 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
715 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
716 Requires<[IsThumb2]> {
717 let Inst{31-27} = 0b11101;
718 let Inst{26-25} = 0b01;
719 let Inst{24-21} = opcod;
720 let Inst{20} = 1; // The S bit.
726 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
727 /// version is not needed since this is only for codegen.
728 let Defs = [CPSR] in {
729 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
731 def ri : T2TwoRegImm<
732 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
733 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
734 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
735 let Inst{31-27} = 0b11110;
737 let Inst{24-21} = opcod;
738 let Inst{20} = 1; // The S bit.
742 def rs : T2TwoRegShiftedReg<
743 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
744 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
745 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
746 let Inst{31-27} = 0b11101;
747 let Inst{26-25} = 0b01;
748 let Inst{24-21} = opcod;
749 let Inst{20} = 1; // The S bit.
754 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
755 // rotate operation that produces a value.
756 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
758 def ri : T2sTwoRegShiftImm<
759 (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi,
760 opc, ".w\t$Rd, $Rm, $imm",
761 [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> {
762 let Inst{31-27} = 0b11101;
763 let Inst{26-21} = 0b010010;
764 let Inst{19-16} = 0b1111; // Rn
765 let Inst{5-4} = opcod;
768 def rr : T2sThreeReg<
769 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr,
770 opc, ".w\t$Rd, $Rn, $Rm",
771 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
772 let Inst{31-27} = 0b11111;
773 let Inst{26-23} = 0b0100;
774 let Inst{22-21} = opcod;
775 let Inst{15-12} = 0b1111;
776 let Inst{7-4} = 0b0000;
780 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
781 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
782 /// a explicit result, only implicitly set CPSR.
783 let isCompare = 1, Defs = [CPSR] in {
784 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
785 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
788 def ri : T2OneRegCmpImm<
789 (outs), (ins GPR:$Rn, t2_so_imm:$imm), iii,
790 opc, ".w\t$Rn, $imm",
791 [(opnode GPR:$Rn, t2_so_imm:$imm)]> {
792 let Inst{31-27} = 0b11110;
794 let Inst{24-21} = opcod;
795 let Inst{20} = 1; // The S bit.
797 let Inst{11-8} = 0b1111; // Rd
800 def rr : T2TwoRegCmp<
801 (outs), (ins GPR:$lhs, rGPR:$rhs), iir,
802 opc, ".w\t$lhs, $rhs",
803 [(opnode GPR:$lhs, rGPR:$rhs)]> {
804 let Inst{31-27} = 0b11101;
805 let Inst{26-25} = 0b01;
806 let Inst{24-21} = opcod;
807 let Inst{20} = 1; // The S bit.
808 let Inst{14-12} = 0b000; // imm3
809 let Inst{11-8} = 0b1111; // Rd
810 let Inst{7-6} = 0b00; // imm2
811 let Inst{5-4} = 0b00; // type
814 def rs : T2OneRegCmpShiftedReg<
815 (outs), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
816 opc, ".w\t$Rn, $ShiftedRm",
817 [(opnode GPR:$Rn, t2_so_reg:$ShiftedRm)]> {
818 let Inst{31-27} = 0b11101;
819 let Inst{26-25} = 0b01;
820 let Inst{24-21} = opcod;
821 let Inst{20} = 1; // The S bit.
822 let Inst{11-8} = 0b1111; // Rd
827 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
828 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
829 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
830 def i12 : T2Ii12<(outs GPR:$Rt), (ins t2addrmode_imm12:$addr), iii,
831 opc, ".w\t$Rt, $addr",
832 [(set GPR:$Rt, (opnode t2addrmode_imm12:$addr))]> {
833 let Inst{31-27} = 0b11111;
834 let Inst{26-25} = 0b00;
835 let Inst{24} = signed;
837 let Inst{22-21} = opcod;
838 let Inst{20} = 1; // load
841 let Inst{15-12} = Rt{3-0};
844 let Inst{19-16} = addr{15-12}; // Rn
845 let Inst{11-0} = addr{11-0}; // imm
847 def i8 : T2Ii8 <(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), iii,
849 [(set GPR:$Rt, (opnode t2addrmode_imm8:$addr))]> {
850 let Inst{31-27} = 0b11111;
851 let Inst{26-25} = 0b00;
852 let Inst{24} = signed;
854 let Inst{22-21} = opcod;
855 let Inst{20} = 1; // load
857 // Offset: index==TRUE, wback==FALSE
858 let Inst{10} = 1; // The P bit.
859 let Inst{8} = 0; // The W bit.
862 let Inst{15-12} = Rt{3-0};
865 let Inst{19-16} = addr{12-9}; // Rn
866 let Inst{9} = addr{8}; // U
867 let Inst{7-0} = addr{7-0}; // imm
869 def s : T2Iso <(outs GPR:$Rt), (ins t2addrmode_so_reg:$addr), iis,
870 opc, ".w\t$Rt, $addr",
871 [(set GPR:$Rt, (opnode t2addrmode_so_reg:$addr))]> {
872 let Inst{31-27} = 0b11111;
873 let Inst{26-25} = 0b00;
874 let Inst{24} = signed;
876 let Inst{22-21} = opcod;
877 let Inst{20} = 1; // load
878 let Inst{11-6} = 0b000000;
881 let Inst{15-12} = Rt{3-0};
884 let Inst{19-16} = addr{9-6}; // Rn
885 let Inst{3-0} = addr{5-2}; // Rm
886 let Inst{5-4} = addr{1-0}; // imm
889 // FIXME: Is the pci variant actually needed?
890 def pci : T2Ipc <(outs GPR:$Rt), (ins i32imm:$addr), iii,
891 opc, ".w\t$Rt, $addr",
892 [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
893 let isReMaterializable = 1;
894 let Inst{31-27} = 0b11111;
895 let Inst{26-25} = 0b00;
896 let Inst{24} = signed;
897 let Inst{23} = ?; // add = (U == '1')
898 let Inst{22-21} = opcod;
899 let Inst{20} = 1; // load
900 let Inst{19-16} = 0b1111; // Rn
904 let Inst{15-12} = Rt{3-0};
905 let Inst{11-0} = addr{11-0};
909 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
910 multiclass T2I_st<bits<2> opcod, string opc,
911 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
912 def i12 : T2Ii12<(outs), (ins GPR:$Rt, t2addrmode_imm12:$addr), iii,
913 opc, ".w\t$Rt, $addr",
914 [(opnode GPR:$Rt, t2addrmode_imm12:$addr)]> {
915 let Inst{31-27} = 0b11111;
916 let Inst{26-23} = 0b0001;
917 let Inst{22-21} = opcod;
918 let Inst{20} = 0; // !load
921 let Inst{15-12} = Rt{3-0};
924 let Inst{19-16} = addr{15-12}; // Rn
925 let Inst{11-0} = addr{11-0}; // imm
927 def i8 : T2Ii8 <(outs), (ins GPR:$Rt, t2addrmode_imm8:$addr), iii,
929 [(opnode GPR:$Rt, t2addrmode_imm8:$addr)]> {
930 let Inst{31-27} = 0b11111;
931 let Inst{26-23} = 0b0000;
932 let Inst{22-21} = opcod;
933 let Inst{20} = 0; // !load
935 // Offset: index==TRUE, wback==FALSE
936 let Inst{10} = 1; // The P bit.
937 let Inst{8} = 0; // The W bit.
940 let Inst{15-12} = Rt{3-0};
943 let Inst{19-16} = addr{12-9}; // Rn
944 let Inst{9} = addr{8}; // U
945 let Inst{7-0} = addr{7-0}; // imm
947 def s : T2Iso <(outs), (ins GPR:$Rt, t2addrmode_so_reg:$addr), iis,
948 opc, ".w\t$Rt, $addr",
949 [(opnode GPR:$Rt, t2addrmode_so_reg:$addr)]> {
950 let Inst{31-27} = 0b11111;
951 let Inst{26-23} = 0b0000;
952 let Inst{22-21} = opcod;
953 let Inst{20} = 0; // !load
954 let Inst{11-6} = 0b000000;
957 let Inst{15-12} = Rt{3-0};
960 let Inst{19-16} = addr{9-6}; // Rn
961 let Inst{3-0} = addr{5-2}; // Rm
962 let Inst{5-4} = addr{1-0}; // imm
966 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
967 /// register and one whose operand is a register rotated by 8/16/24.
968 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
969 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
971 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> {
972 let Inst{31-27} = 0b11111;
973 let Inst{26-23} = 0b0100;
974 let Inst{22-20} = opcod;
975 let Inst{19-16} = 0b1111; // Rn
976 let Inst{15-12} = 0b1111;
978 let Inst{5-4} = 0b00; // rotate
980 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
981 opc, ".w\t$Rd, $Rm, ror $rot",
982 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> {
983 let Inst{31-27} = 0b11111;
984 let Inst{26-23} = 0b0100;
985 let Inst{22-20} = opcod;
986 let Inst{19-16} = 0b1111; // Rn
987 let Inst{15-12} = 0b1111;
991 let Inst{5-4} = rot{1-0}; // rotate
995 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
996 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
997 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
999 [(set rGPR:$Rd, (opnode rGPR:$Rm))]>,
1000 Requires<[HasT2ExtractPack, IsThumb2]> {
1001 let Inst{31-27} = 0b11111;
1002 let Inst{26-23} = 0b0100;
1003 let Inst{22-20} = opcod;
1004 let Inst{19-16} = 0b1111; // Rn
1005 let Inst{15-12} = 0b1111;
1007 let Inst{5-4} = 0b00; // rotate
1009 def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
1010 opc, "\t$dst, $Rm, ror $rot",
1011 [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1012 Requires<[HasT2ExtractPack, IsThumb2]> {
1013 let Inst{31-27} = 0b11111;
1014 let Inst{26-23} = 0b0100;
1015 let Inst{22-20} = opcod;
1016 let Inst{19-16} = 0b1111; // Rn
1017 let Inst{15-12} = 0b1111;
1021 let Inst{5-4} = rot{1-0}; // rotate
1025 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
1027 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
1028 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr,
1029 opc, "\t$Rd, $Rm", []> {
1030 let Inst{31-27} = 0b11111;
1031 let Inst{26-23} = 0b0100;
1032 let Inst{22-20} = opcod;
1033 let Inst{19-16} = 0b1111; // Rn
1034 let Inst{15-12} = 0b1111;
1036 let Inst{5-4} = 0b00; // rotate
1038 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr,
1039 opc, "\t$Rd, $Rm, ror $rot", []> {
1040 let Inst{31-27} = 0b11111;
1041 let Inst{26-23} = 0b0100;
1042 let Inst{22-20} = opcod;
1043 let Inst{19-16} = 0b1111; // Rn
1044 let Inst{15-12} = 0b1111;
1048 let Inst{5-4} = rot{1-0}; // rotate
1052 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
1053 /// register and one whose operand is a register rotated by 8/16/24.
1054 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
1055 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1056 opc, "\t$Rd, $Rn, $Rm",
1057 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
1058 Requires<[HasT2ExtractPack, IsThumb2]> {
1059 let Inst{31-27} = 0b11111;
1060 let Inst{26-23} = 0b0100;
1061 let Inst{22-20} = opcod;
1062 let Inst{15-12} = 0b1111;
1064 let Inst{5-4} = 0b00; // rotate
1066 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
1067 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
1068 [(set rGPR:$Rd, (opnode rGPR:$Rn,
1069 (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1070 Requires<[HasT2ExtractPack, IsThumb2]> {
1071 let Inst{31-27} = 0b11111;
1072 let Inst{26-23} = 0b0100;
1073 let Inst{22-20} = opcod;
1074 let Inst{15-12} = 0b1111;
1078 let Inst{5-4} = rot{1-0}; // rotate
1082 // DO variant - disassembly only, no pattern
1084 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
1085 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
1086 opc, "\t$Rd, $Rn, $Rm", []> {
1087 let Inst{31-27} = 0b11111;
1088 let Inst{26-23} = 0b0100;
1089 let Inst{22-20} = opcod;
1090 let Inst{15-12} = 0b1111;
1092 let Inst{5-4} = 0b00; // rotate
1094 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
1095 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> {
1096 let Inst{31-27} = 0b11111;
1097 let Inst{26-23} = 0b0100;
1098 let Inst{22-20} = opcod;
1099 let Inst{15-12} = 0b1111;
1103 let Inst{5-4} = rot{1-0}; // rotate
1107 //===----------------------------------------------------------------------===//
1109 //===----------------------------------------------------------------------===//
1111 //===----------------------------------------------------------------------===//
1112 // Miscellaneous Instructions.
1115 class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
1116 string asm, list<dag> pattern>
1117 : T2XI<oops, iops, itin, asm, pattern> {
1121 let Inst{11-8} = Rd{3-0};
1122 let Inst{26} = label{11};
1123 let Inst{14-12} = label{10-8};
1124 let Inst{7-0} = label{7-0};
1127 // LEApcrel - Load a pc-relative address into a register without offending the
1129 let neverHasSideEffects = 1 in {
1130 let isReMaterializable = 1 in
1131 def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi,
1132 "adr${p}.w\t$Rd, #$label", []> {
1133 let Inst{31-27} = 0b11110;
1134 let Inst{25-24} = 0b10;
1135 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1138 let Inst{19-16} = 0b1111; // Rn
1143 } // neverHasSideEffects
1144 def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd),
1145 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
1146 "adr${p}.w\t$Rd, #${label}_${id}", []> {
1147 let Inst{31-27} = 0b11110;
1148 let Inst{25-24} = 0b10;
1149 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1152 let Inst{19-16} = 0b1111; // Rn
1156 // ADD r, sp, {so_imm|i12}
1157 def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm),
1158 IIC_iALUi, "add", ".w\t$Rd, $sp, $imm", []> {
1159 let Inst{31-27} = 0b11110;
1161 let Inst{24-21} = 0b1000;
1162 let Inst{20} = ?; // The S bit.
1163 let Inst{19-16} = 0b1101; // Rn = sp
1166 def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm),
1167 IIC_iALUi, "addw", "\t$Rd, $sp, $imm", []> {
1168 let Inst{31-27} = 0b11110;
1170 let Inst{24-21} = 0b0000;
1171 let Inst{20} = 0; // The S bit.
1172 let Inst{19-16} = 0b1101; // Rn = sp
1176 // ADD r, sp, so_reg
1177 def t2ADDrSPs : T2sTwoRegShiftedReg<
1178 (outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$ShiftedRm),
1179 IIC_iALUsi, "add", ".w\t$Rd, $sp, $ShiftedRm", []> {
1180 let Inst{31-27} = 0b11101;
1181 let Inst{26-25} = 0b01;
1182 let Inst{24-21} = 0b1000;
1183 let Inst{20} = ?; // The S bit.
1184 let Inst{19-16} = 0b1101; // Rn = sp
1188 // SUB r, sp, {so_imm|i12}
1189 def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm),
1190 IIC_iALUi, "sub", ".w\t$Rd, $sp, $imm", []> {
1191 let Inst{31-27} = 0b11110;
1193 let Inst{24-21} = 0b1101;
1194 let Inst{20} = ?; // The S bit.
1195 let Inst{19-16} = 0b1101; // Rn = sp
1198 def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm),
1199 IIC_iALUi, "subw", "\t$Rd, $sp, $imm", []> {
1200 let Inst{31-27} = 0b11110;
1202 let Inst{24-21} = 0b0101;
1203 let Inst{20} = 0; // The S bit.
1204 let Inst{19-16} = 0b1101; // Rn = sp
1208 // SUB r, sp, so_reg
1209 def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$imm),
1211 "sub", "\t$Rd, $sp, $imm", []> {
1212 let Inst{31-27} = 0b11101;
1213 let Inst{26-25} = 0b01;
1214 let Inst{24-21} = 0b1101;
1215 let Inst{20} = ?; // The S bit.
1216 let Inst{19-16} = 0b1101; // Rn = sp
1220 // Signed and unsigned division on v7-M
1221 def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1222 "sdiv", "\t$Rd, $Rn, $Rm",
1223 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>,
1224 Requires<[HasDivide, IsThumb2]> {
1225 let Inst{31-27} = 0b11111;
1226 let Inst{26-21} = 0b011100;
1228 let Inst{15-12} = 0b1111;
1229 let Inst{7-4} = 0b1111;
1232 def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi,
1233 "udiv", "\t$Rd, $Rn, $Rm",
1234 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>,
1235 Requires<[HasDivide, IsThumb2]> {
1236 let Inst{31-27} = 0b11111;
1237 let Inst{26-21} = 0b011101;
1239 let Inst{15-12} = 0b1111;
1240 let Inst{7-4} = 0b1111;
1243 //===----------------------------------------------------------------------===//
1244 // Load / store Instructions.
1248 let canFoldAsLoad = 1, isReMaterializable = 1 in
1249 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1250 UnOpFrag<(load node:$Src)>>;
1252 // Loads with zero extension
1253 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1254 UnOpFrag<(zextloadi16 node:$Src)>>;
1255 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1256 UnOpFrag<(zextloadi8 node:$Src)>>;
1258 // Loads with sign extension
1259 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1260 UnOpFrag<(sextloadi16 node:$Src)>>;
1261 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1262 UnOpFrag<(sextloadi8 node:$Src)>>;
1264 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1265 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
1267 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1268 (ins t2addrmode_imm8s4:$addr),
1269 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
1270 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1271 (ins i32imm:$addr), IIC_iLoad_d_i,
1272 "ldrd", "\t$dst1, $addr", []> {
1273 let Inst{19-16} = 0b1111; // Rn
1275 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1277 // zextload i1 -> zextload i8
1278 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1279 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1280 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1281 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1282 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1283 (t2LDRBs t2addrmode_so_reg:$addr)>;
1284 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1285 (t2LDRBpci tconstpool:$addr)>;
1287 // extload -> zextload
1288 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1290 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1291 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1292 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1293 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1294 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1295 (t2LDRBs t2addrmode_so_reg:$addr)>;
1296 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1297 (t2LDRBpci tconstpool:$addr)>;
1299 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1300 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1301 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1302 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1303 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1304 (t2LDRBs t2addrmode_so_reg:$addr)>;
1305 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1306 (t2LDRBpci tconstpool:$addr)>;
1308 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1309 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1310 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1311 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1312 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1313 (t2LDRHs t2addrmode_so_reg:$addr)>;
1314 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1315 (t2LDRHpci tconstpool:$addr)>;
1317 // FIXME: The destination register of the loads and stores can't be PC, but
1318 // can be SP. We need another regclass (similar to rGPR) to represent
1319 // that. Not a pressing issue since these are selected manually,
1324 class T2Iidxld<bit signed, bits<2> opcod, bit pre,
1326 AddrMode am, IndexMode im, InstrItinClass itin,
1327 string opc, string asm, string cstr, list<dag> pattern>
1328 : T2Iidxldst<signed, opcod, 1, pre, oops,
1329 iops, am,im,itin, opc, asm, cstr, pattern>;
1330 class T2Iidxst<bit signed, bits<2> opcod, bit pre,
1332 AddrMode am, IndexMode im, InstrItinClass itin,
1333 string opc, string asm, string cstr, list<dag> pattern>
1334 : T2Iidxldst<signed, opcod, 0, pre, oops,
1335 iops, am,im,itin, opc, asm, cstr, pattern>;
1337 let mayLoad = 1, neverHasSideEffects = 1 in {
1338 def t2LDR_PRE : T2Iidxld<0, 0b10, 1, (outs GPR:$Rt, GPR:$Rn),
1339 (ins t2addrmode_imm8:$addr),
1340 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1341 "ldr", "\t$Rt, $addr!", "$addr.base = $Rn",
1344 def t2LDR_POST : T2Iidxld<0, 0b10, 0, (outs GPR:$Rt, GPR:$Rn),
1345 (ins GPR:$base, t2am_imm8_offset:$offset),
1346 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1347 "ldr", "\t$Rt, [$Rn], $offset", "$base = $Rn",
1350 def t2LDRB_PRE : T2Iidxld<0, 0b00, 1, (outs GPR:$Rt, GPR:$Rn),
1351 (ins t2addrmode_imm8:$addr),
1352 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1353 "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn",
1355 def t2LDRB_POST : T2Iidxld<0, 0b00, 0, (outs GPR:$Rt, GPR:$Rn),
1356 (ins GPR:$base, t2am_imm8_offset:$offset),
1357 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1358 "ldrb", "\t$Rt, [$Rn], $offset", "$base = $Rn",
1361 def t2LDRH_PRE : T2Iidxld<0, 0b01, 1, (outs GPR:$Rt, GPR:$Rn),
1362 (ins t2addrmode_imm8:$addr),
1363 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1364 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn",
1366 def t2LDRH_POST : T2Iidxld<0, 0b01, 0, (outs GPR:$Rt, GPR:$Rn),
1367 (ins GPR:$base, t2am_imm8_offset:$offset),
1368 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1369 "ldrh", "\t$Rt, [$Rn], $offset", "$base = $Rn",
1372 def t2LDRSB_PRE : T2Iidxld<1, 0b00, 1, (outs GPR:$Rt, GPR:$Rn),
1373 (ins t2addrmode_imm8:$addr),
1374 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1375 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn",
1377 def t2LDRSB_POST : T2Iidxld<1, 0b00, 0, (outs GPR:$Rt, GPR:$Rn),
1378 (ins GPR:$base, t2am_imm8_offset:$offset),
1379 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1380 "ldrsb", "\t$Rt, [$Rn], $offset", "$base = $Rn",
1383 def t2LDRSH_PRE : T2Iidxld<1, 0b01, 1, (outs GPR:$Rt, GPR:$Rn),
1384 (ins t2addrmode_imm8:$addr),
1385 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1386 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn",
1388 def t2LDRSH_POST : T2Iidxld<1, 0b01, 0, (outs GPR:$dst, GPR:$Rn),
1389 (ins GPR:$base, t2am_imm8_offset:$offset),
1390 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1391 "ldrsh", "\t$dst, [$Rn], $offset", "$base = $Rn",
1393 } // mayLoad = 1, neverHasSideEffects = 1
1395 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1396 // for disassembly only.
1397 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1398 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1399 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc,
1400 "\t$dst, $addr", []> {
1401 let Inst{31-27} = 0b11111;
1402 let Inst{26-25} = 0b00;
1403 let Inst{24} = signed;
1405 let Inst{22-21} = type;
1406 let Inst{20} = 1; // load
1408 let Inst{10-8} = 0b110; // PUW.
1411 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1412 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1413 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1414 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1415 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1418 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1419 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1420 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1421 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1422 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1423 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1426 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1427 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1428 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1429 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1430 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
1433 def t2STR_PRE : T2Iidxst<0, 0b10, 1, (outs GPR:$base_wb),
1434 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1435 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1436 "str", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1438 (pre_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1440 def t2STR_POST : T2Iidxst<0, 0b10, 0, (outs GPR:$base_wb),
1441 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1442 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1443 "str", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1445 (post_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1447 def t2STRH_PRE : T2Iidxst<0, 0b01, 1, (outs GPR:$base_wb),
1448 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1449 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1450 "strh", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1452 (pre_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1454 def t2STRH_POST : T2Iidxst<0, 0b01, 0, (outs GPR:$base_wb),
1455 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1456 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1457 "strh", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1459 (post_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1461 def t2STRB_PRE : T2Iidxst<0, 0b00, 1, (outs GPR:$base_wb),
1462 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1463 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1464 "strb", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb",
1466 (pre_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1468 def t2STRB_POST : T2Iidxst<0, 0b00, 0, (outs GPR:$base_wb),
1469 (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr),
1470 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1471 "strb", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb",
1473 (post_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>;
1475 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1477 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1478 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1479 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc,
1480 "\t$src, $addr", []> {
1481 let Inst{31-27} = 0b11111;
1482 let Inst{26-25} = 0b00;
1483 let Inst{24} = 0; // not signed
1485 let Inst{22-21} = type;
1486 let Inst{20} = 0; // store
1488 let Inst{10-8} = 0b110; // PUW
1491 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1492 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1493 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1495 // ldrd / strd pre / post variants
1496 // For disassembly only.
1498 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1499 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1500 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1502 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1503 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1504 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1506 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1507 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1508 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1510 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1511 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1512 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
1514 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1515 // data/instruction access. These are for disassembly only.
1516 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1517 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1518 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1520 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1522 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1523 let Inst{31-25} = 0b1111100;
1524 let Inst{24} = instr;
1525 let Inst{23} = 1; // U = 1
1527 let Inst{21} = write;
1529 let Inst{15-12} = 0b1111;
1532 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1534 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1535 let Inst{31-25} = 0b1111100;
1536 let Inst{24} = instr;
1537 let Inst{23} = 0; // U = 0
1539 let Inst{21} = write;
1541 let Inst{15-12} = 0b1111;
1542 let Inst{11-8} = 0b1100;
1545 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1547 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1548 let Inst{31-25} = 0b1111100;
1549 let Inst{24} = instr;
1550 let Inst{23} = 0; // add = TRUE for T1
1552 let Inst{21} = write;
1554 let Inst{15-12} = 0b1111;
1555 let Inst{11-6} = 0000000;
1558 let isCodeGenOnly = 1 in
1559 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc,
1562 let Inst{31-25} = 0b1111100;
1563 let Inst{24} = write;
1564 let Inst{23} = ?; // add = (U == 1)
1566 let Inst{21} = instr;
1568 let Inst{19-16} = 0b1111; // Rn = 0b1111
1569 let Inst{15-12} = 0b1111;
1573 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1574 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1575 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1577 //===----------------------------------------------------------------------===//
1578 // Load / store multiple Instructions.
1581 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1582 InstrItinClass itin_upd, bit L_bit> {
1584 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1585 itin, !strconcat(asm, "ia${p}.w\t$Rn, $regs"), []> {
1589 let Inst{31-27} = 0b11101;
1590 let Inst{26-25} = 0b00;
1591 let Inst{24-23} = 0b01; // Increment After
1593 let Inst{21} = 0; // No writeback
1594 let Inst{20} = L_bit;
1595 let Inst{19-16} = Rn;
1596 let Inst{15-0} = regs;
1599 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1600 itin_upd, !strconcat(asm, "ia${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1604 let Inst{31-27} = 0b11101;
1605 let Inst{26-25} = 0b00;
1606 let Inst{24-23} = 0b01; // Increment After
1608 let Inst{21} = 1; // Writeback
1609 let Inst{20} = L_bit;
1610 let Inst{19-16} = Rn;
1611 let Inst{15-0} = regs;
1614 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1615 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1619 let Inst{31-27} = 0b11101;
1620 let Inst{26-25} = 0b00;
1621 let Inst{24-23} = 0b10; // Decrement Before
1623 let Inst{21} = 0; // No writeback
1624 let Inst{20} = L_bit;
1625 let Inst{19-16} = Rn;
1626 let Inst{15-0} = regs;
1629 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1630 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1634 let Inst{31-27} = 0b11101;
1635 let Inst{26-25} = 0b00;
1636 let Inst{24-23} = 0b10; // Decrement Before
1638 let Inst{21} = 1; // Writeback
1639 let Inst{20} = L_bit;
1640 let Inst{19-16} = Rn;
1641 let Inst{15-0} = regs;
1645 let neverHasSideEffects = 1 in {
1647 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1648 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1650 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1651 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1653 } // neverHasSideEffects
1656 //===----------------------------------------------------------------------===//
1657 // Move Instructions.
1660 let neverHasSideEffects = 1 in
1661 def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1662 "mov", ".w\t$Rd, $Rm", []> {
1663 let Inst{31-27} = 0b11101;
1664 let Inst{26-25} = 0b01;
1665 let Inst{24-21} = 0b0010;
1666 let Inst{20} = ?; // The S bit.
1667 let Inst{19-16} = 0b1111; // Rn
1668 let Inst{14-12} = 0b000;
1669 let Inst{7-4} = 0b0000;
1672 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1673 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
1674 AddedComplexity = 1 in
1675 def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
1676 "mov", ".w\t$Rd, $imm",
1677 [(set rGPR:$Rd, t2_so_imm:$imm)]> {
1678 let Inst{31-27} = 0b11110;
1680 let Inst{24-21} = 0b0010;
1681 let Inst{20} = ?; // The S bit.
1682 let Inst{19-16} = 0b1111; // Rn
1686 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1687 def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm:$imm), IIC_iMOVi,
1688 "movw", "\t$Rd, $imm",
1689 [(set rGPR:$Rd, imm0_65535:$imm)]> {
1690 let Inst{31-27} = 0b11110;
1692 let Inst{24-21} = 0b0010;
1693 let Inst{20} = 0; // The S bit.
1699 let Inst{11-8} = Rd{3-0};
1700 let Inst{19-16} = imm{15-12};
1701 let Inst{26} = imm{11};
1702 let Inst{14-12} = imm{10-8};
1703 let Inst{7-0} = imm{7-0};
1706 let Constraints = "$src = $Rd" in
1707 def t2MOVTi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1708 "movt", "\t$Rd, $imm",
1710 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1711 let Inst{31-27} = 0b11110;
1713 let Inst{24-21} = 0b0110;
1714 let Inst{20} = 0; // The S bit.
1720 let Inst{11-8} = Rd{3-0};
1721 let Inst{19-16} = imm{15-12};
1722 let Inst{26} = imm{11};
1723 let Inst{14-12} = imm{10-8};
1724 let Inst{7-0} = imm{7-0};
1727 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1729 //===----------------------------------------------------------------------===//
1730 // Extend Instructions.
1735 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1736 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1737 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1738 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1739 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1741 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1742 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1743 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1744 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1745 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1747 // TODO: SXT(A){B|H}16 - done for disassembly only
1751 let AddedComplexity = 16 in {
1752 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1753 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1754 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1755 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1756 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1757 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1759 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1760 // The transformation should probably be done as a combiner action
1761 // instead so we can include a check for masking back in the upper
1762 // eight bits of the source into the lower eight bits of the result.
1763 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1764 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1765 // Requires<[HasT2ExtractPack, IsThumb2]>;
1766 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1767 (t2UXTB16r_rot rGPR:$Src, 8)>,
1768 Requires<[HasT2ExtractPack, IsThumb2]>;
1770 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1771 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1772 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1773 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1774 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1777 //===----------------------------------------------------------------------===//
1778 // Arithmetic Instructions.
1781 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1782 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1783 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1784 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1786 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1787 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1788 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1789 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1790 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1791 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1792 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1794 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1795 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1796 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1797 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1798 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1799 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1800 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1801 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1804 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1805 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1806 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1807 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1809 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1810 // The assume-no-carry-in form uses the negation of the input since add/sub
1811 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1812 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1814 // The AddedComplexity preferences the first variant over the others since
1815 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1816 let AddedComplexity = 1 in
1817 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1818 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1819 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1820 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1821 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1822 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1823 let AddedComplexity = 1 in
1824 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1825 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1826 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1827 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1828 // The with-carry-in form matches bitwise not instead of the negation.
1829 // Effectively, the inverse interpretation of the carry flag already accounts
1830 // for part of the negation.
1831 let AddedComplexity = 1 in
1832 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1833 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1834 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1835 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1837 // Select Bytes -- for disassembly only
1839 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1840 "\t$dst, $a, $b", []> {
1841 let Inst{31-27} = 0b11111;
1842 let Inst{26-24} = 0b010;
1844 let Inst{22-20} = 0b010;
1845 let Inst{15-12} = 0b1111;
1847 let Inst{6-4} = 0b000;
1850 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1851 // And Miscellaneous operations -- for disassembly only
1852 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1853 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1854 : T2I<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), NoItinerary, opc,
1855 "\t$Rd, $Rn, $Rm", pat> {
1856 let Inst{31-27} = 0b11111;
1857 let Inst{26-23} = 0b0101;
1858 let Inst{22-20} = op22_20;
1859 let Inst{15-12} = 0b1111;
1860 let Inst{7-4} = op7_4;
1866 let Inst{11-8} = Rd{3-0};
1867 let Inst{19-16} = Rn{3-0};
1868 let Inst{3-0} = Rm{3-0};
1871 // Saturating add/subtract -- for disassembly only
1873 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1874 [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))]>;
1875 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1876 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1877 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1878 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1879 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1880 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1881 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1882 [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))]>;
1883 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1884 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1885 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1886 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1887 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1888 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1889 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1890 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1892 // Signed/Unsigned add/subtract -- for disassembly only
1894 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1895 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1896 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1897 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1898 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1899 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1900 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1901 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1902 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1903 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1904 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1905 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1907 // Signed/Unsigned halving add/subtract -- for disassembly only
1909 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1910 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1911 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1912 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1913 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1914 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1915 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1916 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1917 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1918 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1919 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1920 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1922 // Helper class for disassembly only
1923 // A6.3.16 & A6.3.17
1924 // T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
1925 class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1926 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1927 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
1928 let Inst{31-27} = 0b11111;
1929 let Inst{26-24} = 0b011;
1930 let Inst{23} = long;
1931 let Inst{22-20} = op22_20;
1932 let Inst{7-4} = op7_4;
1935 class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
1936 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
1937 : T2FourReg<oops, iops, itin, opc, asm, pattern> {
1938 let Inst{31-27} = 0b11111;
1939 let Inst{26-24} = 0b011;
1940 let Inst{23} = long;
1941 let Inst{22-20} = op22_20;
1942 let Inst{7-4} = op7_4;
1945 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1947 def t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1948 (ins rGPR:$Rn, rGPR:$Rm),
1949 NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []> {
1950 let Inst{15-12} = 0b1111;
1952 def t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
1953 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
1954 "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>;
1956 // Signed/Unsigned saturate -- for disassembly only
1958 class T2SatI<dag oops, dag iops, InstrItinClass itin,
1959 string opc, string asm, list<dag> pattern>
1960 : T2I<oops, iops, itin, opc, asm, pattern> {
1966 let Inst{11-8} = Rd{3-0};
1967 let Inst{19-16} = Rn{3-0};
1968 let Inst{4-0} = sat_imm{4-0};
1969 let Inst{21} = sh{6};
1970 let Inst{14-12} = sh{4-2};
1971 let Inst{7-6} = sh{1-0};
1974 def t2SSAT: T2I<(outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
1975 NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
1976 [/* For disassembly only; pattern left blank */]> {
1977 let Inst{31-27} = 0b11110;
1978 let Inst{25-22} = 0b1100;
1983 def t2SSAT16: T2I<(outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary,
1984 "ssat16", "\t$Rd, $sat_imm, $Rn",
1985 [/* For disassembly only; pattern left blank */]> {
1986 let Inst{31-27} = 0b11110;
1987 let Inst{25-22} = 0b1100;
1990 let Inst{21} = 1; // sh = '1'
1991 let Inst{14-12} = 0b000; // imm3 = '000'
1992 let Inst{7-6} = 0b00; // imm2 = '00'
1995 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1996 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1997 [/* For disassembly only; pattern left blank */]> {
1998 let Inst{31-27} = 0b11110;
1999 let Inst{25-22} = 0b1110;
2004 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
2005 "usat16", "\t$dst, $bit_pos, $a",
2006 [/* For disassembly only; pattern left blank */]> {
2007 let Inst{31-27} = 0b11110;
2008 let Inst{25-22} = 0b1110;
2011 let Inst{21} = 1; // sh = '1'
2012 let Inst{14-12} = 0b000; // imm3 = '000'
2013 let Inst{7-6} = 0b00; // imm2 = '00'
2016 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
2017 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
2019 //===----------------------------------------------------------------------===//
2020 // Shift and rotate Instructions.
2023 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
2024 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
2025 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
2026 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
2028 let Uses = [CPSR] in {
2029 def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2030 "rrx", "\t$Rd, $Rm",
2031 [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> {
2032 let Inst{31-27} = 0b11101;
2033 let Inst{26-25} = 0b01;
2034 let Inst{24-21} = 0b0010;
2035 let Inst{20} = ?; // The S bit.
2036 let Inst{19-16} = 0b1111; // Rn
2037 let Inst{14-12} = 0b000;
2038 let Inst{7-4} = 0b0011;
2042 let Defs = [CPSR] in {
2043 def t2MOVsrl_flag : T2TwoRegShiftImm<
2044 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2045 "lsrs", ".w\t$Rd, $Rm, #1",
2046 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> {
2047 let Inst{31-27} = 0b11101;
2048 let Inst{26-25} = 0b01;
2049 let Inst{24-21} = 0b0010;
2050 let Inst{20} = 1; // The S bit.
2051 let Inst{19-16} = 0b1111; // Rn
2052 let Inst{5-4} = 0b01; // Shift type.
2053 // Shift amount = Inst{14-12:7-6} = 1.
2054 let Inst{14-12} = 0b000;
2055 let Inst{7-6} = 0b01;
2057 def t2MOVsra_flag : T2TwoRegShiftImm<
2058 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2059 "asrs", ".w\t$Rd, $Rm, #1",
2060 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> {
2061 let Inst{31-27} = 0b11101;
2062 let Inst{26-25} = 0b01;
2063 let Inst{24-21} = 0b0010;
2064 let Inst{20} = 1; // The S bit.
2065 let Inst{19-16} = 0b1111; // Rn
2066 let Inst{5-4} = 0b10; // Shift type.
2067 // Shift amount = Inst{14-12:7-6} = 1.
2068 let Inst{14-12} = 0b000;
2069 let Inst{7-6} = 0b01;
2073 //===----------------------------------------------------------------------===//
2074 // Bitwise Instructions.
2077 defm t2AND : T2I_bin_w_irs<0b0000, "and",
2078 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2079 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2080 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
2081 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2082 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2083 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
2084 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2085 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2087 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
2088 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2089 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2091 class T2BitFI<dag oops, dag iops, InstrItinClass itin,
2092 string opc, string asm, list<dag> pattern>
2093 : T2I<oops, iops, itin, opc, asm, pattern> {
2098 let Inst{11-8} = Rd{3-0};
2099 let Inst{4-0} = msb{4-0};
2100 let Inst{14-12} = lsb{4-2};
2101 let Inst{7-6} = lsb{1-0};
2104 class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2105 string opc, string asm, list<dag> pattern>
2106 : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2109 let Inst{19-16} = Rn{3-0};
2112 let Constraints = "$src = $Rd" in
2113 def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2114 IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2115 [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2116 let Inst{31-27} = 0b11110;
2118 let Inst{24-20} = 0b10110;
2119 let Inst{19-16} = 0b1111; // Rn
2123 let msb{4-0} = imm{9-5};
2124 let lsb{4-0} = imm{4-0};
2127 def t2SBFX: T2TwoRegBitFI<
2128 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2129 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2130 let Inst{31-27} = 0b11110;
2132 let Inst{24-20} = 0b10100;
2136 def t2UBFX: T2TwoRegBitFI<
2137 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
2138 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2139 let Inst{31-27} = 0b11110;
2141 let Inst{24-20} = 0b11100;
2145 // A8.6.18 BFI - Bitfield insert (Encoding T1)
2146 let Constraints = "$src = $Rd" in
2147 def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2148 (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2149 IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2150 [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2151 bf_inv_mask_imm:$imm))]> {
2152 let Inst{31-27} = 0b11110;
2154 let Inst{24-20} = 0b10110;
2158 let msb{4-0} = imm{9-5};
2159 let lsb{4-0} = imm{4-0};
2162 defm t2ORN : T2I_bin_irs<0b0011, "orn",
2163 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2164 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
2166 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2167 let AddedComplexity = 1 in
2168 defm t2MVN : T2I_un_irs <0b0011, "mvn",
2169 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2170 UnOpFrag<(not node:$Src)>, 1, 1>;
2173 let AddedComplexity = 1 in
2174 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
2175 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2177 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2178 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
2179 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2180 Requires<[IsThumb2]>;
2182 def : T2Pat<(t2_so_imm_not:$src),
2183 (t2MVNi t2_so_imm_not:$src)>;
2185 //===----------------------------------------------------------------------===//
2186 // Multiply Instructions.
2188 let isCommutable = 1 in
2189 def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2190 "mul", "\t$Rd, $Rn, $Rm",
2191 [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2192 let Inst{31-27} = 0b11111;
2193 let Inst{26-23} = 0b0110;
2194 let Inst{22-20} = 0b000;
2195 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2196 let Inst{7-4} = 0b0000; // Multiply
2199 def t2MLA: T2FourReg<
2200 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2201 "mla", "\t$Rd, $Rn, $Rm, $Ra",
2202 [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> {
2203 let Inst{31-27} = 0b11111;
2204 let Inst{26-23} = 0b0110;
2205 let Inst{22-20} = 0b000;
2206 let Inst{7-4} = 0b0000; // Multiply
2209 def t2MLS: T2FourReg<
2210 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2211 "mls", "\t$Rd, $Rn, $Rm, $Ra",
2212 [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> {
2213 let Inst{31-27} = 0b11111;
2214 let Inst{26-23} = 0b0110;
2215 let Inst{22-20} = 0b000;
2216 let Inst{7-4} = 0b0001; // Multiply and Subtract
2219 // Extra precision multiplies with low / high results
2220 let neverHasSideEffects = 1 in {
2221 let isCommutable = 1 in {
2222 def t2SMULL : T2FourReg<
2223 (outs rGPR:$Rd, rGPR:$Ra),
2224 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2225 "smull", "\t$Rd, $Ra, $Rn, $Rm", []> {
2226 let Inst{31-27} = 0b11111;
2227 let Inst{26-23} = 0b0111;
2228 let Inst{22-20} = 0b000;
2229 let Inst{7-4} = 0b0000;
2232 def t2UMULL : T2FourReg<
2233 (outs rGPR:$Rd, rGPR:$Ra),
2234 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2235 "umull", "\t$Rd, $Ra, $Rn, $Rm", []> {
2236 let Inst{31-27} = 0b11111;
2237 let Inst{26-23} = 0b0111;
2238 let Inst{22-20} = 0b010;
2239 let Inst{7-4} = 0b0000;
2243 // Multiply + accumulate
2244 def t2SMLAL : T2FourReg<(outs rGPR:$Ra, rGPR:$Rd),
2245 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2246 "smlal", "\t$Ra, $Rd, $Rn, $Rm", []>{
2247 let Inst{31-27} = 0b11111;
2248 let Inst{26-23} = 0b0111;
2249 let Inst{22-20} = 0b100;
2250 let Inst{7-4} = 0b0000;
2253 def t2UMLAL : T2FourReg<(outs rGPR:$Ra, rGPR:$Rd),
2254 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2255 "umlal", "\t$Ra, $Rd, $Rn, $Rm", []>{
2256 let Inst{31-27} = 0b11111;
2257 let Inst{26-23} = 0b0111;
2258 let Inst{22-20} = 0b110;
2259 let Inst{7-4} = 0b0000;
2262 def t2UMAAL : T2FourReg<(outs rGPR:$Ra, rGPR:$Rd),
2263 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64,
2264 "umaal", "\t$Ra, $Rd, $Rn, $Rm", []>{
2265 let Inst{31-27} = 0b11111;
2266 let Inst{26-23} = 0b0111;
2267 let Inst{22-20} = 0b110;
2268 let Inst{7-4} = 0b0110;
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;
2562 let Rn{3-0} = Rm{3-0};
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 (and rGPR:$Rm, 0xFF00), (i32 8)),
2588 (shl rGPR:$Rm, (i32 8))), i16))]>;
2590 def t2PKHBT : T2ThreeReg<
2591 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2592 IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2593 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2594 (and (shl rGPR:$Rm, lsl_amt:$sh),
2596 Requires<[HasT2ExtractPack, IsThumb2]> {
2597 let Inst{31-27} = 0b11101;
2598 let Inst{26-25} = 0b01;
2599 let Inst{24-20} = 0b01100;
2600 let Inst{5} = 0; // BT form
2604 let Inst{14-12} = sh{7-5};
2605 let Inst{7-6} = sh{4-3};
2608 // Alternate cases for PKHBT where identities eliminate some nodes.
2609 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2610 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2611 Requires<[HasT2ExtractPack, IsThumb2]>;
2612 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2613 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2614 Requires<[HasT2ExtractPack, IsThumb2]>;
2616 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2617 // will match the pattern below.
2618 def t2PKHTB : T2ThreeReg<
2619 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
2620 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2621 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
2622 (and (sra rGPR:$Rm, asr_amt:$sh),
2624 Requires<[HasT2ExtractPack, IsThumb2]> {
2625 let Inst{31-27} = 0b11101;
2626 let Inst{26-25} = 0b01;
2627 let Inst{24-20} = 0b01100;
2628 let Inst{5} = 1; // TB form
2632 let Inst{14-12} = sh{7-5};
2633 let Inst{7-6} = sh{4-3};
2636 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2637 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2638 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2639 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2640 Requires<[HasT2ExtractPack, IsThumb2]>;
2641 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2642 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2643 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2644 Requires<[HasT2ExtractPack, IsThumb2]>;
2646 //===----------------------------------------------------------------------===//
2647 // Comparison Instructions...
2649 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2650 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2651 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2652 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2653 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2654 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2656 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2657 // Compare-to-zero still works out, just not the relationals
2658 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2659 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2660 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2661 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2662 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2664 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2665 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2667 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2668 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2670 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2671 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2672 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
2673 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2674 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2675 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
2677 // Conditional moves
2678 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2679 // a two-value operand where a dag node expects two operands. :(
2680 let neverHasSideEffects = 1 in {
2681 def t2MOVCCr : T2TwoReg<
2682 (outs rGPR:$Rd), (ins rGPR:$false, rGPR:$Rm), IIC_iCMOVr,
2683 "mov", ".w\t$Rd, $Rm",
2684 [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2685 RegConstraint<"$false = $Rd"> {
2686 let Inst{31-27} = 0b11101;
2687 let Inst{26-25} = 0b01;
2688 let Inst{24-21} = 0b0010;
2689 let Inst{20} = 0; // The S bit.
2690 let Inst{19-16} = 0b1111; // Rn
2691 let Inst{14-12} = 0b000;
2692 let Inst{7-4} = 0b0000;
2695 let isMoveImm = 1 in
2696 def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2697 IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
2698 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2699 RegConstraint<"$false = $Rd"> {
2700 let Inst{31-27} = 0b11110;
2702 let Inst{24-21} = 0b0010;
2703 let Inst{20} = 0; // The S bit.
2704 let Inst{19-16} = 0b1111; // Rn
2708 let isMoveImm = 1 in
2709 def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm:$imm),
2711 "movw", "\t$Rd, $imm", []>,
2712 RegConstraint<"$false = $Rd"> {
2713 let Inst{31-27} = 0b11110;
2715 let Inst{24-21} = 0b0010;
2716 let Inst{20} = 0; // The S bit.
2722 let Inst{11-8} = Rd{3-0};
2723 let Inst{19-16} = imm{15-12};
2724 let Inst{26} = imm{11};
2725 let Inst{14-12} = imm{10-8};
2726 let Inst{7-0} = imm{7-0};
2729 let isMoveImm = 1 in
2730 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2731 (ins rGPR:$false, i32imm:$src, pred:$p),
2732 IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">;
2734 let isMoveImm = 1 in
2735 def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
2736 IIC_iCMOVi, "mvn", ".w\t$Rd, $imm",
2737 [/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm,
2738 imm:$cc, CCR:$ccr))*/]>,
2739 RegConstraint<"$false = $Rd"> {
2740 let Inst{31-27} = 0b11110;
2742 let Inst{24-21} = 0b0011;
2743 let Inst{20} = 0; // The S bit.
2744 let Inst{19-16} = 0b1111; // Rn
2748 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2749 string opc, string asm, list<dag> pattern>
2750 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> {
2751 let Inst{31-27} = 0b11101;
2752 let Inst{26-25} = 0b01;
2753 let Inst{24-21} = 0b0010;
2754 let Inst{20} = 0; // The S bit.
2755 let Inst{19-16} = 0b1111; // Rn
2756 let Inst{5-4} = opcod; // Shift type.
2758 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd),
2759 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2760 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>,
2761 RegConstraint<"$false = $Rd">;
2762 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd),
2763 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2764 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>,
2765 RegConstraint<"$false = $Rd">;
2766 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd),
2767 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2768 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>,
2769 RegConstraint<"$false = $Rd">;
2770 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
2771 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm),
2772 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
2773 RegConstraint<"$false = $Rd">;
2774 } // neverHasSideEffects
2776 //===----------------------------------------------------------------------===//
2777 // Atomic operations intrinsics
2780 // memory barriers protect the atomic sequences
2781 let hasSideEffects = 1 in {
2782 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2783 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2784 Requires<[IsThumb, HasDB]> {
2786 let Inst{31-4} = 0xf3bf8f5;
2787 let Inst{3-0} = opt;
2791 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2793 [/* For disassembly only; pattern left blank */]>,
2794 Requires<[IsThumb, HasDB]> {
2796 let Inst{31-4} = 0xf3bf8f4;
2797 let Inst{3-0} = opt;
2800 // ISB has only full system option -- for disassembly only
2801 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2802 [/* For disassembly only; pattern left blank */]>,
2803 Requires<[IsThumb2, HasV7]> {
2804 let Inst{31-4} = 0xf3bf8f6;
2805 let Inst{3-0} = 0b1111;
2808 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2809 InstrItinClass itin, string opc, string asm, string cstr,
2810 list<dag> pattern, bits<4> rt2 = 0b1111>
2811 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2812 let Inst{31-27} = 0b11101;
2813 let Inst{26-20} = 0b0001101;
2814 let Inst{11-8} = rt2;
2815 let Inst{7-6} = 0b01;
2816 let Inst{5-4} = opcod;
2817 let Inst{3-0} = 0b1111;
2821 let Inst{19-16} = Rn{3-0};
2822 let Inst{15-12} = Rt{3-0};
2824 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2825 InstrItinClass itin, string opc, string asm, string cstr,
2826 list<dag> pattern, bits<4> rt2 = 0b1111>
2827 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2828 let Inst{31-27} = 0b11101;
2829 let Inst{26-20} = 0b0001100;
2830 let Inst{11-8} = rt2;
2831 let Inst{7-6} = 0b01;
2832 let Inst{5-4} = opcod;
2837 let Inst{11-8} = Rd{3-0};
2838 let Inst{19-16} = Rn{3-0};
2839 let Inst{15-12} = Rt{3-0};
2842 let mayLoad = 1 in {
2843 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2844 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
2846 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2847 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
2849 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2850 Size4Bytes, NoItinerary,
2851 "ldrex", "\t$Rt, [$Rn]", "",
2853 let Inst{31-27} = 0b11101;
2854 let Inst{26-20} = 0b0000101;
2855 let Inst{11-8} = 0b1111;
2856 let Inst{7-0} = 0b00000000; // imm8 = 0
2858 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
2859 AddrModeNone, Size4Bytes, NoItinerary,
2860 "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
2863 let Inst{11-8} = Rt2{3-0};
2867 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2868 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2869 AddrModeNone, Size4Bytes, NoItinerary,
2870 "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
2871 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2872 AddrModeNone, Size4Bytes, NoItinerary,
2873 "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
2874 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2875 AddrModeNone, Size4Bytes, NoItinerary,
2876 "strex", "\t$Rd, $Rt, [$Rn]", "",
2878 let Inst{31-27} = 0b11101;
2879 let Inst{26-20} = 0b0000100;
2880 let Inst{7-0} = 0b00000000; // imm8 = 0
2882 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2883 (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
2884 AddrModeNone, Size4Bytes, NoItinerary,
2885 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
2888 let Inst{11-8} = Rt2{3-0};
2892 // Clear-Exclusive is for disassembly only.
2893 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2894 [/* For disassembly only; pattern left blank */]>,
2895 Requires<[IsARM, HasV7]> {
2896 let Inst{31-20} = 0xf3b;
2897 let Inst{15-14} = 0b10;
2899 let Inst{7-4} = 0b0010;
2902 //===----------------------------------------------------------------------===//
2906 // __aeabi_read_tp preserves the registers r1-r3.
2908 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
2909 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2910 "bl\t__aeabi_read_tp",
2911 [(set R0, ARMthread_pointer)]> {
2912 let Inst{31-27} = 0b11110;
2913 let Inst{15-14} = 0b11;
2918 //===----------------------------------------------------------------------===//
2919 // SJLJ Exception handling intrinsics
2920 // eh_sjlj_setjmp() is an instruction sequence to store the return
2921 // address and save #0 in R0 for the non-longjmp case.
2922 // Since by its nature we may be coming from some other function to get
2923 // here, and we're using the stack frame for the containing function to
2924 // save/restore registers, we can't keep anything live in regs across
2925 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2926 // when we get here from a longjmp(). We force everthing out of registers
2927 // except for our own input by listing the relevant registers in Defs. By
2928 // doing so, we also cause the prologue/epilogue code to actively preserve
2929 // all of the callee-saved resgisters, which is exactly what we want.
2930 // $val is a scratch register for our use.
2932 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2933 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2934 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2935 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2936 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2937 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2938 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2939 Requires<[IsThumb2, HasVFP2]>;
2943 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2944 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2945 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2946 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2947 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2948 Requires<[IsThumb2, NoVFP]>;
2952 //===----------------------------------------------------------------------===//
2953 // Control-Flow Instructions
2956 // FIXME: remove when we have a way to marking a MI with these properties.
2957 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2959 // FIXME: Should pc be an implicit operand like PICADD, etc?
2960 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2961 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2962 def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2963 reglist:$regs, variable_ops),
2965 "ldmia${p}.w\t$Rn!, $regs",
2970 let Inst{31-27} = 0b11101;
2971 let Inst{26-25} = 0b00;
2972 let Inst{24-23} = 0b01; // Increment After
2974 let Inst{21} = 1; // Writeback
2976 let Inst{19-16} = Rn;
2977 let Inst{15-0} = regs;
2980 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2981 let isPredicable = 1 in
2982 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2984 [(br bb:$target)]> {
2985 let Inst{31-27} = 0b11110;
2986 let Inst{15-14} = 0b10;
2990 let Inst{26} = target{19};
2991 let Inst{11} = target{18};
2992 let Inst{13} = target{17};
2993 let Inst{21-16} = target{16-11};
2994 let Inst{10-0} = target{10-0};
2997 let isNotDuplicable = 1, isIndirectBranch = 1 in {
2998 def t2BR_JT : tPseudoInst<(outs),
2999 (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id),
3000 SizeSpecial, IIC_Br,
3001 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
3003 // FIXME: Add a non-pc based case that can be predicated.
3004 def t2TBB_JT : tPseudoInst<(outs),
3005 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3006 SizeSpecial, IIC_Br, []>;
3008 def t2TBH_JT : tPseudoInst<(outs),
3009 (ins GPR:$index, i32imm:$jt, i32imm:$id),
3010 SizeSpecial, IIC_Br, []>;
3012 def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3013 "tbb", "\t[$Rn, $Rm]", []> {
3016 let Inst{27-20} = 0b10001101;
3017 let Inst{19-16} = Rn;
3018 let Inst{15-5} = 0b11110000000;
3019 let Inst{4} = 0; // B form
3023 def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
3024 "tbh", "\t[$Rn, $Rm, lsl #1]", []> {
3027 let Inst{27-20} = 0b10001101;
3028 let Inst{19-16} = Rn;
3029 let Inst{15-5} = 0b11110000000;
3030 let Inst{4} = 1; // H form
3033 } // isNotDuplicable, isIndirectBranch
3035 } // isBranch, isTerminator, isBarrier
3037 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
3038 // a two-value operand where a dag node expects two operands. :(
3039 let isBranch = 1, isTerminator = 1 in
3040 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3042 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
3043 let Inst{31-27} = 0b11110;
3044 let Inst{15-14} = 0b10;
3050 let Defs = [ITSTATE] in
3051 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3052 AddrModeNone, Size2Bytes, IIC_iALUx,
3053 "it$mask\t$cc", "", []> {
3054 // 16-bit instruction.
3055 let Inst{31-16} = 0x0000;
3056 let Inst{15-8} = 0b10111111;
3060 let Inst{7-4} = cc{3-0};
3061 let Inst{3-0} = mask{3-0};
3064 // Branch and Exchange Jazelle -- for disassembly only
3066 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
3067 [/* For disassembly only; pattern left blank */]> {
3068 let Inst{31-27} = 0b11110;
3070 let Inst{25-20} = 0b111100;
3071 let Inst{15-14} = 0b10;
3075 let Inst{19-16} = func{3-0};
3078 // Change Processor State is a system instruction -- for disassembly only.
3079 // The singleton $opt operand contains the following information:
3080 // opt{4-0} = mode from Inst{4-0}
3081 // opt{5} = changemode from Inst{17}
3082 // opt{8-6} = AIF from Inst{8-6}
3083 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
3084 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
3085 [/* For disassembly only; pattern left blank */]> {
3086 let Inst{31-27} = 0b11110;
3088 let Inst{25-20} = 0b111010;
3089 let Inst{15-14} = 0b10;
3095 let Inst{4-0} = opt{4-0};
3098 let Inst{8} = opt{5};
3101 let Inst{5} = opt{6};
3104 let Inst{6} = opt{7};
3107 let Inst{7} = opt{8};
3110 let Inst{10-9} = opt{10-9};
3113 // A6.3.4 Branches and miscellaneous control
3114 // Table A6-14 Change Processor State, and hint instructions
3115 // Helper class for disassembly only.
3116 class T2I_hint<bits<8> op7_0, string opc, string asm>
3117 : T2I<(outs), (ins), NoItinerary, opc, asm,
3118 [/* For disassembly only; pattern left blank */]> {
3119 let Inst{31-20} = 0xf3a;
3120 let Inst{15-14} = 0b10;
3122 let Inst{10-8} = 0b000;
3123 let Inst{7-0} = op7_0;
3126 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
3127 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
3128 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
3129 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
3130 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
3132 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
3133 [/* For disassembly only; pattern left blank */]> {
3134 let Inst{31-20} = 0xf3a;
3135 let Inst{15-14} = 0b10;
3137 let Inst{10-8} = 0b000;
3138 let Inst{7-4} = 0b1111;
3141 // Secure Monitor Call is a system instruction -- for disassembly only
3142 // Option = Inst{19-16}
3143 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
3144 [/* For disassembly only; pattern left blank */]> {
3145 let Inst{31-27} = 0b11110;
3146 let Inst{26-20} = 0b1111111;
3147 let Inst{15-12} = 0b1000;
3150 let Inst{19-16} = opt{3-0};
3153 class T2SRS<bits<12> op31_20,
3154 dag oops, dag iops, InstrItinClass itin,
3155 string opc, string asm, list<dag> pattern>
3156 : T2I<oops, iops, itin, opc, asm, pattern> {
3157 let Inst{31-20} = op31_20{11-0};
3160 let Inst{4-0} = mode{4-0};
3163 // Store Return State is a system instruction -- for disassembly only
3164 def t2SRSDBW : T2SRS<0b111010000010,
3165 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
3166 [/* For disassembly only; pattern left blank */]>;
3167 def t2SRSDB : T2SRS<0b111010000000,
3168 (outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
3169 [/* For disassembly only; pattern left blank */]>;
3170 def t2SRSIAW : T2SRS<0b111010011010,
3171 (outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
3172 [/* For disassembly only; pattern left blank */]>;
3173 def t2SRSIA : T2SRS<0b111010011000,
3174 (outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
3175 [/* For disassembly only; pattern left blank */]>;
3177 // Return From Exception is a system instruction -- for disassembly only
3179 class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3180 string opc, string asm, list<dag> pattern>
3181 : T2I<oops, iops, itin, opc, asm, pattern> {
3182 let Inst{31-20} = op31_20{11-0};
3185 let Inst{19-16} = Rn{3-0};
3188 def t2RFEDBW : T2RFE<0b111010000011,
3189 (outs), (ins rGPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3190 [/* For disassembly only; pattern left blank */]>;
3191 def t2RFEDB : T2RFE<0b111010000001,
3192 (outs), (ins rGPR:$Rn), NoItinerary, "rfeab", "\t$Rn",
3193 [/* For disassembly only; pattern left blank */]>;
3194 def t2RFEIAW : T2RFE<0b111010011011,
3195 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3196 [/* For disassembly only; pattern left blank */]>;
3197 def t2RFEIA : T2RFE<0b111010011001,
3198 (outs), (ins rGPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3199 [/* For disassembly only; pattern left blank */]>;
3201 //===----------------------------------------------------------------------===//
3202 // Non-Instruction Patterns
3205 // 32-bit immediate using movw + movt.
3206 // This is a single pseudo instruction to make it re-materializable.
3207 // FIXME: Remove this when we can do generalized remat.
3208 let isReMaterializable = 1, isMoveImm = 1 in
3209 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3210 [(set rGPR:$dst, (i32 imm:$src))]>,
3211 Requires<[IsThumb, HasV6T2]>;
3213 // ConstantPool, GlobalAddress, and JumpTable
3214 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
3215 Requires<[IsThumb2, DontUseMovt]>;
3216 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
3217 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3218 Requires<[IsThumb2, UseMovt]>;
3220 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3221 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
3223 // Pseudo instruction that combines ldr from constpool and add pc. This should
3224 // be expanded into two instructions late to allow if-conversion and
3226 let canFoldAsLoad = 1, isReMaterializable = 1 in
3227 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3229 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3231 Requires<[IsThumb2]>;
3233 //===----------------------------------------------------------------------===//
3234 // Move between special register and ARM core register -- for disassembly only
3237 class T2SpecialReg<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3238 dag oops, dag iops, InstrItinClass itin,
3239 string opc, string asm, list<dag> pattern>
3240 : T2I<oops, iops, itin, opc, asm, pattern> {
3241 let Inst{31-20} = op31_20{11-0};
3242 let Inst{15-14} = op15_14{1-0};
3243 let Inst{12} = op12{0};
3246 class T2MRS<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3247 dag oops, dag iops, InstrItinClass itin,
3248 string opc, string asm, list<dag> pattern>
3249 : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3251 let Inst{11-8} = Rd{3-0};
3254 def t2MRS : T2MRS<0b111100111110, 0b10, 0,
3255 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3256 [/* For disassembly only; pattern left blank */]>;
3257 def t2MRSsys : T2MRS<0b111100111111, 0b10, 0,
3258 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
3259 [/* For disassembly only; pattern left blank */]>;
3261 class T2MSR<bits<12> op31_20, bits<2> op15_14, bits<1> op12,
3262 dag oops, dag iops, InstrItinClass itin,
3263 string opc, string asm, list<dag> pattern>
3264 : T2SpecialReg<op31_20, op15_14, op12, oops, iops, itin, opc, asm, pattern> {
3267 let Inst{19-16} = Rn{3-0};
3268 let Inst{11-8} = mask{3-0};
3271 def t2MSR : T2MSR<0b111100111000, 0b10, 0,
3272 (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3274 [/* For disassembly only; pattern left blank */]>;
3275 def t2MSRsys : T2MSR<0b111100111001, 0b10, 0,
3276 (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3278 [/* For disassembly only; pattern left blank */]>;