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 T2TwoRegShiftedImm<dag oops, dag iops, InstrItinClass itin,
174 string opc, string asm, list<dag> pattern>
175 : T2sI<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 T2ThreeReg<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{3-0} = Rm{3-0};
199 class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
200 string opc, string asm, list<dag> pattern>
201 : T2sI<oops, iops, itin, opc, asm, pattern> {
206 let Inst{11-8} = Rd{3-0};
207 let Inst{19-16} = Rn{3-0};
208 let Inst{3-0} = ShiftedRm{3-0};
209 let Inst{5-4} = ShiftedRm{6-5};
210 let Inst{14-12} = ShiftedRm{11-9};
211 let Inst{7-6} = ShiftedRm{8-7};
214 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
215 /// unary operation that produces a value. These are predicable and can be
216 /// changed to modify CPSR.
217 multiclass T2I_un_irs<bits<4> opcod, string opc,
218 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
219 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> {
221 def i : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), iii,
223 [(set rGPR:$dst, (opnode t2_so_imm:$src))]> {
224 let isAsCheapAsAMove = Cheap;
225 let isReMaterializable = ReMat;
226 let Inst{31-27} = 0b11110;
228 let Inst{24-21} = opcod;
229 let Inst{20} = ?; // The S bit.
230 let Inst{19-16} = 0b1111; // Rn
234 def r : T2sI<(outs rGPR:$dst), (ins rGPR:$src), iir,
235 opc, ".w\t$dst, $src",
236 [(set rGPR:$dst, (opnode rGPR:$src))]> {
237 let Inst{31-27} = 0b11101;
238 let Inst{26-25} = 0b01;
239 let Inst{24-21} = opcod;
240 let Inst{20} = ?; // The S bit.
241 let Inst{19-16} = 0b1111; // Rn
242 let Inst{14-12} = 0b000; // imm3
243 let Inst{7-6} = 0b00; // imm2
244 let Inst{5-4} = 0b00; // type
247 def s : T2sI<(outs rGPR:$dst), (ins t2_so_reg:$src), iis,
248 opc, ".w\t$dst, $src",
249 [(set rGPR:$dst, (opnode t2_so_reg:$src))]> {
250 let Inst{31-27} = 0b11101;
251 let Inst{26-25} = 0b01;
252 let Inst{24-21} = opcod;
253 let Inst{20} = ?; // The S bit.
254 let Inst{19-16} = 0b1111; // Rn
258 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
259 /// binary operation that produces a value. These are predicable and can be
260 /// changed to modify CPSR.
261 multiclass T2I_bin_irs<bits<4> opcod, string opc,
262 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
263 PatFrag opnode, bit Commutable = 0, string wide = ""> {
265 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), iii,
266 opc, "\t$dst, $lhs, $rhs",
267 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]> {
268 let Inst{31-27} = 0b11110;
270 let Inst{24-21} = opcod;
271 let Inst{20} = ?; // The S bit.
275 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), iir,
276 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
277 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
278 let isCommutable = Commutable;
279 let Inst{31-27} = 0b11101;
280 let Inst{26-25} = 0b01;
281 let Inst{24-21} = opcod;
282 let Inst{20} = ?; // The S bit.
283 let Inst{14-12} = 0b000; // imm3
284 let Inst{7-6} = 0b00; // imm2
285 let Inst{5-4} = 0b00; // type
288 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), iis,
289 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
290 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]> {
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.
298 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
299 // the ".w" prefix to indicate that they are wide.
300 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
301 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
302 PatFrag opnode, bit Commutable = 0> :
303 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
305 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
306 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
307 /// it is equivalent to the T2I_bin_irs counterpart.
308 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
310 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
311 opc, ".w\t$dst, $rhs, $lhs",
312 [(set rGPR:$dst, (opnode t2_so_imm:$lhs, rGPR:$rhs))]> {
313 let Inst{31-27} = 0b11110;
315 let Inst{24-21} = opcod;
316 let Inst{20} = ?; // The S bit.
320 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, rGPR:$lhs), IIC_iALUr,
321 opc, "\t$dst, $rhs, $lhs",
322 [/* For disassembly only; pattern left blank */]> {
323 let Inst{31-27} = 0b11101;
324 let Inst{26-25} = 0b01;
325 let Inst{24-21} = opcod;
326 let Inst{20} = ?; // The S bit.
327 let Inst{14-12} = 0b000; // imm3
328 let Inst{7-6} = 0b00; // imm2
329 let Inst{5-4} = 0b00; // type
332 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_reg:$lhs), IIC_iALUsir,
333 opc, "\t$dst, $rhs, $lhs",
334 [(set rGPR:$dst, (opnode t2_so_reg:$lhs, rGPR:$rhs))]> {
335 let Inst{31-27} = 0b11101;
336 let Inst{26-25} = 0b01;
337 let Inst{24-21} = opcod;
338 let Inst{20} = ?; // The S bit.
342 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
343 /// instruction modifies the CPSR register.
344 let Defs = [CPSR] in {
345 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
346 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
347 PatFrag opnode, bit Commutable = 0> {
349 def ri : T2I<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), iii,
350 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
351 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
352 let Inst{31-27} = 0b11110;
354 let Inst{24-21} = opcod;
355 let Inst{20} = 1; // The S bit.
359 def rr : T2I<(outs rGPR:$dst), (ins GPR:$lhs, rGPR:$rhs), iir,
360 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
361 [(set rGPR:$dst, (opnode GPR:$lhs, rGPR:$rhs))]> {
362 let isCommutable = Commutable;
363 let Inst{31-27} = 0b11101;
364 let Inst{26-25} = 0b01;
365 let Inst{24-21} = opcod;
366 let Inst{20} = 1; // The S bit.
367 let Inst{14-12} = 0b000; // imm3
368 let Inst{7-6} = 0b00; // imm2
369 let Inst{5-4} = 0b00; // type
372 def rs : T2I<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), iis,
373 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
374 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
375 let Inst{31-27} = 0b11101;
376 let Inst{26-25} = 0b01;
377 let Inst{24-21} = opcod;
378 let Inst{20} = 1; // The S bit.
383 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
384 /// patterns for a binary operation that produces a value.
385 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
386 bit Commutable = 0> {
388 // The register-immediate version is re-materializable. This is useful
389 // in particular for taking the address of a local.
390 let isReMaterializable = 1 in {
391 def ri : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
392 opc, ".w\t$dst, $lhs, $rhs",
393 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
394 let Inst{31-27} = 0b11110;
397 let Inst{23-21} = op23_21;
398 let Inst{20} = 0; // The S bit.
403 def ri12 : T2I<(outs rGPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
404 !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
405 [(set rGPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
406 let Inst{31-27} = 0b11110;
409 let Inst{23-21} = op23_21;
410 let Inst{20} = 0; // The S bit.
414 def rr : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, rGPR:$rhs), IIC_iALUr,
415 opc, ".w\t$dst, $lhs, $rhs",
416 [(set rGPR:$dst, (opnode GPR:$lhs, rGPR:$rhs))]> {
417 let isCommutable = Commutable;
418 let Inst{31-27} = 0b11101;
419 let Inst{26-25} = 0b01;
421 let Inst{23-21} = op23_21;
422 let Inst{20} = 0; // The S bit.
423 let Inst{14-12} = 0b000; // imm3
424 let Inst{7-6} = 0b00; // imm2
425 let Inst{5-4} = 0b00; // type
428 def rs : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
429 opc, ".w\t$dst, $lhs, $rhs",
430 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
431 let Inst{31-27} = 0b11101;
432 let Inst{26-25} = 0b01;
434 let Inst{23-21} = op23_21;
435 let Inst{20} = 0; // The S bit.
439 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
440 /// for a binary operation that produces a value and use the carry
441 /// bit. It's not predicable.
442 let Uses = [CPSR] in {
443 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
444 bit Commutable = 0> {
446 def ri : T2TwoRegShiftedImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
447 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
448 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
449 Requires<[IsThumb2]> {
450 let Inst{31-27} = 0b11110;
452 let Inst{24-21} = opcod;
453 let Inst{20} = 0; // The S bit.
457 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
458 opc, ".w\t$Rd, $Rn, $Rm",
459 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
460 Requires<[IsThumb2]> {
461 let isCommutable = Commutable;
462 let Inst{31-27} = 0b11101;
463 let Inst{26-25} = 0b01;
464 let Inst{24-21} = opcod;
465 let Inst{20} = 0; // The S bit.
466 let Inst{14-12} = 0b000; // imm3
467 let Inst{7-6} = 0b00; // imm2
468 let Inst{5-4} = 0b00; // type
471 def rs : T2TwoRegShiftedReg<
472 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
473 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
474 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
475 Requires<[IsThumb2]> {
476 let Inst{31-27} = 0b11101;
477 let Inst{26-25} = 0b01;
478 let Inst{24-21} = opcod;
479 let Inst{20} = 0; // The S bit.
483 // Carry setting variants
484 let Defs = [CPSR] in {
485 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
486 bit Commutable = 0> {
488 def ri : T2TwoRegShiftedImm<
489 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
490 opc, "\t$Rd, $Rn, $imm",
491 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
492 Requires<[IsThumb2]> {
493 let Inst{31-27} = 0b11110;
495 let Inst{24-21} = opcod;
496 let Inst{20} = 1; // The S bit.
500 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
501 opc, ".w\t$Rd, $Rn, $Rm",
502 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
503 Requires<[IsThumb2]> {
504 let isCommutable = Commutable;
505 let Inst{31-27} = 0b11101;
506 let Inst{26-25} = 0b01;
507 let Inst{24-21} = opcod;
508 let Inst{20} = 1; // The S bit.
509 let Inst{14-12} = 0b000; // imm3
510 let Inst{7-6} = 0b00; // imm2
511 let Inst{5-4} = 0b00; // type
514 def rs : T2TwoRegShiftedReg<
515 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
516 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
517 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
518 Requires<[IsThumb2]> {
519 let Inst{31-27} = 0b11101;
520 let Inst{26-25} = 0b01;
521 let Inst{24-21} = opcod;
522 let Inst{20} = 1; // The S bit.
528 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
529 /// version is not needed since this is only for codegen.
530 let Defs = [CPSR] in {
531 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
533 def ri : T2I<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
534 !strconcat(opc, "s"), ".w\t$dst, $rhs, $lhs",
535 [(set rGPR:$dst, (opnode t2_so_imm:$lhs, rGPR:$rhs))]> {
536 let Inst{31-27} = 0b11110;
538 let Inst{24-21} = opcod;
539 let Inst{20} = 1; // The S bit.
543 def rs : T2I<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
544 !strconcat(opc, "s"), "\t$dst, $rhs, $lhs",
545 [(set rGPR:$dst, (opnode t2_so_reg:$lhs, rGPR:$rhs))]> {
546 let Inst{31-27} = 0b11101;
547 let Inst{26-25} = 0b01;
548 let Inst{24-21} = opcod;
549 let Inst{20} = 1; // The S bit.
554 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
555 // rotate operation that produces a value.
556 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
558 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
559 opc, ".w\t$dst, $lhs, $rhs",
560 [(set rGPR:$dst, (opnode rGPR:$lhs, imm1_31:$rhs))]> {
561 let Inst{31-27} = 0b11101;
562 let Inst{26-21} = 0b010010;
563 let Inst{19-16} = 0b1111; // Rn
564 let Inst{5-4} = opcod;
567 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iMOVsr,
568 opc, ".w\t$dst, $lhs, $rhs",
569 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
570 let Inst{31-27} = 0b11111;
571 let Inst{26-23} = 0b0100;
572 let Inst{22-21} = opcod;
573 let Inst{15-12} = 0b1111;
574 let Inst{7-4} = 0b0000;
578 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
579 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
580 /// a explicit result, only implicitly set CPSR.
581 let isCompare = 1, Defs = [CPSR] in {
582 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
583 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
586 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), iii,
587 opc, ".w\t$lhs, $rhs",
588 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
589 let Inst{31-27} = 0b11110;
591 let Inst{24-21} = opcod;
592 let Inst{20} = 1; // The S bit.
594 let Inst{11-8} = 0b1111; // Rd
597 def rr : T2I<(outs), (ins GPR:$lhs, rGPR:$rhs), iir,
598 opc, ".w\t$lhs, $rhs",
599 [(opnode GPR:$lhs, rGPR:$rhs)]> {
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.
604 let Inst{14-12} = 0b000; // imm3
605 let Inst{11-8} = 0b1111; // Rd
606 let Inst{7-6} = 0b00; // imm2
607 let Inst{5-4} = 0b00; // type
610 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), iis,
611 opc, ".w\t$lhs, $rhs",
612 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
613 let Inst{31-27} = 0b11101;
614 let Inst{26-25} = 0b01;
615 let Inst{24-21} = opcod;
616 let Inst{20} = 1; // The S bit.
617 let Inst{11-8} = 0b1111; // Rd
622 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
623 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
624 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
625 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii,
626 opc, ".w\t$dst, $addr",
627 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
628 let Inst{31-27} = 0b11111;
629 let Inst{26-25} = 0b00;
630 let Inst{24} = signed;
632 let Inst{22-21} = opcod;
633 let Inst{20} = 1; // load
635 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii,
636 opc, "\t$dst, $addr",
637 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
638 let Inst{31-27} = 0b11111;
639 let Inst{26-25} = 0b00;
640 let Inst{24} = signed;
642 let Inst{22-21} = opcod;
643 let Inst{20} = 1; // load
645 // Offset: index==TRUE, wback==FALSE
646 let Inst{10} = 1; // The P bit.
647 let Inst{8} = 0; // The W bit.
649 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis,
650 opc, ".w\t$dst, $addr",
651 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
652 let Inst{31-27} = 0b11111;
653 let Inst{26-25} = 0b00;
654 let Inst{24} = signed;
656 let Inst{22-21} = opcod;
657 let Inst{20} = 1; // load
658 let Inst{11-6} = 0b000000;
661 // FIXME: Is the pci variant actually needed?
662 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii,
663 opc, ".w\t$dst, $addr",
664 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
665 let isReMaterializable = 1;
666 let Inst{31-27} = 0b11111;
667 let Inst{26-25} = 0b00;
668 let Inst{24} = signed;
669 let Inst{23} = ?; // add = (U == '1')
670 let Inst{22-21} = opcod;
671 let Inst{20} = 1; // load
672 let Inst{19-16} = 0b1111; // Rn
676 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
677 multiclass T2I_st<bits<2> opcod, string opc,
678 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
679 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii,
680 opc, ".w\t$src, $addr",
681 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
682 let Inst{31-27} = 0b11111;
683 let Inst{26-23} = 0b0001;
684 let Inst{22-21} = opcod;
685 let Inst{20} = 0; // !load
687 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii,
688 opc, "\t$src, $addr",
689 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
690 let Inst{31-27} = 0b11111;
691 let Inst{26-23} = 0b0000;
692 let Inst{22-21} = opcod;
693 let Inst{20} = 0; // !load
695 // Offset: index==TRUE, wback==FALSE
696 let Inst{10} = 1; // The P bit.
697 let Inst{8} = 0; // The W bit.
699 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis,
700 opc, ".w\t$src, $addr",
701 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
702 let Inst{31-27} = 0b11111;
703 let Inst{26-23} = 0b0000;
704 let Inst{22-21} = opcod;
705 let Inst{20} = 0; // !load
706 let Inst{11-6} = 0b000000;
710 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
711 /// register and one whose operand is a register rotated by 8/16/24.
712 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
713 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
714 opc, ".w\t$dst, $src",
715 [(set rGPR:$dst, (opnode rGPR:$src))]> {
716 let Inst{31-27} = 0b11111;
717 let Inst{26-23} = 0b0100;
718 let Inst{22-20} = opcod;
719 let Inst{19-16} = 0b1111; // Rn
720 let Inst{15-12} = 0b1111;
722 let Inst{5-4} = 0b00; // rotate
724 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
725 opc, ".w\t$dst, $src, ror $rot",
726 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]> {
727 let Inst{31-27} = 0b11111;
728 let Inst{26-23} = 0b0100;
729 let Inst{22-20} = opcod;
730 let Inst{19-16} = 0b1111; // Rn
731 let Inst{15-12} = 0b1111;
733 let Inst{5-4} = {?,?}; // rotate
737 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
738 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
739 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
741 [(set rGPR:$dst, (opnode rGPR:$src))]>,
742 Requires<[HasT2ExtractPack, IsThumb2]> {
743 let Inst{31-27} = 0b11111;
744 let Inst{26-23} = 0b0100;
745 let Inst{22-20} = opcod;
746 let Inst{19-16} = 0b1111; // Rn
747 let Inst{15-12} = 0b1111;
749 let Inst{5-4} = 0b00; // rotate
751 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
752 opc, "\t$dst, $src, ror $rot",
753 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]>,
754 Requires<[HasT2ExtractPack, IsThumb2]> {
755 let Inst{31-27} = 0b11111;
756 let Inst{26-23} = 0b0100;
757 let Inst{22-20} = opcod;
758 let Inst{19-16} = 0b1111; // Rn
759 let Inst{15-12} = 0b1111;
761 let Inst{5-4} = {?,?}; // rotate
765 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
767 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
768 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
769 opc, "\t$dst, $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, "\t$dst, $src, ror $rot", []> {
780 let Inst{31-27} = 0b11111;
781 let Inst{26-23} = 0b0100;
782 let Inst{22-20} = opcod;
783 let Inst{19-16} = 0b1111; // Rn
784 let Inst{15-12} = 0b1111;
786 let Inst{5-4} = {?,?}; // rotate
790 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
791 /// register and one whose operand is a register rotated by 8/16/24.
792 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
793 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
794 opc, "\t$dst, $LHS, $RHS",
795 [(set rGPR:$dst, (opnode rGPR:$LHS, rGPR:$RHS))]>,
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{15-12} = 0b1111;
802 let Inst{5-4} = 0b00; // rotate
804 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
805 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
806 [(set rGPR:$dst, (opnode rGPR:$LHS,
807 (rotr rGPR:$RHS, 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{15-12} = 0b1111;
814 let Inst{5-4} = {?,?}; // rotate
818 // DO variant - disassembly only, no pattern
820 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
821 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
822 opc, "\t$dst, $LHS, $RHS", []> {
823 let Inst{31-27} = 0b11111;
824 let Inst{26-23} = 0b0100;
825 let Inst{22-20} = opcod;
826 let Inst{15-12} = 0b1111;
828 let Inst{5-4} = 0b00; // rotate
830 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
831 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
832 let Inst{31-27} = 0b11111;
833 let Inst{26-23} = 0b0100;
834 let Inst{22-20} = opcod;
835 let Inst{15-12} = 0b1111;
837 let Inst{5-4} = {?,?}; // rotate
841 //===----------------------------------------------------------------------===//
843 //===----------------------------------------------------------------------===//
845 //===----------------------------------------------------------------------===//
846 // Miscellaneous Instructions.
849 // LEApcrel - Load a pc-relative address into a register without offending the
851 let neverHasSideEffects = 1 in {
852 let isReMaterializable = 1 in
853 def t2LEApcrel : T2XI<(outs rGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
854 "adr${p}.w\t$dst, #$label", []> {
855 let Inst{31-27} = 0b11110;
856 let Inst{25-24} = 0b10;
857 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
860 let Inst{19-16} = 0b1111; // Rn
863 } // neverHasSideEffects
864 def t2LEApcrelJT : T2XI<(outs rGPR:$dst),
865 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
866 "adr${p}.w\t$dst, #${label}_${id}", []> {
867 let Inst{31-27} = 0b11110;
868 let Inst{25-24} = 0b10;
869 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
872 let Inst{19-16} = 0b1111; // Rn
876 // ADD r, sp, {so_imm|i12}
877 def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
878 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
879 let Inst{31-27} = 0b11110;
881 let Inst{24-21} = 0b1000;
882 let Inst{20} = ?; // The S bit.
883 let Inst{19-16} = 0b1101; // Rn = sp
886 def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
887 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
888 let Inst{31-27} = 0b11110;
890 let Inst{24-21} = 0b0000;
891 let Inst{20} = 0; // The S bit.
892 let Inst{19-16} = 0b1101; // Rn = sp
897 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
898 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
899 let Inst{31-27} = 0b11101;
900 let Inst{26-25} = 0b01;
901 let Inst{24-21} = 0b1000;
902 let Inst{20} = ?; // The S bit.
903 let Inst{19-16} = 0b1101; // Rn = sp
907 // SUB r, sp, {so_imm|i12}
908 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
909 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
910 let Inst{31-27} = 0b11110;
912 let Inst{24-21} = 0b1101;
913 let Inst{20} = ?; // The S bit.
914 let Inst{19-16} = 0b1101; // Rn = sp
917 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
918 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
919 let Inst{31-27} = 0b11110;
921 let Inst{24-21} = 0b0101;
922 let Inst{20} = 0; // The S bit.
923 let Inst{19-16} = 0b1101; // Rn = sp
928 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
930 "sub", "\t$dst, $sp, $rhs", []> {
931 let Inst{31-27} = 0b11101;
932 let Inst{26-25} = 0b01;
933 let Inst{24-21} = 0b1101;
934 let Inst{20} = ?; // The S bit.
935 let Inst{19-16} = 0b1101; // Rn = sp
939 // Signed and unsigned division on v7-M
940 def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
941 "sdiv", "\t$dst, $a, $b",
942 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>,
943 Requires<[HasDivide]> {
944 let Inst{31-27} = 0b11111;
945 let Inst{26-21} = 0b011100;
947 let Inst{15-12} = 0b1111;
948 let Inst{7-4} = 0b1111;
951 def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
952 "udiv", "\t$dst, $a, $b",
953 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>,
954 Requires<[HasDivide]> {
955 let Inst{31-27} = 0b11111;
956 let Inst{26-21} = 0b011101;
958 let Inst{15-12} = 0b1111;
959 let Inst{7-4} = 0b1111;
962 //===----------------------------------------------------------------------===//
963 // Load / store Instructions.
967 let canFoldAsLoad = 1, isReMaterializable = 1 in
968 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
969 UnOpFrag<(load node:$Src)>>;
971 // Loads with zero extension
972 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
973 UnOpFrag<(zextloadi16 node:$Src)>>;
974 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
975 UnOpFrag<(zextloadi8 node:$Src)>>;
977 // Loads with sign extension
978 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
979 UnOpFrag<(sextloadi16 node:$Src)>>;
980 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
981 UnOpFrag<(sextloadi8 node:$Src)>>;
983 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
984 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
986 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
987 (ins t2addrmode_imm8s4:$addr),
988 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
989 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
990 (ins i32imm:$addr), IIC_iLoad_d_i,
991 "ldrd", "\t$dst1, $addr", []> {
992 let Inst{19-16} = 0b1111; // Rn
994 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
996 // zextload i1 -> zextload i8
997 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
998 (t2LDRBi12 t2addrmode_imm12:$addr)>;
999 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1000 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1001 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1002 (t2LDRBs t2addrmode_so_reg:$addr)>;
1003 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1004 (t2LDRBpci tconstpool:$addr)>;
1006 // extload -> zextload
1007 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1009 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1010 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1011 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1012 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1013 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1014 (t2LDRBs t2addrmode_so_reg:$addr)>;
1015 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1016 (t2LDRBpci tconstpool:$addr)>;
1018 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1019 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1020 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1021 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1022 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1023 (t2LDRBs t2addrmode_so_reg:$addr)>;
1024 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1025 (t2LDRBpci tconstpool:$addr)>;
1027 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1028 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1029 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1030 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1031 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1032 (t2LDRHs t2addrmode_so_reg:$addr)>;
1033 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1034 (t2LDRHpci tconstpool:$addr)>;
1036 // FIXME: The destination register of the loads and stores can't be PC, but
1037 // can be SP. We need another regclass (similar to rGPR) to represent
1038 // that. Not a pressing issue since these are selected manually,
1042 let mayLoad = 1, neverHasSideEffects = 1 in {
1043 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1044 (ins t2addrmode_imm8:$addr),
1045 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1046 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
1049 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1050 (ins GPR:$base, t2am_imm8_offset:$offset),
1051 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1052 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
1055 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1056 (ins t2addrmode_imm8:$addr),
1057 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1058 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
1060 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1061 (ins GPR:$base, t2am_imm8_offset:$offset),
1062 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1063 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
1066 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1067 (ins t2addrmode_imm8:$addr),
1068 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1069 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
1071 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1072 (ins GPR:$base, t2am_imm8_offset:$offset),
1073 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1074 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
1077 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1078 (ins t2addrmode_imm8:$addr),
1079 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1080 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
1082 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1083 (ins GPR:$base, t2am_imm8_offset:$offset),
1084 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1085 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1088 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1089 (ins t2addrmode_imm8:$addr),
1090 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1091 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1093 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1094 (ins GPR:$base, t2am_imm8_offset:$offset),
1095 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1096 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1098 } // mayLoad = 1, neverHasSideEffects = 1
1100 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1101 // for disassembly only.
1102 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1103 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1104 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc,
1105 "\t$dst, $addr", []> {
1106 let Inst{31-27} = 0b11111;
1107 let Inst{26-25} = 0b00;
1108 let Inst{24} = signed;
1110 let Inst{22-21} = type;
1111 let Inst{20} = 1; // load
1113 let Inst{10-8} = 0b110; // PUW.
1116 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1117 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1118 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1119 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1120 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1123 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1124 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1125 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1126 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1127 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1128 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1131 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1132 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1133 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1134 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1135 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
1138 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1139 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1140 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1141 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1143 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1145 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1146 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1147 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1148 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1150 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1152 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1153 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1154 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1155 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1157 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1159 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1160 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1161 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1162 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1164 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1166 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1167 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1168 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1169 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1171 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1173 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1174 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1175 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1176 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1178 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1180 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1182 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1183 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1184 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc,
1185 "\t$src, $addr", []> {
1186 let Inst{31-27} = 0b11111;
1187 let Inst{26-25} = 0b00;
1188 let Inst{24} = 0; // not signed
1190 let Inst{22-21} = type;
1191 let Inst{20} = 0; // store
1193 let Inst{10-8} = 0b110; // PUW
1196 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1197 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1198 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1200 // ldrd / strd pre / post variants
1201 // For disassembly only.
1203 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1204 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1205 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1207 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1208 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1209 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1211 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1212 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1213 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1215 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1216 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1217 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
1219 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1220 // data/instruction access. These are for disassembly only.
1221 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1222 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1223 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1225 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1227 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1228 let Inst{31-25} = 0b1111100;
1229 let Inst{24} = instr;
1230 let Inst{23} = 1; // U = 1
1232 let Inst{21} = write;
1234 let Inst{15-12} = 0b1111;
1237 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1239 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1240 let Inst{31-25} = 0b1111100;
1241 let Inst{24} = instr;
1242 let Inst{23} = 0; // U = 0
1244 let Inst{21} = write;
1246 let Inst{15-12} = 0b1111;
1247 let Inst{11-8} = 0b1100;
1250 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1252 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1253 let Inst{31-25} = 0b1111100;
1254 let Inst{24} = instr;
1255 let Inst{23} = 0; // add = TRUE for T1
1257 let Inst{21} = write;
1259 let Inst{15-12} = 0b1111;
1260 let Inst{11-6} = 0000000;
1263 let isCodeGenOnly = 1 in
1264 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc,
1267 let Inst{31-25} = 0b1111100;
1268 let Inst{24} = write;
1269 let Inst{23} = ?; // add = (U == 1)
1271 let Inst{21} = instr;
1273 let Inst{19-16} = 0b1111; // Rn = 0b1111
1274 let Inst{15-12} = 0b1111;
1278 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1279 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1280 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1282 //===----------------------------------------------------------------------===//
1283 // Load / store multiple Instructions.
1286 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1287 isCodeGenOnly = 1 in {
1288 def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1289 reglist:$dsts, variable_ops), IIC_iLoad_m,
1290 "ldm${amode}${p}.w\t$Rn, $dsts", []> {
1291 let Inst{31-27} = 0b11101;
1292 let Inst{26-25} = 0b00;
1293 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1295 let Inst{21} = 0; // The W bit.
1296 let Inst{20} = 1; // Load
1299 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1300 reglist:$dsts, variable_ops),
1302 "ldm${amode}${p}.w\t$Rn!, $dsts",
1304 let Inst{31-27} = 0b11101;
1305 let Inst{26-25} = 0b00;
1306 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1308 let Inst{21} = 1; // The W bit.
1309 let Inst{20} = 1; // Load
1311 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1313 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1314 isCodeGenOnly = 1 in {
1315 def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1316 reglist:$srcs, variable_ops), IIC_iStore_m,
1317 "stm${amode}${p}.w\t$Rn, $srcs", []> {
1318 let Inst{31-27} = 0b11101;
1319 let Inst{26-25} = 0b00;
1320 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1322 let Inst{21} = 0; // The W bit.
1323 let Inst{20} = 0; // Store
1326 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1327 reglist:$srcs, variable_ops),
1329 "stm${amode}${p}.w\t$Rn!, $srcs",
1331 let Inst{31-27} = 0b11101;
1332 let Inst{26-25} = 0b00;
1333 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1335 let Inst{21} = 1; // The W bit.
1336 let Inst{20} = 0; // Store
1338 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1340 //===----------------------------------------------------------------------===//
1341 // Move Instructions.
1344 let neverHasSideEffects = 1 in
1345 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1346 "mov", ".w\t$dst, $src", []> {
1347 let Inst{31-27} = 0b11101;
1348 let Inst{26-25} = 0b01;
1349 let Inst{24-21} = 0b0010;
1350 let Inst{20} = ?; // The S bit.
1351 let Inst{19-16} = 0b1111; // Rn
1352 let Inst{14-12} = 0b000;
1353 let Inst{7-4} = 0b0000;
1356 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1357 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1358 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1359 "mov", ".w\t$dst, $src",
1360 [(set rGPR:$dst, t2_so_imm:$src)]> {
1361 let Inst{31-27} = 0b11110;
1363 let Inst{24-21} = 0b0010;
1364 let Inst{20} = ?; // The S bit.
1365 let Inst{19-16} = 0b1111; // Rn
1369 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1370 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1371 "movw", "\t$dst, $src",
1372 [(set rGPR:$dst, imm0_65535:$src)]> {
1373 let Inst{31-27} = 0b11110;
1375 let Inst{24-21} = 0b0010;
1376 let Inst{20} = 0; // The S bit.
1380 let Constraints = "$src = $dst" in
1381 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1382 "movt", "\t$dst, $imm",
1384 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1385 let Inst{31-27} = 0b11110;
1387 let Inst{24-21} = 0b0110;
1388 let Inst{20} = 0; // The S bit.
1392 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1394 //===----------------------------------------------------------------------===//
1395 // Extend Instructions.
1400 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1401 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1402 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1403 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1404 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1406 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1407 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1408 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1409 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1410 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1412 // TODO: SXT(A){B|H}16 - done for disassembly only
1416 let AddedComplexity = 16 in {
1417 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1418 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1419 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1420 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1421 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1422 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1424 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1425 // The transformation should probably be done as a combiner action
1426 // instead so we can include a check for masking back in the upper
1427 // eight bits of the source into the lower eight bits of the result.
1428 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1429 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1430 // Requires<[HasT2ExtractPack, IsThumb2]>;
1431 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1432 (t2UXTB16r_rot rGPR:$Src, 8)>,
1433 Requires<[HasT2ExtractPack, IsThumb2]>;
1435 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1436 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1437 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1438 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1439 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1442 //===----------------------------------------------------------------------===//
1443 // Arithmetic Instructions.
1446 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1447 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1448 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1449 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1451 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1452 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1453 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1454 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1455 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1456 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1457 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1459 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1460 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1461 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1462 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1463 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1464 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1465 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1466 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1469 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1470 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1471 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1472 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1474 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1475 // The assume-no-carry-in form uses the negation of the input since add/sub
1476 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1477 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1479 // The AddedComplexity preferences the first variant over the others since
1480 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1481 let AddedComplexity = 1 in
1482 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1483 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1484 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1485 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1486 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1487 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1488 let AddedComplexity = 1 in
1489 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1490 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1491 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1492 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1493 // The with-carry-in form matches bitwise not instead of the negation.
1494 // Effectively, the inverse interpretation of the carry flag already accounts
1495 // for part of the negation.
1496 let AddedComplexity = 1 in
1497 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1498 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1499 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1500 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1502 // Select Bytes -- for disassembly only
1504 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1505 "\t$dst, $a, $b", []> {
1506 let Inst{31-27} = 0b11111;
1507 let Inst{26-24} = 0b010;
1509 let Inst{22-20} = 0b010;
1510 let Inst{15-12} = 0b1111;
1512 let Inst{6-4} = 0b000;
1515 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1516 // And Miscellaneous operations -- for disassembly only
1517 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1518 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1519 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1520 "\t$dst, $a, $b", pat> {
1521 let Inst{31-27} = 0b11111;
1522 let Inst{26-23} = 0b0101;
1523 let Inst{22-20} = op22_20;
1524 let Inst{15-12} = 0b1111;
1525 let Inst{7-4} = op7_4;
1528 // Saturating add/subtract -- for disassembly only
1530 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1531 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1532 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1533 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1534 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1535 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1536 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1537 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1538 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1539 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1540 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1541 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1542 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1543 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1544 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1545 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1546 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1547 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1549 // Signed/Unsigned add/subtract -- for disassembly only
1551 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1552 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1553 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1554 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1555 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1556 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1557 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1558 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1559 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1560 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1561 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1562 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1564 // Signed/Unsigned halving add/subtract -- for disassembly only
1566 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1567 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1568 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1569 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1570 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1571 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1572 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1573 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1574 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1575 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1576 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1577 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1579 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1581 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1582 (ins rGPR:$a, rGPR:$b),
1583 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1584 let Inst{15-12} = 0b1111;
1586 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1587 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1588 "\t$dst, $a, $b, $acc", []>;
1590 // Signed/Unsigned saturate -- for disassembly only
1592 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1593 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1594 [/* For disassembly only; pattern left blank */]> {
1595 let Inst{31-27} = 0b11110;
1596 let Inst{25-22} = 0b1100;
1601 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1602 "ssat16", "\t$dst, $bit_pos, $a",
1603 [/* For disassembly only; pattern left blank */]> {
1604 let Inst{31-27} = 0b11110;
1605 let Inst{25-22} = 0b1100;
1608 let Inst{21} = 1; // sh = '1'
1609 let Inst{14-12} = 0b000; // imm3 = '000'
1610 let Inst{7-6} = 0b00; // imm2 = '00'
1613 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1614 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1615 [/* For disassembly only; pattern left blank */]> {
1616 let Inst{31-27} = 0b11110;
1617 let Inst{25-22} = 0b1110;
1622 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1623 "usat16", "\t$dst, $bit_pos, $a",
1624 [/* For disassembly only; pattern left blank */]> {
1625 let Inst{31-27} = 0b11110;
1626 let Inst{25-22} = 0b1110;
1629 let Inst{21} = 1; // sh = '1'
1630 let Inst{14-12} = 0b000; // imm3 = '000'
1631 let Inst{7-6} = 0b00; // imm2 = '00'
1634 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1635 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1637 //===----------------------------------------------------------------------===//
1638 // Shift and rotate Instructions.
1641 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1642 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1643 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1644 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1646 let Uses = [CPSR] in {
1647 def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1648 "rrx", "\t$dst, $src",
1649 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1650 let Inst{31-27} = 0b11101;
1651 let Inst{26-25} = 0b01;
1652 let Inst{24-21} = 0b0010;
1653 let Inst{20} = ?; // The S bit.
1654 let Inst{19-16} = 0b1111; // Rn
1655 let Inst{14-12} = 0b000;
1656 let Inst{7-4} = 0b0011;
1660 let Defs = [CPSR] in {
1661 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1662 "lsrs", ".w\t$dst, $src, #1",
1663 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1664 let Inst{31-27} = 0b11101;
1665 let Inst{26-25} = 0b01;
1666 let Inst{24-21} = 0b0010;
1667 let Inst{20} = 1; // The S bit.
1668 let Inst{19-16} = 0b1111; // Rn
1669 let Inst{5-4} = 0b01; // Shift type.
1670 // Shift amount = Inst{14-12:7-6} = 1.
1671 let Inst{14-12} = 0b000;
1672 let Inst{7-6} = 0b01;
1674 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1675 "asrs", ".w\t$dst, $src, #1",
1676 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1677 let Inst{31-27} = 0b11101;
1678 let Inst{26-25} = 0b01;
1679 let Inst{24-21} = 0b0010;
1680 let Inst{20} = 1; // The S bit.
1681 let Inst{19-16} = 0b1111; // Rn
1682 let Inst{5-4} = 0b10; // Shift type.
1683 // Shift amount = Inst{14-12:7-6} = 1.
1684 let Inst{14-12} = 0b000;
1685 let Inst{7-6} = 0b01;
1689 //===----------------------------------------------------------------------===//
1690 // Bitwise Instructions.
1693 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1694 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1695 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1696 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1697 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1698 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1699 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1700 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1701 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1703 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1704 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1705 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1707 let Constraints = "$src = $dst" in
1708 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1709 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1710 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1711 let Inst{31-27} = 0b11110;
1713 let Inst{24-20} = 0b10110;
1714 let Inst{19-16} = 0b1111; // Rn
1718 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1719 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1720 let Inst{31-27} = 0b11110;
1722 let Inst{24-20} = 0b10100;
1726 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1727 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1728 let Inst{31-27} = 0b11110;
1730 let Inst{24-20} = 0b11100;
1734 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1735 let Constraints = "$src = $dst" in
1736 def t2BFI : T2I<(outs rGPR:$dst),
1737 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1738 IIC_iBITi, "bfi", "\t$dst, $val, $imm",
1739 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1740 bf_inv_mask_imm:$imm))]> {
1741 let Inst{31-27} = 0b11110;
1743 let Inst{24-20} = 0b10110;
1747 defm t2ORN : T2I_bin_irs<0b0011, "orn",
1748 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1749 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
1751 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1752 let AddedComplexity = 1 in
1753 defm t2MVN : T2I_un_irs <0b0011, "mvn",
1754 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
1755 UnOpFrag<(not node:$Src)>, 1, 1>;
1758 let AddedComplexity = 1 in
1759 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1760 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1762 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1763 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1764 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1765 Requires<[IsThumb2]>;
1767 def : T2Pat<(t2_so_imm_not:$src),
1768 (t2MVNi t2_so_imm_not:$src)>;
1770 //===----------------------------------------------------------------------===//
1771 // Multiply Instructions.
1773 let isCommutable = 1 in
1774 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1775 "mul", "\t$dst, $a, $b",
1776 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1777 let Inst{31-27} = 0b11111;
1778 let Inst{26-23} = 0b0110;
1779 let Inst{22-20} = 0b000;
1780 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1781 let Inst{7-4} = 0b0000; // Multiply
1784 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1785 "mla", "\t$dst, $a, $b, $c",
1786 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1787 let Inst{31-27} = 0b11111;
1788 let Inst{26-23} = 0b0110;
1789 let Inst{22-20} = 0b000;
1790 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1791 let Inst{7-4} = 0b0000; // Multiply
1794 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1795 "mls", "\t$dst, $a, $b, $c",
1796 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1797 let Inst{31-27} = 0b11111;
1798 let Inst{26-23} = 0b0110;
1799 let Inst{22-20} = 0b000;
1800 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1801 let Inst{7-4} = 0b0001; // Multiply and Subtract
1804 // Extra precision multiplies with low / high results
1805 let neverHasSideEffects = 1 in {
1806 let isCommutable = 1 in {
1807 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1808 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1809 "smull", "\t$ldst, $hdst, $a, $b", []> {
1810 let Inst{31-27} = 0b11111;
1811 let Inst{26-23} = 0b0111;
1812 let Inst{22-20} = 0b000;
1813 let Inst{7-4} = 0b0000;
1816 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1817 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1818 "umull", "\t$ldst, $hdst, $a, $b", []> {
1819 let Inst{31-27} = 0b11111;
1820 let Inst{26-23} = 0b0111;
1821 let Inst{22-20} = 0b010;
1822 let Inst{7-4} = 0b0000;
1826 // Multiply + accumulate
1827 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1828 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1829 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1830 let Inst{31-27} = 0b11111;
1831 let Inst{26-23} = 0b0111;
1832 let Inst{22-20} = 0b100;
1833 let Inst{7-4} = 0b0000;
1836 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1837 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1838 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1839 let Inst{31-27} = 0b11111;
1840 let Inst{26-23} = 0b0111;
1841 let Inst{22-20} = 0b110;
1842 let Inst{7-4} = 0b0000;
1845 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1846 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1847 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1848 let Inst{31-27} = 0b11111;
1849 let Inst{26-23} = 0b0111;
1850 let Inst{22-20} = 0b110;
1851 let Inst{7-4} = 0b0110;
1853 } // neverHasSideEffects
1855 // Rounding variants of the below included for disassembly only
1857 // Most significant word multiply
1858 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1859 "smmul", "\t$dst, $a, $b",
1860 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
1861 let Inst{31-27} = 0b11111;
1862 let Inst{26-23} = 0b0110;
1863 let Inst{22-20} = 0b101;
1864 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1865 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1868 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1869 "smmulr", "\t$dst, $a, $b", []> {
1870 let Inst{31-27} = 0b11111;
1871 let Inst{26-23} = 0b0110;
1872 let Inst{22-20} = 0b101;
1873 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1874 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1877 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1878 "smmla", "\t$dst, $a, $b, $c",
1879 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
1880 let Inst{31-27} = 0b11111;
1881 let Inst{26-23} = 0b0110;
1882 let Inst{22-20} = 0b101;
1883 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1884 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1887 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1888 "smmlar", "\t$dst, $a, $b, $c", []> {
1889 let Inst{31-27} = 0b11111;
1890 let Inst{26-23} = 0b0110;
1891 let Inst{22-20} = 0b101;
1892 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1893 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1896 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1897 "smmls", "\t$dst, $a, $b, $c",
1898 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
1899 let Inst{31-27} = 0b11111;
1900 let Inst{26-23} = 0b0110;
1901 let Inst{22-20} = 0b110;
1902 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1903 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1906 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1907 "smmlsr", "\t$dst, $a, $b, $c", []> {
1908 let Inst{31-27} = 0b11111;
1909 let Inst{26-23} = 0b0110;
1910 let Inst{22-20} = 0b110;
1911 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1912 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1915 multiclass T2I_smul<string opc, PatFrag opnode> {
1916 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1917 !strconcat(opc, "bb"), "\t$dst, $a, $b",
1918 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1919 (sext_inreg rGPR:$b, i16)))]> {
1920 let Inst{31-27} = 0b11111;
1921 let Inst{26-23} = 0b0110;
1922 let Inst{22-20} = 0b001;
1923 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1924 let Inst{7-6} = 0b00;
1925 let Inst{5-4} = 0b00;
1928 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1929 !strconcat(opc, "bt"), "\t$dst, $a, $b",
1930 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1931 (sra rGPR:$b, (i32 16))))]> {
1932 let Inst{31-27} = 0b11111;
1933 let Inst{26-23} = 0b0110;
1934 let Inst{22-20} = 0b001;
1935 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1936 let Inst{7-6} = 0b00;
1937 let Inst{5-4} = 0b01;
1940 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1941 !strconcat(opc, "tb"), "\t$dst, $a, $b",
1942 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1943 (sext_inreg rGPR:$b, i16)))]> {
1944 let Inst{31-27} = 0b11111;
1945 let Inst{26-23} = 0b0110;
1946 let Inst{22-20} = 0b001;
1947 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1948 let Inst{7-6} = 0b00;
1949 let Inst{5-4} = 0b10;
1952 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1953 !strconcat(opc, "tt"), "\t$dst, $a, $b",
1954 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1955 (sra rGPR:$b, (i32 16))))]> {
1956 let Inst{31-27} = 0b11111;
1957 let Inst{26-23} = 0b0110;
1958 let Inst{22-20} = 0b001;
1959 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1960 let Inst{7-6} = 0b00;
1961 let Inst{5-4} = 0b11;
1964 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1965 !strconcat(opc, "wb"), "\t$dst, $a, $b",
1966 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1967 (sext_inreg rGPR:$b, i16)), (i32 16)))]> {
1968 let Inst{31-27} = 0b11111;
1969 let Inst{26-23} = 0b0110;
1970 let Inst{22-20} = 0b011;
1971 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1972 let Inst{7-6} = 0b00;
1973 let Inst{5-4} = 0b00;
1976 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1977 !strconcat(opc, "wt"), "\t$dst, $a, $b",
1978 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1979 (sra rGPR:$b, (i32 16))), (i32 16)))]> {
1980 let Inst{31-27} = 0b11111;
1981 let Inst{26-23} = 0b0110;
1982 let Inst{22-20} = 0b011;
1983 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1984 let Inst{7-6} = 0b00;
1985 let Inst{5-4} = 0b01;
1990 multiclass T2I_smla<string opc, PatFrag opnode> {
1991 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
1992 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1993 [(set rGPR:$dst, (add rGPR:$acc,
1994 (opnode (sext_inreg rGPR:$a, i16),
1995 (sext_inreg rGPR:$b, i16))))]> {
1996 let Inst{31-27} = 0b11111;
1997 let Inst{26-23} = 0b0110;
1998 let Inst{22-20} = 0b001;
1999 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2000 let Inst{7-6} = 0b00;
2001 let Inst{5-4} = 0b00;
2004 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2005 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2006 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
2007 (sra rGPR:$b, (i32 16)))))]> {
2008 let Inst{31-27} = 0b11111;
2009 let Inst{26-23} = 0b0110;
2010 let Inst{22-20} = 0b001;
2011 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2012 let Inst{7-6} = 0b00;
2013 let Inst{5-4} = 0b01;
2016 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2017 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2018 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2019 (sext_inreg rGPR:$b, i16))))]> {
2020 let Inst{31-27} = 0b11111;
2021 let Inst{26-23} = 0b0110;
2022 let Inst{22-20} = 0b001;
2023 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2024 let Inst{7-6} = 0b00;
2025 let Inst{5-4} = 0b10;
2028 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2029 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2030 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2031 (sra rGPR:$b, (i32 16)))))]> {
2032 let Inst{31-27} = 0b11111;
2033 let Inst{26-23} = 0b0110;
2034 let Inst{22-20} = 0b001;
2035 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2036 let Inst{7-6} = 0b00;
2037 let Inst{5-4} = 0b11;
2040 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2041 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2042 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2043 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2044 let Inst{31-27} = 0b11111;
2045 let Inst{26-23} = 0b0110;
2046 let Inst{22-20} = 0b011;
2047 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2048 let Inst{7-6} = 0b00;
2049 let Inst{5-4} = 0b00;
2052 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2053 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2054 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2055 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2056 let Inst{31-27} = 0b11111;
2057 let Inst{26-23} = 0b0110;
2058 let Inst{22-20} = 0b011;
2059 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2060 let Inst{7-6} = 0b00;
2061 let Inst{5-4} = 0b01;
2065 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2066 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2068 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2069 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2070 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2071 [/* For disassembly only; pattern left blank */]>;
2072 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2073 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2074 [/* For disassembly only; pattern left blank */]>;
2075 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2076 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2077 [/* For disassembly only; pattern left blank */]>;
2078 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2079 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2080 [/* For disassembly only; pattern left blank */]>;
2082 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2083 // These are for disassembly only.
2085 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2086 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2087 let Inst{15-12} = 0b1111;
2089 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2090 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2091 let Inst{15-12} = 0b1111;
2093 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2094 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2095 let Inst{15-12} = 0b1111;
2097 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2098 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2099 let Inst{15-12} = 0b1111;
2101 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2102 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2103 "\t$dst, $a, $b, $acc", []>;
2104 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2105 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2106 "\t$dst, $a, $b, $acc", []>;
2107 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2108 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2109 "\t$dst, $a, $b, $acc", []>;
2110 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2111 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2112 "\t$dst, $a, $b, $acc", []>;
2113 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2114 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2115 "\t$ldst, $hdst, $a, $b", []>;
2116 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2117 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2118 "\t$ldst, $hdst, $a, $b", []>;
2119 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2120 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2121 "\t$ldst, $hdst, $a, $b", []>;
2122 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2123 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2124 "\t$ldst, $hdst, $a, $b", []>;
2126 //===----------------------------------------------------------------------===//
2127 // Misc. Arithmetic Instructions.
2130 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2131 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2132 : T2I<oops, iops, itin, opc, asm, pattern> {
2133 let Inst{31-27} = 0b11111;
2134 let Inst{26-22} = 0b01010;
2135 let Inst{21-20} = op1;
2136 let Inst{15-12} = 0b1111;
2137 let Inst{7-6} = 0b10;
2138 let Inst{5-4} = op2;
2141 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2142 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2144 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2145 "rbit", "\t$dst, $src",
2146 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2148 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2149 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2151 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2152 "rev16", ".w\t$dst, $src",
2154 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2155 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2156 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2157 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2159 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2160 "revsh", ".w\t$dst, $src",
2163 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2164 (shl rGPR:$src, (i32 8))), i16))]>;
2166 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2167 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2168 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2169 (and (shl rGPR:$src2, lsl_amt:$sh),
2171 Requires<[HasT2ExtractPack, IsThumb2]> {
2172 let Inst{31-27} = 0b11101;
2173 let Inst{26-25} = 0b01;
2174 let Inst{24-20} = 0b01100;
2175 let Inst{5} = 0; // BT form
2179 // Alternate cases for PKHBT where identities eliminate some nodes.
2180 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2181 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2182 Requires<[HasT2ExtractPack, IsThumb2]>;
2183 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2184 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2185 Requires<[HasT2ExtractPack, IsThumb2]>;
2187 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2188 // will match the pattern below.
2189 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2190 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2191 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2192 (and (sra rGPR:$src2, asr_amt:$sh),
2194 Requires<[HasT2ExtractPack, IsThumb2]> {
2195 let Inst{31-27} = 0b11101;
2196 let Inst{26-25} = 0b01;
2197 let Inst{24-20} = 0b01100;
2198 let Inst{5} = 1; // TB form
2202 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2203 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2204 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2205 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2206 Requires<[HasT2ExtractPack, IsThumb2]>;
2207 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2208 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2209 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2210 Requires<[HasT2ExtractPack, IsThumb2]>;
2212 //===----------------------------------------------------------------------===//
2213 // Comparison Instructions...
2215 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2216 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2217 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2218 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2219 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2220 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2222 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2223 // Compare-to-zero still works out, just not the relationals
2224 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2225 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2226 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2227 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2228 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2230 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2231 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2233 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2234 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2236 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2237 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2238 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2239 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2240 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2241 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2243 // Conditional moves
2244 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2245 // a two-value operand where a dag node expects two operands. :(
2246 let neverHasSideEffects = 1 in {
2247 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2248 "mov", ".w\t$dst, $true",
2249 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2250 RegConstraint<"$false = $dst"> {
2251 let Inst{31-27} = 0b11101;
2252 let Inst{26-25} = 0b01;
2253 let Inst{24-21} = 0b0010;
2254 let Inst{20} = 0; // The S bit.
2255 let Inst{19-16} = 0b1111; // Rn
2256 let Inst{14-12} = 0b000;
2257 let Inst{7-4} = 0b0000;
2260 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2261 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2262 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2263 RegConstraint<"$false = $dst"> {
2264 let Inst{31-27} = 0b11110;
2266 let Inst{24-21} = 0b0010;
2267 let Inst{20} = 0; // The S bit.
2268 let Inst{19-16} = 0b1111; // Rn
2272 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
2274 "movw", "\t$dst, $src", []>,
2275 RegConstraint<"$false = $dst"> {
2276 let Inst{31-27} = 0b11110;
2278 let Inst{24-21} = 0b0010;
2279 let Inst{20} = 0; // The S bit.
2283 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2284 (ins rGPR:$false, i32imm:$src, pred:$p),
2285 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">;
2287 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2288 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2289 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
2290 imm:$cc, CCR:$ccr))*/]>,
2291 RegConstraint<"$false = $dst"> {
2292 let Inst{31-27} = 0b11110;
2294 let Inst{24-21} = 0b0011;
2295 let Inst{20} = 0; // The S bit.
2296 let Inst{19-16} = 0b1111; // Rn
2300 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2301 string opc, string asm, list<dag> pattern>
2302 : T2I<oops, iops, itin, opc, asm, pattern> {
2303 let Inst{31-27} = 0b11101;
2304 let Inst{26-25} = 0b01;
2305 let Inst{24-21} = 0b0010;
2306 let Inst{20} = 0; // The S bit.
2307 let Inst{19-16} = 0b1111; // Rn
2308 let Inst{5-4} = opcod; // Shift type.
2310 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2311 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2312 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2313 RegConstraint<"$false = $dst">;
2314 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2315 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2316 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2317 RegConstraint<"$false = $dst">;
2318 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2319 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2320 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2321 RegConstraint<"$false = $dst">;
2322 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2323 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2324 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2325 RegConstraint<"$false = $dst">;
2326 } // neverHasSideEffects
2328 //===----------------------------------------------------------------------===//
2329 // Atomic operations intrinsics
2332 // memory barriers protect the atomic sequences
2333 let hasSideEffects = 1 in {
2334 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2335 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2336 Requires<[IsThumb, HasDB]> {
2338 let Inst{31-4} = 0xf3bf8f5;
2339 let Inst{3-0} = opt;
2343 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2345 [/* For disassembly only; pattern left blank */]>,
2346 Requires<[IsThumb, HasDB]> {
2348 let Inst{31-4} = 0xf3bf8f4;
2349 let Inst{3-0} = opt;
2352 // ISB has only full system option -- for disassembly only
2353 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2354 [/* For disassembly only; pattern left blank */]>,
2355 Requires<[IsThumb2, HasV7]> {
2356 let Inst{31-4} = 0xf3bf8f6;
2357 let Inst{3-0} = 0b1111;
2360 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2361 InstrItinClass itin, string opc, string asm, string cstr,
2362 list<dag> pattern, bits<4> rt2 = 0b1111>
2363 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2364 let Inst{31-27} = 0b11101;
2365 let Inst{26-20} = 0b0001101;
2366 let Inst{11-8} = rt2;
2367 let Inst{7-6} = 0b01;
2368 let Inst{5-4} = opcod;
2369 let Inst{3-0} = 0b1111;
2371 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2372 InstrItinClass itin, string opc, string asm, string cstr,
2373 list<dag> pattern, bits<4> rt2 = 0b1111>
2374 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2375 let Inst{31-27} = 0b11101;
2376 let Inst{26-20} = 0b0001100;
2377 let Inst{11-8} = rt2;
2378 let Inst{7-6} = 0b01;
2379 let Inst{5-4} = opcod;
2382 let mayLoad = 1 in {
2383 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2384 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2386 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2387 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2389 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2390 Size4Bytes, NoItinerary,
2391 "ldrex", "\t$dest, [$ptr]", "",
2393 let Inst{31-27} = 0b11101;
2394 let Inst{26-20} = 0b0000101;
2395 let Inst{11-8} = 0b1111;
2396 let Inst{7-0} = 0b00000000; // imm8 = 0
2398 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2399 AddrModeNone, Size4Bytes, NoItinerary,
2400 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2404 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2405 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2406 AddrModeNone, Size4Bytes, NoItinerary,
2407 "strexb", "\t$success, $src, [$ptr]", "", []>;
2408 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2409 AddrModeNone, Size4Bytes, NoItinerary,
2410 "strexh", "\t$success, $src, [$ptr]", "", []>;
2411 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2412 AddrModeNone, Size4Bytes, NoItinerary,
2413 "strex", "\t$success, $src, [$ptr]", "",
2415 let Inst{31-27} = 0b11101;
2416 let Inst{26-20} = 0b0000100;
2417 let Inst{7-0} = 0b00000000; // imm8 = 0
2419 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2420 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2421 AddrModeNone, Size4Bytes, NoItinerary,
2422 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2426 // Clear-Exclusive is for disassembly only.
2427 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2428 [/* For disassembly only; pattern left blank */]>,
2429 Requires<[IsARM, HasV7]> {
2430 let Inst{31-20} = 0xf3b;
2431 let Inst{15-14} = 0b10;
2433 let Inst{7-4} = 0b0010;
2436 //===----------------------------------------------------------------------===//
2440 // __aeabi_read_tp preserves the registers r1-r3.
2442 Defs = [R0, R12, LR, CPSR] in {
2443 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2444 "bl\t__aeabi_read_tp",
2445 [(set R0, ARMthread_pointer)]> {
2446 let Inst{31-27} = 0b11110;
2447 let Inst{15-14} = 0b11;
2452 //===----------------------------------------------------------------------===//
2453 // SJLJ Exception handling intrinsics
2454 // eh_sjlj_setjmp() is an instruction sequence to store the return
2455 // address and save #0 in R0 for the non-longjmp case.
2456 // Since by its nature we may be coming from some other function to get
2457 // here, and we're using the stack frame for the containing function to
2458 // save/restore registers, we can't keep anything live in regs across
2459 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2460 // when we get here from a longjmp(). We force everthing out of registers
2461 // except for our own input by listing the relevant registers in Defs. By
2462 // doing so, we also cause the prologue/epilogue code to actively preserve
2463 // all of the callee-saved resgisters, which is exactly what we want.
2464 // $val is a scratch register for our use.
2466 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2467 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2468 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2469 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2470 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2471 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2472 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2473 Requires<[IsThumb2, HasVFP2]>;
2477 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2478 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2479 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2480 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2481 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2482 Requires<[IsThumb2, NoVFP]>;
2486 //===----------------------------------------------------------------------===//
2487 // Control-Flow Instructions
2490 // FIXME: remove when we have a way to marking a MI with these properties.
2491 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2493 // FIXME: Should pc be an implicit operand like PICADD, etc?
2494 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2495 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2496 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
2497 reglist:$dsts, variable_ops),
2499 "ldm${amode}${p}.w\t$Rn!, $dsts",
2501 let Inst{31-27} = 0b11101;
2502 let Inst{26-25} = 0b00;
2503 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2505 let Inst{21} = 1; // The W bit.
2506 let Inst{20} = 1; // Load
2509 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2510 let isPredicable = 1 in
2511 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2513 [(br bb:$target)]> {
2514 let Inst{31-27} = 0b11110;
2515 let Inst{15-14} = 0b10;
2519 let isNotDuplicable = 1, isIndirectBranch = 1,
2520 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
2523 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2524 IIC_Br, "mov\tpc, $target$jt",
2525 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2526 let Inst{31-27} = 0b11101;
2527 let Inst{26-20} = 0b0100100;
2528 let Inst{19-16} = 0b1111;
2529 let Inst{14-12} = 0b000;
2530 let Inst{11-8} = 0b1111; // Rd = pc
2531 let Inst{7-4} = 0b0000;
2534 // FIXME: Add a non-pc based case that can be predicated.
2535 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2538 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2539 IIC_Br, "tbb\t$index$jt", []> {
2540 let Inst{31-27} = 0b11101;
2541 let Inst{26-20} = 0b0001101;
2542 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2543 let Inst{15-8} = 0b11110000;
2544 let Inst{7-4} = 0b0000; // B form
2547 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2550 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2551 IIC_Br, "tbh\t$index$jt", []> {
2552 let Inst{31-27} = 0b11101;
2553 let Inst{26-20} = 0b0001101;
2554 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2555 let Inst{15-8} = 0b11110000;
2556 let Inst{7-4} = 0b0001; // H form
2559 // Generic versions of the above two instructions, for disassembly only
2561 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2562 "tbb", "\t[$a, $b]", []>{
2563 let Inst{31-27} = 0b11101;
2564 let Inst{26-20} = 0b0001101;
2565 let Inst{15-8} = 0b11110000;
2566 let Inst{7-4} = 0b0000; // B form
2569 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2570 "tbh", "\t[$a, $b, lsl #1]", []> {
2571 let Inst{31-27} = 0b11101;
2572 let Inst{26-20} = 0b0001101;
2573 let Inst{15-8} = 0b11110000;
2574 let Inst{7-4} = 0b0001; // H form
2576 } // isNotDuplicable, isIndirectBranch
2578 } // isBranch, isTerminator, isBarrier
2580 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2581 // a two-value operand where a dag node expects two operands. :(
2582 let isBranch = 1, isTerminator = 1 in
2583 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2585 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2586 let Inst{31-27} = 0b11110;
2587 let Inst{15-14} = 0b10;
2593 let Defs = [ITSTATE] in
2594 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2595 AddrModeNone, Size2Bytes, IIC_iALUx,
2596 "it$mask\t$cc", "", []> {
2597 // 16-bit instruction.
2598 let Inst{31-16} = 0x0000;
2599 let Inst{15-8} = 0b10111111;
2602 // Branch and Exchange Jazelle -- for disassembly only
2604 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2605 [/* For disassembly only; pattern left blank */]> {
2606 let Inst{31-27} = 0b11110;
2608 let Inst{25-20} = 0b111100;
2609 let Inst{15-14} = 0b10;
2613 // Change Processor State is a system instruction -- for disassembly only.
2614 // The singleton $opt operand contains the following information:
2615 // opt{4-0} = mode from Inst{4-0}
2616 // opt{5} = changemode from Inst{17}
2617 // opt{8-6} = AIF from Inst{8-6}
2618 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2619 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2620 [/* For disassembly only; pattern left blank */]> {
2621 let Inst{31-27} = 0b11110;
2623 let Inst{25-20} = 0b111010;
2624 let Inst{15-14} = 0b10;
2628 // A6.3.4 Branches and miscellaneous control
2629 // Table A6-14 Change Processor State, and hint instructions
2630 // Helper class for disassembly only.
2631 class T2I_hint<bits<8> op7_0, string opc, string asm>
2632 : T2I<(outs), (ins), NoItinerary, opc, asm,
2633 [/* For disassembly only; pattern left blank */]> {
2634 let Inst{31-20} = 0xf3a;
2635 let Inst{15-14} = 0b10;
2637 let Inst{10-8} = 0b000;
2638 let Inst{7-0} = op7_0;
2641 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2642 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2643 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2644 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2645 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2647 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2648 [/* For disassembly only; pattern left blank */]> {
2649 let Inst{31-20} = 0xf3a;
2650 let Inst{15-14} = 0b10;
2652 let Inst{10-8} = 0b000;
2653 let Inst{7-4} = 0b1111;
2656 // Secure Monitor Call is a system instruction -- for disassembly only
2657 // Option = Inst{19-16}
2658 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2659 [/* For disassembly only; pattern left blank */]> {
2660 let Inst{31-27} = 0b11110;
2661 let Inst{26-20} = 0b1111111;
2662 let Inst{15-12} = 0b1000;
2665 // Store Return State is a system instruction -- for disassembly only
2666 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2667 [/* For disassembly only; pattern left blank */]> {
2668 let Inst{31-27} = 0b11101;
2669 let Inst{26-20} = 0b0000010; // W = 1
2672 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2673 [/* For disassembly only; pattern left blank */]> {
2674 let Inst{31-27} = 0b11101;
2675 let Inst{26-20} = 0b0000000; // W = 0
2678 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2679 [/* For disassembly only; pattern left blank */]> {
2680 let Inst{31-27} = 0b11101;
2681 let Inst{26-20} = 0b0011010; // W = 1
2684 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2685 [/* For disassembly only; pattern left blank */]> {
2686 let Inst{31-27} = 0b11101;
2687 let Inst{26-20} = 0b0011000; // W = 0
2690 // Return From Exception is a system instruction -- for disassembly only
2691 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2692 [/* For disassembly only; pattern left blank */]> {
2693 let Inst{31-27} = 0b11101;
2694 let Inst{26-20} = 0b0000011; // W = 1
2697 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2698 [/* For disassembly only; pattern left blank */]> {
2699 let Inst{31-27} = 0b11101;
2700 let Inst{26-20} = 0b0000001; // W = 0
2703 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2704 [/* For disassembly only; pattern left blank */]> {
2705 let Inst{31-27} = 0b11101;
2706 let Inst{26-20} = 0b0011011; // W = 1
2709 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2710 [/* For disassembly only; pattern left blank */]> {
2711 let Inst{31-27} = 0b11101;
2712 let Inst{26-20} = 0b0011001; // W = 0
2715 //===----------------------------------------------------------------------===//
2716 // Non-Instruction Patterns
2719 // Two piece so_imms.
2720 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2721 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2722 (t2_so_imm2part_2 imm:$RHS))>;
2723 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2724 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2725 (t2_so_imm2part_2 imm:$RHS))>;
2726 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2727 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2728 (t2_so_imm2part_2 imm:$RHS))>;
2729 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2730 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2731 (t2_so_neg_imm2part_2 imm:$RHS))>;
2733 // 32-bit immediate using movw + movt.
2734 // This is a single pseudo instruction to make it re-materializable.
2735 // FIXME: Remove this when we can do generalized remat.
2736 let isReMaterializable = 1 in
2737 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
2738 "", [(set rGPR:$dst, (i32 imm:$src))]>,
2739 Requires<[IsThumb, HasV6T2]>;
2741 // ConstantPool, GlobalAddress, and JumpTable
2742 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2743 Requires<[IsThumb2, DontUseMovt]>;
2744 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2745 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2746 Requires<[IsThumb2, UseMovt]>;
2748 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2749 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2751 // Pseudo instruction that combines ldr from constpool and add pc. This should
2752 // be expanded into two instructions late to allow if-conversion and
2754 let canFoldAsLoad = 1, isReMaterializable = 1 in
2755 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2757 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2759 Requires<[IsThumb2]>;
2761 //===----------------------------------------------------------------------===//
2762 // Move between special register and ARM core register -- for disassembly only
2766 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2767 [/* For disassembly only; pattern left blank */]> {
2768 let Inst{31-27} = 0b11110;
2770 let Inst{25-21} = 0b11111;
2771 let Inst{20} = 0; // The R bit.
2772 let Inst{15-14} = 0b10;
2777 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2778 [/* For disassembly only; pattern left blank */]> {
2779 let Inst{31-27} = 0b11110;
2781 let Inst{25-21} = 0b11111;
2782 let Inst{20} = 1; // The R bit.
2783 let Inst{15-14} = 0b10;
2788 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2789 "\tcpsr$mask, $src",
2790 [/* For disassembly only; pattern left blank */]> {
2791 let Inst{31-27} = 0b11110;
2793 let Inst{25-21} = 0b11100;
2794 let Inst{20} = 0; // The R bit.
2795 let Inst{15-14} = 0b10;
2800 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2801 "\tspsr$mask, $src",
2802 [/* For disassembly only; pattern left blank */]> {
2803 let Inst{31-27} = 0b11110;
2805 let Inst{25-21} = 0b11100;
2806 let Inst{20} = 1; // The R bit.
2807 let Inst{15-14} = 0b10;