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 multiclass thumb2_ldst_mult<string asm, InstrItinClass itin,
1287 InstrItinClass itin_upd, bit L_bit> {
1289 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1290 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
1294 let Inst{31-27} = 0b11101;
1295 let Inst{26-25} = 0b00;
1296 let Inst{24-23} = 0b01; // Increment After
1298 let Inst{21} = 0; // No writeback
1299 let Inst{20} = L_bit;
1300 let Inst{19-16} = Rn;
1301 let Inst{15-0} = regs;
1304 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1305 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1309 let Inst{31-27} = 0b11101;
1310 let Inst{26-25} = 0b00;
1311 let Inst{24-23} = 0b01; // Increment After
1313 let Inst{21} = 1; // Writeback
1314 let Inst{20} = L_bit;
1315 let Inst{19-16} = Rn;
1316 let Inst{15-0} = regs;
1319 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1320 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> {
1324 let Inst{31-27} = 0b11101;
1325 let Inst{26-25} = 0b00;
1326 let Inst{24-23} = 0b10; // Decrement Before
1328 let Inst{21} = 0; // No writeback
1329 let Inst{20} = L_bit;
1330 let Inst{19-16} = Rn;
1331 let Inst{15-0} = regs;
1334 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1335 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> {
1339 let Inst{31-27} = 0b11101;
1340 let Inst{26-25} = 0b00;
1341 let Inst{24-23} = 0b10; // Decrement Before
1343 let Inst{21} = 1; // Writeback
1344 let Inst{20} = L_bit;
1345 let Inst{19-16} = Rn;
1346 let Inst{15-0} = regs;
1351 let neverHasSideEffects = 1 in {
1353 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1354 defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1356 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1357 defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1359 } // neverHasSideEffects
1362 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1363 isCodeGenOnly = 1 in {
1364 def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1365 reglist:$dsts, variable_ops), IIC_iLoad_m,
1366 "ldm${amode}${p}.w\t$Rn, $dsts", []> {
1367 let Inst{31-27} = 0b11101;
1368 let Inst{26-25} = 0b00;
1369 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1371 let Inst{21} = 0; // The W bit.
1372 let Inst{20} = 1; // Load
1375 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1376 reglist:$dsts, variable_ops),
1378 "ldm${amode}${p}.w\t$Rn!, $dsts",
1380 let Inst{31-27} = 0b11101;
1381 let Inst{26-25} = 0b00;
1382 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1384 let Inst{21} = 1; // The W bit.
1385 let Inst{20} = 1; // Load
1387 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1389 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1390 isCodeGenOnly = 1 in {
1391 def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1392 reglist:$srcs, variable_ops), IIC_iStore_m,
1393 "stm${amode}${p}.w\t$Rn, $srcs", []> {
1394 let Inst{31-27} = 0b11101;
1395 let Inst{26-25} = 0b00;
1396 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1398 let Inst{21} = 0; // The W bit.
1399 let Inst{20} = 0; // Store
1402 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1403 reglist:$srcs, variable_ops),
1405 "stm${amode}${p}.w\t$Rn!, $srcs",
1407 let Inst{31-27} = 0b11101;
1408 let Inst{26-25} = 0b00;
1409 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1411 let Inst{21} = 1; // The W bit.
1412 let Inst{20} = 0; // Store
1414 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1416 //===----------------------------------------------------------------------===//
1417 // Move Instructions.
1420 let neverHasSideEffects = 1 in
1421 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1422 "mov", ".w\t$dst, $src", []> {
1423 let Inst{31-27} = 0b11101;
1424 let Inst{26-25} = 0b01;
1425 let Inst{24-21} = 0b0010;
1426 let Inst{20} = ?; // The S bit.
1427 let Inst{19-16} = 0b1111; // Rn
1428 let Inst{14-12} = 0b000;
1429 let Inst{7-4} = 0b0000;
1432 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1433 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1434 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1435 "mov", ".w\t$dst, $src",
1436 [(set rGPR:$dst, t2_so_imm:$src)]> {
1437 let Inst{31-27} = 0b11110;
1439 let Inst{24-21} = 0b0010;
1440 let Inst{20} = ?; // The S bit.
1441 let Inst{19-16} = 0b1111; // Rn
1445 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1446 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1447 "movw", "\t$dst, $src",
1448 [(set rGPR:$dst, imm0_65535:$src)]> {
1449 let Inst{31-27} = 0b11110;
1451 let Inst{24-21} = 0b0010;
1452 let Inst{20} = 0; // The S bit.
1456 let Constraints = "$src = $dst" in
1457 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1458 "movt", "\t$dst, $imm",
1460 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1461 let Inst{31-27} = 0b11110;
1463 let Inst{24-21} = 0b0110;
1464 let Inst{20} = 0; // The S bit.
1468 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1470 //===----------------------------------------------------------------------===//
1471 // Extend Instructions.
1476 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1477 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1478 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1479 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1480 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1482 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1483 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1484 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1485 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1486 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1488 // TODO: SXT(A){B|H}16 - done for disassembly only
1492 let AddedComplexity = 16 in {
1493 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1494 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1495 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1496 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1497 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1498 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1500 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1501 // The transformation should probably be done as a combiner action
1502 // instead so we can include a check for masking back in the upper
1503 // eight bits of the source into the lower eight bits of the result.
1504 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1505 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1506 // Requires<[HasT2ExtractPack, IsThumb2]>;
1507 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1508 (t2UXTB16r_rot rGPR:$Src, 8)>,
1509 Requires<[HasT2ExtractPack, IsThumb2]>;
1511 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1512 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1513 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1514 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1515 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1518 //===----------------------------------------------------------------------===//
1519 // Arithmetic Instructions.
1522 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1523 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1524 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1525 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1527 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1528 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1529 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1530 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1531 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1532 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1533 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1535 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1536 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1537 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1538 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1539 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1540 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1541 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1542 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1545 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1546 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1547 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1548 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1550 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1551 // The assume-no-carry-in form uses the negation of the input since add/sub
1552 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1553 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1555 // The AddedComplexity preferences the first variant over the others since
1556 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1557 let AddedComplexity = 1 in
1558 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1559 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1560 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1561 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1562 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1563 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1564 let AddedComplexity = 1 in
1565 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1566 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1567 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1568 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1569 // The with-carry-in form matches bitwise not instead of the negation.
1570 // Effectively, the inverse interpretation of the carry flag already accounts
1571 // for part of the negation.
1572 let AddedComplexity = 1 in
1573 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1574 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1575 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1576 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1578 // Select Bytes -- for disassembly only
1580 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1581 "\t$dst, $a, $b", []> {
1582 let Inst{31-27} = 0b11111;
1583 let Inst{26-24} = 0b010;
1585 let Inst{22-20} = 0b010;
1586 let Inst{15-12} = 0b1111;
1588 let Inst{6-4} = 0b000;
1591 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1592 // And Miscellaneous operations -- for disassembly only
1593 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1594 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1595 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1596 "\t$dst, $a, $b", pat> {
1597 let Inst{31-27} = 0b11111;
1598 let Inst{26-23} = 0b0101;
1599 let Inst{22-20} = op22_20;
1600 let Inst{15-12} = 0b1111;
1601 let Inst{7-4} = op7_4;
1604 // Saturating add/subtract -- for disassembly only
1606 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1607 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1608 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1609 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1610 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1611 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1612 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1613 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1614 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1615 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1616 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1617 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1618 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1619 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1620 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1621 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1622 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1623 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1625 // Signed/Unsigned add/subtract -- for disassembly only
1627 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1628 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1629 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1630 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1631 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1632 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1633 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1634 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1635 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1636 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1637 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1638 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1640 // Signed/Unsigned halving add/subtract -- for disassembly only
1642 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1643 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1644 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1645 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1646 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1647 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1648 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1649 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1650 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1651 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1652 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1653 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1655 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1657 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1658 (ins rGPR:$a, rGPR:$b),
1659 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1660 let Inst{15-12} = 0b1111;
1662 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1663 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1664 "\t$dst, $a, $b, $acc", []>;
1666 // Signed/Unsigned saturate -- for disassembly only
1668 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1669 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1670 [/* For disassembly only; pattern left blank */]> {
1671 let Inst{31-27} = 0b11110;
1672 let Inst{25-22} = 0b1100;
1677 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1678 "ssat16", "\t$dst, $bit_pos, $a",
1679 [/* For disassembly only; pattern left blank */]> {
1680 let Inst{31-27} = 0b11110;
1681 let Inst{25-22} = 0b1100;
1684 let Inst{21} = 1; // sh = '1'
1685 let Inst{14-12} = 0b000; // imm3 = '000'
1686 let Inst{7-6} = 0b00; // imm2 = '00'
1689 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1690 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1691 [/* For disassembly only; pattern left blank */]> {
1692 let Inst{31-27} = 0b11110;
1693 let Inst{25-22} = 0b1110;
1698 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1699 "usat16", "\t$dst, $bit_pos, $a",
1700 [/* For disassembly only; pattern left blank */]> {
1701 let Inst{31-27} = 0b11110;
1702 let Inst{25-22} = 0b1110;
1705 let Inst{21} = 1; // sh = '1'
1706 let Inst{14-12} = 0b000; // imm3 = '000'
1707 let Inst{7-6} = 0b00; // imm2 = '00'
1710 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1711 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1713 //===----------------------------------------------------------------------===//
1714 // Shift and rotate Instructions.
1717 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1718 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1719 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1720 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1722 let Uses = [CPSR] in {
1723 def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1724 "rrx", "\t$dst, $src",
1725 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1726 let Inst{31-27} = 0b11101;
1727 let Inst{26-25} = 0b01;
1728 let Inst{24-21} = 0b0010;
1729 let Inst{20} = ?; // The S bit.
1730 let Inst{19-16} = 0b1111; // Rn
1731 let Inst{14-12} = 0b000;
1732 let Inst{7-4} = 0b0011;
1736 let Defs = [CPSR] in {
1737 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1738 "lsrs", ".w\t$dst, $src, #1",
1739 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1740 let Inst{31-27} = 0b11101;
1741 let Inst{26-25} = 0b01;
1742 let Inst{24-21} = 0b0010;
1743 let Inst{20} = 1; // The S bit.
1744 let Inst{19-16} = 0b1111; // Rn
1745 let Inst{5-4} = 0b01; // Shift type.
1746 // Shift amount = Inst{14-12:7-6} = 1.
1747 let Inst{14-12} = 0b000;
1748 let Inst{7-6} = 0b01;
1750 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1751 "asrs", ".w\t$dst, $src, #1",
1752 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1753 let Inst{31-27} = 0b11101;
1754 let Inst{26-25} = 0b01;
1755 let Inst{24-21} = 0b0010;
1756 let Inst{20} = 1; // The S bit.
1757 let Inst{19-16} = 0b1111; // Rn
1758 let Inst{5-4} = 0b10; // Shift type.
1759 // Shift amount = Inst{14-12:7-6} = 1.
1760 let Inst{14-12} = 0b000;
1761 let Inst{7-6} = 0b01;
1765 //===----------------------------------------------------------------------===//
1766 // Bitwise Instructions.
1769 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1770 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1771 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1772 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1773 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1774 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1775 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1776 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1777 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1779 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1780 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1781 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1783 let Constraints = "$src = $dst" in
1784 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1785 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1786 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1787 let Inst{31-27} = 0b11110;
1789 let Inst{24-20} = 0b10110;
1790 let Inst{19-16} = 0b1111; // Rn
1794 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1795 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1796 let Inst{31-27} = 0b11110;
1798 let Inst{24-20} = 0b10100;
1802 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1803 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1804 let Inst{31-27} = 0b11110;
1806 let Inst{24-20} = 0b11100;
1810 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1811 let Constraints = "$src = $dst" in
1812 def t2BFI : T2I<(outs rGPR:$dst),
1813 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1814 IIC_iBITi, "bfi", "\t$dst, $val, $imm",
1815 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1816 bf_inv_mask_imm:$imm))]> {
1817 let Inst{31-27} = 0b11110;
1819 let Inst{24-20} = 0b10110;
1823 defm t2ORN : T2I_bin_irs<0b0011, "orn",
1824 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1825 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
1827 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1828 let AddedComplexity = 1 in
1829 defm t2MVN : T2I_un_irs <0b0011, "mvn",
1830 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
1831 UnOpFrag<(not node:$Src)>, 1, 1>;
1834 let AddedComplexity = 1 in
1835 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1836 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1838 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1839 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1840 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1841 Requires<[IsThumb2]>;
1843 def : T2Pat<(t2_so_imm_not:$src),
1844 (t2MVNi t2_so_imm_not:$src)>;
1846 //===----------------------------------------------------------------------===//
1847 // Multiply Instructions.
1849 let isCommutable = 1 in
1850 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1851 "mul", "\t$dst, $a, $b",
1852 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1853 let Inst{31-27} = 0b11111;
1854 let Inst{26-23} = 0b0110;
1855 let Inst{22-20} = 0b000;
1856 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1857 let Inst{7-4} = 0b0000; // Multiply
1860 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1861 "mla", "\t$dst, $a, $b, $c",
1862 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1863 let Inst{31-27} = 0b11111;
1864 let Inst{26-23} = 0b0110;
1865 let Inst{22-20} = 0b000;
1866 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1867 let Inst{7-4} = 0b0000; // Multiply
1870 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1871 "mls", "\t$dst, $a, $b, $c",
1872 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1873 let Inst{31-27} = 0b11111;
1874 let Inst{26-23} = 0b0110;
1875 let Inst{22-20} = 0b000;
1876 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1877 let Inst{7-4} = 0b0001; // Multiply and Subtract
1880 // Extra precision multiplies with low / high results
1881 let neverHasSideEffects = 1 in {
1882 let isCommutable = 1 in {
1883 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1884 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1885 "smull", "\t$ldst, $hdst, $a, $b", []> {
1886 let Inst{31-27} = 0b11111;
1887 let Inst{26-23} = 0b0111;
1888 let Inst{22-20} = 0b000;
1889 let Inst{7-4} = 0b0000;
1892 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1893 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1894 "umull", "\t$ldst, $hdst, $a, $b", []> {
1895 let Inst{31-27} = 0b11111;
1896 let Inst{26-23} = 0b0111;
1897 let Inst{22-20} = 0b010;
1898 let Inst{7-4} = 0b0000;
1902 // Multiply + accumulate
1903 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1904 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1905 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1906 let Inst{31-27} = 0b11111;
1907 let Inst{26-23} = 0b0111;
1908 let Inst{22-20} = 0b100;
1909 let Inst{7-4} = 0b0000;
1912 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1913 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1914 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1915 let Inst{31-27} = 0b11111;
1916 let Inst{26-23} = 0b0111;
1917 let Inst{22-20} = 0b110;
1918 let Inst{7-4} = 0b0000;
1921 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1922 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1923 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1924 let Inst{31-27} = 0b11111;
1925 let Inst{26-23} = 0b0111;
1926 let Inst{22-20} = 0b110;
1927 let Inst{7-4} = 0b0110;
1929 } // neverHasSideEffects
1931 // Rounding variants of the below included for disassembly only
1933 // Most significant word multiply
1934 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1935 "smmul", "\t$dst, $a, $b",
1936 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
1937 let Inst{31-27} = 0b11111;
1938 let Inst{26-23} = 0b0110;
1939 let Inst{22-20} = 0b101;
1940 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1941 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1944 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1945 "smmulr", "\t$dst, $a, $b", []> {
1946 let Inst{31-27} = 0b11111;
1947 let Inst{26-23} = 0b0110;
1948 let Inst{22-20} = 0b101;
1949 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1950 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1953 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1954 "smmla", "\t$dst, $a, $b, $c",
1955 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
1956 let Inst{31-27} = 0b11111;
1957 let Inst{26-23} = 0b0110;
1958 let Inst{22-20} = 0b101;
1959 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1960 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1963 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1964 "smmlar", "\t$dst, $a, $b, $c", []> {
1965 let Inst{31-27} = 0b11111;
1966 let Inst{26-23} = 0b0110;
1967 let Inst{22-20} = 0b101;
1968 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1969 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1972 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1973 "smmls", "\t$dst, $a, $b, $c",
1974 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
1975 let Inst{31-27} = 0b11111;
1976 let Inst{26-23} = 0b0110;
1977 let Inst{22-20} = 0b110;
1978 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1979 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1982 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1983 "smmlsr", "\t$dst, $a, $b, $c", []> {
1984 let Inst{31-27} = 0b11111;
1985 let Inst{26-23} = 0b0110;
1986 let Inst{22-20} = 0b110;
1987 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1988 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1991 multiclass T2I_smul<string opc, PatFrag opnode> {
1992 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1993 !strconcat(opc, "bb"), "\t$dst, $a, $b",
1994 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2000 let Inst{7-6} = 0b00;
2001 let Inst{5-4} = 0b00;
2004 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2005 !strconcat(opc, "bt"), "\t$dst, $a, $b",
2006 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2012 let Inst{7-6} = 0b00;
2013 let Inst{5-4} = 0b01;
2016 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2017 !strconcat(opc, "tb"), "\t$dst, $a, $b",
2018 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2024 let Inst{7-6} = 0b00;
2025 let Inst{5-4} = 0b10;
2028 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2029 !strconcat(opc, "tt"), "\t$dst, $a, $b",
2030 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2036 let Inst{7-6} = 0b00;
2037 let Inst{5-4} = 0b11;
2040 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2041 !strconcat(opc, "wb"), "\t$dst, $a, $b",
2042 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2048 let Inst{7-6} = 0b00;
2049 let Inst{5-4} = 0b00;
2052 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
2053 !strconcat(opc, "wt"), "\t$dst, $a, $b",
2054 [(set rGPR:$dst, (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} = 0b1111; // Ra = 0b1111 (no accumulate)
2060 let Inst{7-6} = 0b00;
2061 let Inst{5-4} = 0b01;
2066 multiclass T2I_smla<string opc, PatFrag opnode> {
2067 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2068 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2069 [(set rGPR:$dst, (add rGPR:$acc,
2070 (opnode (sext_inreg rGPR:$a, i16),
2071 (sext_inreg rGPR:$b, i16))))]> {
2072 let Inst{31-27} = 0b11111;
2073 let Inst{26-23} = 0b0110;
2074 let Inst{22-20} = 0b001;
2075 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2076 let Inst{7-6} = 0b00;
2077 let Inst{5-4} = 0b00;
2080 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2081 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2082 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
2083 (sra rGPR:$b, (i32 16)))))]> {
2084 let Inst{31-27} = 0b11111;
2085 let Inst{26-23} = 0b0110;
2086 let Inst{22-20} = 0b001;
2087 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2088 let Inst{7-6} = 0b00;
2089 let Inst{5-4} = 0b01;
2092 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2093 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2094 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2095 (sext_inreg rGPR:$b, i16))))]> {
2096 let Inst{31-27} = 0b11111;
2097 let Inst{26-23} = 0b0110;
2098 let Inst{22-20} = 0b001;
2099 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2100 let Inst{7-6} = 0b00;
2101 let Inst{5-4} = 0b10;
2104 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2105 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2106 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2107 (sra rGPR:$b, (i32 16)))))]> {
2108 let Inst{31-27} = 0b11111;
2109 let Inst{26-23} = 0b0110;
2110 let Inst{22-20} = 0b001;
2111 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2112 let Inst{7-6} = 0b00;
2113 let Inst{5-4} = 0b11;
2116 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2117 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2118 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2119 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2120 let Inst{31-27} = 0b11111;
2121 let Inst{26-23} = 0b0110;
2122 let Inst{22-20} = 0b011;
2123 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2124 let Inst{7-6} = 0b00;
2125 let Inst{5-4} = 0b00;
2128 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2129 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2130 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2131 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2132 let Inst{31-27} = 0b11111;
2133 let Inst{26-23} = 0b0110;
2134 let Inst{22-20} = 0b011;
2135 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2136 let Inst{7-6} = 0b00;
2137 let Inst{5-4} = 0b01;
2141 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2142 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2144 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2145 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2146 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2147 [/* For disassembly only; pattern left blank */]>;
2148 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2149 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2150 [/* For disassembly only; pattern left blank */]>;
2151 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2152 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2153 [/* For disassembly only; pattern left blank */]>;
2154 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2155 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2156 [/* For disassembly only; pattern left blank */]>;
2158 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2159 // These are for disassembly only.
2161 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2162 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2163 let Inst{15-12} = 0b1111;
2165 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2166 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2167 let Inst{15-12} = 0b1111;
2169 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2170 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2171 let Inst{15-12} = 0b1111;
2173 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2174 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2175 let Inst{15-12} = 0b1111;
2177 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2178 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2179 "\t$dst, $a, $b, $acc", []>;
2180 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2181 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2182 "\t$dst, $a, $b, $acc", []>;
2183 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2184 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2185 "\t$dst, $a, $b, $acc", []>;
2186 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2187 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2188 "\t$dst, $a, $b, $acc", []>;
2189 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2190 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2191 "\t$ldst, $hdst, $a, $b", []>;
2192 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2193 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2194 "\t$ldst, $hdst, $a, $b", []>;
2195 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2196 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2197 "\t$ldst, $hdst, $a, $b", []>;
2198 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2199 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2200 "\t$ldst, $hdst, $a, $b", []>;
2202 //===----------------------------------------------------------------------===//
2203 // Misc. Arithmetic Instructions.
2206 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2207 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2208 : T2I<oops, iops, itin, opc, asm, pattern> {
2209 let Inst{31-27} = 0b11111;
2210 let Inst{26-22} = 0b01010;
2211 let Inst{21-20} = op1;
2212 let Inst{15-12} = 0b1111;
2213 let Inst{7-6} = 0b10;
2214 let Inst{5-4} = op2;
2217 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2218 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2220 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2221 "rbit", "\t$dst, $src",
2222 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2224 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2225 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2227 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2228 "rev16", ".w\t$dst, $src",
2230 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2231 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2232 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2233 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2235 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2236 "revsh", ".w\t$dst, $src",
2239 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2240 (shl rGPR:$src, (i32 8))), i16))]>;
2242 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2243 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2244 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2245 (and (shl rGPR:$src2, lsl_amt:$sh),
2247 Requires<[HasT2ExtractPack, IsThumb2]> {
2248 let Inst{31-27} = 0b11101;
2249 let Inst{26-25} = 0b01;
2250 let Inst{24-20} = 0b01100;
2251 let Inst{5} = 0; // BT form
2255 // Alternate cases for PKHBT where identities eliminate some nodes.
2256 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2257 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2258 Requires<[HasT2ExtractPack, IsThumb2]>;
2259 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2260 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2261 Requires<[HasT2ExtractPack, IsThumb2]>;
2263 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2264 // will match the pattern below.
2265 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2266 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2267 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2268 (and (sra rGPR:$src2, asr_amt:$sh),
2270 Requires<[HasT2ExtractPack, IsThumb2]> {
2271 let Inst{31-27} = 0b11101;
2272 let Inst{26-25} = 0b01;
2273 let Inst{24-20} = 0b01100;
2274 let Inst{5} = 1; // TB form
2278 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2279 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2280 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2281 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2282 Requires<[HasT2ExtractPack, IsThumb2]>;
2283 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2284 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2285 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2286 Requires<[HasT2ExtractPack, IsThumb2]>;
2288 //===----------------------------------------------------------------------===//
2289 // Comparison Instructions...
2291 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2292 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2293 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2294 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2295 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2296 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2298 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2299 // Compare-to-zero still works out, just not the relationals
2300 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2301 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2302 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2303 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2304 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2306 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2307 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2309 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2310 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2312 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2313 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2314 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2315 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2316 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2317 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2319 // Conditional moves
2320 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2321 // a two-value operand where a dag node expects two operands. :(
2322 let neverHasSideEffects = 1 in {
2323 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2324 "mov", ".w\t$dst, $true",
2325 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2326 RegConstraint<"$false = $dst"> {
2327 let Inst{31-27} = 0b11101;
2328 let Inst{26-25} = 0b01;
2329 let Inst{24-21} = 0b0010;
2330 let Inst{20} = 0; // The S bit.
2331 let Inst{19-16} = 0b1111; // Rn
2332 let Inst{14-12} = 0b000;
2333 let Inst{7-4} = 0b0000;
2336 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2337 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2338 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2339 RegConstraint<"$false = $dst"> {
2340 let Inst{31-27} = 0b11110;
2342 let Inst{24-21} = 0b0010;
2343 let Inst{20} = 0; // The S bit.
2344 let Inst{19-16} = 0b1111; // Rn
2348 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
2350 "movw", "\t$dst, $src", []>,
2351 RegConstraint<"$false = $dst"> {
2352 let Inst{31-27} = 0b11110;
2354 let Inst{24-21} = 0b0010;
2355 let Inst{20} = 0; // The S bit.
2359 def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
2360 (ins rGPR:$false, i32imm:$src, pred:$p),
2361 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">;
2363 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2364 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2365 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
2366 imm:$cc, CCR:$ccr))*/]>,
2367 RegConstraint<"$false = $dst"> {
2368 let Inst{31-27} = 0b11110;
2370 let Inst{24-21} = 0b0011;
2371 let Inst{20} = 0; // The S bit.
2372 let Inst{19-16} = 0b1111; // Rn
2376 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2377 string opc, string asm, list<dag> pattern>
2378 : T2I<oops, iops, itin, opc, asm, pattern> {
2379 let Inst{31-27} = 0b11101;
2380 let Inst{26-25} = 0b01;
2381 let Inst{24-21} = 0b0010;
2382 let Inst{20} = 0; // The S bit.
2383 let Inst{19-16} = 0b1111; // Rn
2384 let Inst{5-4} = opcod; // Shift type.
2386 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2387 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2388 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2389 RegConstraint<"$false = $dst">;
2390 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2391 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2392 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2393 RegConstraint<"$false = $dst">;
2394 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2395 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2396 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2397 RegConstraint<"$false = $dst">;
2398 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2399 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2400 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2401 RegConstraint<"$false = $dst">;
2402 } // neverHasSideEffects
2404 //===----------------------------------------------------------------------===//
2405 // Atomic operations intrinsics
2408 // memory barriers protect the atomic sequences
2409 let hasSideEffects = 1 in {
2410 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2411 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2412 Requires<[IsThumb, HasDB]> {
2414 let Inst{31-4} = 0xf3bf8f5;
2415 let Inst{3-0} = opt;
2419 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2421 [/* For disassembly only; pattern left blank */]>,
2422 Requires<[IsThumb, HasDB]> {
2424 let Inst{31-4} = 0xf3bf8f4;
2425 let Inst{3-0} = opt;
2428 // ISB has only full system option -- for disassembly only
2429 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2430 [/* For disassembly only; pattern left blank */]>,
2431 Requires<[IsThumb2, HasV7]> {
2432 let Inst{31-4} = 0xf3bf8f6;
2433 let Inst{3-0} = 0b1111;
2436 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2437 InstrItinClass itin, string opc, string asm, string cstr,
2438 list<dag> pattern, bits<4> rt2 = 0b1111>
2439 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2440 let Inst{31-27} = 0b11101;
2441 let Inst{26-20} = 0b0001101;
2442 let Inst{11-8} = rt2;
2443 let Inst{7-6} = 0b01;
2444 let Inst{5-4} = opcod;
2445 let Inst{3-0} = 0b1111;
2447 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2448 InstrItinClass itin, string opc, string asm, string cstr,
2449 list<dag> pattern, bits<4> rt2 = 0b1111>
2450 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2451 let Inst{31-27} = 0b11101;
2452 let Inst{26-20} = 0b0001100;
2453 let Inst{11-8} = rt2;
2454 let Inst{7-6} = 0b01;
2455 let Inst{5-4} = opcod;
2458 let mayLoad = 1 in {
2459 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2460 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2462 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2463 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2465 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2466 Size4Bytes, NoItinerary,
2467 "ldrex", "\t$dest, [$ptr]", "",
2469 let Inst{31-27} = 0b11101;
2470 let Inst{26-20} = 0b0000101;
2471 let Inst{11-8} = 0b1111;
2472 let Inst{7-0} = 0b00000000; // imm8 = 0
2474 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2475 AddrModeNone, Size4Bytes, NoItinerary,
2476 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2480 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2481 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2482 AddrModeNone, Size4Bytes, NoItinerary,
2483 "strexb", "\t$success, $src, [$ptr]", "", []>;
2484 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2485 AddrModeNone, Size4Bytes, NoItinerary,
2486 "strexh", "\t$success, $src, [$ptr]", "", []>;
2487 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2488 AddrModeNone, Size4Bytes, NoItinerary,
2489 "strex", "\t$success, $src, [$ptr]", "",
2491 let Inst{31-27} = 0b11101;
2492 let Inst{26-20} = 0b0000100;
2493 let Inst{7-0} = 0b00000000; // imm8 = 0
2495 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2496 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2497 AddrModeNone, Size4Bytes, NoItinerary,
2498 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2502 // Clear-Exclusive is for disassembly only.
2503 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2504 [/* For disassembly only; pattern left blank */]>,
2505 Requires<[IsARM, HasV7]> {
2506 let Inst{31-20} = 0xf3b;
2507 let Inst{15-14} = 0b10;
2509 let Inst{7-4} = 0b0010;
2512 //===----------------------------------------------------------------------===//
2516 // __aeabi_read_tp preserves the registers r1-r3.
2518 Defs = [R0, R12, LR, CPSR] in {
2519 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2520 "bl\t__aeabi_read_tp",
2521 [(set R0, ARMthread_pointer)]> {
2522 let Inst{31-27} = 0b11110;
2523 let Inst{15-14} = 0b11;
2528 //===----------------------------------------------------------------------===//
2529 // SJLJ Exception handling intrinsics
2530 // eh_sjlj_setjmp() is an instruction sequence to store the return
2531 // address and save #0 in R0 for the non-longjmp case.
2532 // Since by its nature we may be coming from some other function to get
2533 // here, and we're using the stack frame for the containing function to
2534 // save/restore registers, we can't keep anything live in regs across
2535 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2536 // when we get here from a longjmp(). We force everthing out of registers
2537 // except for our own input by listing the relevant registers in Defs. By
2538 // doing so, we also cause the prologue/epilogue code to actively preserve
2539 // all of the callee-saved resgisters, which is exactly what we want.
2540 // $val is a scratch register for our use.
2542 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2543 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2544 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2545 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2546 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2547 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2548 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2549 Requires<[IsThumb2, HasVFP2]>;
2553 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2554 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2555 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2556 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2557 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2558 Requires<[IsThumb2, NoVFP]>;
2562 //===----------------------------------------------------------------------===//
2563 // Control-Flow Instructions
2566 // FIXME: remove when we have a way to marking a MI with these properties.
2567 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2569 // FIXME: Should pc be an implicit operand like PICADD, etc?
2570 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2571 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2572 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
2573 reglist:$dsts, variable_ops),
2575 "ldm${amode}${p}.w\t$Rn!, $dsts",
2577 let Inst{31-27} = 0b11101;
2578 let Inst{26-25} = 0b00;
2579 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2581 let Inst{21} = 1; // The W bit.
2582 let Inst{20} = 1; // Load
2585 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2586 let isPredicable = 1 in
2587 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2589 [(br bb:$target)]> {
2590 let Inst{31-27} = 0b11110;
2591 let Inst{15-14} = 0b10;
2595 let isNotDuplicable = 1, isIndirectBranch = 1,
2596 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
2599 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2600 IIC_Br, "mov\tpc, $target$jt",
2601 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2602 let Inst{31-27} = 0b11101;
2603 let Inst{26-20} = 0b0100100;
2604 let Inst{19-16} = 0b1111;
2605 let Inst{14-12} = 0b000;
2606 let Inst{11-8} = 0b1111; // Rd = pc
2607 let Inst{7-4} = 0b0000;
2610 // FIXME: Add a non-pc based case that can be predicated.
2611 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2614 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2615 IIC_Br, "tbb\t$index$jt", []> {
2616 let Inst{31-27} = 0b11101;
2617 let Inst{26-20} = 0b0001101;
2618 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2619 let Inst{15-8} = 0b11110000;
2620 let Inst{7-4} = 0b0000; // B form
2623 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2626 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2627 IIC_Br, "tbh\t$index$jt", []> {
2628 let Inst{31-27} = 0b11101;
2629 let Inst{26-20} = 0b0001101;
2630 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2631 let Inst{15-8} = 0b11110000;
2632 let Inst{7-4} = 0b0001; // H form
2635 // Generic versions of the above two instructions, for disassembly only
2637 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2638 "tbb", "\t[$a, $b]", []>{
2639 let Inst{31-27} = 0b11101;
2640 let Inst{26-20} = 0b0001101;
2641 let Inst{15-8} = 0b11110000;
2642 let Inst{7-4} = 0b0000; // B form
2645 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2646 "tbh", "\t[$a, $b, lsl #1]", []> {
2647 let Inst{31-27} = 0b11101;
2648 let Inst{26-20} = 0b0001101;
2649 let Inst{15-8} = 0b11110000;
2650 let Inst{7-4} = 0b0001; // H form
2652 } // isNotDuplicable, isIndirectBranch
2654 } // isBranch, isTerminator, isBarrier
2656 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2657 // a two-value operand where a dag node expects two operands. :(
2658 let isBranch = 1, isTerminator = 1 in
2659 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2661 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2662 let Inst{31-27} = 0b11110;
2663 let Inst{15-14} = 0b10;
2669 let Defs = [ITSTATE] in
2670 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2671 AddrModeNone, Size2Bytes, IIC_iALUx,
2672 "it$mask\t$cc", "", []> {
2673 // 16-bit instruction.
2674 let Inst{31-16} = 0x0000;
2675 let Inst{15-8} = 0b10111111;
2678 // Branch and Exchange Jazelle -- for disassembly only
2680 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2681 [/* For disassembly only; pattern left blank */]> {
2682 let Inst{31-27} = 0b11110;
2684 let Inst{25-20} = 0b111100;
2685 let Inst{15-14} = 0b10;
2689 // Change Processor State is a system instruction -- for disassembly only.
2690 // The singleton $opt operand contains the following information:
2691 // opt{4-0} = mode from Inst{4-0}
2692 // opt{5} = changemode from Inst{17}
2693 // opt{8-6} = AIF from Inst{8-6}
2694 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2695 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2696 [/* For disassembly only; pattern left blank */]> {
2697 let Inst{31-27} = 0b11110;
2699 let Inst{25-20} = 0b111010;
2700 let Inst{15-14} = 0b10;
2704 // A6.3.4 Branches and miscellaneous control
2705 // Table A6-14 Change Processor State, and hint instructions
2706 // Helper class for disassembly only.
2707 class T2I_hint<bits<8> op7_0, string opc, string asm>
2708 : T2I<(outs), (ins), NoItinerary, opc, asm,
2709 [/* For disassembly only; pattern left blank */]> {
2710 let Inst{31-20} = 0xf3a;
2711 let Inst{15-14} = 0b10;
2713 let Inst{10-8} = 0b000;
2714 let Inst{7-0} = op7_0;
2717 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2718 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2719 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2720 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2721 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2723 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2724 [/* For disassembly only; pattern left blank */]> {
2725 let Inst{31-20} = 0xf3a;
2726 let Inst{15-14} = 0b10;
2728 let Inst{10-8} = 0b000;
2729 let Inst{7-4} = 0b1111;
2732 // Secure Monitor Call is a system instruction -- for disassembly only
2733 // Option = Inst{19-16}
2734 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2735 [/* For disassembly only; pattern left blank */]> {
2736 let Inst{31-27} = 0b11110;
2737 let Inst{26-20} = 0b1111111;
2738 let Inst{15-12} = 0b1000;
2741 // Store Return State is a system instruction -- for disassembly only
2742 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2743 [/* For disassembly only; pattern left blank */]> {
2744 let Inst{31-27} = 0b11101;
2745 let Inst{26-20} = 0b0000010; // W = 1
2748 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2749 [/* For disassembly only; pattern left blank */]> {
2750 let Inst{31-27} = 0b11101;
2751 let Inst{26-20} = 0b0000000; // W = 0
2754 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2755 [/* For disassembly only; pattern left blank */]> {
2756 let Inst{31-27} = 0b11101;
2757 let Inst{26-20} = 0b0011010; // W = 1
2760 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2761 [/* For disassembly only; pattern left blank */]> {
2762 let Inst{31-27} = 0b11101;
2763 let Inst{26-20} = 0b0011000; // W = 0
2766 // Return From Exception is a system instruction -- for disassembly only
2767 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2768 [/* For disassembly only; pattern left blank */]> {
2769 let Inst{31-27} = 0b11101;
2770 let Inst{26-20} = 0b0000011; // W = 1
2773 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2774 [/* For disassembly only; pattern left blank */]> {
2775 let Inst{31-27} = 0b11101;
2776 let Inst{26-20} = 0b0000001; // W = 0
2779 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2780 [/* For disassembly only; pattern left blank */]> {
2781 let Inst{31-27} = 0b11101;
2782 let Inst{26-20} = 0b0011011; // W = 1
2785 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2786 [/* For disassembly only; pattern left blank */]> {
2787 let Inst{31-27} = 0b11101;
2788 let Inst{26-20} = 0b0011001; // W = 0
2791 //===----------------------------------------------------------------------===//
2792 // Non-Instruction Patterns
2795 // Two piece so_imms.
2796 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2797 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2798 (t2_so_imm2part_2 imm:$RHS))>;
2799 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2800 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2801 (t2_so_imm2part_2 imm:$RHS))>;
2802 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2803 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2804 (t2_so_imm2part_2 imm:$RHS))>;
2805 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2806 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2807 (t2_so_neg_imm2part_2 imm:$RHS))>;
2809 // 32-bit immediate using movw + movt.
2810 // This is a single pseudo instruction to make it re-materializable.
2811 // FIXME: Remove this when we can do generalized remat.
2812 let isReMaterializable = 1 in
2813 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
2814 "", [(set rGPR:$dst, (i32 imm:$src))]>,
2815 Requires<[IsThumb, HasV6T2]>;
2817 // ConstantPool, GlobalAddress, and JumpTable
2818 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2819 Requires<[IsThumb2, DontUseMovt]>;
2820 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2821 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2822 Requires<[IsThumb2, UseMovt]>;
2824 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2825 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2827 // Pseudo instruction that combines ldr from constpool and add pc. This should
2828 // be expanded into two instructions late to allow if-conversion and
2830 let canFoldAsLoad = 1, isReMaterializable = 1 in
2831 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2833 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2835 Requires<[IsThumb2]>;
2837 //===----------------------------------------------------------------------===//
2838 // Move between special register and ARM core register -- for disassembly only
2842 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2843 [/* For disassembly only; pattern left blank */]> {
2844 let Inst{31-27} = 0b11110;
2846 let Inst{25-21} = 0b11111;
2847 let Inst{20} = 0; // The R bit.
2848 let Inst{15-14} = 0b10;
2853 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2854 [/* For disassembly only; pattern left blank */]> {
2855 let Inst{31-27} = 0b11110;
2857 let Inst{25-21} = 0b11111;
2858 let Inst{20} = 1; // The R bit.
2859 let Inst{15-14} = 0b10;
2864 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2865 "\tcpsr$mask, $src",
2866 [/* For disassembly only; pattern left blank */]> {
2867 let Inst{31-27} = 0b11110;
2869 let Inst{25-21} = 0b11100;
2870 let Inst{20} = 0; // The R bit.
2871 let Inst{15-14} = 0b10;
2876 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2877 "\tspsr$mask, $src",
2878 [/* For disassembly only; pattern left blank */]> {
2879 let Inst{31-27} = 0b11110;
2881 let Inst{25-21} = 0b11100;
2882 let Inst{20} = 1; // The R bit.
2883 let Inst{15-14} = 0b10;