1 //===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Thumb2 instruction set.
12 //===----------------------------------------------------------------------===//
14 // IT block predicate field
15 def it_pred : Operand<i32> {
16 let PrintMethod = "printMandatoryPredicateOperand";
19 // IT block condition mask
20 def it_mask : Operand<i32> {
21 let PrintMethod = "printThumbITMask";
24 // Table branch address
25 def tb_addrmode : Operand<i32> {
26 let PrintMethod = "printTBAddrMode";
29 // Shifted operands. No register controlled shifts for Thumb2.
30 // Note: We do not support rrx shifted operands yet.
31 def t2_so_reg : Operand<i32>, // reg imm
32 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
34 string EncoderMethod = "getT2SORegOpValue";
35 let PrintMethod = "printT2SOOperand";
36 let MIOperandInfo = (ops rGPR, i32imm);
39 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
40 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
41 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
44 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
45 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
46 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
49 // t2_so_imm - Match a 32-bit immediate operand, which is an
50 // 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
51 // immediate splatted into multiple bytes of the word. t2_so_imm values are
52 // represented in the imm field in the same 12-bit form that they are encoded
53 // into t2_so_imm instructions: the 8-bit immediate is the least significant
54 // bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
55 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
56 string EncoderMethod = "getT2SOImmOpValue";
59 // t2_so_imm_not - Match an immediate that is a complement
61 def t2_so_imm_not : Operand<i32>,
63 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64 }], t2_so_imm_not_XFORM>;
66 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67 def t2_so_imm_neg : Operand<i32>,
69 return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
70 }], t2_so_imm_neg_XFORM>;
72 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
73 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74 // to get the first/second pieces.
75 def t2_so_imm2part : Operand<i32>,
77 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
81 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83 return CurDAG->getTargetConstant(V, MVT::i32);
86 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88 return CurDAG->getTargetConstant(V, MVT::i32);
91 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
96 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98 return CurDAG->getTargetConstant(V, MVT::i32);
101 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103 return CurDAG->getTargetConstant(V, MVT::i32);
106 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107 def imm1_31 : PatLeaf<(i32 imm), [{
108 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
111 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
112 def imm0_4095 : Operand<i32>,
113 PatLeaf<(i32 imm), [{
114 return (uint32_t)N->getZExtValue() < 4096;
117 def imm0_4095_neg : PatLeaf<(i32 imm), [{
118 return (uint32_t)(-N->getZExtValue()) < 4096;
121 def imm0_255_neg : PatLeaf<(i32 imm), [{
122 return (uint32_t)(-N->getZExtValue()) < 255;
125 def imm0_255_not : PatLeaf<(i32 imm), [{
126 return (uint32_t)(~N->getZExtValue()) < 255;
129 // Define Thumb2 specific addressing modes.
131 // t2addrmode_imm12 := reg + imm12
132 def t2addrmode_imm12 : Operand<i32>,
133 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
134 let PrintMethod = "printAddrModeImm12Operand";
135 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
138 // t2addrmode_imm8 := reg +/- imm8
139 def t2addrmode_imm8 : Operand<i32>,
140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
141 let PrintMethod = "printT2AddrModeImm8Operand";
142 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
145 def t2am_imm8_offset : Operand<i32>,
146 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
147 [], [SDNPWantRoot]> {
148 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
151 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
152 def t2addrmode_imm8s4 : Operand<i32> {
153 let PrintMethod = "printT2AddrModeImm8s4Operand";
154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
157 def t2am_imm8s4_offset : Operand<i32> {
158 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
161 // t2addrmode_so_reg := reg + (reg << imm2)
162 def t2addrmode_so_reg : Operand<i32>,
163 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
164 let PrintMethod = "printT2AddrModeSoRegOperand";
165 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
169 //===----------------------------------------------------------------------===//
170 // Multiclass helpers...
173 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
174 string opc, string asm, list<dag> pattern>
175 : T2I<oops, iops, itin, opc, asm, pattern> {
180 let Inst{11-8} = Rd{3-0};
181 let Inst{19-16} = Rn{3-0};
182 let Inst{26} = imm{11};
183 let Inst{14-12} = imm{10-8};
184 let Inst{7-0} = imm{7-0};
187 class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
188 string opc, string asm, list<dag> pattern>
189 : T2sI<oops, iops, itin, opc, asm, pattern> {
194 let Inst{11-8} = Rd{3-0};
195 let Inst{19-16} = Rn{3-0};
196 let Inst{26} = imm{11};
197 let Inst{14-12} = imm{10-8};
198 let Inst{7-0} = imm{7-0};
201 class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
202 string opc, string asm, list<dag> pattern>
203 : T2I<oops, iops, itin, opc, asm, pattern> {
208 let Inst{11-8} = Rd{3-0};
209 let Inst{19-16} = Rn{3-0};
210 let Inst{3-0} = Rm{3-0};
213 class T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
214 string opc, string asm, list<dag> pattern>
215 : T2sI<oops, iops, itin, opc, asm, pattern> {
220 let Inst{11-8} = Rd{3-0};
221 let Inst{19-16} = Rn{3-0};
222 let Inst{3-0} = Rm{3-0};
225 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
226 string opc, string asm, list<dag> pattern>
227 : T2I<oops, iops, itin, opc, asm, pattern> {
232 let Inst{11-8} = Rd{3-0};
233 let Inst{19-16} = Rn{3-0};
234 let Inst{3-0} = ShiftedRm{3-0};
235 let Inst{5-4} = ShiftedRm{6-5};
236 let Inst{14-12} = ShiftedRm{11-9};
237 let Inst{7-6} = ShiftedRm{8-7};
240 class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
241 string opc, string asm, list<dag> pattern>
242 : T2sI<oops, iops, itin, opc, asm, pattern> {
247 let Inst{11-8} = Rd{3-0};
248 let Inst{19-16} = Rn{3-0};
249 let Inst{3-0} = ShiftedRm{3-0};
250 let Inst{5-4} = ShiftedRm{6-5};
251 let Inst{14-12} = ShiftedRm{11-9};
252 let Inst{7-6} = ShiftedRm{8-7};
255 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
256 /// unary operation that produces a value. These are predicable and can be
257 /// changed to modify CPSR.
258 multiclass T2I_un_irs<bits<4> opcod, string opc,
259 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
260 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
262 def i : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), iii,
264 [(set rGPR:$dst, (opnode t2_so_imm:$src))]> {
265 let isAsCheapAsAMove = Cheap;
266 let isReMaterializable = ReMat;
267 let Inst{31-27} = 0b11110;
269 let Inst{24-21} = opcod;
270 let Inst{20} = ?; // The S bit.
271 let Inst{19-16} = 0b1111; // Rn
275 def r : T2sI<(outs rGPR:$dst), (ins rGPR:$src), iir,
276 opc, ".w\t$dst, $src",
277 [(set rGPR:$dst, (opnode rGPR:$src))]> {
278 let Inst{31-27} = 0b11101;
279 let Inst{26-25} = 0b01;
280 let Inst{24-21} = opcod;
281 let Inst{20} = ?; // The S bit.
282 let Inst{19-16} = 0b1111; // Rn
283 let Inst{14-12} = 0b000; // imm3
284 let Inst{7-6} = 0b00; // imm2
285 let Inst{5-4} = 0b00; // type
288 def s : T2sI<(outs rGPR:$dst), (ins t2_so_reg:$src), iis,
289 opc, ".w\t$dst, $src",
290 [(set rGPR:$dst, (opnode t2_so_reg:$src))]> {
291 let Inst{31-27} = 0b11101;
292 let Inst{26-25} = 0b01;
293 let Inst{24-21} = opcod;
294 let Inst{20} = ?; // The S bit.
295 let Inst{19-16} = 0b1111; // Rn
299 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
300 /// binary operation that produces a value. These are predicable and can be
301 /// changed to modify CPSR.
302 multiclass T2I_bin_irs<bits<4> opcod, string opc,
303 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
304 PatFrag opnode, bit Commutable = 0, string wide = ""> {
306 def ri : T2sTwoRegImm<
307 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
308 opc, "\t$Rd, $Rn, $imm",
309 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
310 let Inst{31-27} = 0b11110;
312 let Inst{24-21} = opcod;
313 let Inst{20} = ?; // The S bit.
317 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
318 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
319 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
320 let isCommutable = Commutable;
321 let Inst{31-27} = 0b11101;
322 let Inst{26-25} = 0b01;
323 let Inst{24-21} = opcod;
324 let Inst{20} = ?; // The S bit.
325 let Inst{14-12} = 0b000; // imm3
326 let Inst{7-6} = 0b00; // imm2
327 let Inst{5-4} = 0b00; // type
330 def rs : T2sTwoRegShiftedReg<
331 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
332 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
333 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
334 let Inst{31-27} = 0b11101;
335 let Inst{26-25} = 0b01;
336 let Inst{24-21} = opcod;
337 let Inst{20} = ?; // The S bit.
341 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
342 // the ".w" prefix to indicate that they are wide.
343 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
344 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
345 PatFrag opnode, bit Commutable = 0> :
346 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
348 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
349 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
350 /// it is equivalent to the T2I_bin_irs counterpart.
351 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
353 def ri : T2sTwoRegImm<
354 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
355 opc, ".w\t$Rd, $Rn, $imm",
356 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
357 let Inst{31-27} = 0b11110;
359 let Inst{24-21} = opcod;
360 let Inst{20} = ?; // The S bit.
364 def rr : T2sThreeReg<
365 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
366 opc, "\t$Rd, $Rn, $Rm",
367 [/* For disassembly only; pattern left blank */]> {
368 let Inst{31-27} = 0b11101;
369 let Inst{26-25} = 0b01;
370 let Inst{24-21} = opcod;
371 let Inst{20} = ?; // The S bit.
372 let Inst{14-12} = 0b000; // imm3
373 let Inst{7-6} = 0b00; // imm2
374 let Inst{5-4} = 0b00; // type
377 def rs : T2sTwoRegShiftedReg<
378 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
379 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
380 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
381 let Inst{31-27} = 0b11101;
382 let Inst{26-25} = 0b01;
383 let Inst{24-21} = opcod;
384 let Inst{20} = ?; // The S bit.
388 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
389 /// instruction modifies the CPSR register.
390 let Defs = [CPSR] in {
391 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
392 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
393 PatFrag opnode, bit Commutable = 0> {
395 def ri : T2TwoRegImm<
396 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
397 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
398 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
399 let Inst{31-27} = 0b11110;
401 let Inst{24-21} = opcod;
402 let Inst{20} = 1; // The S bit.
407 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
408 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
409 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
410 let isCommutable = Commutable;
411 let Inst{31-27} = 0b11101;
412 let Inst{26-25} = 0b01;
413 let Inst{24-21} = opcod;
414 let Inst{20} = 1; // The S bit.
415 let Inst{14-12} = 0b000; // imm3
416 let Inst{7-6} = 0b00; // imm2
417 let Inst{5-4} = 0b00; // type
420 def rs : T2TwoRegShiftedReg<
421 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
422 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
423 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
424 let Inst{31-27} = 0b11101;
425 let Inst{26-25} = 0b01;
426 let Inst{24-21} = opcod;
427 let Inst{20} = 1; // The S bit.
432 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
433 /// patterns for a binary operation that produces a value.
434 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
435 bit Commutable = 0> {
437 // The register-immediate version is re-materializable. This is useful
438 // in particular for taking the address of a local.
439 let isReMaterializable = 1 in {
440 def ri : T2sTwoRegImm<
441 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
442 opc, ".w\t$Rd, $Rn, $imm",
443 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
444 let Inst{31-27} = 0b11110;
447 let Inst{23-21} = op23_21;
448 let Inst{20} = 0; // The S bit.
453 def ri12 : T2TwoRegImm<
454 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
455 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
456 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
457 let Inst{31-27} = 0b11110;
460 let Inst{23-21} = op23_21;
461 let Inst{20} = 0; // The S bit.
465 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
466 opc, ".w\t$Rd, $Rn, $Rm",
467 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
468 let isCommutable = Commutable;
469 let Inst{31-27} = 0b11101;
470 let Inst{26-25} = 0b01;
472 let Inst{23-21} = op23_21;
473 let Inst{20} = 0; // The S bit.
474 let Inst{14-12} = 0b000; // imm3
475 let Inst{7-6} = 0b00; // imm2
476 let Inst{5-4} = 0b00; // type
479 def rs : T2sTwoRegShiftedReg<
480 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
481 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
482 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
483 let Inst{31-27} = 0b11101;
484 let Inst{26-25} = 0b01;
486 let Inst{23-21} = op23_21;
487 let Inst{20} = 0; // The S bit.
491 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
492 /// for a binary operation that produces a value and use the carry
493 /// bit. It's not predicable.
494 let Uses = [CPSR] in {
495 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
496 bit Commutable = 0> {
498 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
499 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
500 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
501 Requires<[IsThumb2]> {
502 let Inst{31-27} = 0b11110;
504 let Inst{24-21} = opcod;
505 let Inst{20} = 0; // The S bit.
509 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
510 opc, ".w\t$Rd, $Rn, $Rm",
511 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
512 Requires<[IsThumb2]> {
513 let isCommutable = Commutable;
514 let Inst{31-27} = 0b11101;
515 let Inst{26-25} = 0b01;
516 let Inst{24-21} = opcod;
517 let Inst{20} = 0; // 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_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
526 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
527 Requires<[IsThumb2]> {
528 let Inst{31-27} = 0b11101;
529 let Inst{26-25} = 0b01;
530 let Inst{24-21} = opcod;
531 let Inst{20} = 0; // The S bit.
535 // Carry setting variants
536 let Defs = [CPSR] in {
537 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
538 bit Commutable = 0> {
540 def ri : T2sTwoRegImm<
541 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
542 opc, "\t$Rd, $Rn, $imm",
543 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
544 Requires<[IsThumb2]> {
545 let Inst{31-27} = 0b11110;
547 let Inst{24-21} = opcod;
548 let Inst{20} = 1; // The S bit.
552 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
553 opc, ".w\t$Rd, $Rn, $Rm",
554 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
555 Requires<[IsThumb2]> {
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 : T2sTwoRegShiftedReg<
567 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
568 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
569 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
570 Requires<[IsThumb2]> {
571 let Inst{31-27} = 0b11101;
572 let Inst{26-25} = 0b01;
573 let Inst{24-21} = opcod;
574 let Inst{20} = 1; // The S bit.
580 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
581 /// version is not needed since this is only for codegen.
582 let Defs = [CPSR] in {
583 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
585 def ri : T2TwoRegImm<
586 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
587 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
588 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
589 let Inst{31-27} = 0b11110;
591 let Inst{24-21} = opcod;
592 let Inst{20} = 1; // The S bit.
596 def rs : T2TwoRegShiftedReg<
597 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
598 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
599 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
600 let Inst{31-27} = 0b11101;
601 let Inst{26-25} = 0b01;
602 let Inst{24-21} = opcod;
603 let Inst{20} = 1; // The S bit.
608 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
609 // rotate operation that produces a value.
610 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
612 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
613 opc, ".w\t$dst, $lhs, $rhs",
614 [(set rGPR:$dst, (opnode rGPR:$lhs, imm1_31:$rhs))]> {
615 let Inst{31-27} = 0b11101;
616 let Inst{26-21} = 0b010010;
617 let Inst{19-16} = 0b1111; // Rn
618 let Inst{5-4} = opcod;
621 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iMOVsr,
622 opc, ".w\t$dst, $lhs, $rhs",
623 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
624 let Inst{31-27} = 0b11111;
625 let Inst{26-23} = 0b0100;
626 let Inst{22-21} = opcod;
627 let Inst{15-12} = 0b1111;
628 let Inst{7-4} = 0b0000;
632 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
633 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
634 /// a explicit result, only implicitly set CPSR.
635 let isCompare = 1, Defs = [CPSR] in {
636 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
637 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
640 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), iii,
641 opc, ".w\t$lhs, $rhs",
642 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
643 let Inst{31-27} = 0b11110;
645 let Inst{24-21} = opcod;
646 let Inst{20} = 1; // The S bit.
648 let Inst{11-8} = 0b1111; // Rd
651 def rr : T2I<(outs), (ins GPR:$lhs, rGPR:$rhs), iir,
652 opc, ".w\t$lhs, $rhs",
653 [(opnode GPR:$lhs, rGPR:$rhs)]> {
654 let Inst{31-27} = 0b11101;
655 let Inst{26-25} = 0b01;
656 let Inst{24-21} = opcod;
657 let Inst{20} = 1; // The S bit.
658 let Inst{14-12} = 0b000; // imm3
659 let Inst{11-8} = 0b1111; // Rd
660 let Inst{7-6} = 0b00; // imm2
661 let Inst{5-4} = 0b00; // type
664 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), iis,
665 opc, ".w\t$lhs, $rhs",
666 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
667 let Inst{31-27} = 0b11101;
668 let Inst{26-25} = 0b01;
669 let Inst{24-21} = opcod;
670 let Inst{20} = 1; // The S bit.
671 let Inst{11-8} = 0b1111; // Rd
676 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
677 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
678 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
679 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii,
680 opc, ".w\t$dst, $addr",
681 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
682 let Inst{31-27} = 0b11111;
683 let Inst{26-25} = 0b00;
684 let Inst{24} = signed;
686 let Inst{22-21} = opcod;
687 let Inst{20} = 1; // load
689 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii,
690 opc, "\t$dst, $addr",
691 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
692 let Inst{31-27} = 0b11111;
693 let Inst{26-25} = 0b00;
694 let Inst{24} = signed;
696 let Inst{22-21} = opcod;
697 let Inst{20} = 1; // load
699 // Offset: index==TRUE, wback==FALSE
700 let Inst{10} = 1; // The P bit.
701 let Inst{8} = 0; // The W bit.
703 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis,
704 opc, ".w\t$dst, $addr",
705 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
706 let Inst{31-27} = 0b11111;
707 let Inst{26-25} = 0b00;
708 let Inst{24} = signed;
710 let Inst{22-21} = opcod;
711 let Inst{20} = 1; // load
712 let Inst{11-6} = 0b000000;
715 // FIXME: Is the pci variant actually needed?
716 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii,
717 opc, ".w\t$dst, $addr",
718 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
719 let isReMaterializable = 1;
720 let Inst{31-27} = 0b11111;
721 let Inst{26-25} = 0b00;
722 let Inst{24} = signed;
723 let Inst{23} = ?; // add = (U == '1')
724 let Inst{22-21} = opcod;
725 let Inst{20} = 1; // load
726 let Inst{19-16} = 0b1111; // Rn
730 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
731 multiclass T2I_st<bits<2> opcod, string opc,
732 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
733 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii,
734 opc, ".w\t$src, $addr",
735 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
736 let Inst{31-27} = 0b11111;
737 let Inst{26-23} = 0b0001;
738 let Inst{22-21} = opcod;
739 let Inst{20} = 0; // !load
741 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii,
742 opc, "\t$src, $addr",
743 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
744 let Inst{31-27} = 0b11111;
745 let Inst{26-23} = 0b0000;
746 let Inst{22-21} = opcod;
747 let Inst{20} = 0; // !load
749 // Offset: index==TRUE, wback==FALSE
750 let Inst{10} = 1; // The P bit.
751 let Inst{8} = 0; // The W bit.
753 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis,
754 opc, ".w\t$src, $addr",
755 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
756 let Inst{31-27} = 0b11111;
757 let Inst{26-23} = 0b0000;
758 let Inst{22-21} = opcod;
759 let Inst{20} = 0; // !load
760 let Inst{11-6} = 0b000000;
764 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
765 /// register and one whose operand is a register rotated by 8/16/24.
766 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
767 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
768 opc, ".w\t$dst, $src",
769 [(set rGPR:$dst, (opnode rGPR:$src))]> {
770 let Inst{31-27} = 0b11111;
771 let Inst{26-23} = 0b0100;
772 let Inst{22-20} = opcod;
773 let Inst{19-16} = 0b1111; // Rn
774 let Inst{15-12} = 0b1111;
776 let Inst{5-4} = 0b00; // rotate
778 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
779 opc, ".w\t$dst, $src, ror $rot",
780 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]> {
781 let Inst{31-27} = 0b11111;
782 let Inst{26-23} = 0b0100;
783 let Inst{22-20} = opcod;
784 let Inst{19-16} = 0b1111; // Rn
785 let Inst{15-12} = 0b1111;
787 let Inst{5-4} = {?,?}; // rotate
791 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
792 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
793 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
795 [(set rGPR:$dst, (opnode rGPR:$src))]>,
796 Requires<[HasT2ExtractPack, IsThumb2]> {
797 let Inst{31-27} = 0b11111;
798 let Inst{26-23} = 0b0100;
799 let Inst{22-20} = opcod;
800 let Inst{19-16} = 0b1111; // Rn
801 let Inst{15-12} = 0b1111;
803 let Inst{5-4} = 0b00; // rotate
805 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
806 opc, "\t$dst, $src, ror $rot",
807 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]>,
808 Requires<[HasT2ExtractPack, IsThumb2]> {
809 let Inst{31-27} = 0b11111;
810 let Inst{26-23} = 0b0100;
811 let Inst{22-20} = opcod;
812 let Inst{19-16} = 0b1111; // Rn
813 let Inst{15-12} = 0b1111;
815 let Inst{5-4} = {?,?}; // rotate
819 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
821 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
822 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
823 opc, "\t$dst, $src", []> {
824 let Inst{31-27} = 0b11111;
825 let Inst{26-23} = 0b0100;
826 let Inst{22-20} = opcod;
827 let Inst{19-16} = 0b1111; // Rn
828 let Inst{15-12} = 0b1111;
830 let Inst{5-4} = 0b00; // rotate
832 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
833 opc, "\t$dst, $src, ror $rot", []> {
834 let Inst{31-27} = 0b11111;
835 let Inst{26-23} = 0b0100;
836 let Inst{22-20} = opcod;
837 let Inst{19-16} = 0b1111; // Rn
838 let Inst{15-12} = 0b1111;
840 let Inst{5-4} = {?,?}; // rotate
844 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
845 /// register and one whose operand is a register rotated by 8/16/24.
846 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
847 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
848 opc, "\t$dst, $LHS, $RHS",
849 [(set rGPR:$dst, (opnode rGPR:$LHS, rGPR:$RHS))]>,
850 Requires<[HasT2ExtractPack, IsThumb2]> {
851 let Inst{31-27} = 0b11111;
852 let Inst{26-23} = 0b0100;
853 let Inst{22-20} = opcod;
854 let Inst{15-12} = 0b1111;
856 let Inst{5-4} = 0b00; // rotate
858 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
859 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
860 [(set rGPR:$dst, (opnode rGPR:$LHS,
861 (rotr rGPR:$RHS, rot_imm:$rot)))]>,
862 Requires<[HasT2ExtractPack, IsThumb2]> {
863 let Inst{31-27} = 0b11111;
864 let Inst{26-23} = 0b0100;
865 let Inst{22-20} = opcod;
866 let Inst{15-12} = 0b1111;
868 let Inst{5-4} = {?,?}; // rotate
872 // DO variant - disassembly only, no pattern
874 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
875 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
876 opc, "\t$dst, $LHS, $RHS", []> {
877 let Inst{31-27} = 0b11111;
878 let Inst{26-23} = 0b0100;
879 let Inst{22-20} = opcod;
880 let Inst{15-12} = 0b1111;
882 let Inst{5-4} = 0b00; // rotate
884 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
885 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
886 let Inst{31-27} = 0b11111;
887 let Inst{26-23} = 0b0100;
888 let Inst{22-20} = opcod;
889 let Inst{15-12} = 0b1111;
891 let Inst{5-4} = {?,?}; // rotate
895 //===----------------------------------------------------------------------===//
897 //===----------------------------------------------------------------------===//
899 //===----------------------------------------------------------------------===//
900 // Miscellaneous Instructions.
903 // LEApcrel - Load a pc-relative address into a register without offending the
905 let neverHasSideEffects = 1 in {
906 let isReMaterializable = 1 in
907 def t2LEApcrel : T2XI<(outs rGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
908 "adr${p}.w\t$dst, #$label", []> {
909 let Inst{31-27} = 0b11110;
910 let Inst{25-24} = 0b10;
911 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
914 let Inst{19-16} = 0b1111; // Rn
917 } // neverHasSideEffects
918 def t2LEApcrelJT : T2XI<(outs rGPR:$dst),
919 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
920 "adr${p}.w\t$dst, #${label}_${id}", []> {
921 let Inst{31-27} = 0b11110;
922 let Inst{25-24} = 0b10;
923 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
926 let Inst{19-16} = 0b1111; // Rn
930 // ADD r, sp, {so_imm|i12}
931 def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
932 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
933 let Inst{31-27} = 0b11110;
935 let Inst{24-21} = 0b1000;
936 let Inst{20} = ?; // The S bit.
937 let Inst{19-16} = 0b1101; // Rn = sp
940 def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
941 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
942 let Inst{31-27} = 0b11110;
944 let Inst{24-21} = 0b0000;
945 let Inst{20} = 0; // The S bit.
946 let Inst{19-16} = 0b1101; // Rn = sp
951 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
952 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
953 let Inst{31-27} = 0b11101;
954 let Inst{26-25} = 0b01;
955 let Inst{24-21} = 0b1000;
956 let Inst{20} = ?; // The S bit.
957 let Inst{19-16} = 0b1101; // Rn = sp
961 // SUB r, sp, {so_imm|i12}
962 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
963 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
964 let Inst{31-27} = 0b11110;
966 let Inst{24-21} = 0b1101;
967 let Inst{20} = ?; // The S bit.
968 let Inst{19-16} = 0b1101; // Rn = sp
971 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
972 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
973 let Inst{31-27} = 0b11110;
975 let Inst{24-21} = 0b0101;
976 let Inst{20} = 0; // The S bit.
977 let Inst{19-16} = 0b1101; // Rn = sp
982 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
984 "sub", "\t$dst, $sp, $rhs", []> {
985 let Inst{31-27} = 0b11101;
986 let Inst{26-25} = 0b01;
987 let Inst{24-21} = 0b1101;
988 let Inst{20} = ?; // The S bit.
989 let Inst{19-16} = 0b1101; // Rn = sp
993 // Signed and unsigned division on v7-M
994 def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
995 "sdiv", "\t$dst, $a, $b",
996 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>,
997 Requires<[HasDivide]> {
998 let Inst{31-27} = 0b11111;
999 let Inst{26-21} = 0b011100;
1001 let Inst{15-12} = 0b1111;
1002 let Inst{7-4} = 0b1111;
1005 def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
1006 "udiv", "\t$dst, $a, $b",
1007 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>,
1008 Requires<[HasDivide]> {
1009 let Inst{31-27} = 0b11111;
1010 let Inst{26-21} = 0b011101;
1012 let Inst{15-12} = 0b1111;
1013 let Inst{7-4} = 0b1111;
1016 //===----------------------------------------------------------------------===//
1017 // Load / store Instructions.
1021 let canFoldAsLoad = 1, isReMaterializable = 1 in
1022 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
1023 UnOpFrag<(load node:$Src)>>;
1025 // Loads with zero extension
1026 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1027 UnOpFrag<(zextloadi16 node:$Src)>>;
1028 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1029 UnOpFrag<(zextloadi8 node:$Src)>>;
1031 // Loads with sign extension
1032 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1033 UnOpFrag<(sextloadi16 node:$Src)>>;
1034 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1035 UnOpFrag<(sextloadi8 node:$Src)>>;
1037 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1038 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
1040 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1041 (ins t2addrmode_imm8s4:$addr),
1042 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
1043 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1044 (ins i32imm:$addr), IIC_iLoad_d_i,
1045 "ldrd", "\t$dst1, $addr", []> {
1046 let Inst{19-16} = 0b1111; // Rn
1048 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1050 // zextload i1 -> zextload i8
1051 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1052 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1053 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1054 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1055 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1056 (t2LDRBs t2addrmode_so_reg:$addr)>;
1057 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1058 (t2LDRBpci tconstpool:$addr)>;
1060 // extload -> zextload
1061 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1063 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1064 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1065 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1066 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1067 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1068 (t2LDRBs t2addrmode_so_reg:$addr)>;
1069 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1070 (t2LDRBpci tconstpool:$addr)>;
1072 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1073 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1074 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1075 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1076 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1077 (t2LDRBs t2addrmode_so_reg:$addr)>;
1078 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1079 (t2LDRBpci tconstpool:$addr)>;
1081 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1082 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1083 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1084 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1085 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1086 (t2LDRHs t2addrmode_so_reg:$addr)>;
1087 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1088 (t2LDRHpci tconstpool:$addr)>;
1090 // FIXME: The destination register of the loads and stores can't be PC, but
1091 // can be SP. We need another regclass (similar to rGPR) to represent
1092 // that. Not a pressing issue since these are selected manually,
1096 let mayLoad = 1, neverHasSideEffects = 1 in {
1097 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1098 (ins t2addrmode_imm8:$addr),
1099 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1100 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
1103 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1104 (ins GPR:$base, t2am_imm8_offset:$offset),
1105 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1106 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
1109 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1110 (ins t2addrmode_imm8:$addr),
1111 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1112 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
1114 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1115 (ins GPR:$base, t2am_imm8_offset:$offset),
1116 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1117 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
1120 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1121 (ins t2addrmode_imm8:$addr),
1122 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1123 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
1125 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1126 (ins GPR:$base, t2am_imm8_offset:$offset),
1127 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1128 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
1131 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1132 (ins t2addrmode_imm8:$addr),
1133 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1134 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
1136 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1137 (ins GPR:$base, t2am_imm8_offset:$offset),
1138 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1139 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1142 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1143 (ins t2addrmode_imm8:$addr),
1144 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1145 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1147 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1148 (ins GPR:$base, t2am_imm8_offset:$offset),
1149 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1150 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1152 } // mayLoad = 1, neverHasSideEffects = 1
1154 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1155 // for disassembly only.
1156 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1157 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1158 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc,
1159 "\t$dst, $addr", []> {
1160 let Inst{31-27} = 0b11111;
1161 let Inst{26-25} = 0b00;
1162 let Inst{24} = signed;
1164 let Inst{22-21} = type;
1165 let Inst{20} = 1; // load
1167 let Inst{10-8} = 0b110; // PUW.
1170 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1171 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1172 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1173 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1174 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1177 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1178 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1179 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1180 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1181 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1182 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1185 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1186 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1187 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1188 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1189 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
1192 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1193 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1194 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1195 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1197 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1199 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1200 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1201 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1202 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1204 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1206 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1207 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1208 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1209 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1211 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1213 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1214 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1215 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1216 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1218 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1220 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1221 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1222 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1223 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1225 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1227 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1228 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1229 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1230 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1232 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1234 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1236 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1237 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1238 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc,
1239 "\t$src, $addr", []> {
1240 let Inst{31-27} = 0b11111;
1241 let Inst{26-25} = 0b00;
1242 let Inst{24} = 0; // not signed
1244 let Inst{22-21} = type;
1245 let Inst{20} = 0; // store
1247 let Inst{10-8} = 0b110; // PUW
1250 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1251 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1252 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1254 // ldrd / strd pre / post variants
1255 // For disassembly only.
1257 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1258 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1259 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1261 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1262 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1263 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1265 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1266 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1267 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1269 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1270 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1271 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
1273 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1274 // data/instruction access. These are for disassembly only.
1275 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1276 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1277 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1279 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1281 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1282 let Inst{31-25} = 0b1111100;
1283 let Inst{24} = instr;
1284 let Inst{23} = 1; // U = 1
1286 let Inst{21} = write;
1288 let Inst{15-12} = 0b1111;
1291 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1293 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1294 let Inst{31-25} = 0b1111100;
1295 let Inst{24} = instr;
1296 let Inst{23} = 0; // U = 0
1298 let Inst{21} = write;
1300 let Inst{15-12} = 0b1111;
1301 let Inst{11-8} = 0b1100;
1304 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1306 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1307 let Inst{31-25} = 0b1111100;
1308 let Inst{24} = instr;
1309 let Inst{23} = 0; // add = TRUE for T1
1311 let Inst{21} = write;
1313 let Inst{15-12} = 0b1111;
1314 let Inst{11-6} = 0000000;
1317 let isCodeGenOnly = 1 in
1318 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc,
1321 let Inst{31-25} = 0b1111100;
1322 let Inst{24} = write;
1323 let Inst{23} = ?; // add = (U == 1)
1325 let Inst{21} = instr;
1327 let Inst{19-16} = 0b1111; // Rn = 0b1111
1328 let Inst{15-12} = 0b1111;
1332 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1333 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1334 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1336 //===----------------------------------------------------------------------===//
1337 // Load / store multiple Instructions.
1340 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1341 InstrItinClass itin_upd, bit L_bit> {
1343 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1344 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
1348 let Inst{31-27} = 0b11101;
1349 let Inst{26-25} = 0b00;
1350 let Inst{24-23} = 0b01; // Increment After
1352 let Inst{21} = 0; // No writeback
1353 let Inst{20} = L_bit;
1354 let Inst{19-16} = Rn;
1355 let Inst{15-0} = regs;
1358 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1359 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1363 let Inst{31-27} = 0b11101;
1364 let Inst{26-25} = 0b00;
1365 let Inst{24-23} = 0b01; // Increment After
1367 let Inst{21} = 1; // Writeback
1368 let Inst{20} = L_bit;
1369 let Inst{19-16} = Rn;
1370 let Inst{15-0} = regs;
1373 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1374 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1378 let Inst{31-27} = 0b11101;
1379 let Inst{26-25} = 0b00;
1380 let Inst{24-23} = 0b10; // Decrement Before
1382 let Inst{21} = 0; // No writeback
1383 let Inst{20} = L_bit;
1384 let Inst{19-16} = Rn;
1385 let Inst{15-0} = regs;
1388 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1389 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1393 let Inst{31-27} = 0b11101;
1394 let Inst{26-25} = 0b00;
1395 let Inst{24-23} = 0b10; // Decrement Before
1397 let Inst{21} = 1; // Writeback
1398 let Inst{20} = L_bit;
1399 let Inst{19-16} = Rn;
1400 let Inst{15-0} = regs;
1405 let neverHasSideEffects = 1 in {
1407 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1408 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1410 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1411 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1413 } // neverHasSideEffects
1416 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1417 isCodeGenOnly = 1 in {
1418 def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1419 reglist:$dsts, variable_ops), IIC_iLoad_m,
1420 "ldm${amode}${p}.w\t$Rn, $dsts", []> {
1421 let Inst{31-27} = 0b11101;
1422 let Inst{26-25} = 0b00;
1423 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1425 let Inst{21} = 0; // The W bit.
1426 let Inst{20} = 1; // Load
1429 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1430 reglist:$dsts, variable_ops),
1432 "ldm${amode}${p}.w\t$Rn!, $dsts",
1434 let Inst{31-27} = 0b11101;
1435 let Inst{26-25} = 0b00;
1436 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1438 let Inst{21} = 1; // The W bit.
1439 let Inst{20} = 1; // Load
1441 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1443 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1444 isCodeGenOnly = 1 in {
1445 def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1446 reglist:$srcs, variable_ops), IIC_iStore_m,
1447 "stm${amode}${p}.w\t$Rn, $srcs", []> {
1448 let Inst{31-27} = 0b11101;
1449 let Inst{26-25} = 0b00;
1450 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1452 let Inst{21} = 0; // The W bit.
1453 let Inst{20} = 0; // Store
1456 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1457 reglist:$srcs, variable_ops),
1459 "stm${amode}${p}.w\t$Rn!, $srcs",
1461 let Inst{31-27} = 0b11101;
1462 let Inst{26-25} = 0b00;
1463 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1465 let Inst{21} = 1; // The W bit.
1466 let Inst{20} = 0; // Store
1468 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1470 //===----------------------------------------------------------------------===//
1471 // Move Instructions.
1474 let neverHasSideEffects = 1 in
1475 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1476 "mov", ".w\t$dst, $src", []> {
1477 let Inst{31-27} = 0b11101;
1478 let Inst{26-25} = 0b01;
1479 let Inst{24-21} = 0b0010;
1480 let Inst{20} = ?; // The S bit.
1481 let Inst{19-16} = 0b1111; // Rn
1482 let Inst{14-12} = 0b000;
1483 let Inst{7-4} = 0b0000;
1486 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1487 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1488 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1489 "mov", ".w\t$dst, $src",
1490 [(set rGPR:$dst, t2_so_imm:$src)]> {
1491 let Inst{31-27} = 0b11110;
1493 let Inst{24-21} = 0b0010;
1494 let Inst{20} = ?; // The S bit.
1495 let Inst{19-16} = 0b1111; // Rn
1499 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1500 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1501 "movw", "\t$dst, $src",
1502 [(set rGPR:$dst, imm0_65535:$src)]> {
1503 let Inst{31-27} = 0b11110;
1505 let Inst{24-21} = 0b0010;
1506 let Inst{20} = 0; // The S bit.
1510 let Constraints = "$src = $dst" in
1511 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1512 "movt", "\t$dst, $imm",
1514 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1515 let Inst{31-27} = 0b11110;
1517 let Inst{24-21} = 0b0110;
1518 let Inst{20} = 0; // The S bit.
1522 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1524 //===----------------------------------------------------------------------===//
1525 // Extend Instructions.
1530 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1531 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1532 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1533 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1534 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1536 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1537 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1538 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1539 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1540 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1542 // TODO: SXT(A){B|H}16 - done for disassembly only
1546 let AddedComplexity = 16 in {
1547 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1548 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1549 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1550 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1551 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1552 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1554 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1555 // The transformation should probably be done as a combiner action
1556 // instead so we can include a check for masking back in the upper
1557 // eight bits of the source into the lower eight bits of the result.
1558 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1559 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1560 // Requires<[HasT2ExtractPack, IsThumb2]>;
1561 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1562 (t2UXTB16r_rot rGPR:$Src, 8)>,
1563 Requires<[HasT2ExtractPack, IsThumb2]>;
1565 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1566 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1567 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1568 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1569 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1572 //===----------------------------------------------------------------------===//
1573 // Arithmetic Instructions.
1576 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1577 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1578 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1579 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1581 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1582 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1583 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1584 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1585 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1586 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1587 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1589 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1590 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1591 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1592 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1593 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1594 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1595 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1596 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1599 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1600 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1601 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1602 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1604 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1605 // The assume-no-carry-in form uses the negation of the input since add/sub
1606 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1607 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1609 // The AddedComplexity preferences the first variant over the others since
1610 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1611 let AddedComplexity = 1 in
1612 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1613 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1614 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1615 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1616 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1617 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1618 let AddedComplexity = 1 in
1619 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1620 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1621 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1622 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1623 // The with-carry-in form matches bitwise not instead of the negation.
1624 // Effectively, the inverse interpretation of the carry flag already accounts
1625 // for part of the negation.
1626 let AddedComplexity = 1 in
1627 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1628 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1629 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1630 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1632 // Select Bytes -- for disassembly only
1634 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1635 "\t$dst, $a, $b", []> {
1636 let Inst{31-27} = 0b11111;
1637 let Inst{26-24} = 0b010;
1639 let Inst{22-20} = 0b010;
1640 let Inst{15-12} = 0b1111;
1642 let Inst{6-4} = 0b000;
1645 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1646 // And Miscellaneous operations -- for disassembly only
1647 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1648 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1649 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1650 "\t$dst, $a, $b", pat> {
1651 let Inst{31-27} = 0b11111;
1652 let Inst{26-23} = 0b0101;
1653 let Inst{22-20} = op22_20;
1654 let Inst{15-12} = 0b1111;
1655 let Inst{7-4} = op7_4;
1658 // Saturating add/subtract -- for disassembly only
1660 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1661 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1662 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1663 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1664 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1665 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1666 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1667 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1668 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1669 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1670 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1671 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1672 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1673 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1674 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1675 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1676 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1677 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1679 // Signed/Unsigned add/subtract -- for disassembly only
1681 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1682 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1683 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1684 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1685 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1686 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1687 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1688 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1689 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1690 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1691 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1692 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1694 // Signed/Unsigned halving add/subtract -- for disassembly only
1696 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1697 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1698 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1699 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1700 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1701 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1702 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1703 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1704 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1705 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1706 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1707 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1709 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1711 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1712 (ins rGPR:$a, rGPR:$b),
1713 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1714 let Inst{15-12} = 0b1111;
1716 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1717 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1718 "\t$dst, $a, $b, $acc", []>;
1720 // Signed/Unsigned saturate -- for disassembly only
1722 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1723 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1724 [/* For disassembly only; pattern left blank */]> {
1725 let Inst{31-27} = 0b11110;
1726 let Inst{25-22} = 0b1100;
1731 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1732 "ssat16", "\t$dst, $bit_pos, $a",
1733 [/* For disassembly only; pattern left blank */]> {
1734 let Inst{31-27} = 0b11110;
1735 let Inst{25-22} = 0b1100;
1738 let Inst{21} = 1; // sh = '1'
1739 let Inst{14-12} = 0b000; // imm3 = '000'
1740 let Inst{7-6} = 0b00; // imm2 = '00'
1743 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1744 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1745 [/* For disassembly only; pattern left blank */]> {
1746 let Inst{31-27} = 0b11110;
1747 let Inst{25-22} = 0b1110;
1752 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1753 "usat16", "\t$dst, $bit_pos, $a",
1754 [/* For disassembly only; pattern left blank */]> {
1755 let Inst{31-27} = 0b11110;
1756 let Inst{25-22} = 0b1110;
1759 let Inst{21} = 1; // sh = '1'
1760 let Inst{14-12} = 0b000; // imm3 = '000'
1761 let Inst{7-6} = 0b00; // imm2 = '00'
1764 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1765 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1767 //===----------------------------------------------------------------------===//
1768 // Shift and rotate Instructions.
1771 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1772 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1773 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1774 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1776 let Uses = [CPSR] in {
1777 def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1778 "rrx", "\t$dst, $src",
1779 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1780 let Inst{31-27} = 0b11101;
1781 let Inst{26-25} = 0b01;
1782 let Inst{24-21} = 0b0010;
1783 let Inst{20} = ?; // The S bit.
1784 let Inst{19-16} = 0b1111; // Rn
1785 let Inst{14-12} = 0b000;
1786 let Inst{7-4} = 0b0011;
1790 let Defs = [CPSR] in {
1791 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1792 "lsrs", ".w\t$dst, $src, #1",
1793 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1794 let Inst{31-27} = 0b11101;
1795 let Inst{26-25} = 0b01;
1796 let Inst{24-21} = 0b0010;
1797 let Inst{20} = 1; // The S bit.
1798 let Inst{19-16} = 0b1111; // Rn
1799 let Inst{5-4} = 0b01; // Shift type.
1800 // Shift amount = Inst{14-12:7-6} = 1.
1801 let Inst{14-12} = 0b000;
1802 let Inst{7-6} = 0b01;
1804 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1805 "asrs", ".w\t$dst, $src, #1",
1806 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1807 let Inst{31-27} = 0b11101;
1808 let Inst{26-25} = 0b01;
1809 let Inst{24-21} = 0b0010;
1810 let Inst{20} = 1; // The S bit.
1811 let Inst{19-16} = 0b1111; // Rn
1812 let Inst{5-4} = 0b10; // Shift type.
1813 // Shift amount = Inst{14-12:7-6} = 1.
1814 let Inst{14-12} = 0b000;
1815 let Inst{7-6} = 0b01;
1819 //===----------------------------------------------------------------------===//
1820 // Bitwise Instructions.
1823 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1824 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1825 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1826 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1827 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1828 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1829 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1830 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1831 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1833 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1834 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1835 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1837 let Constraints = "$src = $dst" in
1838 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1839 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1840 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1841 let Inst{31-27} = 0b11110;
1843 let Inst{24-20} = 0b10110;
1844 let Inst{19-16} = 0b1111; // Rn
1848 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1849 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1850 let Inst{31-27} = 0b11110;
1852 let Inst{24-20} = 0b10100;
1856 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1857 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1858 let Inst{31-27} = 0b11110;
1860 let Inst{24-20} = 0b11100;
1864 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1865 let Constraints = "$src = $dst" in
1866 def t2BFI : T2I<(outs rGPR:$dst),
1867 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1868 IIC_iBITi, "bfi", "\t$dst, $val, $imm",
1869 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1870 bf_inv_mask_imm:$imm))]> {
1871 let Inst{31-27} = 0b11110;
1873 let Inst{24-20} = 0b10110;
1877 defm t2ORN : T2I_bin_irs<0b0011, "orn",
1878 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1879 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
1881 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1882 let AddedComplexity = 1 in
1883 defm t2MVN : T2I_un_irs <0b0011, "mvn",
1884 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
1885 UnOpFrag<(not node:$Src)>, 1, 1>;
1888 let AddedComplexity = 1 in
1889 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1890 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1892 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1893 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1894 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1895 Requires<[IsThumb2]>;
1897 def : T2Pat<(t2_so_imm_not:$src),
1898 (t2MVNi t2_so_imm_not:$src)>;
1900 //===----------------------------------------------------------------------===//
1901 // Multiply Instructions.
1903 let isCommutable = 1 in
1904 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1905 "mul", "\t$dst, $a, $b",
1906 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1907 let Inst{31-27} = 0b11111;
1908 let Inst{26-23} = 0b0110;
1909 let Inst{22-20} = 0b000;
1910 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1911 let Inst{7-4} = 0b0000; // Multiply
1914 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1915 "mla", "\t$dst, $a, $b, $c",
1916 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1917 let Inst{31-27} = 0b11111;
1918 let Inst{26-23} = 0b0110;
1919 let Inst{22-20} = 0b000;
1920 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1921 let Inst{7-4} = 0b0000; // Multiply
1924 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1925 "mls", "\t$dst, $a, $b, $c",
1926 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1927 let Inst{31-27} = 0b11111;
1928 let Inst{26-23} = 0b0110;
1929 let Inst{22-20} = 0b000;
1930 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1931 let Inst{7-4} = 0b0001; // Multiply and Subtract
1934 // Extra precision multiplies with low / high results
1935 let neverHasSideEffects = 1 in {
1936 let isCommutable = 1 in {
1937 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1938 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1939 "smull", "\t$ldst, $hdst, $a, $b", []> {
1940 let Inst{31-27} = 0b11111;
1941 let Inst{26-23} = 0b0111;
1942 let Inst{22-20} = 0b000;
1943 let Inst{7-4} = 0b0000;
1946 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1947 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1948 "umull", "\t$ldst, $hdst, $a, $b", []> {
1949 let Inst{31-27} = 0b11111;
1950 let Inst{26-23} = 0b0111;
1951 let Inst{22-20} = 0b010;
1952 let Inst{7-4} = 0b0000;
1956 // Multiply + accumulate
1957 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1958 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1959 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1960 let Inst{31-27} = 0b11111;
1961 let Inst{26-23} = 0b0111;
1962 let Inst{22-20} = 0b100;
1963 let Inst{7-4} = 0b0000;
1966 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1967 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1968 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1969 let Inst{31-27} = 0b11111;
1970 let Inst{26-23} = 0b0111;
1971 let Inst{22-20} = 0b110;
1972 let Inst{7-4} = 0b0000;
1975 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1976 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1977 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1978 let Inst{31-27} = 0b11111;
1979 let Inst{26-23} = 0b0111;
1980 let Inst{22-20} = 0b110;
1981 let Inst{7-4} = 0b0110;
1983 } // neverHasSideEffects
1985 // Rounding variants of the below included for disassembly only
1987 // Most significant word multiply
1988 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1989 "smmul", "\t$dst, $a, $b",
1990 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
1991 let Inst{31-27} = 0b11111;
1992 let Inst{26-23} = 0b0110;
1993 let Inst{22-20} = 0b101;
1994 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1995 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1998 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1999 "smmulr", "\t$dst, $a, $b", []> {
2000 let Inst{31-27} = 0b11111;
2001 let Inst{26-23} = 0b0110;
2002 let Inst{22-20} = 0b101;
2003 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2004 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2007 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2008 "smmla", "\t$dst, $a, $b, $c",
2009 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
2010 let Inst{31-27} = 0b11111;
2011 let Inst{26-23} = 0b0110;
2012 let Inst{22-20} = 0b101;
2013 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2014 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2017 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2018 "smmlar", "\t$dst, $a, $b, $c", []> {
2019 let Inst{31-27} = 0b11111;
2020 let Inst{26-23} = 0b0110;
2021 let Inst{22-20} = 0b101;
2022 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2023 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2026 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2027 "smmls", "\t$dst, $a, $b, $c",
2028 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
2029 let Inst{31-27} = 0b11111;
2030 let Inst{26-23} = 0b0110;
2031 let Inst{22-20} = 0b110;
2032 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2033 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2036 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
2037 "smmlsr", "\t$dst, $a, $b, $c", []> {
2038 let Inst{31-27} = 0b11111;
2039 let Inst{26-23} = 0b0110;
2040 let Inst{22-20} = 0b110;
2041 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2042 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2045 multiclass T2I_smul<string opc, PatFrag opnode> {
2046 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2047 !strconcat(opc, "bb"), "\t$dst, $a, $b",
2048 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
2049 (sext_inreg rGPR:$b, i16)))]> {
2050 let Inst{31-27} = 0b11111;
2051 let Inst{26-23} = 0b0110;
2052 let Inst{22-20} = 0b001;
2053 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2054 let Inst{7-6} = 0b00;
2055 let Inst{5-4} = 0b00;
2058 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2059 !strconcat(opc, "bt"), "\t$dst, $a, $b",
2060 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
2061 (sra rGPR:$b, (i32 16))))]> {
2062 let Inst{31-27} = 0b11111;
2063 let Inst{26-23} = 0b0110;
2064 let Inst{22-20} = 0b001;
2065 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2066 let Inst{7-6} = 0b00;
2067 let Inst{5-4} = 0b01;
2070 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2071 !strconcat(opc, "tb"), "\t$dst, $a, $b",
2072 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
2073 (sext_inreg rGPR:$b, i16)))]> {
2074 let Inst{31-27} = 0b11111;
2075 let Inst{26-23} = 0b0110;
2076 let Inst{22-20} = 0b001;
2077 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2078 let Inst{7-6} = 0b00;
2079 let Inst{5-4} = 0b10;
2082 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2083 !strconcat(opc, "tt"), "\t$dst, $a, $b",
2084 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
2085 (sra rGPR:$b, (i32 16))))]> {
2086 let Inst{31-27} = 0b11111;
2087 let Inst{26-23} = 0b0110;
2088 let Inst{22-20} = 0b001;
2089 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2090 let Inst{7-6} = 0b00;
2091 let Inst{5-4} = 0b11;
2094 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2095 !strconcat(opc, "wb"), "\t$dst, $a, $b",
2096 [(set rGPR:$dst, (sra (opnode rGPR:$a,
2097 (sext_inreg rGPR:$b, i16)), (i32 16)))]> {
2098 let Inst{31-27} = 0b11111;
2099 let Inst{26-23} = 0b0110;
2100 let Inst{22-20} = 0b011;
2101 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2102 let Inst{7-6} = 0b00;
2103 let Inst{5-4} = 0b00;
2106 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2107 !strconcat(opc, "wt"), "\t$dst, $a, $b",
2108 [(set rGPR:$dst, (sra (opnode rGPR:$a,
2109 (sra rGPR:$b, (i32 16))), (i32 16)))]> {
2110 let Inst{31-27} = 0b11111;
2111 let Inst{26-23} = 0b0110;
2112 let Inst{22-20} = 0b011;
2113 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2114 let Inst{7-6} = 0b00;
2115 let Inst{5-4} = 0b01;
2120 multiclass T2I_smla<string opc, PatFrag opnode> {
2121 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2122 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2123 [(set rGPR:$dst, (add rGPR:$acc,
2124 (opnode (sext_inreg rGPR:$a, i16),
2125 (sext_inreg rGPR:$b, i16))))]> {
2126 let Inst{31-27} = 0b11111;
2127 let Inst{26-23} = 0b0110;
2128 let Inst{22-20} = 0b001;
2129 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2130 let Inst{7-6} = 0b00;
2131 let Inst{5-4} = 0b00;
2134 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2135 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2136 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
2137 (sra rGPR:$b, (i32 16)))))]> {
2138 let Inst{31-27} = 0b11111;
2139 let Inst{26-23} = 0b0110;
2140 let Inst{22-20} = 0b001;
2141 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2142 let Inst{7-6} = 0b00;
2143 let Inst{5-4} = 0b01;
2146 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2147 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2148 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2149 (sext_inreg rGPR:$b, i16))))]> {
2150 let Inst{31-27} = 0b11111;
2151 let Inst{26-23} = 0b0110;
2152 let Inst{22-20} = 0b001;
2153 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2154 let Inst{7-6} = 0b00;
2155 let Inst{5-4} = 0b10;
2158 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2159 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2160 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2161 (sra rGPR:$b, (i32 16)))))]> {
2162 let Inst{31-27} = 0b11111;
2163 let Inst{26-23} = 0b0110;
2164 let Inst{22-20} = 0b001;
2165 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2166 let Inst{7-6} = 0b00;
2167 let Inst{5-4} = 0b11;
2170 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2171 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2172 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2173 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2174 let Inst{31-27} = 0b11111;
2175 let Inst{26-23} = 0b0110;
2176 let Inst{22-20} = 0b011;
2177 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2178 let Inst{7-6} = 0b00;
2179 let Inst{5-4} = 0b00;
2182 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2183 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2184 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2185 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2186 let Inst{31-27} = 0b11111;
2187 let Inst{26-23} = 0b0110;
2188 let Inst{22-20} = 0b011;
2189 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2190 let Inst{7-6} = 0b00;
2191 let Inst{5-4} = 0b01;
2195 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2196 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2198 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2199 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2200 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2201 [/* For disassembly only; pattern left blank */]>;
2202 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2203 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2204 [/* For disassembly only; pattern left blank */]>;
2205 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2206 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2207 [/* For disassembly only; pattern left blank */]>;
2208 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2209 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2210 [/* For disassembly only; pattern left blank */]>;
2212 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2213 // These are for disassembly only.
2215 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2216 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2217 let Inst{15-12} = 0b1111;
2219 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2220 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2221 let Inst{15-12} = 0b1111;
2223 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2224 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2225 let Inst{15-12} = 0b1111;
2227 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2228 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2229 let Inst{15-12} = 0b1111;
2231 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2232 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2233 "\t$dst, $a, $b, $acc", []>;
2234 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2235 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2236 "\t$dst, $a, $b, $acc", []>;
2237 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2238 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2239 "\t$dst, $a, $b, $acc", []>;
2240 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2241 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2242 "\t$dst, $a, $b, $acc", []>;
2243 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2244 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2245 "\t$ldst, $hdst, $a, $b", []>;
2246 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2247 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2248 "\t$ldst, $hdst, $a, $b", []>;
2249 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2250 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2251 "\t$ldst, $hdst, $a, $b", []>;
2252 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2253 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2254 "\t$ldst, $hdst, $a, $b", []>;
2256 //===----------------------------------------------------------------------===//
2257 // Misc. Arithmetic Instructions.
2260 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2261 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2262 : T2I<oops, iops, itin, opc, asm, pattern> {
2263 let Inst{31-27} = 0b11111;
2264 let Inst{26-22} = 0b01010;
2265 let Inst{21-20} = op1;
2266 let Inst{15-12} = 0b1111;
2267 let Inst{7-6} = 0b10;
2268 let Inst{5-4} = op2;
2271 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2272 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2274 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2275 "rbit", "\t$dst, $src",
2276 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2278 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2279 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2281 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2282 "rev16", ".w\t$dst, $src",
2284 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2285 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2286 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2287 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2289 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2290 "revsh", ".w\t$dst, $src",
2293 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2294 (shl rGPR:$src, (i32 8))), i16))]>;
2296 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2297 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2298 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2299 (and (shl rGPR:$src2, lsl_amt:$sh),
2301 Requires<[HasT2ExtractPack, IsThumb2]> {
2302 let Inst{31-27} = 0b11101;
2303 let Inst{26-25} = 0b01;
2304 let Inst{24-20} = 0b01100;
2305 let Inst{5} = 0; // BT form
2309 // Alternate cases for PKHBT where identities eliminate some nodes.
2310 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2311 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2312 Requires<[HasT2ExtractPack, IsThumb2]>;
2313 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2314 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2315 Requires<[HasT2ExtractPack, IsThumb2]>;
2317 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2318 // will match the pattern below.
2319 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2320 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2321 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2322 (and (sra rGPR:$src2, asr_amt:$sh),
2324 Requires<[HasT2ExtractPack, IsThumb2]> {
2325 let Inst{31-27} = 0b11101;
2326 let Inst{26-25} = 0b01;
2327 let Inst{24-20} = 0b01100;
2328 let Inst{5} = 1; // TB form
2332 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2333 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2334 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2335 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2336 Requires<[HasT2ExtractPack, IsThumb2]>;
2337 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2338 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2339 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2340 Requires<[HasT2ExtractPack, IsThumb2]>;
2342 //===----------------------------------------------------------------------===//
2343 // Comparison Instructions...
2345 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2346 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2347 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2348 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2349 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2350 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2352 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2353 // Compare-to-zero still works out, just not the relationals
2354 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2355 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2356 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2357 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2358 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2360 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2361 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2363 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2364 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2366 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2367 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2368 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2369 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2370 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2371 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2373 // Conditional moves
2374 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2375 // a two-value operand where a dag node expects two operands. :(
2376 let neverHasSideEffects = 1 in {
2377 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2378 "mov", ".w\t$dst, $true",
2379 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2380 RegConstraint<"$false = $dst"> {
2381 let Inst{31-27} = 0b11101;
2382 let Inst{26-25} = 0b01;
2383 let Inst{24-21} = 0b0010;
2384 let Inst{20} = 0; // The S bit.
2385 let Inst{19-16} = 0b1111; // Rn
2386 let Inst{14-12} = 0b000;
2387 let Inst{7-4} = 0b0000;
2390 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2391 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2392 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2393 RegConstraint<"$false = $dst"> {
2394 let Inst{31-27} = 0b11110;
2396 let Inst{24-21} = 0b0010;
2397 let Inst{20} = 0; // The S bit.
2398 let Inst{19-16} = 0b1111; // Rn
2402 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
2404 "movw", "\t$dst, $src", []>,
2405 RegConstraint<"$false = $dst"> {
2406 let Inst{31-27} = 0b11110;
2408 let Inst{24-21} = 0b0010;
2409 let Inst{20} = 0; // The S bit.
2413 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2414 (ins rGPR:$false, i32imm:$src, pred:$p),
2415 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">;
2417 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2418 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2419 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
2420 imm:$cc, CCR:$ccr))*/]>,
2421 RegConstraint<"$false = $dst"> {
2422 let Inst{31-27} = 0b11110;
2424 let Inst{24-21} = 0b0011;
2425 let Inst{20} = 0; // The S bit.
2426 let Inst{19-16} = 0b1111; // Rn
2430 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2431 string opc, string asm, list<dag> pattern>
2432 : T2I<oops, iops, itin, opc, asm, pattern> {
2433 let Inst{31-27} = 0b11101;
2434 let Inst{26-25} = 0b01;
2435 let Inst{24-21} = 0b0010;
2436 let Inst{20} = 0; // The S bit.
2437 let Inst{19-16} = 0b1111; // Rn
2438 let Inst{5-4} = opcod; // Shift type.
2440 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2441 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2442 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2443 RegConstraint<"$false = $dst">;
2444 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2445 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2446 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2447 RegConstraint<"$false = $dst">;
2448 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2449 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2450 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2451 RegConstraint<"$false = $dst">;
2452 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2453 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2454 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2455 RegConstraint<"$false = $dst">;
2456 } // neverHasSideEffects
2458 //===----------------------------------------------------------------------===//
2459 // Atomic operations intrinsics
2462 // memory barriers protect the atomic sequences
2463 let hasSideEffects = 1 in {
2464 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2465 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2466 Requires<[IsThumb, HasDB]> {
2468 let Inst{31-4} = 0xf3bf8f5;
2469 let Inst{3-0} = opt;
2473 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2475 [/* For disassembly only; pattern left blank */]>,
2476 Requires<[IsThumb, HasDB]> {
2478 let Inst{31-4} = 0xf3bf8f4;
2479 let Inst{3-0} = opt;
2482 // ISB has only full system option -- for disassembly only
2483 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2484 [/* For disassembly only; pattern left blank */]>,
2485 Requires<[IsThumb2, HasV7]> {
2486 let Inst{31-4} = 0xf3bf8f6;
2487 let Inst{3-0} = 0b1111;
2490 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2491 InstrItinClass itin, string opc, string asm, string cstr,
2492 list<dag> pattern, bits<4> rt2 = 0b1111>
2493 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2494 let Inst{31-27} = 0b11101;
2495 let Inst{26-20} = 0b0001101;
2496 let Inst{11-8} = rt2;
2497 let Inst{7-6} = 0b01;
2498 let Inst{5-4} = opcod;
2499 let Inst{3-0} = 0b1111;
2501 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2502 InstrItinClass itin, string opc, string asm, string cstr,
2503 list<dag> pattern, bits<4> rt2 = 0b1111>
2504 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2505 let Inst{31-27} = 0b11101;
2506 let Inst{26-20} = 0b0001100;
2507 let Inst{11-8} = rt2;
2508 let Inst{7-6} = 0b01;
2509 let Inst{5-4} = opcod;
2512 let mayLoad = 1 in {
2513 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2514 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2516 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2517 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2519 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2520 Size4Bytes, NoItinerary,
2521 "ldrex", "\t$dest, [$ptr]", "",
2523 let Inst{31-27} = 0b11101;
2524 let Inst{26-20} = 0b0000101;
2525 let Inst{11-8} = 0b1111;
2526 let Inst{7-0} = 0b00000000; // imm8 = 0
2528 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2529 AddrModeNone, Size4Bytes, NoItinerary,
2530 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2534 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2535 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2536 AddrModeNone, Size4Bytes, NoItinerary,
2537 "strexb", "\t$success, $src, [$ptr]", "", []>;
2538 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2539 AddrModeNone, Size4Bytes, NoItinerary,
2540 "strexh", "\t$success, $src, [$ptr]", "", []>;
2541 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2542 AddrModeNone, Size4Bytes, NoItinerary,
2543 "strex", "\t$success, $src, [$ptr]", "",
2545 let Inst{31-27} = 0b11101;
2546 let Inst{26-20} = 0b0000100;
2547 let Inst{7-0} = 0b00000000; // imm8 = 0
2549 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2550 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2551 AddrModeNone, Size4Bytes, NoItinerary,
2552 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2556 // Clear-Exclusive is for disassembly only.
2557 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2558 [/* For disassembly only; pattern left blank */]>,
2559 Requires<[IsARM, HasV7]> {
2560 let Inst{31-20} = 0xf3b;
2561 let Inst{15-14} = 0b10;
2563 let Inst{7-4} = 0b0010;
2566 //===----------------------------------------------------------------------===//
2570 // __aeabi_read_tp preserves the registers r1-r3.
2572 Defs = [R0, R12, LR, CPSR] in {
2573 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2574 "bl\t__aeabi_read_tp",
2575 [(set R0, ARMthread_pointer)]> {
2576 let Inst{31-27} = 0b11110;
2577 let Inst{15-14} = 0b11;
2582 //===----------------------------------------------------------------------===//
2583 // SJLJ Exception handling intrinsics
2584 // eh_sjlj_setjmp() is an instruction sequence to store the return
2585 // address and save #0 in R0 for the non-longjmp case.
2586 // Since by its nature we may be coming from some other function to get
2587 // here, and we're using the stack frame for the containing function to
2588 // save/restore registers, we can't keep anything live in regs across
2589 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2590 // when we get here from a longjmp(). We force everthing out of registers
2591 // except for our own input by listing the relevant registers in Defs. By
2592 // doing so, we also cause the prologue/epilogue code to actively preserve
2593 // all of the callee-saved resgisters, which is exactly what we want.
2594 // $val is a scratch register for our use.
2596 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2597 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2598 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2599 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2600 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2601 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2602 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2603 Requires<[IsThumb2, HasVFP2]>;
2607 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2608 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2609 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2610 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2611 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2612 Requires<[IsThumb2, NoVFP]>;
2616 //===----------------------------------------------------------------------===//
2617 // Control-Flow Instructions
2620 // FIXME: remove when we have a way to marking a MI with these properties.
2621 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2623 // FIXME: Should pc be an implicit operand like PICADD, etc?
2624 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2625 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2626 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
2627 reglist:$dsts, variable_ops),
2629 "ldm${amode}${p}.w\t$Rn!, $dsts",
2631 let Inst{31-27} = 0b11101;
2632 let Inst{26-25} = 0b00;
2633 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2635 let Inst{21} = 1; // The W bit.
2636 let Inst{20} = 1; // Load
2639 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2640 let isPredicable = 1 in
2641 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2643 [(br bb:$target)]> {
2644 let Inst{31-27} = 0b11110;
2645 let Inst{15-14} = 0b10;
2649 let isNotDuplicable = 1, isIndirectBranch = 1,
2650 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
2653 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2654 IIC_Br, "mov\tpc, $target$jt",
2655 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2656 let Inst{31-27} = 0b11101;
2657 let Inst{26-20} = 0b0100100;
2658 let Inst{19-16} = 0b1111;
2659 let Inst{14-12} = 0b000;
2660 let Inst{11-8} = 0b1111; // Rd = pc
2661 let Inst{7-4} = 0b0000;
2664 // FIXME: Add a non-pc based case that can be predicated.
2665 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2668 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2669 IIC_Br, "tbb\t$index$jt", []> {
2670 let Inst{31-27} = 0b11101;
2671 let Inst{26-20} = 0b0001101;
2672 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2673 let Inst{15-8} = 0b11110000;
2674 let Inst{7-4} = 0b0000; // B form
2677 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2680 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2681 IIC_Br, "tbh\t$index$jt", []> {
2682 let Inst{31-27} = 0b11101;
2683 let Inst{26-20} = 0b0001101;
2684 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2685 let Inst{15-8} = 0b11110000;
2686 let Inst{7-4} = 0b0001; // H form
2689 // Generic versions of the above two instructions, for disassembly only
2691 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2692 "tbb", "\t[$a, $b]", []>{
2693 let Inst{31-27} = 0b11101;
2694 let Inst{26-20} = 0b0001101;
2695 let Inst{15-8} = 0b11110000;
2696 let Inst{7-4} = 0b0000; // B form
2699 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2700 "tbh", "\t[$a, $b, lsl #1]", []> {
2701 let Inst{31-27} = 0b11101;
2702 let Inst{26-20} = 0b0001101;
2703 let Inst{15-8} = 0b11110000;
2704 let Inst{7-4} = 0b0001; // H form
2706 } // isNotDuplicable, isIndirectBranch
2708 } // isBranch, isTerminator, isBarrier
2710 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2711 // a two-value operand where a dag node expects two operands. :(
2712 let isBranch = 1, isTerminator = 1 in
2713 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2715 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2716 let Inst{31-27} = 0b11110;
2717 let Inst{15-14} = 0b10;
2723 let Defs = [ITSTATE] in
2724 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2725 AddrModeNone, Size2Bytes, IIC_iALUx,
2726 "it$mask\t$cc", "", []> {
2727 // 16-bit instruction.
2728 let Inst{31-16} = 0x0000;
2729 let Inst{15-8} = 0b10111111;
2732 // Branch and Exchange Jazelle -- for disassembly only
2734 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2735 [/* For disassembly only; pattern left blank */]> {
2736 let Inst{31-27} = 0b11110;
2738 let Inst{25-20} = 0b111100;
2739 let Inst{15-14} = 0b10;
2743 // Change Processor State is a system instruction -- for disassembly only.
2744 // The singleton $opt operand contains the following information:
2745 // opt{4-0} = mode from Inst{4-0}
2746 // opt{5} = changemode from Inst{17}
2747 // opt{8-6} = AIF from Inst{8-6}
2748 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2749 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2750 [/* For disassembly only; pattern left blank */]> {
2751 let Inst{31-27} = 0b11110;
2753 let Inst{25-20} = 0b111010;
2754 let Inst{15-14} = 0b10;
2758 // A6.3.4 Branches and miscellaneous control
2759 // Table A6-14 Change Processor State, and hint instructions
2760 // Helper class for disassembly only.
2761 class T2I_hint<bits<8> op7_0, string opc, string asm>
2762 : T2I<(outs), (ins), NoItinerary, opc, asm,
2763 [/* For disassembly only; pattern left blank */]> {
2764 let Inst{31-20} = 0xf3a;
2765 let Inst{15-14} = 0b10;
2767 let Inst{10-8} = 0b000;
2768 let Inst{7-0} = op7_0;
2771 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2772 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2773 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2774 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2775 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2777 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2778 [/* For disassembly only; pattern left blank */]> {
2779 let Inst{31-20} = 0xf3a;
2780 let Inst{15-14} = 0b10;
2782 let Inst{10-8} = 0b000;
2783 let Inst{7-4} = 0b1111;
2786 // Secure Monitor Call is a system instruction -- for disassembly only
2787 // Option = Inst{19-16}
2788 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2789 [/* For disassembly only; pattern left blank */]> {
2790 let Inst{31-27} = 0b11110;
2791 let Inst{26-20} = 0b1111111;
2792 let Inst{15-12} = 0b1000;
2795 // Store Return State is a system instruction -- for disassembly only
2796 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2797 [/* For disassembly only; pattern left blank */]> {
2798 let Inst{31-27} = 0b11101;
2799 let Inst{26-20} = 0b0000010; // W = 1
2802 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2803 [/* For disassembly only; pattern left blank */]> {
2804 let Inst{31-27} = 0b11101;
2805 let Inst{26-20} = 0b0000000; // W = 0
2808 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2809 [/* For disassembly only; pattern left blank */]> {
2810 let Inst{31-27} = 0b11101;
2811 let Inst{26-20} = 0b0011010; // W = 1
2814 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2815 [/* For disassembly only; pattern left blank */]> {
2816 let Inst{31-27} = 0b11101;
2817 let Inst{26-20} = 0b0011000; // W = 0
2820 // Return From Exception is a system instruction -- for disassembly only
2821 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2822 [/* For disassembly only; pattern left blank */]> {
2823 let Inst{31-27} = 0b11101;
2824 let Inst{26-20} = 0b0000011; // W = 1
2827 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2828 [/* For disassembly only; pattern left blank */]> {
2829 let Inst{31-27} = 0b11101;
2830 let Inst{26-20} = 0b0000001; // W = 0
2833 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2834 [/* For disassembly only; pattern left blank */]> {
2835 let Inst{31-27} = 0b11101;
2836 let Inst{26-20} = 0b0011011; // W = 1
2839 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2840 [/* For disassembly only; pattern left blank */]> {
2841 let Inst{31-27} = 0b11101;
2842 let Inst{26-20} = 0b0011001; // W = 0
2845 //===----------------------------------------------------------------------===//
2846 // Non-Instruction Patterns
2849 // Two piece so_imms.
2850 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2851 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2852 (t2_so_imm2part_2 imm:$RHS))>;
2853 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2854 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2855 (t2_so_imm2part_2 imm:$RHS))>;
2856 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2857 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2858 (t2_so_imm2part_2 imm:$RHS))>;
2859 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2860 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2861 (t2_so_neg_imm2part_2 imm:$RHS))>;
2863 // 32-bit immediate using movw + movt.
2864 // This is a single pseudo instruction to make it re-materializable.
2865 // FIXME: Remove this when we can do generalized remat.
2866 let isReMaterializable = 1 in
2867 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
2868 "", [(set rGPR:$dst, (i32 imm:$src))]>,
2869 Requires<[IsThumb, HasV6T2]>;
2871 // ConstantPool, GlobalAddress, and JumpTable
2872 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2873 Requires<[IsThumb2, DontUseMovt]>;
2874 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2875 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2876 Requires<[IsThumb2, UseMovt]>;
2878 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2879 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2881 // Pseudo instruction that combines ldr from constpool and add pc. This should
2882 // be expanded into two instructions late to allow if-conversion and
2884 let canFoldAsLoad = 1, isReMaterializable = 1 in
2885 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2887 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2889 Requires<[IsThumb2]>;
2891 //===----------------------------------------------------------------------===//
2892 // Move between special register and ARM core register -- for disassembly only
2896 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2897 [/* For disassembly only; pattern left blank */]> {
2898 let Inst{31-27} = 0b11110;
2900 let Inst{25-21} = 0b11111;
2901 let Inst{20} = 0; // The R bit.
2902 let Inst{15-14} = 0b10;
2907 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2908 [/* For disassembly only; pattern left blank */]> {
2909 let Inst{31-27} = 0b11110;
2911 let Inst{25-21} = 0b11111;
2912 let Inst{20} = 1; // The R bit.
2913 let Inst{15-14} = 0b10;
2918 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2919 "\tcpsr$mask, $src",
2920 [/* For disassembly only; pattern left blank */]> {
2921 let Inst{31-27} = 0b11110;
2923 let Inst{25-21} = 0b11100;
2924 let Inst{20} = 0; // The R bit.
2925 let Inst{15-14} = 0b10;
2930 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2931 "\tspsr$mask, $src",
2932 [/* For disassembly only; pattern left blank */]> {
2933 let Inst{31-27} = 0b11110;
2935 let Inst{25-21} = 0b11100;
2936 let Inst{20} = 1; // The R bit.
2937 let Inst{15-14} = 0b10;