1 //===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Thumb2 instruction set.
12 //===----------------------------------------------------------------------===//
14 // IT block predicate field
15 def it_pred : Operand<i32> {
16 let PrintMethod = "printMandatoryPredicateOperand";
19 // IT block condition mask
20 def it_mask : Operand<i32> {
21 let PrintMethod = "printThumbITMask";
24 // Table branch address
25 def tb_addrmode : Operand<i32> {
26 let PrintMethod = "printTBAddrMode";
29 // Shifted operands. No register controlled shifts for Thumb2.
30 // Note: We do not support rrx shifted operands yet.
31 def t2_so_reg : Operand<i32>, // reg imm
32 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
34 string EncoderMethod = "getT2SORegOpValue";
35 let PrintMethod = "printT2SOOperand";
36 let MIOperandInfo = (ops rGPR, i32imm);
39 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
40 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
41 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
44 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
45 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
46 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
49 // t2_so_imm - Match a 32-bit immediate operand, which is an
50 // 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
51 // immediate splatted into multiple bytes of the word. t2_so_imm values are
52 // represented in the imm field in the same 12-bit form that they are encoded
53 // into t2_so_imm instructions: the 8-bit immediate is the least significant
54 // bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
55 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
56 string EncoderMethod = "getT2SOImmOpValue";
59 // t2_so_imm_not - Match an immediate that is a complement
61 def t2_so_imm_not : Operand<i32>,
63 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64 }], t2_so_imm_not_XFORM>;
66 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67 def t2_so_imm_neg : Operand<i32>,
69 return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
70 }], t2_so_imm_neg_XFORM>;
72 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
73 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74 // to get the first/second pieces.
75 def t2_so_imm2part : Operand<i32>,
77 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
81 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83 return CurDAG->getTargetConstant(V, MVT::i32);
86 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88 return CurDAG->getTargetConstant(V, MVT::i32);
91 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
96 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98 return CurDAG->getTargetConstant(V, MVT::i32);
101 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103 return CurDAG->getTargetConstant(V, MVT::i32);
106 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107 def imm1_31 : PatLeaf<(i32 imm), [{
108 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
111 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
112 def imm0_4095 : Operand<i32>,
113 PatLeaf<(i32 imm), [{
114 return (uint32_t)N->getZExtValue() < 4096;
117 def imm0_4095_neg : PatLeaf<(i32 imm), [{
118 return (uint32_t)(-N->getZExtValue()) < 4096;
121 def imm0_255_neg : PatLeaf<(i32 imm), [{
122 return (uint32_t)(-N->getZExtValue()) < 255;
125 def imm0_255_not : PatLeaf<(i32 imm), [{
126 return (uint32_t)(~N->getZExtValue()) < 255;
129 // Define Thumb2 specific addressing modes.
131 // t2addrmode_imm12 := reg + imm12
132 def t2addrmode_imm12 : Operand<i32>,
133 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
134 let PrintMethod = "printAddrModeImm12Operand";
135 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
138 // t2addrmode_imm8 := reg +/- imm8
139 def t2addrmode_imm8 : Operand<i32>,
140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
141 let PrintMethod = "printT2AddrModeImm8Operand";
142 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
145 def t2am_imm8_offset : Operand<i32>,
146 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
147 [], [SDNPWantRoot]> {
148 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
151 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
152 def t2addrmode_imm8s4 : Operand<i32> {
153 let PrintMethod = "printT2AddrModeImm8s4Operand";
154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
157 def t2am_imm8s4_offset : Operand<i32> {
158 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
161 // t2addrmode_so_reg := reg + (reg << imm2)
162 def t2addrmode_so_reg : Operand<i32>,
163 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
164 let PrintMethod = "printT2AddrModeSoRegOperand";
165 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
169 //===----------------------------------------------------------------------===//
170 // Multiclass helpers...
173 class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
174 string opc, string asm, list<dag> pattern>
175 : 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 : T2TwoRegImm<
266 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
267 opc, "\t$Rd, $Rn, $imm",
268 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> {
269 let Inst{31-27} = 0b11110;
271 let Inst{24-21} = opcod;
272 let Inst{20} = ?; // The S bit.
277 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
278 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
279 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> {
280 let isCommutable = Commutable;
281 let Inst{31-27} = 0b11101;
282 let Inst{26-25} = 0b01;
283 let Inst{24-21} = opcod;
284 let Inst{20} = ?; // The S bit.
285 let Inst{14-12} = 0b000; // imm3
286 let Inst{7-6} = 0b00; // imm2
287 let Inst{5-4} = 0b00; // type
290 def rs : T2TwoRegShiftedReg<
291 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
292 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
293 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> {
294 let Inst{31-27} = 0b11101;
295 let Inst{26-25} = 0b01;
296 let Inst{24-21} = opcod;
297 let Inst{20} = ?; // The S bit.
301 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
302 // the ".w" prefix to indicate that they are wide.
303 multiclass T2I_bin_w_irs<bits<4> opcod, string opc,
304 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
305 PatFrag opnode, bit Commutable = 0> :
306 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">;
308 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
309 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
310 /// it is equivalent to the T2I_bin_irs counterpart.
311 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
313 def ri : T2TwoRegImm<
314 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
315 opc, ".w\t$Rd, $imm, $Rn",
316 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
317 let Inst{31-27} = 0b11110;
319 let Inst{24-21} = opcod;
320 let Inst{20} = ?; // The S bit.
324 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
325 opc, "\t$Rd, $Rm, $Rn",
326 [/* For disassembly only; pattern left blank */]> {
327 let Inst{31-27} = 0b11101;
328 let Inst{26-25} = 0b01;
329 let Inst{24-21} = opcod;
330 let Inst{20} = ?; // The S bit.
331 let Inst{14-12} = 0b000; // imm3
332 let Inst{7-6} = 0b00; // imm2
333 let Inst{5-4} = 0b00; // type
336 def rs : T2TwoRegShiftedReg<
337 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
338 IIC_iALUsir, opc, "\t$Rd, $ShiftedRm, $Rn",
339 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
340 let Inst{31-27} = 0b11101;
341 let Inst{26-25} = 0b01;
342 let Inst{24-21} = opcod;
343 let Inst{20} = ?; // The S bit.
347 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
348 /// instruction modifies the CPSR register.
349 let Defs = [CPSR] in {
350 multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
351 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
352 PatFrag opnode, bit Commutable = 0> {
354 def ri : T2TwoRegImm<(outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
355 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
356 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
357 let Inst{31-27} = 0b11110;
359 let Inst{24-21} = opcod;
360 let Inst{20} = 1; // The S bit.
364 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
365 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
366 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
367 let isCommutable = Commutable;
368 let Inst{31-27} = 0b11101;
369 let Inst{26-25} = 0b01;
370 let Inst{24-21} = opcod;
371 let Inst{20} = 1; // The S bit.
372 let Inst{14-12} = 0b000; // imm3
373 let Inst{7-6} = 0b00; // imm2
374 let Inst{5-4} = 0b00; // type
377 def rs : T2TwoRegShiftedReg<
378 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
379 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
380 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
381 let Inst{31-27} = 0b11101;
382 let Inst{26-25} = 0b01;
383 let Inst{24-21} = opcod;
384 let Inst{20} = 1; // The S bit.
389 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
390 /// patterns for a binary operation that produces a value.
391 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
392 bit Commutable = 0> {
394 // The register-immediate version is re-materializable. This is useful
395 // in particular for taking the address of a local.
396 let isReMaterializable = 1 in {
397 def ri : T2TwoRegImm<
398 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
399 opc, ".w\t$Rd, $Rn, $imm",
400 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
401 let Inst{31-27} = 0b11110;
404 let Inst{23-21} = op23_21;
405 let Inst{20} = 0; // The S bit.
410 def ri12 : T2TwoRegImm<
411 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
412 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
413 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> {
414 let Inst{31-27} = 0b11110;
417 let Inst{23-21} = op23_21;
418 let Inst{20} = 0; // The S bit.
422 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr,
423 opc, ".w\t$Rd, $Rn, $Rm",
424 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> {
425 let isCommutable = Commutable;
426 let Inst{31-27} = 0b11101;
427 let Inst{26-25} = 0b01;
429 let Inst{23-21} = op23_21;
430 let Inst{20} = 0; // The S bit.
431 let Inst{14-12} = 0b000; // imm3
432 let Inst{7-6} = 0b00; // imm2
433 let Inst{5-4} = 0b00; // type
436 def rs : T2TwoRegShiftedReg<
437 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm),
438 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
439 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
440 let Inst{31-27} = 0b11101;
441 let Inst{26-25} = 0b01;
443 let Inst{23-21} = op23_21;
444 let Inst{20} = 0; // The S bit.
448 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
449 /// for a binary operation that produces a value and use the carry
450 /// bit. It's not predicable.
451 let Uses = [CPSR] in {
452 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
453 bit Commutable = 0> {
455 def ri : T2TwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
456 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
457 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
458 Requires<[IsThumb2]> {
459 let Inst{31-27} = 0b11110;
461 let Inst{24-21} = opcod;
462 let Inst{20} = 0; // The S bit.
466 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
467 opc, ".w\t$Rd, $Rn, $Rm",
468 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
469 Requires<[IsThumb2]> {
470 let isCommutable = Commutable;
471 let Inst{31-27} = 0b11101;
472 let Inst{26-25} = 0b01;
473 let Inst{24-21} = opcod;
474 let Inst{20} = 0; // The S bit.
475 let Inst{14-12} = 0b000; // imm3
476 let Inst{7-6} = 0b00; // imm2
477 let Inst{5-4} = 0b00; // type
480 def rs : T2TwoRegShiftedReg<
481 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
482 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
483 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
484 Requires<[IsThumb2]> {
485 let Inst{31-27} = 0b11101;
486 let Inst{26-25} = 0b01;
487 let Inst{24-21} = opcod;
488 let Inst{20} = 0; // The S bit.
492 // Carry setting variants
493 let Defs = [CPSR] in {
494 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
495 bit Commutable = 0> {
497 def ri : T2TwoRegImm<
498 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
499 opc, "\t$Rd, $Rn, $imm",
500 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
501 Requires<[IsThumb2]> {
502 let Inst{31-27} = 0b11110;
504 let Inst{24-21} = opcod;
505 let Inst{20} = 1; // The S bit.
509 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
510 opc, ".w\t$Rd, $Rn, $Rm",
511 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
512 Requires<[IsThumb2]> {
513 let isCommutable = Commutable;
514 let Inst{31-27} = 0b11101;
515 let Inst{26-25} = 0b01;
516 let Inst{24-21} = opcod;
517 let Inst{20} = 1; // The S bit.
518 let Inst{14-12} = 0b000; // imm3
519 let Inst{7-6} = 0b00; // imm2
520 let Inst{5-4} = 0b00; // type
523 def rs : T2TwoRegShiftedReg<
524 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
525 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
526 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
527 Requires<[IsThumb2]> {
528 let Inst{31-27} = 0b11101;
529 let Inst{26-25} = 0b01;
530 let Inst{24-21} = opcod;
531 let Inst{20} = 1; // The S bit.
537 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
538 /// version is not needed since this is only for codegen.
539 let Defs = [CPSR] in {
540 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
542 def ri : T2TwoRegImm<
543 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
544 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
545 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
546 let Inst{31-27} = 0b11110;
548 let Inst{24-21} = opcod;
549 let Inst{20} = 1; // The S bit.
553 def rs : T2TwoRegShiftedReg<
554 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
555 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
556 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
557 let Inst{31-27} = 0b11101;
558 let Inst{26-25} = 0b01;
559 let Inst{24-21} = opcod;
560 let Inst{20} = 1; // The S bit.
565 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
566 // rotate operation that produces a value.
567 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
569 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
570 opc, ".w\t$dst, $lhs, $rhs",
571 [(set rGPR:$dst, (opnode rGPR:$lhs, imm1_31:$rhs))]> {
572 let Inst{31-27} = 0b11101;
573 let Inst{26-21} = 0b010010;
574 let Inst{19-16} = 0b1111; // Rn
575 let Inst{5-4} = opcod;
578 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iMOVsr,
579 opc, ".w\t$dst, $lhs, $rhs",
580 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
581 let Inst{31-27} = 0b11111;
582 let Inst{26-23} = 0b0100;
583 let Inst{22-21} = opcod;
584 let Inst{15-12} = 0b1111;
585 let Inst{7-4} = 0b0000;
589 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
590 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
591 /// a explicit result, only implicitly set CPSR.
592 let isCompare = 1, Defs = [CPSR] in {
593 multiclass T2I_cmp_irs<bits<4> opcod, string opc,
594 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
597 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), iii,
598 opc, ".w\t$lhs, $rhs",
599 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
600 let Inst{31-27} = 0b11110;
602 let Inst{24-21} = opcod;
603 let Inst{20} = 1; // The S bit.
605 let Inst{11-8} = 0b1111; // Rd
608 def rr : T2I<(outs), (ins GPR:$lhs, rGPR:$rhs), iir,
609 opc, ".w\t$lhs, $rhs",
610 [(opnode GPR:$lhs, rGPR:$rhs)]> {
611 let Inst{31-27} = 0b11101;
612 let Inst{26-25} = 0b01;
613 let Inst{24-21} = opcod;
614 let Inst{20} = 1; // The S bit.
615 let Inst{14-12} = 0b000; // imm3
616 let Inst{11-8} = 0b1111; // Rd
617 let Inst{7-6} = 0b00; // imm2
618 let Inst{5-4} = 0b00; // type
621 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), iis,
622 opc, ".w\t$lhs, $rhs",
623 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
624 let Inst{31-27} = 0b11101;
625 let Inst{26-25} = 0b01;
626 let Inst{24-21} = opcod;
627 let Inst{20} = 1; // The S bit.
628 let Inst{11-8} = 0b1111; // Rd
633 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
634 multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
635 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
636 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii,
637 opc, ".w\t$dst, $addr",
638 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
639 let Inst{31-27} = 0b11111;
640 let Inst{26-25} = 0b00;
641 let Inst{24} = signed;
643 let Inst{22-21} = opcod;
644 let Inst{20} = 1; // load
646 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii,
647 opc, "\t$dst, $addr",
648 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
649 let Inst{31-27} = 0b11111;
650 let Inst{26-25} = 0b00;
651 let Inst{24} = signed;
653 let Inst{22-21} = opcod;
654 let Inst{20} = 1; // load
656 // Offset: index==TRUE, wback==FALSE
657 let Inst{10} = 1; // The P bit.
658 let Inst{8} = 0; // The W bit.
660 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis,
661 opc, ".w\t$dst, $addr",
662 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
663 let Inst{31-27} = 0b11111;
664 let Inst{26-25} = 0b00;
665 let Inst{24} = signed;
667 let Inst{22-21} = opcod;
668 let Inst{20} = 1; // load
669 let Inst{11-6} = 0b000000;
672 // FIXME: Is the pci variant actually needed?
673 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii,
674 opc, ".w\t$dst, $addr",
675 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
676 let isReMaterializable = 1;
677 let Inst{31-27} = 0b11111;
678 let Inst{26-25} = 0b00;
679 let Inst{24} = signed;
680 let Inst{23} = ?; // add = (U == '1')
681 let Inst{22-21} = opcod;
682 let Inst{20} = 1; // load
683 let Inst{19-16} = 0b1111; // Rn
687 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
688 multiclass T2I_st<bits<2> opcod, string opc,
689 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> {
690 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii,
691 opc, ".w\t$src, $addr",
692 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
693 let Inst{31-27} = 0b11111;
694 let Inst{26-23} = 0b0001;
695 let Inst{22-21} = opcod;
696 let Inst{20} = 0; // !load
698 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii,
699 opc, "\t$src, $addr",
700 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
701 let Inst{31-27} = 0b11111;
702 let Inst{26-23} = 0b0000;
703 let Inst{22-21} = opcod;
704 let Inst{20} = 0; // !load
706 // Offset: index==TRUE, wback==FALSE
707 let Inst{10} = 1; // The P bit.
708 let Inst{8} = 0; // The W bit.
710 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis,
711 opc, ".w\t$src, $addr",
712 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
713 let Inst{31-27} = 0b11111;
714 let Inst{26-23} = 0b0000;
715 let Inst{22-21} = opcod;
716 let Inst{20} = 0; // !load
717 let Inst{11-6} = 0b000000;
721 /// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
722 /// register and one whose operand is a register rotated by 8/16/24.
723 multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
724 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
725 opc, ".w\t$dst, $src",
726 [(set rGPR:$dst, (opnode rGPR:$src))]> {
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} = 0b00; // rotate
735 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
736 opc, ".w\t$dst, $src, ror $rot",
737 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]> {
738 let Inst{31-27} = 0b11111;
739 let Inst{26-23} = 0b0100;
740 let Inst{22-20} = opcod;
741 let Inst{19-16} = 0b1111; // Rn
742 let Inst{15-12} = 0b1111;
744 let Inst{5-4} = {?,?}; // rotate
748 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
749 multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
750 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
752 [(set rGPR:$dst, (opnode rGPR:$src))]>,
753 Requires<[HasT2ExtractPack, IsThumb2]> {
754 let Inst{31-27} = 0b11111;
755 let Inst{26-23} = 0b0100;
756 let Inst{22-20} = opcod;
757 let Inst{19-16} = 0b1111; // Rn
758 let Inst{15-12} = 0b1111;
760 let Inst{5-4} = 0b00; // rotate
762 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
763 opc, "\t$dst, $src, ror $rot",
764 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]>,
765 Requires<[HasT2ExtractPack, IsThumb2]> {
766 let Inst{31-27} = 0b11111;
767 let Inst{26-23} = 0b0100;
768 let Inst{22-20} = opcod;
769 let Inst{19-16} = 0b1111; // Rn
770 let Inst{15-12} = 0b1111;
772 let Inst{5-4} = {?,?}; // rotate
776 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
778 multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> {
779 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iEXTr,
780 opc, "\t$dst, $src", []> {
781 let Inst{31-27} = 0b11111;
782 let Inst{26-23} = 0b0100;
783 let Inst{22-20} = opcod;
784 let Inst{19-16} = 0b1111; // Rn
785 let Inst{15-12} = 0b1111;
787 let Inst{5-4} = 0b00; // rotate
789 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iEXTr,
790 opc, "\t$dst, $src, ror $rot", []> {
791 let Inst{31-27} = 0b11111;
792 let Inst{26-23} = 0b0100;
793 let Inst{22-20} = opcod;
794 let Inst{19-16} = 0b1111; // Rn
795 let Inst{15-12} = 0b1111;
797 let Inst{5-4} = {?,?}; // rotate
801 /// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
802 /// register and one whose operand is a register rotated by 8/16/24.
803 multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
804 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
805 opc, "\t$dst, $LHS, $RHS",
806 [(set rGPR:$dst, (opnode rGPR:$LHS, rGPR:$RHS))]>,
807 Requires<[HasT2ExtractPack, IsThumb2]> {
808 let Inst{31-27} = 0b11111;
809 let Inst{26-23} = 0b0100;
810 let Inst{22-20} = opcod;
811 let Inst{15-12} = 0b1111;
813 let Inst{5-4} = 0b00; // rotate
815 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
816 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
817 [(set rGPR:$dst, (opnode rGPR:$LHS,
818 (rotr rGPR:$RHS, rot_imm:$rot)))]>,
819 Requires<[HasT2ExtractPack, IsThumb2]> {
820 let Inst{31-27} = 0b11111;
821 let Inst{26-23} = 0b0100;
822 let Inst{22-20} = opcod;
823 let Inst{15-12} = 0b1111;
825 let Inst{5-4} = {?,?}; // rotate
829 // DO variant - disassembly only, no pattern
831 multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
832 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iEXTAr,
833 opc, "\t$dst, $LHS, $RHS", []> {
834 let Inst{31-27} = 0b11111;
835 let Inst{26-23} = 0b0100;
836 let Inst{22-20} = opcod;
837 let Inst{15-12} = 0b1111;
839 let Inst{5-4} = 0b00; // rotate
841 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
842 IIC_iEXTAsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
843 let Inst{31-27} = 0b11111;
844 let Inst{26-23} = 0b0100;
845 let Inst{22-20} = opcod;
846 let Inst{15-12} = 0b1111;
848 let Inst{5-4} = {?,?}; // rotate
852 //===----------------------------------------------------------------------===//
854 //===----------------------------------------------------------------------===//
856 //===----------------------------------------------------------------------===//
857 // Miscellaneous Instructions.
860 // LEApcrel - Load a pc-relative address into a register without offending the
862 let neverHasSideEffects = 1 in {
863 let isReMaterializable = 1 in
864 def t2LEApcrel : T2XI<(outs rGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
865 "adr${p}.w\t$dst, #$label", []> {
866 let Inst{31-27} = 0b11110;
867 let Inst{25-24} = 0b10;
868 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
871 let Inst{19-16} = 0b1111; // Rn
874 } // neverHasSideEffects
875 def t2LEApcrelJT : T2XI<(outs rGPR:$dst),
876 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
877 "adr${p}.w\t$dst, #${label}_${id}", []> {
878 let Inst{31-27} = 0b11110;
879 let Inst{25-24} = 0b10;
880 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
883 let Inst{19-16} = 0b1111; // Rn
887 // ADD r, sp, {so_imm|i12}
888 def t2ADDrSPi : T2TwoRegImm<
889 (outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm),
890 IIC_iALUi, "add", ".w\t$Rn, $Rn, $imm", []> {
891 let Inst{31-27} = 0b11110;
893 let Inst{24-21} = 0b1000;
894 let Inst{20} = ?; // The S bit.
895 let Inst{19-16} = 0b1101;
898 def t2ADDrSPi12 : T2TwoRegImm<
899 (outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm),
900 IIC_iALUi, "addw", "\t$Rd, $Rn, $imm", []> {
901 let Inst{31-27} = 0b11110;
903 let Inst{24-21} = 0b0000;
904 let Inst{20} = 0; // The S bit.
905 let Inst{19-16} = 0b1101; // Rn = sp
910 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
911 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
912 let Inst{31-27} = 0b11101;
913 let Inst{26-25} = 0b01;
914 let Inst{24-21} = 0b1000;
915 let Inst{20} = ?; // The S bit.
916 let Inst{19-16} = 0b1101; // Rn = sp
920 // SUB r, sp, {so_imm|i12}
921 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
922 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
923 let Inst{31-27} = 0b11110;
925 let Inst{24-21} = 0b1101;
926 let Inst{20} = ?; // The S bit.
927 let Inst{19-16} = 0b1101; // Rn = sp
930 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
931 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
932 let Inst{31-27} = 0b11110;
934 let Inst{24-21} = 0b0101;
935 let Inst{20} = 0; // The S bit.
936 let Inst{19-16} = 0b1101; // Rn = sp
941 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
943 "sub", "\t$dst, $sp, $rhs", []> {
944 let Inst{31-27} = 0b11101;
945 let Inst{26-25} = 0b01;
946 let Inst{24-21} = 0b1101;
947 let Inst{20} = ?; // The S bit.
948 let Inst{19-16} = 0b1101; // Rn = sp
952 // Signed and unsigned division on v7-M
953 def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
954 "sdiv", "\t$dst, $a, $b",
955 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>,
956 Requires<[HasDivide]> {
957 let Inst{31-27} = 0b11111;
958 let Inst{26-21} = 0b011100;
960 let Inst{15-12} = 0b1111;
961 let Inst{7-4} = 0b1111;
964 def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
965 "udiv", "\t$dst, $a, $b",
966 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>,
967 Requires<[HasDivide]> {
968 let Inst{31-27} = 0b11111;
969 let Inst{26-21} = 0b011101;
971 let Inst{15-12} = 0b1111;
972 let Inst{7-4} = 0b1111;
975 //===----------------------------------------------------------------------===//
976 // Load / store Instructions.
980 let canFoldAsLoad = 1, isReMaterializable = 1 in
981 defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si,
982 UnOpFrag<(load node:$Src)>>;
984 // Loads with zero extension
985 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
986 UnOpFrag<(zextloadi16 node:$Src)>>;
987 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
988 UnOpFrag<(zextloadi8 node:$Src)>>;
990 // Loads with sign extension
991 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
992 UnOpFrag<(sextloadi16 node:$Src)>>;
993 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
994 UnOpFrag<(sextloadi8 node:$Src)>>;
996 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
997 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
999 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1000 (ins t2addrmode_imm8s4:$addr),
1001 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
1002 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
1003 (ins i32imm:$addr), IIC_iLoad_d_i,
1004 "ldrd", "\t$dst1, $addr", []> {
1005 let Inst{19-16} = 0b1111; // Rn
1007 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1009 // zextload i1 -> zextload i8
1010 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1011 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1012 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
1013 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1014 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1015 (t2LDRBs t2addrmode_so_reg:$addr)>;
1016 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1017 (t2LDRBpci tconstpool:$addr)>;
1019 // extload -> zextload
1020 // FIXME: Reduce the number of patterns by legalizing extload to zextload
1022 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
1023 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1024 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
1025 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1026 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
1027 (t2LDRBs t2addrmode_so_reg:$addr)>;
1028 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
1029 (t2LDRBpci tconstpool:$addr)>;
1031 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
1032 (t2LDRBi12 t2addrmode_imm12:$addr)>;
1033 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
1034 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1035 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1036 (t2LDRBs t2addrmode_so_reg:$addr)>;
1037 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1038 (t2LDRBpci tconstpool:$addr)>;
1040 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1041 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1042 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1043 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1044 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1045 (t2LDRHs t2addrmode_so_reg:$addr)>;
1046 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1047 (t2LDRHpci tconstpool:$addr)>;
1049 // FIXME: The destination register of the loads and stores can't be PC, but
1050 // can be SP. We need another regclass (similar to rGPR) to represent
1051 // that. Not a pressing issue since these are selected manually,
1055 let mayLoad = 1, neverHasSideEffects = 1 in {
1056 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1057 (ins t2addrmode_imm8:$addr),
1058 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1059 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
1062 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1063 (ins GPR:$base, t2am_imm8_offset:$offset),
1064 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1065 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
1068 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1069 (ins t2addrmode_imm8:$addr),
1070 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1071 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
1073 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1074 (ins GPR:$base, t2am_imm8_offset:$offset),
1075 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1076 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
1079 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1080 (ins t2addrmode_imm8:$addr),
1081 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1082 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
1084 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1085 (ins GPR:$base, t2am_imm8_offset:$offset),
1086 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1087 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
1090 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1091 (ins t2addrmode_imm8:$addr),
1092 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1093 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
1095 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1096 (ins GPR:$base, t2am_imm8_offset:$offset),
1097 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1098 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1101 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1102 (ins t2addrmode_imm8:$addr),
1103 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1104 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1106 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1107 (ins GPR:$base, t2am_imm8_offset:$offset),
1108 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1109 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1111 } // mayLoad = 1, neverHasSideEffects = 1
1113 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1114 // for disassembly only.
1115 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1116 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1117 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc,
1118 "\t$dst, $addr", []> {
1119 let Inst{31-27} = 0b11111;
1120 let Inst{26-25} = 0b00;
1121 let Inst{24} = signed;
1123 let Inst{22-21} = type;
1124 let Inst{20} = 1; // load
1126 let Inst{10-8} = 0b110; // PUW.
1129 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1130 def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1131 def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1132 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1133 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1136 defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si,
1137 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1138 defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1139 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1140 defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1141 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1144 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1145 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1146 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1147 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1148 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
1151 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1152 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1153 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1154 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1156 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1158 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1159 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1160 AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1161 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1163 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1165 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1166 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1167 AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1168 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1170 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1172 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1173 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1174 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1175 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1177 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1179 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1180 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1181 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1182 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1184 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1186 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1187 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1188 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1189 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1191 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1193 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1195 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1196 class T2IstT<bits<2> type, string opc, InstrItinClass ii>
1197 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc,
1198 "\t$src, $addr", []> {
1199 let Inst{31-27} = 0b11111;
1200 let Inst{26-25} = 0b00;
1201 let Inst{24} = 0; // not signed
1203 let Inst{22-21} = type;
1204 let Inst{20} = 0; // store
1206 let Inst{10-8} = 0b110; // PUW
1209 def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>;
1210 def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1211 def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1213 // ldrd / strd pre / post variants
1214 // For disassembly only.
1216 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1217 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1218 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1220 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1221 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
1222 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1224 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1225 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1226 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1228 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1229 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1230 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
1232 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1233 // data/instruction access. These are for disassembly only.
1234 // instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1235 // (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
1236 multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1238 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1240 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
1241 let Inst{31-25} = 0b1111100;
1242 let Inst{24} = instr;
1243 let Inst{23} = 1; // U = 1
1245 let Inst{21} = write;
1247 let Inst{15-12} = 0b1111;
1250 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
1252 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
1253 let Inst{31-25} = 0b1111100;
1254 let Inst{24} = instr;
1255 let Inst{23} = 0; // U = 0
1257 let Inst{21} = write;
1259 let Inst{15-12} = 0b1111;
1260 let Inst{11-8} = 0b1100;
1263 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1265 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
1266 let Inst{31-25} = 0b1111100;
1267 let Inst{24} = instr;
1268 let Inst{23} = 0; // add = TRUE for T1
1270 let Inst{21} = write;
1272 let Inst{15-12} = 0b1111;
1273 let Inst{11-6} = 0000000;
1276 let isCodeGenOnly = 1 in
1277 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc,
1280 let Inst{31-25} = 0b1111100;
1281 let Inst{24} = write;
1282 let Inst{23} = ?; // add = (U == 1)
1284 let Inst{21} = instr;
1286 let Inst{19-16} = 0b1111; // Rn = 0b1111
1287 let Inst{15-12} = 0b1111;
1291 defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
1292 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1293 defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
1295 //===----------------------------------------------------------------------===//
1296 // Load / store multiple Instructions.
1299 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1300 isCodeGenOnly = 1 in {
1301 def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1302 reglist:$dsts, variable_ops), IIC_iLoad_m,
1303 "ldm${amode}${p}.w\t$Rn, $dsts", []> {
1304 let Inst{31-27} = 0b11101;
1305 let Inst{26-25} = 0b00;
1306 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1308 let Inst{21} = 0; // The W bit.
1309 let Inst{20} = 1; // Load
1312 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1313 reglist:$dsts, variable_ops),
1315 "ldm${amode}${p}.w\t$Rn!, $dsts",
1317 let Inst{31-27} = 0b11101;
1318 let Inst{26-25} = 0b00;
1319 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1321 let Inst{21} = 1; // The W bit.
1322 let Inst{20} = 1; // Load
1324 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1326 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1327 isCodeGenOnly = 1 in {
1328 def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1329 reglist:$srcs, variable_ops), IIC_iStore_m,
1330 "stm${amode}${p}.w\t$Rn, $srcs", []> {
1331 let Inst{31-27} = 0b11101;
1332 let Inst{26-25} = 0b00;
1333 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1335 let Inst{21} = 0; // The W bit.
1336 let Inst{20} = 0; // Store
1339 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1340 reglist:$srcs, variable_ops),
1342 "stm${amode}${p}.w\t$Rn!, $srcs",
1344 let Inst{31-27} = 0b11101;
1345 let Inst{26-25} = 0b00;
1346 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1348 let Inst{21} = 1; // The W bit.
1349 let Inst{20} = 0; // Store
1351 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1353 //===----------------------------------------------------------------------===//
1354 // Move Instructions.
1357 let neverHasSideEffects = 1 in
1358 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1359 "mov", ".w\t$dst, $src", []> {
1360 let Inst{31-27} = 0b11101;
1361 let Inst{26-25} = 0b01;
1362 let Inst{24-21} = 0b0010;
1363 let Inst{20} = ?; // The S bit.
1364 let Inst{19-16} = 0b1111; // Rn
1365 let Inst{14-12} = 0b000;
1366 let Inst{7-4} = 0b0000;
1369 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1370 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1371 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1372 "mov", ".w\t$dst, $src",
1373 [(set rGPR:$dst, t2_so_imm:$src)]> {
1374 let Inst{31-27} = 0b11110;
1376 let Inst{24-21} = 0b0010;
1377 let Inst{20} = ?; // The S bit.
1378 let Inst{19-16} = 0b1111; // Rn
1382 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1383 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1384 "movw", "\t$dst, $src",
1385 [(set rGPR:$dst, imm0_65535:$src)]> {
1386 let Inst{31-27} = 0b11110;
1388 let Inst{24-21} = 0b0010;
1389 let Inst{20} = 0; // The S bit.
1393 let Constraints = "$src = $dst" in
1394 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1395 "movt", "\t$dst, $imm",
1397 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1398 let Inst{31-27} = 0b11110;
1400 let Inst{24-21} = 0b0110;
1401 let Inst{20} = 0; // The S bit.
1405 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1407 //===----------------------------------------------------------------------===//
1408 // Extend Instructions.
1413 defm t2SXTB : T2I_ext_rrot<0b100, "sxtb",
1414 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1415 defm t2SXTH : T2I_ext_rrot<0b000, "sxth",
1416 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1417 defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1419 defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1420 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1421 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1422 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1423 defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
1425 // TODO: SXT(A){B|H}16 - done for disassembly only
1429 let AddedComplexity = 16 in {
1430 defm t2UXTB : T2I_ext_rrot<0b101, "uxtb",
1431 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1432 defm t2UXTH : T2I_ext_rrot<0b001, "uxth",
1433 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1434 defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
1435 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1437 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1438 // The transformation should probably be done as a combiner action
1439 // instead so we can include a check for masking back in the upper
1440 // eight bits of the source into the lower eight bits of the result.
1441 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1442 // (t2UXTB16r_rot rGPR:$Src, 24)>,
1443 // Requires<[HasT2ExtractPack, IsThumb2]>;
1444 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1445 (t2UXTB16r_rot rGPR:$Src, 8)>,
1446 Requires<[HasT2ExtractPack, IsThumb2]>;
1448 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
1449 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1450 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
1451 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1452 defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
1455 //===----------------------------------------------------------------------===//
1456 // Arithmetic Instructions.
1459 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1460 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1461 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1462 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1464 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1465 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1466 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1467 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1468 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1469 IIC_iALUi, IIC_iALUr, IIC_iALUsi,
1470 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1472 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1473 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1474 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1475 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1476 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1477 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1478 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1479 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1482 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1483 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1484 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1485 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1487 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1488 // The assume-no-carry-in form uses the negation of the input since add/sub
1489 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1490 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1492 // The AddedComplexity preferences the first variant over the others since
1493 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1494 let AddedComplexity = 1 in
1495 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1496 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1497 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1498 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1499 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1500 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1501 let AddedComplexity = 1 in
1502 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1503 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1504 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1505 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1506 // The with-carry-in form matches bitwise not instead of the negation.
1507 // Effectively, the inverse interpretation of the carry flag already accounts
1508 // for part of the negation.
1509 let AddedComplexity = 1 in
1510 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1511 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1512 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1513 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1515 // Select Bytes -- for disassembly only
1517 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1518 "\t$dst, $a, $b", []> {
1519 let Inst{31-27} = 0b11111;
1520 let Inst{26-24} = 0b010;
1522 let Inst{22-20} = 0b010;
1523 let Inst{15-12} = 0b1111;
1525 let Inst{6-4} = 0b000;
1528 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1529 // And Miscellaneous operations -- for disassembly only
1530 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1531 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1532 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1533 "\t$dst, $a, $b", pat> {
1534 let Inst{31-27} = 0b11111;
1535 let Inst{26-23} = 0b0101;
1536 let Inst{22-20} = op22_20;
1537 let Inst{15-12} = 0b1111;
1538 let Inst{7-4} = op7_4;
1541 // Saturating add/subtract -- for disassembly only
1543 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1544 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1545 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1546 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1547 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1548 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1549 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1550 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1551 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1552 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1553 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1554 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1555 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1556 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1557 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1558 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1559 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1560 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1562 // Signed/Unsigned add/subtract -- for disassembly only
1564 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1565 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1566 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1567 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1568 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1569 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1570 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1571 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1572 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1573 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1574 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1575 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1577 // Signed/Unsigned halving add/subtract -- for disassembly only
1579 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1580 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1581 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1582 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1583 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1584 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1585 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1586 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1587 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1588 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1589 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1590 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1592 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1594 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1595 (ins rGPR:$a, rGPR:$b),
1596 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1597 let Inst{15-12} = 0b1111;
1599 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1600 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1601 "\t$dst, $a, $b, $acc", []>;
1603 // Signed/Unsigned saturate -- for disassembly only
1605 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1606 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1607 [/* For disassembly only; pattern left blank */]> {
1608 let Inst{31-27} = 0b11110;
1609 let Inst{25-22} = 0b1100;
1614 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1615 "ssat16", "\t$dst, $bit_pos, $a",
1616 [/* For disassembly only; pattern left blank */]> {
1617 let Inst{31-27} = 0b11110;
1618 let Inst{25-22} = 0b1100;
1621 let Inst{21} = 1; // sh = '1'
1622 let Inst{14-12} = 0b000; // imm3 = '000'
1623 let Inst{7-6} = 0b00; // imm2 = '00'
1626 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1627 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1628 [/* For disassembly only; pattern left blank */]> {
1629 let Inst{31-27} = 0b11110;
1630 let Inst{25-22} = 0b1110;
1635 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1636 "usat16", "\t$dst, $bit_pos, $a",
1637 [/* For disassembly only; pattern left blank */]> {
1638 let Inst{31-27} = 0b11110;
1639 let Inst{25-22} = 0b1110;
1642 let Inst{21} = 1; // sh = '1'
1643 let Inst{14-12} = 0b000; // imm3 = '000'
1644 let Inst{7-6} = 0b00; // imm2 = '00'
1647 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1648 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1650 //===----------------------------------------------------------------------===//
1651 // Shift and rotate Instructions.
1654 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1655 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1656 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1657 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1659 let Uses = [CPSR] in {
1660 def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1661 "rrx", "\t$dst, $src",
1662 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1663 let Inst{31-27} = 0b11101;
1664 let Inst{26-25} = 0b01;
1665 let Inst{24-21} = 0b0010;
1666 let Inst{20} = ?; // The S bit.
1667 let Inst{19-16} = 0b1111; // Rn
1668 let Inst{14-12} = 0b000;
1669 let Inst{7-4} = 0b0011;
1673 let Defs = [CPSR] in {
1674 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1675 "lsrs", ".w\t$dst, $src, #1",
1676 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1677 let Inst{31-27} = 0b11101;
1678 let Inst{26-25} = 0b01;
1679 let Inst{24-21} = 0b0010;
1680 let Inst{20} = 1; // The S bit.
1681 let Inst{19-16} = 0b1111; // Rn
1682 let Inst{5-4} = 0b01; // Shift type.
1683 // Shift amount = Inst{14-12:7-6} = 1.
1684 let Inst{14-12} = 0b000;
1685 let Inst{7-6} = 0b01;
1687 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1688 "asrs", ".w\t$dst, $src, #1",
1689 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1690 let Inst{31-27} = 0b11101;
1691 let Inst{26-25} = 0b01;
1692 let Inst{24-21} = 0b0010;
1693 let Inst{20} = 1; // The S bit.
1694 let Inst{19-16} = 0b1111; // Rn
1695 let Inst{5-4} = 0b10; // Shift type.
1696 // Shift amount = Inst{14-12:7-6} = 1.
1697 let Inst{14-12} = 0b000;
1698 let Inst{7-6} = 0b01;
1702 //===----------------------------------------------------------------------===//
1703 // Bitwise Instructions.
1706 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1707 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1708 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1709 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1710 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1711 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1712 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1713 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1714 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1716 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1717 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1718 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1720 let Constraints = "$src = $dst" in
1721 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1722 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1723 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1724 let Inst{31-27} = 0b11110;
1726 let Inst{24-20} = 0b10110;
1727 let Inst{19-16} = 0b1111; // Rn
1731 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1732 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1733 let Inst{31-27} = 0b11110;
1735 let Inst{24-20} = 0b10100;
1739 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1740 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1741 let Inst{31-27} = 0b11110;
1743 let Inst{24-20} = 0b11100;
1747 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1748 let Constraints = "$src = $dst" in
1749 def t2BFI : T2I<(outs rGPR:$dst),
1750 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1751 IIC_iBITi, "bfi", "\t$dst, $val, $imm",
1752 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1753 bf_inv_mask_imm:$imm))]> {
1754 let Inst{31-27} = 0b11110;
1756 let Inst{24-20} = 0b10110;
1760 defm t2ORN : T2I_bin_irs<0b0011, "orn",
1761 IIC_iBITi, IIC_iBITr, IIC_iBITsi,
1762 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
1764 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1765 let AddedComplexity = 1 in
1766 defm t2MVN : T2I_un_irs <0b0011, "mvn",
1767 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
1768 UnOpFrag<(not node:$Src)>, 1, 1>;
1771 let AddedComplexity = 1 in
1772 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1773 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1775 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1776 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1777 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1778 Requires<[IsThumb2]>;
1780 def : T2Pat<(t2_so_imm_not:$src),
1781 (t2MVNi t2_so_imm_not:$src)>;
1783 //===----------------------------------------------------------------------===//
1784 // Multiply Instructions.
1786 let isCommutable = 1 in
1787 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1788 "mul", "\t$dst, $a, $b",
1789 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1790 let Inst{31-27} = 0b11111;
1791 let Inst{26-23} = 0b0110;
1792 let Inst{22-20} = 0b000;
1793 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1794 let Inst{7-4} = 0b0000; // Multiply
1797 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1798 "mla", "\t$dst, $a, $b, $c",
1799 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1800 let Inst{31-27} = 0b11111;
1801 let Inst{26-23} = 0b0110;
1802 let Inst{22-20} = 0b000;
1803 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1804 let Inst{7-4} = 0b0000; // Multiply
1807 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1808 "mls", "\t$dst, $a, $b, $c",
1809 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1810 let Inst{31-27} = 0b11111;
1811 let Inst{26-23} = 0b0110;
1812 let Inst{22-20} = 0b000;
1813 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1814 let Inst{7-4} = 0b0001; // Multiply and Subtract
1817 // Extra precision multiplies with low / high results
1818 let neverHasSideEffects = 1 in {
1819 let isCommutable = 1 in {
1820 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1821 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1822 "smull", "\t$ldst, $hdst, $a, $b", []> {
1823 let Inst{31-27} = 0b11111;
1824 let Inst{26-23} = 0b0111;
1825 let Inst{22-20} = 0b000;
1826 let Inst{7-4} = 0b0000;
1829 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1830 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1831 "umull", "\t$ldst, $hdst, $a, $b", []> {
1832 let Inst{31-27} = 0b11111;
1833 let Inst{26-23} = 0b0111;
1834 let Inst{22-20} = 0b010;
1835 let Inst{7-4} = 0b0000;
1839 // Multiply + accumulate
1840 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1841 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1842 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1843 let Inst{31-27} = 0b11111;
1844 let Inst{26-23} = 0b0111;
1845 let Inst{22-20} = 0b100;
1846 let Inst{7-4} = 0b0000;
1849 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1850 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1851 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1852 let Inst{31-27} = 0b11111;
1853 let Inst{26-23} = 0b0111;
1854 let Inst{22-20} = 0b110;
1855 let Inst{7-4} = 0b0000;
1858 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1859 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1860 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1861 let Inst{31-27} = 0b11111;
1862 let Inst{26-23} = 0b0111;
1863 let Inst{22-20} = 0b110;
1864 let Inst{7-4} = 0b0110;
1866 } // neverHasSideEffects
1868 // Rounding variants of the below included for disassembly only
1870 // Most significant word multiply
1871 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1872 "smmul", "\t$dst, $a, $b",
1873 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
1874 let Inst{31-27} = 0b11111;
1875 let Inst{26-23} = 0b0110;
1876 let Inst{22-20} = 0b101;
1877 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1878 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1881 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1882 "smmulr", "\t$dst, $a, $b", []> {
1883 let Inst{31-27} = 0b11111;
1884 let Inst{26-23} = 0b0110;
1885 let Inst{22-20} = 0b101;
1886 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1887 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1890 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1891 "smmla", "\t$dst, $a, $b, $c",
1892 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
1893 let Inst{31-27} = 0b11111;
1894 let Inst{26-23} = 0b0110;
1895 let Inst{22-20} = 0b101;
1896 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1897 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1900 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1901 "smmlar", "\t$dst, $a, $b, $c", []> {
1902 let Inst{31-27} = 0b11111;
1903 let Inst{26-23} = 0b0110;
1904 let Inst{22-20} = 0b101;
1905 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1906 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1909 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1910 "smmls", "\t$dst, $a, $b, $c",
1911 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
1912 let Inst{31-27} = 0b11111;
1913 let Inst{26-23} = 0b0110;
1914 let Inst{22-20} = 0b110;
1915 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1916 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1919 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1920 "smmlsr", "\t$dst, $a, $b, $c", []> {
1921 let Inst{31-27} = 0b11111;
1922 let Inst{26-23} = 0b0110;
1923 let Inst{22-20} = 0b110;
1924 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1925 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1928 multiclass T2I_smul<string opc, PatFrag opnode> {
1929 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1930 !strconcat(opc, "bb"), "\t$dst, $a, $b",
1931 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1932 (sext_inreg rGPR:$b, i16)))]> {
1933 let Inst{31-27} = 0b11111;
1934 let Inst{26-23} = 0b0110;
1935 let Inst{22-20} = 0b001;
1936 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1937 let Inst{7-6} = 0b00;
1938 let Inst{5-4} = 0b00;
1941 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1942 !strconcat(opc, "bt"), "\t$dst, $a, $b",
1943 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1944 (sra rGPR:$b, (i32 16))))]> {
1945 let Inst{31-27} = 0b11111;
1946 let Inst{26-23} = 0b0110;
1947 let Inst{22-20} = 0b001;
1948 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1949 let Inst{7-6} = 0b00;
1950 let Inst{5-4} = 0b01;
1953 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1954 !strconcat(opc, "tb"), "\t$dst, $a, $b",
1955 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1956 (sext_inreg rGPR:$b, i16)))]> {
1957 let Inst{31-27} = 0b11111;
1958 let Inst{26-23} = 0b0110;
1959 let Inst{22-20} = 0b001;
1960 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1961 let Inst{7-6} = 0b00;
1962 let Inst{5-4} = 0b10;
1965 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1966 !strconcat(opc, "tt"), "\t$dst, $a, $b",
1967 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1968 (sra rGPR:$b, (i32 16))))]> {
1969 let Inst{31-27} = 0b11111;
1970 let Inst{26-23} = 0b0110;
1971 let Inst{22-20} = 0b001;
1972 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1973 let Inst{7-6} = 0b00;
1974 let Inst{5-4} = 0b11;
1977 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1978 !strconcat(opc, "wb"), "\t$dst, $a, $b",
1979 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1980 (sext_inreg rGPR:$b, i16)), (i32 16)))]> {
1981 let Inst{31-27} = 0b11111;
1982 let Inst{26-23} = 0b0110;
1983 let Inst{22-20} = 0b011;
1984 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1985 let Inst{7-6} = 0b00;
1986 let Inst{5-4} = 0b00;
1989 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1990 !strconcat(opc, "wt"), "\t$dst, $a, $b",
1991 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1992 (sra rGPR:$b, (i32 16))), (i32 16)))]> {
1993 let Inst{31-27} = 0b11111;
1994 let Inst{26-23} = 0b0110;
1995 let Inst{22-20} = 0b011;
1996 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1997 let Inst{7-6} = 0b00;
1998 let Inst{5-4} = 0b01;
2003 multiclass T2I_smla<string opc, PatFrag opnode> {
2004 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2005 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
2006 [(set rGPR:$dst, (add rGPR:$acc,
2007 (opnode (sext_inreg rGPR:$a, i16),
2008 (sext_inreg rGPR:$b, i16))))]> {
2009 let Inst{31-27} = 0b11111;
2010 let Inst{26-23} = 0b0110;
2011 let Inst{22-20} = 0b001;
2012 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2013 let Inst{7-6} = 0b00;
2014 let Inst{5-4} = 0b00;
2017 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2018 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
2019 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
2020 (sra rGPR:$b, (i32 16)))))]> {
2021 let Inst{31-27} = 0b11111;
2022 let Inst{26-23} = 0b0110;
2023 let Inst{22-20} = 0b001;
2024 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2025 let Inst{7-6} = 0b00;
2026 let Inst{5-4} = 0b01;
2029 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2030 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
2031 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2032 (sext_inreg rGPR:$b, i16))))]> {
2033 let Inst{31-27} = 0b11111;
2034 let Inst{26-23} = 0b0110;
2035 let Inst{22-20} = 0b001;
2036 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2037 let Inst{7-6} = 0b00;
2038 let Inst{5-4} = 0b10;
2041 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2042 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2043 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2044 (sra rGPR:$b, (i32 16)))))]> {
2045 let Inst{31-27} = 0b11111;
2046 let Inst{26-23} = 0b0110;
2047 let Inst{22-20} = 0b001;
2048 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2049 let Inst{7-6} = 0b00;
2050 let Inst{5-4} = 0b11;
2053 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2054 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2055 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2056 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2057 let Inst{31-27} = 0b11111;
2058 let Inst{26-23} = 0b0110;
2059 let Inst{22-20} = 0b011;
2060 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2061 let Inst{7-6} = 0b00;
2062 let Inst{5-4} = 0b00;
2065 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2066 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2067 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2068 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2069 let Inst{31-27} = 0b11111;
2070 let Inst{26-23} = 0b0110;
2071 let Inst{22-20} = 0b011;
2072 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2073 let Inst{7-6} = 0b00;
2074 let Inst{5-4} = 0b01;
2078 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2079 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2081 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2082 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2083 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2084 [/* For disassembly only; pattern left blank */]>;
2085 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2086 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2087 [/* For disassembly only; pattern left blank */]>;
2088 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2089 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2090 [/* For disassembly only; pattern left blank */]>;
2091 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2092 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2093 [/* For disassembly only; pattern left blank */]>;
2095 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2096 // These are for disassembly only.
2098 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2099 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2100 let Inst{15-12} = 0b1111;
2102 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2103 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2104 let Inst{15-12} = 0b1111;
2106 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2107 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2108 let Inst{15-12} = 0b1111;
2110 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2111 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2112 let Inst{15-12} = 0b1111;
2114 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2115 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2116 "\t$dst, $a, $b, $acc", []>;
2117 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2118 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2119 "\t$dst, $a, $b, $acc", []>;
2120 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2121 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2122 "\t$dst, $a, $b, $acc", []>;
2123 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2124 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2125 "\t$dst, $a, $b, $acc", []>;
2126 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2127 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2128 "\t$ldst, $hdst, $a, $b", []>;
2129 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2130 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2131 "\t$ldst, $hdst, $a, $b", []>;
2132 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2133 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2134 "\t$ldst, $hdst, $a, $b", []>;
2135 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2136 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2137 "\t$ldst, $hdst, $a, $b", []>;
2139 //===----------------------------------------------------------------------===//
2140 // Misc. Arithmetic Instructions.
2143 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2144 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2145 : T2I<oops, iops, itin, opc, asm, pattern> {
2146 let Inst{31-27} = 0b11111;
2147 let Inst{26-22} = 0b01010;
2148 let Inst{21-20} = op1;
2149 let Inst{15-12} = 0b1111;
2150 let Inst{7-6} = 0b10;
2151 let Inst{5-4} = op2;
2154 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2155 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2157 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2158 "rbit", "\t$dst, $src",
2159 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2161 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2162 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2164 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2165 "rev16", ".w\t$dst, $src",
2167 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2168 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2169 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2170 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2172 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2173 "revsh", ".w\t$dst, $src",
2176 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2177 (shl rGPR:$src, (i32 8))), i16))]>;
2179 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2180 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2181 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2182 (and (shl rGPR:$src2, lsl_amt:$sh),
2184 Requires<[HasT2ExtractPack, IsThumb2]> {
2185 let Inst{31-27} = 0b11101;
2186 let Inst{26-25} = 0b01;
2187 let Inst{24-20} = 0b01100;
2188 let Inst{5} = 0; // BT form
2192 // Alternate cases for PKHBT where identities eliminate some nodes.
2193 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2194 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2195 Requires<[HasT2ExtractPack, IsThumb2]>;
2196 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2197 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2198 Requires<[HasT2ExtractPack, IsThumb2]>;
2200 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2201 // will match the pattern below.
2202 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2203 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2204 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2205 (and (sra rGPR:$src2, asr_amt:$sh),
2207 Requires<[HasT2ExtractPack, IsThumb2]> {
2208 let Inst{31-27} = 0b11101;
2209 let Inst{26-25} = 0b01;
2210 let Inst{24-20} = 0b01100;
2211 let Inst{5} = 1; // TB form
2215 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2216 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2217 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2218 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2219 Requires<[HasT2ExtractPack, IsThumb2]>;
2220 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2221 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2222 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2223 Requires<[HasT2ExtractPack, IsThumb2]>;
2225 //===----------------------------------------------------------------------===//
2226 // Comparison Instructions...
2228 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2229 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2230 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2231 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2232 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2233 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2235 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2236 // Compare-to-zero still works out, just not the relationals
2237 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2238 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2239 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2240 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
2241 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2243 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2244 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2246 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2247 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2249 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2250 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2251 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2252 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2253 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
2254 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2256 // Conditional moves
2257 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2258 // a two-value operand where a dag node expects two operands. :(
2259 let neverHasSideEffects = 1, isAsCheapAsAMove = 1 in {
2260 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2261 "mov", ".w\t$dst, $true",
2262 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2263 RegConstraint<"$false = $dst"> {
2264 let Inst{31-27} = 0b11101;
2265 let Inst{26-25} = 0b01;
2266 let Inst{24-21} = 0b0010;
2267 let Inst{20} = 0; // The S bit.
2268 let Inst{19-16} = 0b1111; // Rn
2269 let Inst{14-12} = 0b000;
2270 let Inst{7-4} = 0b0000;
2273 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2274 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2275 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2276 RegConstraint<"$false = $dst"> {
2277 let Inst{31-27} = 0b11110;
2279 let Inst{24-21} = 0b0010;
2280 let Inst{20} = 0; // The S bit.
2281 let Inst{19-16} = 0b1111; // Rn
2285 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
2287 "movw", "\t$dst, $src", []>,
2288 RegConstraint<"$false = $dst"> {
2289 let Inst{31-27} = 0b11110;
2291 let Inst{24-21} = 0b0010;
2292 let Inst{20} = 0; // The S bit.
2296 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2297 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2298 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
2299 imm:$cc, CCR:$ccr))*/]>,
2300 RegConstraint<"$false = $dst"> {
2301 let Inst{31-27} = 0b11110;
2303 let Inst{24-21} = 0b0011;
2304 let Inst{20} = 0; // The S bit.
2305 let Inst{19-16} = 0b1111; // Rn
2309 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2310 string opc, string asm, list<dag> pattern>
2311 : T2I<oops, iops, itin, opc, asm, pattern> {
2312 let Inst{31-27} = 0b11101;
2313 let Inst{26-25} = 0b01;
2314 let Inst{24-21} = 0b0010;
2315 let Inst{20} = 0; // The S bit.
2316 let Inst{19-16} = 0b1111; // Rn
2317 let Inst{5-4} = opcod; // Shift type.
2319 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2320 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2321 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2322 RegConstraint<"$false = $dst">;
2323 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2324 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2325 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2326 RegConstraint<"$false = $dst">;
2327 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2328 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2329 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2330 RegConstraint<"$false = $dst">;
2331 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2332 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2333 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2334 RegConstraint<"$false = $dst">;
2335 } // neverHasSideEffects
2337 //===----------------------------------------------------------------------===//
2338 // Atomic operations intrinsics
2341 // memory barriers protect the atomic sequences
2342 let hasSideEffects = 1 in {
2343 def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2344 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2345 Requires<[IsThumb, HasDB]> {
2347 let Inst{31-4} = 0xf3bf8f5;
2348 let Inst{3-0} = opt;
2352 def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
2354 [/* For disassembly only; pattern left blank */]>,
2355 Requires<[IsThumb, HasDB]> {
2357 let Inst{31-4} = 0xf3bf8f4;
2358 let Inst{3-0} = opt;
2361 // ISB has only full system option -- for disassembly only
2362 def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
2363 [/* For disassembly only; pattern left blank */]>,
2364 Requires<[IsThumb2, HasV7]> {
2365 let Inst{31-4} = 0xf3bf8f6;
2366 let Inst{3-0} = 0b1111;
2369 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2370 InstrItinClass itin, string opc, string asm, string cstr,
2371 list<dag> pattern, bits<4> rt2 = 0b1111>
2372 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2373 let Inst{31-27} = 0b11101;
2374 let Inst{26-20} = 0b0001101;
2375 let Inst{11-8} = rt2;
2376 let Inst{7-6} = 0b01;
2377 let Inst{5-4} = opcod;
2378 let Inst{3-0} = 0b1111;
2380 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2381 InstrItinClass itin, string opc, string asm, string cstr,
2382 list<dag> pattern, bits<4> rt2 = 0b1111>
2383 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2384 let Inst{31-27} = 0b11101;
2385 let Inst{26-20} = 0b0001100;
2386 let Inst{11-8} = rt2;
2387 let Inst{7-6} = 0b01;
2388 let Inst{5-4} = opcod;
2391 let mayLoad = 1 in {
2392 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2393 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2395 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2396 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2398 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2399 Size4Bytes, NoItinerary,
2400 "ldrex", "\t$dest, [$ptr]", "",
2402 let Inst{31-27} = 0b11101;
2403 let Inst{26-20} = 0b0000101;
2404 let Inst{11-8} = 0b1111;
2405 let Inst{7-0} = 0b00000000; // imm8 = 0
2407 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2408 AddrModeNone, Size4Bytes, NoItinerary,
2409 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2413 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2414 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2415 AddrModeNone, Size4Bytes, NoItinerary,
2416 "strexb", "\t$success, $src, [$ptr]", "", []>;
2417 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2418 AddrModeNone, Size4Bytes, NoItinerary,
2419 "strexh", "\t$success, $src, [$ptr]", "", []>;
2420 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2421 AddrModeNone, Size4Bytes, NoItinerary,
2422 "strex", "\t$success, $src, [$ptr]", "",
2424 let Inst{31-27} = 0b11101;
2425 let Inst{26-20} = 0b0000100;
2426 let Inst{7-0} = 0b00000000; // imm8 = 0
2428 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2429 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2430 AddrModeNone, Size4Bytes, NoItinerary,
2431 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2435 // Clear-Exclusive is for disassembly only.
2436 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2437 [/* For disassembly only; pattern left blank */]>,
2438 Requires<[IsARM, HasV7]> {
2439 let Inst{31-20} = 0xf3b;
2440 let Inst{15-14} = 0b10;
2442 let Inst{7-4} = 0b0010;
2445 //===----------------------------------------------------------------------===//
2449 // __aeabi_read_tp preserves the registers r1-r3.
2451 Defs = [R0, R12, LR, CPSR] in {
2452 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2453 "bl\t__aeabi_read_tp",
2454 [(set R0, ARMthread_pointer)]> {
2455 let Inst{31-27} = 0b11110;
2456 let Inst{15-14} = 0b11;
2461 //===----------------------------------------------------------------------===//
2462 // SJLJ Exception handling intrinsics
2463 // eh_sjlj_setjmp() is an instruction sequence to store the return
2464 // address and save #0 in R0 for the non-longjmp case.
2465 // Since by its nature we may be coming from some other function to get
2466 // here, and we're using the stack frame for the containing function to
2467 // save/restore registers, we can't keep anything live in regs across
2468 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2469 // when we get here from a longjmp(). We force everthing out of registers
2470 // except for our own input by listing the relevant registers in Defs. By
2471 // doing so, we also cause the prologue/epilogue code to actively preserve
2472 // all of the callee-saved resgisters, which is exactly what we want.
2473 // $val is a scratch register for our use.
2475 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2476 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2477 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2478 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2479 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2480 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2481 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2482 Requires<[IsThumb2, HasVFP2]>;
2486 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2487 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
2488 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2489 AddrModeNone, SizeSpecial, NoItinerary, "", "",
2490 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2491 Requires<[IsThumb2, NoVFP]>;
2495 //===----------------------------------------------------------------------===//
2496 // Control-Flow Instructions
2499 // FIXME: remove when we have a way to marking a MI with these properties.
2500 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2502 // FIXME: Should pc be an implicit operand like PICADD, etc?
2503 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2504 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2505 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
2506 reglist:$dsts, variable_ops),
2508 "ldm${amode}${p}.w\t$Rn!, $dsts",
2510 let Inst{31-27} = 0b11101;
2511 let Inst{26-25} = 0b00;
2512 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2514 let Inst{21} = 1; // The W bit.
2515 let Inst{20} = 1; // Load
2518 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2519 let isPredicable = 1 in
2520 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2522 [(br bb:$target)]> {
2523 let Inst{31-27} = 0b11110;
2524 let Inst{15-14} = 0b10;
2528 let isNotDuplicable = 1, isIndirectBranch = 1,
2529 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
2532 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2533 IIC_Br, "mov\tpc, $target$jt",
2534 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2535 let Inst{31-27} = 0b11101;
2536 let Inst{26-20} = 0b0100100;
2537 let Inst{19-16} = 0b1111;
2538 let Inst{14-12} = 0b000;
2539 let Inst{11-8} = 0b1111; // Rd = pc
2540 let Inst{7-4} = 0b0000;
2543 // FIXME: Add a non-pc based case that can be predicated.
2544 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2547 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2548 IIC_Br, "tbb\t$index$jt", []> {
2549 let Inst{31-27} = 0b11101;
2550 let Inst{26-20} = 0b0001101;
2551 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2552 let Inst{15-8} = 0b11110000;
2553 let Inst{7-4} = 0b0000; // B form
2556 let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
2559 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2560 IIC_Br, "tbh\t$index$jt", []> {
2561 let Inst{31-27} = 0b11101;
2562 let Inst{26-20} = 0b0001101;
2563 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2564 let Inst{15-8} = 0b11110000;
2565 let Inst{7-4} = 0b0001; // H form
2568 // Generic versions of the above two instructions, for disassembly only
2570 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2571 "tbb", "\t[$a, $b]", []>{
2572 let Inst{31-27} = 0b11101;
2573 let Inst{26-20} = 0b0001101;
2574 let Inst{15-8} = 0b11110000;
2575 let Inst{7-4} = 0b0000; // B form
2578 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2579 "tbh", "\t[$a, $b, lsl #1]", []> {
2580 let Inst{31-27} = 0b11101;
2581 let Inst{26-20} = 0b0001101;
2582 let Inst{15-8} = 0b11110000;
2583 let Inst{7-4} = 0b0001; // H form
2585 } // isNotDuplicable, isIndirectBranch
2587 } // isBranch, isTerminator, isBarrier
2589 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2590 // a two-value operand where a dag node expects two operands. :(
2591 let isBranch = 1, isTerminator = 1 in
2592 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2594 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2595 let Inst{31-27} = 0b11110;
2596 let Inst{15-14} = 0b10;
2602 let Defs = [ITSTATE] in
2603 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2604 AddrModeNone, Size2Bytes, IIC_iALUx,
2605 "it$mask\t$cc", "", []> {
2606 // 16-bit instruction.
2607 let Inst{31-16} = 0x0000;
2608 let Inst{15-8} = 0b10111111;
2611 // Branch and Exchange Jazelle -- for disassembly only
2613 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2614 [/* For disassembly only; pattern left blank */]> {
2615 let Inst{31-27} = 0b11110;
2617 let Inst{25-20} = 0b111100;
2618 let Inst{15-14} = 0b10;
2622 // Change Processor State is a system instruction -- for disassembly only.
2623 // The singleton $opt operand contains the following information:
2624 // opt{4-0} = mode from Inst{4-0}
2625 // opt{5} = changemode from Inst{17}
2626 // opt{8-6} = AIF from Inst{8-6}
2627 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2628 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2629 [/* For disassembly only; pattern left blank */]> {
2630 let Inst{31-27} = 0b11110;
2632 let Inst{25-20} = 0b111010;
2633 let Inst{15-14} = 0b10;
2637 // A6.3.4 Branches and miscellaneous control
2638 // Table A6-14 Change Processor State, and hint instructions
2639 // Helper class for disassembly only.
2640 class T2I_hint<bits<8> op7_0, string opc, string asm>
2641 : T2I<(outs), (ins), NoItinerary, opc, asm,
2642 [/* For disassembly only; pattern left blank */]> {
2643 let Inst{31-20} = 0xf3a;
2644 let Inst{15-14} = 0b10;
2646 let Inst{10-8} = 0b000;
2647 let Inst{7-0} = op7_0;
2650 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2651 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2652 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2653 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2654 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2656 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2657 [/* For disassembly only; pattern left blank */]> {
2658 let Inst{31-20} = 0xf3a;
2659 let Inst{15-14} = 0b10;
2661 let Inst{10-8} = 0b000;
2662 let Inst{7-4} = 0b1111;
2665 // Secure Monitor Call is a system instruction -- for disassembly only
2666 // Option = Inst{19-16}
2667 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2668 [/* For disassembly only; pattern left blank */]> {
2669 let Inst{31-27} = 0b11110;
2670 let Inst{26-20} = 0b1111111;
2671 let Inst{15-12} = 0b1000;
2674 // Store Return State is a system instruction -- for disassembly only
2675 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2676 [/* For disassembly only; pattern left blank */]> {
2677 let Inst{31-27} = 0b11101;
2678 let Inst{26-20} = 0b0000010; // W = 1
2681 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2682 [/* For disassembly only; pattern left blank */]> {
2683 let Inst{31-27} = 0b11101;
2684 let Inst{26-20} = 0b0000000; // W = 0
2687 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2688 [/* For disassembly only; pattern left blank */]> {
2689 let Inst{31-27} = 0b11101;
2690 let Inst{26-20} = 0b0011010; // W = 1
2693 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2694 [/* For disassembly only; pattern left blank */]> {
2695 let Inst{31-27} = 0b11101;
2696 let Inst{26-20} = 0b0011000; // W = 0
2699 // Return From Exception is a system instruction -- for disassembly only
2700 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2701 [/* For disassembly only; pattern left blank */]> {
2702 let Inst{31-27} = 0b11101;
2703 let Inst{26-20} = 0b0000011; // W = 1
2706 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2707 [/* For disassembly only; pattern left blank */]> {
2708 let Inst{31-27} = 0b11101;
2709 let Inst{26-20} = 0b0000001; // W = 0
2712 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2713 [/* For disassembly only; pattern left blank */]> {
2714 let Inst{31-27} = 0b11101;
2715 let Inst{26-20} = 0b0011011; // W = 1
2718 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2719 [/* For disassembly only; pattern left blank */]> {
2720 let Inst{31-27} = 0b11101;
2721 let Inst{26-20} = 0b0011001; // W = 0
2724 //===----------------------------------------------------------------------===//
2725 // Non-Instruction Patterns
2728 // Two piece so_imms.
2729 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2730 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2731 (t2_so_imm2part_2 imm:$RHS))>;
2732 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2733 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2734 (t2_so_imm2part_2 imm:$RHS))>;
2735 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2736 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2737 (t2_so_imm2part_2 imm:$RHS))>;
2738 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2739 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2740 (t2_so_neg_imm2part_2 imm:$RHS))>;
2742 // 32-bit immediate using movw + movt.
2743 // This is a single pseudo instruction to make it re-materializable.
2744 // FIXME: Remove this when we can do generalized remat.
2745 let isReMaterializable = 1 in
2746 def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
2747 "", [(set rGPR:$dst, (i32 imm:$src))]>,
2748 Requires<[IsThumb, HasV6T2]>;
2750 // ConstantPool, GlobalAddress, and JumpTable
2751 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2752 Requires<[IsThumb2, DontUseMovt]>;
2753 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2754 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2755 Requires<[IsThumb2, UseMovt]>;
2757 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2758 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2760 // Pseudo instruction that combines ldr from constpool and add pc. This should
2761 // be expanded into two instructions late to allow if-conversion and
2763 let canFoldAsLoad = 1, isReMaterializable = 1 in
2764 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2766 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2768 Requires<[IsThumb2]>;
2770 //===----------------------------------------------------------------------===//
2771 // Move between special register and ARM core register -- for disassembly only
2775 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2776 [/* For disassembly only; pattern left blank */]> {
2777 let Inst{31-27} = 0b11110;
2779 let Inst{25-21} = 0b11111;
2780 let Inst{20} = 0; // The R bit.
2781 let Inst{15-14} = 0b10;
2786 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2787 [/* For disassembly only; pattern left blank */]> {
2788 let Inst{31-27} = 0b11110;
2790 let Inst{25-21} = 0b11111;
2791 let Inst{20} = 1; // The R bit.
2792 let Inst{15-14} = 0b10;
2797 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2798 "\tcpsr$mask, $src",
2799 [/* For disassembly only; pattern left blank */]> {
2800 let Inst{31-27} = 0b11110;
2802 let Inst{25-21} = 0b11100;
2803 let Inst{20} = 0; // The R bit.
2804 let Inst{15-14} = 0b10;
2809 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2810 "\tspsr$mask, $src",
2811 [/* For disassembly only; pattern left blank */]> {
2812 let Inst{31-27} = 0b11110;
2814 let Inst{25-21} = 0b11100;
2815 let Inst{20} = 1; // The R bit.
2816 let Inst{15-14} = 0b10;