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 let PrintMethod = "printT2SOOperand";
35 let MIOperandInfo = (ops rGPR, i32imm);
38 // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
39 def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
40 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
43 // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
44 def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
45 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
48 // t2_so_imm - Match a 32-bit immediate operand, which is an
49 // 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
50 // immediate splatted into multiple bytes of the word. t2_so_imm values are
51 // represented in the imm field in the same 12-bit form that they are encoded
52 // into t2_so_imm instructions: the 8-bit immediate is the least significant
53 // bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
54 def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]>;
56 // t2_so_imm_not - Match an immediate that is a complement
58 def t2_so_imm_not : Operand<i32>,
60 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
61 }], t2_so_imm_not_XFORM>;
63 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
64 def t2_so_imm_neg : Operand<i32>,
66 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
67 }], t2_so_imm_neg_XFORM>;
69 // Break t2_so_imm's up into two pieces. This handles immediates with up to 16
70 // bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
71 // to get the first/second pieces.
72 def t2_so_imm2part : Operand<i32>,
74 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
78 def t2_so_imm2part_1 : SDNodeXForm<imm, [{
79 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
80 return CurDAG->getTargetConstant(V, MVT::i32);
83 def t2_so_imm2part_2 : SDNodeXForm<imm, [{
84 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
85 return CurDAG->getTargetConstant(V, MVT::i32);
88 def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
89 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
93 def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
94 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
95 return CurDAG->getTargetConstant(V, MVT::i32);
98 def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
99 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
100 return CurDAG->getTargetConstant(V, MVT::i32);
103 /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
104 def imm1_31 : PatLeaf<(i32 imm), [{
105 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
108 /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
109 def imm0_4095 : Operand<i32>,
110 PatLeaf<(i32 imm), [{
111 return (uint32_t)N->getZExtValue() < 4096;
114 def imm0_4095_neg : PatLeaf<(i32 imm), [{
115 return (uint32_t)(-N->getZExtValue()) < 4096;
118 def imm0_255_neg : PatLeaf<(i32 imm), [{
119 return (uint32_t)(-N->getZExtValue()) < 255;
122 def imm0_255_not : PatLeaf<(i32 imm), [{
123 return (uint32_t)(~N->getZExtValue()) < 255;
126 // Define Thumb2 specific addressing modes.
128 // t2addrmode_imm12 := reg + imm12
129 def t2addrmode_imm12 : Operand<i32>,
130 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
131 let PrintMethod = "printT2AddrModeImm12Operand";
132 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
135 // t2addrmode_imm8 := reg +/- imm8
136 def t2addrmode_imm8 : Operand<i32>,
137 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
138 let PrintMethod = "printT2AddrModeImm8Operand";
139 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
142 def t2am_imm8_offset : Operand<i32>,
143 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
144 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
147 // t2addrmode_imm8s4 := reg +/- (imm8 << 2)
148 def t2addrmode_imm8s4 : Operand<i32>,
149 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
150 let PrintMethod = "printT2AddrModeImm8s4Operand";
151 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
154 def t2am_imm8s4_offset : Operand<i32> {
155 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
158 // t2addrmode_so_reg := reg + (reg << imm2)
159 def t2addrmode_so_reg : Operand<i32>,
160 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
161 let PrintMethod = "printT2AddrModeSoRegOperand";
162 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
166 //===----------------------------------------------------------------------===//
167 // Multiclass helpers...
170 /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
171 /// unary operation that produces a value. These are predicable and can be
172 /// changed to modify CPSR.
173 multiclass T2I_un_irs<bits<4> opcod, string opc, PatFrag opnode,
174 bit Cheap = 0, bit ReMat = 0> {
176 def i : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
178 [(set rGPR:$dst, (opnode t2_so_imm:$src))]> {
179 let isAsCheapAsAMove = Cheap;
180 let isReMaterializable = ReMat;
181 let Inst{31-27} = 0b11110;
183 let Inst{24-21} = opcod;
184 let Inst{20} = ?; // The S bit.
185 let Inst{19-16} = 0b1111; // Rn
189 def r : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVr,
190 opc, ".w\t$dst, $src",
191 [(set rGPR:$dst, (opnode rGPR:$src))]> {
192 let Inst{31-27} = 0b11101;
193 let Inst{26-25} = 0b01;
194 let Inst{24-21} = opcod;
195 let Inst{20} = ?; // The S bit.
196 let Inst{19-16} = 0b1111; // Rn
197 let Inst{14-12} = 0b000; // imm3
198 let Inst{7-6} = 0b00; // imm2
199 let Inst{5-4} = 0b00; // type
202 def s : T2sI<(outs rGPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
203 opc, ".w\t$dst, $src",
204 [(set rGPR:$dst, (opnode t2_so_reg:$src))]> {
205 let Inst{31-27} = 0b11101;
206 let Inst{26-25} = 0b01;
207 let Inst{24-21} = opcod;
208 let Inst{20} = ?; // The S bit.
209 let Inst{19-16} = 0b1111; // Rn
213 /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
214 /// binary operation that produces a value. These are predicable and can be
215 /// changed to modify CPSR.
216 multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
217 bit Commutable = 0, string wide = ""> {
219 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
220 opc, "\t$dst, $lhs, $rhs",
221 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]> {
222 let Inst{31-27} = 0b11110;
224 let Inst{24-21} = opcod;
225 let Inst{20} = ?; // The S bit.
229 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iALUr,
230 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
231 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
232 let isCommutable = Commutable;
233 let Inst{31-27} = 0b11101;
234 let Inst{26-25} = 0b01;
235 let Inst{24-21} = opcod;
236 let Inst{20} = ?; // The S bit.
237 let Inst{14-12} = 0b000; // imm3
238 let Inst{7-6} = 0b00; // imm2
239 let Inst{5-4} = 0b00; // type
242 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
243 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
244 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]> {
245 let Inst{31-27} = 0b11101;
246 let Inst{26-25} = 0b01;
247 let Inst{24-21} = opcod;
248 let Inst{20} = ?; // The S bit.
252 /// T2I_bin_cpsr_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for
253 /// a binary operation that produces a value. These are predicable and modify
255 multiclass T2I_bin_cpsr_irs<bits<4> opcod, string opc, PatFrag opnode,
256 bit Commutable = 0, string wide = ""> {
258 def ri : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs),
259 IIC_iALUi, opc, "\t$dst, $lhs, $rhs",
260 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]> {
261 let Inst{31-27} = 0b11110;
263 let Inst{24-21} = opcod;
264 let Inst{20} = 1; // The S bit.
268 def rr : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs),
269 IIC_iALUr, opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
270 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
271 let isCommutable = Commutable;
272 let Inst{31-27} = 0b11101;
273 let Inst{26-25} = 0b01;
274 let Inst{24-21} = opcod;
275 let Inst{20} = 1; // The S bit.
276 let Inst{14-12} = 0b000; // imm3
277 let Inst{7-6} = 0b00; // imm2
278 let Inst{5-4} = 0b00; // type
281 def rs : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs),
282 IIC_iALUsi, opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
283 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]> {
284 let Inst{31-27} = 0b11101;
285 let Inst{26-25} = 0b01;
286 let Inst{24-21} = opcod;
287 let Inst{20} = 1; // The S bit.
291 /// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
292 // the ".w" prefix to indicate that they are wide.
293 multiclass T2I_bin_w_irs<bits<4> opcod, string opc, PatFrag opnode,
294 bit Commutable = 0> :
295 T2I_bin_irs<opcod, opc, opnode, Commutable, ".w">;
297 /// T2I_bin_sw_irs - Same as T2I_bin_w_irs except these operations set
299 multiclass T2I_bin_sw_irs<bits<4> opcod, string opc, PatFrag opnode,
300 bit Commutable = 0> :
301 T2I_bin_cpsr_irs<opcod, opc, opnode, Commutable, ".w">;
303 /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
304 /// reversed. The 'rr' form is only defined for the disassembler; for codegen
305 /// it is equivalent to the T2I_bin_irs counterpart.
306 multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
308 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
309 opc, ".w\t$dst, $rhs, $lhs",
310 [(set rGPR:$dst, (opnode t2_so_imm:$lhs, rGPR:$rhs))]> {
311 let Inst{31-27} = 0b11110;
313 let Inst{24-21} = opcod;
314 let Inst{20} = ?; // The S bit.
318 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, rGPR:$lhs), IIC_iALUr,
319 opc, "\t$dst, $rhs, $lhs",
320 [/* For disassembly only; pattern left blank */]> {
321 let Inst{31-27} = 0b11101;
322 let Inst{26-25} = 0b01;
323 let Inst{24-21} = opcod;
324 let Inst{20} = ?; // The S bit.
325 let Inst{14-12} = 0b000; // imm3
326 let Inst{7-6} = 0b00; // imm2
327 let Inst{5-4} = 0b00; // type
330 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
331 opc, "\t$dst, $rhs, $lhs",
332 [(set rGPR:$dst, (opnode t2_so_reg:$lhs, rGPR:$rhs))]> {
333 let Inst{31-27} = 0b11101;
334 let Inst{26-25} = 0b01;
335 let Inst{24-21} = opcod;
336 let Inst{20} = ?; // The S bit.
340 /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
341 /// instruction modifies the CPSR register.
342 let Defs = [CPSR] in {
343 multiclass T2I_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
344 bit Commutable = 0> {
346 def ri : T2I<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
347 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
348 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
349 let Inst{31-27} = 0b11110;
351 let Inst{24-21} = opcod;
352 let Inst{20} = 1; // The S bit.
356 def rr : T2I<(outs rGPR:$dst), (ins GPR:$lhs, rGPR:$rhs), IIC_iALUr,
357 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
358 [(set rGPR:$dst, (opnode GPR:$lhs, rGPR:$rhs))]> {
359 let isCommutable = Commutable;
360 let Inst{31-27} = 0b11101;
361 let Inst{26-25} = 0b01;
362 let Inst{24-21} = opcod;
363 let Inst{20} = 1; // The S bit.
364 let Inst{14-12} = 0b000; // imm3
365 let Inst{7-6} = 0b00; // imm2
366 let Inst{5-4} = 0b00; // type
369 def rs : T2I<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
370 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
371 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
372 let Inst{31-27} = 0b11101;
373 let Inst{26-25} = 0b01;
374 let Inst{24-21} = opcod;
375 let Inst{20} = 1; // The S bit.
380 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
381 /// patterns for a binary operation that produces a value.
382 multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
383 bit Commutable = 0> {
385 def ri : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
386 opc, ".w\t$dst, $lhs, $rhs",
387 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
388 let Inst{31-27} = 0b11110;
391 let Inst{23-21} = op23_21;
392 let Inst{20} = 0; // The S bit.
396 def ri12 : T2I<(outs rGPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
397 !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
398 [(set rGPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
399 let Inst{31-27} = 0b11110;
402 let Inst{23-21} = op23_21;
403 let Inst{20} = 0; // The S bit.
407 def rr : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, rGPR:$rhs), IIC_iALUr,
408 opc, ".w\t$dst, $lhs, $rhs",
409 [(set rGPR:$dst, (opnode GPR:$lhs, rGPR:$rhs))]> {
410 let isCommutable = Commutable;
411 let Inst{31-27} = 0b11101;
412 let Inst{26-25} = 0b01;
414 let Inst{23-21} = op23_21;
415 let Inst{20} = 0; // The S bit.
416 let Inst{14-12} = 0b000; // imm3
417 let Inst{7-6} = 0b00; // imm2
418 let Inst{5-4} = 0b00; // type
421 def rs : T2sI<(outs rGPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
422 opc, ".w\t$dst, $lhs, $rhs",
423 [(set rGPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
424 let Inst{31-27} = 0b11101;
425 let Inst{26-25} = 0b01;
427 let Inst{23-21} = op23_21;
428 let Inst{20} = 0; // The S bit.
432 /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
433 /// for a binary operation that produces a value and use the carry
434 /// bit. It's not predicable.
435 let Uses = [CPSR] in {
436 multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
437 bit Commutable = 0> {
439 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
440 opc, "\t$dst, $lhs, $rhs",
441 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]>,
442 Requires<[IsThumb2]> {
443 let Inst{31-27} = 0b11110;
445 let Inst{24-21} = opcod;
446 let Inst{20} = 0; // The S bit.
450 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iALUr,
451 opc, ".w\t$dst, $lhs, $rhs",
452 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]>,
453 Requires<[IsThumb2]> {
454 let isCommutable = Commutable;
455 let Inst{31-27} = 0b11101;
456 let Inst{26-25} = 0b01;
457 let Inst{24-21} = opcod;
458 let Inst{20} = 0; // The S bit.
459 let Inst{14-12} = 0b000; // imm3
460 let Inst{7-6} = 0b00; // imm2
461 let Inst{5-4} = 0b00; // type
464 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
465 opc, ".w\t$dst, $lhs, $rhs",
466 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]>,
467 Requires<[IsThumb2]> {
468 let Inst{31-27} = 0b11101;
469 let Inst{26-25} = 0b01;
470 let Inst{24-21} = opcod;
471 let Inst{20} = 0; // The S bit.
475 // Carry setting variants
476 let Defs = [CPSR] in {
477 multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
478 bit Commutable = 0> {
480 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
481 opc, "\t$dst, $lhs, $rhs",
482 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]>,
483 Requires<[IsThumb2]> {
484 let Inst{31-27} = 0b11110;
486 let Inst{24-21} = opcod;
487 let Inst{20} = 1; // The S bit.
491 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iALUr,
492 opc, ".w\t$dst, $lhs, $rhs",
493 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]>,
494 Requires<[IsThumb2]> {
495 let isCommutable = Commutable;
496 let Inst{31-27} = 0b11101;
497 let Inst{26-25} = 0b01;
498 let Inst{24-21} = opcod;
499 let Inst{20} = 1; // The S bit.
500 let Inst{14-12} = 0b000; // imm3
501 let Inst{7-6} = 0b00; // imm2
502 let Inst{5-4} = 0b00; // type
505 def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
506 opc, ".w\t$dst, $lhs, $rhs",
507 [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]>,
508 Requires<[IsThumb2]> {
509 let Inst{31-27} = 0b11101;
510 let Inst{26-25} = 0b01;
511 let Inst{24-21} = opcod;
512 let Inst{20} = 1; // The S bit.
518 /// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
519 /// version is not needed since this is only for codegen.
520 let Defs = [CPSR] in {
521 multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
523 def ri : T2I<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
524 !strconcat(opc, "s"), ".w\t$dst, $rhs, $lhs",
525 [(set rGPR:$dst, (opnode t2_so_imm:$lhs, rGPR:$rhs))]> {
526 let Inst{31-27} = 0b11110;
528 let Inst{24-21} = opcod;
529 let Inst{20} = 1; // The S bit.
533 def rs : T2I<(outs rGPR:$dst), (ins rGPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
534 !strconcat(opc, "s"), "\t$dst, $rhs, $lhs",
535 [(set rGPR:$dst, (opnode t2_so_reg:$lhs, rGPR:$rhs))]> {
536 let Inst{31-27} = 0b11101;
537 let Inst{26-25} = 0b01;
538 let Inst{24-21} = opcod;
539 let Inst{20} = 1; // The S bit.
544 /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
545 // rotate operation that produces a value.
546 multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
548 def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
549 opc, ".w\t$dst, $lhs, $rhs",
550 [(set rGPR:$dst, (opnode rGPR:$lhs, imm1_31:$rhs))]> {
551 let Inst{31-27} = 0b11101;
552 let Inst{26-21} = 0b010010;
553 let Inst{19-16} = 0b1111; // Rn
554 let Inst{5-4} = opcod;
557 def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iMOVsr,
558 opc, ".w\t$dst, $lhs, $rhs",
559 [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> {
560 let Inst{31-27} = 0b11111;
561 let Inst{26-23} = 0b0100;
562 let Inst{22-21} = opcod;
563 let Inst{15-12} = 0b1111;
564 let Inst{7-4} = 0b0000;
568 /// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
569 /// patterns. Similar to T2I_bin_irs except the instruction does not produce
570 /// a explicit result, only implicitly set CPSR.
571 let isCompare = 1, Defs = [CPSR] in {
572 multiclass T2I_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
574 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
575 opc, ".w\t$lhs, $rhs",
576 [(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
577 let Inst{31-27} = 0b11110;
579 let Inst{24-21} = opcod;
580 let Inst{20} = 1; // The S bit.
582 let Inst{11-8} = 0b1111; // Rd
585 def rr : T2I<(outs), (ins GPR:$lhs, rGPR:$rhs), IIC_iCMPr,
586 opc, ".w\t$lhs, $rhs",
587 [(opnode GPR:$lhs, rGPR:$rhs)]> {
588 let Inst{31-27} = 0b11101;
589 let Inst{26-25} = 0b01;
590 let Inst{24-21} = opcod;
591 let Inst{20} = 1; // The S bit.
592 let Inst{14-12} = 0b000; // imm3
593 let Inst{11-8} = 0b1111; // Rd
594 let Inst{7-6} = 0b00; // imm2
595 let Inst{5-4} = 0b00; // type
598 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
599 opc, ".w\t$lhs, $rhs",
600 [(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
601 let Inst{31-27} = 0b11101;
602 let Inst{26-25} = 0b01;
603 let Inst{24-21} = opcod;
604 let Inst{20} = 1; // The S bit.
605 let Inst{11-8} = 0b1111; // Rd
610 /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
611 multiclass T2I_ld<bit signed, bits<2> opcod, string opc, PatFrag opnode> {
612 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
613 opc, ".w\t$dst, $addr",
614 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
615 let Inst{31-27} = 0b11111;
616 let Inst{26-25} = 0b00;
617 let Inst{24} = signed;
619 let Inst{22-21} = opcod;
620 let Inst{20} = 1; // load
622 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
623 opc, "\t$dst, $addr",
624 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
625 let Inst{31-27} = 0b11111;
626 let Inst{26-25} = 0b00;
627 let Inst{24} = signed;
629 let Inst{22-21} = opcod;
630 let Inst{20} = 1; // load
632 // Offset: index==TRUE, wback==FALSE
633 let Inst{10} = 1; // The P bit.
634 let Inst{8} = 0; // The W bit.
636 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
637 opc, ".w\t$dst, $addr",
638 [(set GPR:$dst, (opnode t2addrmode_so_reg:$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
645 let Inst{11-6} = 0b000000;
647 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
648 opc, ".w\t$dst, $addr",
649 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
650 let isReMaterializable = 1;
651 let Inst{31-27} = 0b11111;
652 let Inst{26-25} = 0b00;
653 let Inst{24} = signed;
654 let Inst{23} = ?; // add = (U == '1')
655 let Inst{22-21} = opcod;
656 let Inst{20} = 1; // load
657 let Inst{19-16} = 0b1111; // Rn
661 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
662 multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
663 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
664 opc, ".w\t$src, $addr",
665 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
666 let Inst{31-27} = 0b11111;
667 let Inst{26-23} = 0b0001;
668 let Inst{22-21} = opcod;
669 let Inst{20} = 0; // !load
671 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
672 opc, "\t$src, $addr",
673 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
674 let Inst{31-27} = 0b11111;
675 let Inst{26-23} = 0b0000;
676 let Inst{22-21} = opcod;
677 let Inst{20} = 0; // !load
679 // Offset: index==TRUE, wback==FALSE
680 let Inst{10} = 1; // The P bit.
681 let Inst{8} = 0; // The W bit.
683 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
684 opc, ".w\t$src, $addr",
685 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
686 let Inst{31-27} = 0b11111;
687 let Inst{26-23} = 0b0000;
688 let Inst{22-21} = opcod;
689 let Inst{20} = 0; // !load
690 let Inst{11-6} = 0b000000;
694 /// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
695 /// register and one whose operand is a register rotated by 8/16/24.
696 multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
697 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
698 opc, ".w\t$dst, $src",
699 [(set rGPR:$dst, (opnode rGPR:$src))]> {
700 let Inst{31-27} = 0b11111;
701 let Inst{26-23} = 0b0100;
702 let Inst{22-20} = opcod;
703 let Inst{19-16} = 0b1111; // Rn
704 let Inst{15-12} = 0b1111;
706 let Inst{5-4} = 0b00; // rotate
708 def r_rot : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$rot), IIC_iUNAsi,
709 opc, ".w\t$dst, $src, ror $rot",
710 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]> {
711 let Inst{31-27} = 0b11111;
712 let Inst{26-23} = 0b0100;
713 let Inst{22-20} = opcod;
714 let Inst{19-16} = 0b1111; // Rn
715 let Inst{15-12} = 0b1111;
717 let Inst{5-4} = {?,?}; // rotate
721 // UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
722 multiclass T2I_unary_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
723 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
725 [(set rGPR:$dst, (opnode rGPR:$src))]>,
726 Requires<[HasT2ExtractPack]> {
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_iUNAsi,
736 opc, "\t$dst, $src, ror $rot",
737 [(set rGPR:$dst, (opnode (rotr rGPR:$src, rot_imm:$rot)))]>,
738 Requires<[HasT2ExtractPack]> {
739 let Inst{31-27} = 0b11111;
740 let Inst{26-23} = 0b0100;
741 let Inst{22-20} = opcod;
742 let Inst{19-16} = 0b1111; // Rn
743 let Inst{15-12} = 0b1111;
745 let Inst{5-4} = {?,?}; // rotate
749 // SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
751 multiclass T2I_unary_rrot_sxtb16<bits<3> opcod, string opc> {
752 def r : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
753 opc, "\t$dst, $src", []> {
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_iUNAsi,
763 opc, "\t$dst, $src, ror $rot", []> {
764 let Inst{31-27} = 0b11111;
765 let Inst{26-23} = 0b0100;
766 let Inst{22-20} = opcod;
767 let Inst{19-16} = 0b1111; // Rn
768 let Inst{15-12} = 0b1111;
770 let Inst{5-4} = {?,?}; // rotate
774 /// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
775 /// register and one whose operand is a register rotated by 8/16/24.
776 multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
777 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iALUr,
778 opc, "\t$dst, $LHS, $RHS",
779 [(set rGPR:$dst, (opnode rGPR:$LHS, rGPR:$RHS))]>,
780 Requires<[HasT2ExtractPack]> {
781 let Inst{31-27} = 0b11111;
782 let Inst{26-23} = 0b0100;
783 let Inst{22-20} = opcod;
784 let Inst{15-12} = 0b1111;
786 let Inst{5-4} = 0b00; // rotate
788 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
789 IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
790 [(set rGPR:$dst, (opnode rGPR:$LHS,
791 (rotr rGPR:$RHS, rot_imm:$rot)))]>,
792 Requires<[HasT2ExtractPack]> {
793 let Inst{31-27} = 0b11111;
794 let Inst{26-23} = 0b0100;
795 let Inst{22-20} = opcod;
796 let Inst{15-12} = 0b1111;
798 let Inst{5-4} = {?,?}; // rotate
802 // DO variant - disassembly only, no pattern
804 multiclass T2I_bin_rrot_DO<bits<3> opcod, string opc> {
805 def rr : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS), IIC_iALUr,
806 opc, "\t$dst, $LHS, $RHS", []> {
807 let Inst{31-27} = 0b11111;
808 let Inst{26-23} = 0b0100;
809 let Inst{22-20} = opcod;
810 let Inst{15-12} = 0b1111;
812 let Inst{5-4} = 0b00; // rotate
814 def rr_rot : T2I<(outs rGPR:$dst), (ins rGPR:$LHS, rGPR:$RHS, i32imm:$rot),
815 IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
816 let Inst{31-27} = 0b11111;
817 let Inst{26-23} = 0b0100;
818 let Inst{22-20} = opcod;
819 let Inst{15-12} = 0b1111;
821 let Inst{5-4} = {?,?}; // rotate
825 //===----------------------------------------------------------------------===//
827 //===----------------------------------------------------------------------===//
829 //===----------------------------------------------------------------------===//
830 // Miscellaneous Instructions.
833 // LEApcrel - Load a pc-relative address into a register without offending the
835 let neverHasSideEffects = 1 in {
836 let isReMaterializable = 1 in
837 def t2LEApcrel : T2XI<(outs rGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
838 "adr${p}.w\t$dst, #$label", []> {
839 let Inst{31-27} = 0b11110;
840 let Inst{25-24} = 0b10;
841 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
844 let Inst{19-16} = 0b1111; // Rn
847 } // neverHasSideEffects
848 def t2LEApcrelJT : T2XI<(outs rGPR:$dst),
849 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
850 "adr${p}.w\t$dst, #${label}_${id}", []> {
851 let Inst{31-27} = 0b11110;
852 let Inst{25-24} = 0b10;
853 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
856 let Inst{19-16} = 0b1111; // Rn
860 // ADD r, sp, {so_imm|i12}
861 def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
862 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
863 let Inst{31-27} = 0b11110;
865 let Inst{24-21} = 0b1000;
866 let Inst{20} = ?; // The S bit.
867 let Inst{19-16} = 0b1101; // Rn = sp
870 def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
871 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
872 let Inst{31-27} = 0b11110;
874 let Inst{24-21} = 0b0000;
875 let Inst{20} = 0; // The S bit.
876 let Inst{19-16} = 0b1101; // Rn = sp
881 def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
882 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
883 let Inst{31-27} = 0b11101;
884 let Inst{26-25} = 0b01;
885 let Inst{24-21} = 0b1000;
886 let Inst{20} = ?; // The S bit.
887 let Inst{19-16} = 0b1101; // Rn = sp
891 // SUB r, sp, {so_imm|i12}
892 def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
893 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
894 let Inst{31-27} = 0b11110;
896 let Inst{24-21} = 0b1101;
897 let Inst{20} = ?; // The S bit.
898 let Inst{19-16} = 0b1101; // Rn = sp
901 def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
902 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
903 let Inst{31-27} = 0b11110;
905 let Inst{24-21} = 0b0101;
906 let Inst{20} = 0; // The S bit.
907 let Inst{19-16} = 0b1101; // Rn = sp
912 def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
914 "sub", "\t$dst, $sp, $rhs", []> {
915 let Inst{31-27} = 0b11101;
916 let Inst{26-25} = 0b01;
917 let Inst{24-21} = 0b1101;
918 let Inst{20} = ?; // The S bit.
919 let Inst{19-16} = 0b1101; // Rn = sp
923 // Signed and unsigned division on v7-M
924 def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
925 "sdiv", "\t$dst, $a, $b",
926 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>,
927 Requires<[HasDivide]> {
928 let Inst{31-27} = 0b11111;
929 let Inst{26-21} = 0b011100;
931 let Inst{15-12} = 0b1111;
932 let Inst{7-4} = 0b1111;
935 def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi,
936 "udiv", "\t$dst, $a, $b",
937 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>,
938 Requires<[HasDivide]> {
939 let Inst{31-27} = 0b11111;
940 let Inst{26-21} = 0b011101;
942 let Inst{15-12} = 0b1111;
943 let Inst{7-4} = 0b1111;
946 //===----------------------------------------------------------------------===//
947 // Load / store Instructions.
951 let canFoldAsLoad = 1, isReMaterializable = 1 in
952 defm t2LDR : T2I_ld<0, 0b10, "ldr", UnOpFrag<(load node:$Src)>>;
954 // Loads with zero extension
955 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
956 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
958 // Loads with sign extension
959 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
960 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
962 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
964 def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
965 (ins t2addrmode_imm8s4:$addr),
966 IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
967 def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
968 (ins i32imm:$addr), IIC_iLoadi,
969 "ldrd", "\t$dst1, $addr", []> {
970 let Inst{19-16} = 0b1111; // Rn
972 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
974 // zextload i1 -> zextload i8
975 def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
976 (t2LDRBi12 t2addrmode_imm12:$addr)>;
977 def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
978 (t2LDRBi8 t2addrmode_imm8:$addr)>;
979 def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
980 (t2LDRBs t2addrmode_so_reg:$addr)>;
981 def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
982 (t2LDRBpci tconstpool:$addr)>;
984 // extload -> zextload
985 // FIXME: Reduce the number of patterns by legalizing extload to zextload
987 def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
988 (t2LDRBi12 t2addrmode_imm12:$addr)>;
989 def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
990 (t2LDRBi8 t2addrmode_imm8:$addr)>;
991 def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
992 (t2LDRBs t2addrmode_so_reg:$addr)>;
993 def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
994 (t2LDRBpci tconstpool:$addr)>;
996 def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
997 (t2LDRBi12 t2addrmode_imm12:$addr)>;
998 def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
999 (t2LDRBi8 t2addrmode_imm8:$addr)>;
1000 def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
1001 (t2LDRBs t2addrmode_so_reg:$addr)>;
1002 def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
1003 (t2LDRBpci tconstpool:$addr)>;
1005 def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1006 (t2LDRHi12 t2addrmode_imm12:$addr)>;
1007 def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
1008 (t2LDRHi8 t2addrmode_imm8:$addr)>;
1009 def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1010 (t2LDRHs t2addrmode_so_reg:$addr)>;
1011 def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1012 (t2LDRHpci tconstpool:$addr)>;
1014 // FIXME: The destination register of the loads and stores can't be PC, but
1015 // can be SP. We need another regclass (similar to rGPR) to represent
1016 // that. Not a pressing issue since these are selected manually,
1020 let mayLoad = 1, neverHasSideEffects = 1 in {
1021 def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1022 (ins t2addrmode_imm8:$addr),
1023 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1024 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
1027 def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1028 (ins GPR:$base, t2am_imm8_offset:$offset),
1029 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1030 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
1033 def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1034 (ins t2addrmode_imm8:$addr),
1035 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1036 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
1038 def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1039 (ins GPR:$base, t2am_imm8_offset:$offset),
1040 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1041 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
1044 def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1045 (ins t2addrmode_imm8:$addr),
1046 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1047 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
1049 def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1050 (ins GPR:$base, t2am_imm8_offset:$offset),
1051 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1052 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
1055 def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1056 (ins t2addrmode_imm8:$addr),
1057 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1058 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
1060 def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1061 (ins GPR:$base, t2am_imm8_offset:$offset),
1062 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1063 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1066 def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1067 (ins t2addrmode_imm8:$addr),
1068 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1069 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1071 def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1072 (ins GPR:$base, t2am_imm8_offset:$offset),
1073 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1074 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1076 } // mayLoad = 1, neverHasSideEffects = 1
1078 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1079 // for disassembly only.
1080 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1081 class T2IldT<bit signed, bits<2> type, string opc>
1082 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
1083 "\t$dst, $addr", []> {
1084 let Inst{31-27} = 0b11111;
1085 let Inst{26-25} = 0b00;
1086 let Inst{24} = signed;
1088 let Inst{22-21} = type;
1089 let Inst{20} = 1; // load
1091 let Inst{10-8} = 0b110; // PUW.
1094 def t2LDRT : T2IldT<0, 0b10, "ldrt">;
1095 def t2LDRBT : T2IldT<0, 0b00, "ldrbt">;
1096 def t2LDRHT : T2IldT<0, 0b01, "ldrht">;
1097 def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt">;
1098 def t2LDRSHT : T2IldT<1, 0b01, "ldrsht">;
1101 defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
1102 defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1103 defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1106 let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1107 def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1108 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1109 IIC_iStorer, "strd", "\t$src1, $addr", []>;
1112 def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1113 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1114 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1115 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1117 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1119 def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1120 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1121 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1122 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1124 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1126 def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1127 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1128 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1129 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1131 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1133 def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1134 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1135 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1136 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1138 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1140 def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1141 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1142 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1143 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1145 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1147 def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1148 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1149 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1150 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1152 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1154 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1156 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1157 class T2IstT<bits<2> type, string opc>
1158 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), IIC_iStorei, opc,
1159 "\t$src, $addr", []> {
1160 let Inst{31-27} = 0b11111;
1161 let Inst{26-25} = 0b00;
1162 let Inst{24} = 0; // not signed
1164 let Inst{22-21} = type;
1165 let Inst{20} = 0; // store
1167 let Inst{10-8} = 0b110; // PUW
1170 def t2STRT : T2IstT<0b10, "strt">;
1171 def t2STRBT : T2IstT<0b00, "strbt">;
1172 def t2STRHT : T2IstT<0b01, "strht">;
1174 // ldrd / strd pre / post variants
1175 // For disassembly only.
1177 def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1178 (ins GPR:$base, t2am_imm8s4_offset:$imm), NoItinerary,
1179 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
1181 def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
1182 (ins GPR:$base, t2am_imm8s4_offset:$imm), NoItinerary,
1183 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
1185 def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
1186 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1187 NoItinerary, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
1189 def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
1190 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
1191 NoItinerary, "strd", "\t$src1, $src2, [$base], $imm", []>;
1193 // T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1194 // data/instruction access. These are for disassembly only.
1196 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
1197 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
1198 multiclass T2Ipl<bit instr, bit write, string opc> {
1200 def i12 : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
1201 "\t[$base, $imm]", []> {
1202 let Inst{31-25} = 0b1111100;
1203 let Inst{24} = instr;
1204 let Inst{23} = 1; // U = 1
1206 let Inst{21} = write;
1208 let Inst{15-12} = 0b1111;
1211 def i8 : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
1212 "\t[$base, $imm]", []> {
1213 let Inst{31-25} = 0b1111100;
1214 let Inst{24} = instr;
1215 let Inst{23} = 0; // U = 0
1217 let Inst{21} = write;
1219 let Inst{15-12} = 0b1111;
1220 let Inst{11-8} = 0b1100;
1223 def pci : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
1224 "\t[pc, $imm]", []> {
1225 let Inst{31-25} = 0b1111100;
1226 let Inst{24} = instr;
1227 let Inst{23} = ?; // add = (U == 1)
1229 let Inst{21} = write;
1231 let Inst{19-16} = 0b1111; // Rn = 0b1111
1232 let Inst{15-12} = 0b1111;
1235 def r : T2I<(outs), (ins GPR:$base, GPR:$a), IIC_iLoadi, opc,
1236 "\t[$base, $a]", []> {
1237 let Inst{31-25} = 0b1111100;
1238 let Inst{24} = instr;
1239 let Inst{23} = 0; // add = TRUE for T1
1241 let Inst{21} = write;
1243 let Inst{15-12} = 0b1111;
1244 let Inst{11-6} = 0000000;
1245 let Inst{5-4} = 0b00; // no shift is applied
1248 def s : T2I<(outs), (ins GPR:$base, GPR:$a, i32imm:$shamt), IIC_iLoadi, opc,
1249 "\t[$base, $a, lsl $shamt]", []> {
1250 let Inst{31-25} = 0b1111100;
1251 let Inst{24} = instr;
1252 let Inst{23} = 0; // add = TRUE for T1
1254 let Inst{21} = write;
1256 let Inst{15-12} = 0b1111;
1257 let Inst{11-6} = 0000000;
1261 defm t2PLD : T2Ipl<0, 0, "pld">;
1262 defm t2PLDW : T2Ipl<0, 1, "pldw">;
1263 defm t2PLI : T2Ipl<1, 0, "pli">;
1265 //===----------------------------------------------------------------------===//
1266 // Load / store multiple Instructions.
1269 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1270 def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
1271 reglist:$dsts, variable_ops), IIC_iLoadm,
1272 "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts", []> {
1273 let Inst{31-27} = 0b11101;
1274 let Inst{26-25} = 0b00;
1275 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1277 let Inst{21} = 0; // The W bit.
1278 let Inst{20} = 1; // Load
1281 def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1282 reglist:$dsts, variable_ops), IIC_iLoadm,
1283 "ldm${addr:submode}${p}${addr:wide}\t$addr!, $dsts",
1284 "$addr.addr = $wb", []> {
1285 let Inst{31-27} = 0b11101;
1286 let Inst{26-25} = 0b00;
1287 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1289 let Inst{21} = 1; // The W bit.
1290 let Inst{20} = 1; // Load
1292 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1294 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1295 def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
1296 reglist:$srcs, variable_ops), IIC_iStorem,
1297 "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs", []> {
1298 let Inst{31-27} = 0b11101;
1299 let Inst{26-25} = 0b00;
1300 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1302 let Inst{21} = 0; // The W bit.
1303 let Inst{20} = 0; // Store
1306 def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1307 reglist:$srcs, variable_ops),
1309 "stm${addr:submode}${p}${addr:wide}\t$addr!, $srcs",
1310 "$addr.addr = $wb", []> {
1311 let Inst{31-27} = 0b11101;
1312 let Inst{26-25} = 0b00;
1313 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1315 let Inst{21} = 1; // The W bit.
1316 let Inst{20} = 0; // Store
1318 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1320 //===----------------------------------------------------------------------===//
1321 // Move Instructions.
1324 let neverHasSideEffects = 1 in
1325 def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1326 "mov", ".w\t$dst, $src", []> {
1327 let Inst{31-27} = 0b11101;
1328 let Inst{26-25} = 0b01;
1329 let Inst{24-21} = 0b0010;
1330 let Inst{20} = ?; // The S bit.
1331 let Inst{19-16} = 0b1111; // Rn
1332 let Inst{14-12} = 0b000;
1333 let Inst{7-4} = 0b0000;
1336 // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1337 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1338 def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1339 "mov", ".w\t$dst, $src",
1340 [(set rGPR:$dst, t2_so_imm:$src)]> {
1341 let Inst{31-27} = 0b11110;
1343 let Inst{24-21} = 0b0010;
1344 let Inst{20} = ?; // The S bit.
1345 let Inst{19-16} = 0b1111; // Rn
1349 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1350 def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1351 "movw", "\t$dst, $src",
1352 [(set rGPR:$dst, imm0_65535:$src)]> {
1353 let Inst{31-27} = 0b11110;
1355 let Inst{24-21} = 0b0010;
1356 let Inst{20} = 0; // The S bit.
1360 let Constraints = "$src = $dst" in
1361 def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi,
1362 "movt", "\t$dst, $imm",
1364 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> {
1365 let Inst{31-27} = 0b11110;
1367 let Inst{24-21} = 0b0110;
1368 let Inst{20} = 0; // The S bit.
1372 def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1374 //===----------------------------------------------------------------------===//
1375 // Extend Instructions.
1380 defm t2SXTB : T2I_unary_rrot<0b100, "sxtb",
1381 UnOpFrag<(sext_inreg node:$Src, i8)>>;
1382 defm t2SXTH : T2I_unary_rrot<0b000, "sxth",
1383 UnOpFrag<(sext_inreg node:$Src, i16)>>;
1384 defm t2SXTB16 : T2I_unary_rrot_sxtb16<0b010, "sxtb16">;
1386 defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
1387 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1388 defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
1389 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1390 defm t2SXTAB16 : T2I_bin_rrot_DO<0b010, "sxtab16">;
1392 // TODO: SXT(A){B|H}16 - done for disassembly only
1396 let AddedComplexity = 16 in {
1397 defm t2UXTB : T2I_unary_rrot<0b101, "uxtb",
1398 UnOpFrag<(and node:$Src, 0x000000FF)>>;
1399 defm t2UXTH : T2I_unary_rrot<0b001, "uxth",
1400 UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1401 defm t2UXTB16 : T2I_unary_rrot_uxtb16<0b011, "uxtb16",
1402 UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1404 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1405 // The transformation should probably be done as a combiner action
1406 // instead so we can include a check for masking back in the upper
1407 // eight bits of the source into the lower eight bits of the result.
1408 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
1409 // (t2UXTB16r_rot rGPR:$Src, 24)>, Requires<[HasT2ExtractPack]>;
1410 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
1411 (t2UXTB16r_rot rGPR:$Src, 8)>, Requires<[HasT2ExtractPack]>;
1413 defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
1414 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1415 defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
1416 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1417 defm t2UXTAB16 : T2I_bin_rrot_DO<0b011, "uxtab16">;
1420 //===----------------------------------------------------------------------===//
1421 // Arithmetic Instructions.
1424 defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1425 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1426 defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1427 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1429 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1430 defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1431 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1432 defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1433 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1435 defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1436 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1437 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1438 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1439 defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1440 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1441 defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1442 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1445 defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
1446 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1447 defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1448 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1450 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1451 // The assume-no-carry-in form uses the negation of the input since add/sub
1452 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1453 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1455 // The AddedComplexity preferences the first variant over the others since
1456 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
1457 let AddedComplexity = 1 in
1458 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1459 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1460 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1461 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1462 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1463 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1464 let AddedComplexity = 1 in
1465 def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm),
1466 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>;
1467 def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm),
1468 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>;
1469 // The with-carry-in form matches bitwise not instead of the negation.
1470 // Effectively, the inverse interpretation of the carry flag already accounts
1471 // for part of the negation.
1472 let AddedComplexity = 1 in
1473 def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm),
1474 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>;
1475 def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm),
1476 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>;
1478 // Select Bytes -- for disassembly only
1480 def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1481 "\t$dst, $a, $b", []> {
1482 let Inst{31-27} = 0b11111;
1483 let Inst{26-24} = 0b010;
1485 let Inst{22-20} = 0b010;
1486 let Inst{15-12} = 0b1111;
1488 let Inst{6-4} = 0b000;
1491 // A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1492 // And Miscellaneous operations -- for disassembly only
1493 class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
1494 list<dag> pat = [/* For disassembly only; pattern left blank */]>
1495 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc,
1496 "\t$dst, $a, $b", pat> {
1497 let Inst{31-27} = 0b11111;
1498 let Inst{26-23} = 0b0101;
1499 let Inst{22-20} = op22_20;
1500 let Inst{15-12} = 0b1111;
1501 let Inst{7-4} = op7_4;
1504 // Saturating add/subtract -- for disassembly only
1506 def t2QADD : T2I_pam<0b000, 0b1000, "qadd",
1507 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>;
1508 def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1509 def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1510 def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1511 def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1512 def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1513 def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1514 def t2QSUB : T2I_pam<0b000, 0b1010, "qsub",
1515 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>;
1516 def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1517 def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1518 def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1519 def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1520 def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1521 def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1522 def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1523 def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1525 // Signed/Unsigned add/subtract -- for disassembly only
1527 def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1528 def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1529 def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1530 def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1531 def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1532 def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1533 def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1534 def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1535 def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1536 def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1537 def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1538 def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1540 // Signed/Unsigned halving add/subtract -- for disassembly only
1542 def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1543 def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1544 def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1545 def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1546 def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1547 def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1548 def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1549 def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1550 def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1551 def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1552 def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1553 def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1555 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1557 def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1558 (ins rGPR:$a, rGPR:$b),
1559 NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1560 let Inst{15-12} = 0b1111;
1562 def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst),
1563 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8",
1564 "\t$dst, $a, $b, $acc", []>;
1566 // Signed/Unsigned saturate -- for disassembly only
1568 def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1569 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1570 [/* For disassembly only; pattern left blank */]> {
1571 let Inst{31-27} = 0b11110;
1572 let Inst{25-22} = 0b1100;
1577 def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1578 "ssat16", "\t$dst, $bit_pos, $a",
1579 [/* For disassembly only; pattern left blank */]> {
1580 let Inst{31-27} = 0b11110;
1581 let Inst{25-22} = 0b1100;
1584 let Inst{21} = 1; // sh = '1'
1585 let Inst{14-12} = 0b000; // imm3 = '000'
1586 let Inst{7-6} = 0b00; // imm2 = '00'
1589 def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh),
1590 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1591 [/* For disassembly only; pattern left blank */]> {
1592 let Inst{31-27} = 0b11110;
1593 let Inst{25-22} = 0b1110;
1598 def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary,
1599 "usat16", "\t$dst, $bit_pos, $a",
1600 [/* For disassembly only; pattern left blank */]> {
1601 let Inst{31-27} = 0b11110;
1602 let Inst{25-22} = 0b1110;
1605 let Inst{21} = 1; // sh = '1'
1606 let Inst{14-12} = 0b000; // imm3 = '000'
1607 let Inst{7-6} = 0b00; // imm2 = '00'
1610 def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>;
1611 def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
1613 //===----------------------------------------------------------------------===//
1614 // Shift and rotate Instructions.
1617 defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1618 defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1619 defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1620 defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1622 let Uses = [CPSR] in {
1623 def t2MOVrx : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1624 "rrx", "\t$dst, $src",
1625 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> {
1626 let Inst{31-27} = 0b11101;
1627 let Inst{26-25} = 0b01;
1628 let Inst{24-21} = 0b0010;
1629 let Inst{20} = ?; // The S bit.
1630 let Inst{19-16} = 0b1111; // Rn
1631 let Inst{14-12} = 0b000;
1632 let Inst{7-4} = 0b0011;
1636 let Defs = [CPSR] in {
1637 def t2MOVsrl_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1638 "lsrs", ".w\t$dst, $src, #1",
1639 [(set rGPR:$dst, (ARMsrl_flag rGPR:$src))]> {
1640 let Inst{31-27} = 0b11101;
1641 let Inst{26-25} = 0b01;
1642 let Inst{24-21} = 0b0010;
1643 let Inst{20} = 1; // The S bit.
1644 let Inst{19-16} = 0b1111; // Rn
1645 let Inst{5-4} = 0b01; // Shift type.
1646 // Shift amount = Inst{14-12:7-6} = 1.
1647 let Inst{14-12} = 0b000;
1648 let Inst{7-6} = 0b01;
1650 def t2MOVsra_flag : T2I<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi,
1651 "asrs", ".w\t$dst, $src, #1",
1652 [(set rGPR:$dst, (ARMsra_flag rGPR:$src))]> {
1653 let Inst{31-27} = 0b11101;
1654 let Inst{26-25} = 0b01;
1655 let Inst{24-21} = 0b0010;
1656 let Inst{20} = 1; // The S bit.
1657 let Inst{19-16} = 0b1111; // Rn
1658 let Inst{5-4} = 0b10; // Shift type.
1659 // Shift amount = Inst{14-12:7-6} = 1.
1660 let Inst{14-12} = 0b000;
1661 let Inst{7-6} = 0b01;
1665 //===----------------------------------------------------------------------===//
1666 // Bitwise Instructions.
1669 defm t2AND : T2I_bin_w_irs<0b0000, "and",
1670 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1671 defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1672 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1673 defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1674 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1676 defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1677 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1679 //let Defs = [CPSR] in
1680 defm t2ANDS : T2I_bin_sw_irs<0b0000, "and",
1681 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>;
1683 let Constraints = "$src = $dst" in
1684 def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm),
1685 IIC_iUNAsi, "bfc", "\t$dst, $imm",
1686 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
1687 let Inst{31-27} = 0b11110;
1689 let Inst{24-20} = 0b10110;
1690 let Inst{19-16} = 0b1111; // Rn
1694 def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1695 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1696 let Inst{31-27} = 0b11110;
1698 let Inst{24-20} = 0b10100;
1702 def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width),
1703 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1704 let Inst{31-27} = 0b11110;
1706 let Inst{24-20} = 0b11100;
1710 // A8.6.18 BFI - Bitfield insert (Encoding T1)
1711 let Constraints = "$src = $dst" in
1712 def t2BFI : T2I<(outs rGPR:$dst),
1713 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm),
1714 IIC_iALUi, "bfi", "\t$dst, $val, $imm",
1715 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val,
1716 bf_inv_mask_imm:$imm))]> {
1717 let Inst{31-27} = 0b11110;
1719 let Inst{24-20} = 0b10110;
1723 defm t2ORN : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or node:$LHS,
1724 (not node:$RHS))>, 0, "">;
1726 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1727 let AddedComplexity = 1 in
1728 defm t2MVN : T2I_un_irs <0b0011, "mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
1731 let AddedComplexity = 1 in
1732 def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
1733 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
1735 // FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1736 def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
1737 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
1738 Requires<[IsThumb2]>;
1740 def : T2Pat<(t2_so_imm_not:$src),
1741 (t2MVNi t2_so_imm_not:$src)>;
1743 //===----------------------------------------------------------------------===//
1744 // Multiply Instructions.
1746 let isCommutable = 1 in
1747 def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1748 "mul", "\t$dst, $a, $b",
1749 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> {
1750 let Inst{31-27} = 0b11111;
1751 let Inst{26-23} = 0b0110;
1752 let Inst{22-20} = 0b000;
1753 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1754 let Inst{7-4} = 0b0000; // Multiply
1757 def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1758 "mla", "\t$dst, $a, $b, $c",
1759 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> {
1760 let Inst{31-27} = 0b11111;
1761 let Inst{26-23} = 0b0110;
1762 let Inst{22-20} = 0b000;
1763 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1764 let Inst{7-4} = 0b0000; // Multiply
1767 def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1768 "mls", "\t$dst, $a, $b, $c",
1769 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> {
1770 let Inst{31-27} = 0b11111;
1771 let Inst{26-23} = 0b0110;
1772 let Inst{22-20} = 0b000;
1773 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1774 let Inst{7-4} = 0b0001; // Multiply and Subtract
1777 // Extra precision multiplies with low / high results
1778 let neverHasSideEffects = 1 in {
1779 let isCommutable = 1 in {
1780 def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1781 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1782 "smull", "\t$ldst, $hdst, $a, $b", []> {
1783 let Inst{31-27} = 0b11111;
1784 let Inst{26-23} = 0b0111;
1785 let Inst{22-20} = 0b000;
1786 let Inst{7-4} = 0b0000;
1789 def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1790 (ins rGPR:$a, rGPR:$b), IIC_iMUL64,
1791 "umull", "\t$ldst, $hdst, $a, $b", []> {
1792 let Inst{31-27} = 0b11111;
1793 let Inst{26-23} = 0b0111;
1794 let Inst{22-20} = 0b010;
1795 let Inst{7-4} = 0b0000;
1799 // Multiply + accumulate
1800 def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1801 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1802 "smlal", "\t$ldst, $hdst, $a, $b", []>{
1803 let Inst{31-27} = 0b11111;
1804 let Inst{26-23} = 0b0111;
1805 let Inst{22-20} = 0b100;
1806 let Inst{7-4} = 0b0000;
1809 def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1810 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1811 "umlal", "\t$ldst, $hdst, $a, $b", []>{
1812 let Inst{31-27} = 0b11111;
1813 let Inst{26-23} = 0b0111;
1814 let Inst{22-20} = 0b110;
1815 let Inst{7-4} = 0b0000;
1818 def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst),
1819 (ins rGPR:$a, rGPR:$b), IIC_iMAC64,
1820 "umaal", "\t$ldst, $hdst, $a, $b", []>{
1821 let Inst{31-27} = 0b11111;
1822 let Inst{26-23} = 0b0111;
1823 let Inst{22-20} = 0b110;
1824 let Inst{7-4} = 0b0110;
1826 } // neverHasSideEffects
1828 // Rounding variants of the below included for disassembly only
1830 // Most significant word multiply
1831 def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1832 "smmul", "\t$dst, $a, $b",
1833 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> {
1834 let Inst{31-27} = 0b11111;
1835 let Inst{26-23} = 0b0110;
1836 let Inst{22-20} = 0b101;
1837 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1838 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1841 def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1842 "smmulr", "\t$dst, $a, $b", []> {
1843 let Inst{31-27} = 0b11111;
1844 let Inst{26-23} = 0b0110;
1845 let Inst{22-20} = 0b101;
1846 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1847 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1850 def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1851 "smmla", "\t$dst, $a, $b, $c",
1852 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> {
1853 let Inst{31-27} = 0b11111;
1854 let Inst{26-23} = 0b0110;
1855 let Inst{22-20} = 0b101;
1856 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1857 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1860 def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1861 "smmlar", "\t$dst, $a, $b, $c", []> {
1862 let Inst{31-27} = 0b11111;
1863 let Inst{26-23} = 0b0110;
1864 let Inst{22-20} = 0b101;
1865 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1866 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1869 def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1870 "smmls", "\t$dst, $a, $b, $c",
1871 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> {
1872 let Inst{31-27} = 0b11111;
1873 let Inst{26-23} = 0b0110;
1874 let Inst{22-20} = 0b110;
1875 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1876 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1879 def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32,
1880 "smmlsr", "\t$dst, $a, $b, $c", []> {
1881 let Inst{31-27} = 0b11111;
1882 let Inst{26-23} = 0b0110;
1883 let Inst{22-20} = 0b110;
1884 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1885 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1888 multiclass T2I_smul<string opc, PatFrag opnode> {
1889 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1890 !strconcat(opc, "bb"), "\t$dst, $a, $b",
1891 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1892 (sext_inreg rGPR:$b, i16)))]> {
1893 let Inst{31-27} = 0b11111;
1894 let Inst{26-23} = 0b0110;
1895 let Inst{22-20} = 0b001;
1896 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1897 let Inst{7-6} = 0b00;
1898 let Inst{5-4} = 0b00;
1901 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1902 !strconcat(opc, "bt"), "\t$dst, $a, $b",
1903 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16),
1904 (sra rGPR:$b, (i32 16))))]> {
1905 let Inst{31-27} = 0b11111;
1906 let Inst{26-23} = 0b0110;
1907 let Inst{22-20} = 0b001;
1908 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1909 let Inst{7-6} = 0b00;
1910 let Inst{5-4} = 0b01;
1913 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1914 !strconcat(opc, "tb"), "\t$dst, $a, $b",
1915 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1916 (sext_inreg rGPR:$b, i16)))]> {
1917 let Inst{31-27} = 0b11111;
1918 let Inst{26-23} = 0b0110;
1919 let Inst{22-20} = 0b001;
1920 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1921 let Inst{7-6} = 0b00;
1922 let Inst{5-4} = 0b10;
1925 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32,
1926 !strconcat(opc, "tt"), "\t$dst, $a, $b",
1927 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)),
1928 (sra rGPR:$b, (i32 16))))]> {
1929 let Inst{31-27} = 0b11111;
1930 let Inst{26-23} = 0b0110;
1931 let Inst{22-20} = 0b001;
1932 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1933 let Inst{7-6} = 0b00;
1934 let Inst{5-4} = 0b11;
1937 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1938 !strconcat(opc, "wb"), "\t$dst, $a, $b",
1939 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1940 (sext_inreg rGPR:$b, i16)), (i32 16)))]> {
1941 let Inst{31-27} = 0b11111;
1942 let Inst{26-23} = 0b0110;
1943 let Inst{22-20} = 0b011;
1944 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1945 let Inst{7-6} = 0b00;
1946 let Inst{5-4} = 0b00;
1949 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16,
1950 !strconcat(opc, "wt"), "\t$dst, $a, $b",
1951 [(set rGPR:$dst, (sra (opnode rGPR:$a,
1952 (sra rGPR:$b, (i32 16))), (i32 16)))]> {
1953 let Inst{31-27} = 0b11111;
1954 let Inst{26-23} = 0b0110;
1955 let Inst{22-20} = 0b011;
1956 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1957 let Inst{7-6} = 0b00;
1958 let Inst{5-4} = 0b01;
1963 multiclass T2I_smla<string opc, PatFrag opnode> {
1964 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
1965 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1966 [(set rGPR:$dst, (add rGPR:$acc,
1967 (opnode (sext_inreg rGPR:$a, i16),
1968 (sext_inreg rGPR:$b, i16))))]> {
1969 let Inst{31-27} = 0b11111;
1970 let Inst{26-23} = 0b0110;
1971 let Inst{22-20} = 0b001;
1972 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1973 let Inst{7-6} = 0b00;
1974 let Inst{5-4} = 0b00;
1977 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
1978 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1979 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
1980 (sra rGPR:$b, (i32 16)))))]> {
1981 let Inst{31-27} = 0b11111;
1982 let Inst{26-23} = 0b0110;
1983 let Inst{22-20} = 0b001;
1984 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1985 let Inst{7-6} = 0b00;
1986 let Inst{5-4} = 0b01;
1989 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
1990 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1991 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
1992 (sext_inreg rGPR:$b, i16))))]> {
1993 let Inst{31-27} = 0b11111;
1994 let Inst{26-23} = 0b0110;
1995 let Inst{22-20} = 0b001;
1996 let Inst{15-12} = {?, ?, ?, ?}; // Ra
1997 let Inst{7-6} = 0b00;
1998 let Inst{5-4} = 0b10;
2001 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2002 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
2003 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
2004 (sra rGPR:$b, (i32 16)))))]> {
2005 let Inst{31-27} = 0b11111;
2006 let Inst{26-23} = 0b0110;
2007 let Inst{22-20} = 0b001;
2008 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2009 let Inst{7-6} = 0b00;
2010 let Inst{5-4} = 0b11;
2013 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2014 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
2015 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2016 (sext_inreg rGPR:$b, i16)), (i32 16))))]> {
2017 let Inst{31-27} = 0b11111;
2018 let Inst{26-23} = 0b0110;
2019 let Inst{22-20} = 0b011;
2020 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2021 let Inst{7-6} = 0b00;
2022 let Inst{5-4} = 0b00;
2025 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
2026 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
2027 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
2028 (sra rGPR:$b, (i32 16))), (i32 16))))]> {
2029 let Inst{31-27} = 0b11111;
2030 let Inst{26-23} = 0b0110;
2031 let Inst{22-20} = 0b011;
2032 let Inst{15-12} = {?, ?, ?, ?}; // Ra
2033 let Inst{7-6} = 0b00;
2034 let Inst{5-4} = 0b01;
2038 defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2039 defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2041 // Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
2042 def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
2043 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2044 [/* For disassembly only; pattern left blank */]>;
2045 def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
2046 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2047 [/* For disassembly only; pattern left blank */]>;
2048 def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
2049 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2050 [/* For disassembly only; pattern left blank */]>;
2051 def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
2052 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2053 [/* For disassembly only; pattern left blank */]>;
2055 // Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2056 // These are for disassembly only.
2058 def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2059 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
2060 let Inst{15-12} = 0b1111;
2062 def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2063 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
2064 let Inst{15-12} = 0b1111;
2066 def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2067 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
2068 let Inst{15-12} = 0b1111;
2070 def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
2071 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
2072 let Inst{15-12} = 0b1111;
2074 def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
2075 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
2076 "\t$dst, $a, $b, $acc", []>;
2077 def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
2078 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
2079 "\t$dst, $a, $b, $acc", []>;
2080 def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
2081 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
2082 "\t$dst, $a, $b, $acc", []>;
2083 def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
2084 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
2085 "\t$dst, $a, $b, $acc", []>;
2086 def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2087 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
2088 "\t$ldst, $hdst, $a, $b", []>;
2089 def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2090 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
2091 "\t$ldst, $hdst, $a, $b", []>;
2092 def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
2093 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
2094 "\t$ldst, $hdst, $a, $b", []>;
2095 def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
2096 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
2097 "\t$ldst, $hdst, $a, $b", []>;
2099 //===----------------------------------------------------------------------===//
2100 // Misc. Arithmetic Instructions.
2103 class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2104 InstrItinClass itin, string opc, string asm, list<dag> pattern>
2105 : T2I<oops, iops, itin, opc, asm, pattern> {
2106 let Inst{31-27} = 0b11111;
2107 let Inst{26-22} = 0b01010;
2108 let Inst{21-20} = op1;
2109 let Inst{15-12} = 0b1111;
2110 let Inst{7-6} = 0b10;
2111 let Inst{5-4} = op2;
2114 def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2115 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
2117 def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2118 "rbit", "\t$dst, $src",
2119 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
2121 def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2122 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
2124 def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2125 "rev16", ".w\t$dst, $src",
2127 (or (and (srl rGPR:$src, (i32 8)), 0xFF),
2128 (or (and (shl rGPR:$src, (i32 8)), 0xFF00),
2129 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
2130 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>;
2132 def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
2133 "revsh", ".w\t$dst, $src",
2136 (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
2137 (shl rGPR:$src, (i32 8))), i16))]>;
2139 def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2140 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
2141 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
2142 (and (shl rGPR:$src2, lsl_amt:$sh),
2144 Requires<[HasT2ExtractPack]> {
2145 let Inst{31-27} = 0b11101;
2146 let Inst{26-25} = 0b01;
2147 let Inst{24-20} = 0b01100;
2148 let Inst{5} = 0; // BT form
2152 // Alternate cases for PKHBT where identities eliminate some nodes.
2153 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2154 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
2155 Requires<[HasT2ExtractPack]>;
2156 def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
2157 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
2158 Requires<[HasT2ExtractPack]>;
2160 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2161 // will match the pattern below.
2162 def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
2163 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2$sh",
2164 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
2165 (and (sra rGPR:$src2, asr_amt:$sh),
2167 Requires<[HasT2ExtractPack]> {
2168 let Inst{31-27} = 0b11101;
2169 let Inst{26-25} = 0b01;
2170 let Inst{24-20} = 0b01100;
2171 let Inst{5} = 1; // TB form
2175 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2176 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2177 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
2178 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
2179 Requires<[HasT2ExtractPack]>;
2180 def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
2181 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
2182 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
2183 Requires<[HasT2ExtractPack]>;
2185 //===----------------------------------------------------------------------===//
2186 // Comparison Instructions...
2188 defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2189 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2190 defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2191 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2193 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2194 // Compare-to-zero still works out, just not the relationals
2195 //defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2196 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2197 defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2198 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2200 //def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2201 // (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2203 def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2204 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2206 defm t2TST : T2I_cmp_irs<0b0000, "tst",
2207 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2208 defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2209 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2211 // Conditional moves
2212 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2213 // a two-value operand where a dag node expects two operands. :(
2214 let neverHasSideEffects = 1 in {
2215 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
2216 "mov", ".w\t$dst, $true",
2217 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
2218 RegConstraint<"$false = $dst"> {
2219 let Inst{31-27} = 0b11101;
2220 let Inst{26-25} = 0b01;
2221 let Inst{24-21} = 0b0010;
2222 let Inst{20} = 0; // The S bit.
2223 let Inst{19-16} = 0b1111; // Rn
2224 let Inst{14-12} = 0b000;
2225 let Inst{7-4} = 0b0000;
2228 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2229 IIC_iCMOVi, "mov", ".w\t$dst, $true",
2230 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2231 RegConstraint<"$false = $dst"> {
2232 let Inst{31-27} = 0b11110;
2234 let Inst{24-21} = 0b0010;
2235 let Inst{20} = 0; // The S bit.
2236 let Inst{19-16} = 0b1111; // Rn
2240 class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2241 string opc, string asm, list<dag> pattern>
2242 : T2I<oops, iops, itin, opc, asm, pattern> {
2243 let Inst{31-27} = 0b11101;
2244 let Inst{26-25} = 0b01;
2245 let Inst{24-21} = 0b0010;
2246 let Inst{20} = 0; // The S bit.
2247 let Inst{19-16} = 0b1111; // Rn
2248 let Inst{5-4} = opcod; // Shift type.
2250 def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
2251 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2252 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2253 RegConstraint<"$false = $dst">;
2254 def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
2255 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2256 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2257 RegConstraint<"$false = $dst">;
2258 def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
2259 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2260 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2261 RegConstraint<"$false = $dst">;
2262 def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
2263 (ins rGPR:$false, rGPR:$true, i32imm:$rhs),
2264 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2265 RegConstraint<"$false = $dst">;
2266 } // neverHasSideEffects
2268 //===----------------------------------------------------------------------===//
2269 // Atomic operations intrinsics
2272 // memory barriers protect the atomic sequences
2273 let hasSideEffects = 1 in {
2274 def t2DMBsy : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "dmb", "",
2275 [(ARMMemBarrier)]>, Requires<[IsThumb, HasDB]> {
2276 let Inst{31-4} = 0xF3BF8F5;
2277 // FIXME: add support for options other than a full system DMB
2278 let Inst{3-0} = 0b1111;
2281 def t2DSBsy : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "dsb", "",
2282 [(ARMSyncBarrier)]>, Requires<[IsThumb, HasDB]> {
2283 let Inst{31-4} = 0xF3BF8F4;
2284 // FIXME: add support for options other than a full system DSB
2285 let Inst{3-0} = 0b1111;
2289 // Helper class for multiclass T2MemB -- for disassembly only
2290 class T2I_memb<string opc, string asm>
2291 : T2I<(outs), (ins), NoItinerary, opc, asm,
2292 [/* For disassembly only; pattern left blank */]>,
2293 Requires<[IsThumb2, HasV7]> {
2294 let Inst{31-20} = 0xf3b;
2295 let Inst{15-14} = 0b10;
2299 multiclass T2MemB<bits<4> op7_4, string opc> {
2301 def st : T2I_memb<opc, "\tst"> {
2302 let Inst{7-4} = op7_4;
2303 let Inst{3-0} = 0b1110;
2306 def ish : T2I_memb<opc, "\tish"> {
2307 let Inst{7-4} = op7_4;
2308 let Inst{3-0} = 0b1011;
2311 def ishst : T2I_memb<opc, "\tishst"> {
2312 let Inst{7-4} = op7_4;
2313 let Inst{3-0} = 0b1010;
2316 def nsh : T2I_memb<opc, "\tnsh"> {
2317 let Inst{7-4} = op7_4;
2318 let Inst{3-0} = 0b0111;
2321 def nshst : T2I_memb<opc, "\tnshst"> {
2322 let Inst{7-4} = op7_4;
2323 let Inst{3-0} = 0b0110;
2326 def osh : T2I_memb<opc, "\tosh"> {
2327 let Inst{7-4} = op7_4;
2328 let Inst{3-0} = 0b0011;
2331 def oshst : T2I_memb<opc, "\toshst"> {
2332 let Inst{7-4} = op7_4;
2333 let Inst{3-0} = 0b0010;
2337 // These DMB variants are for disassembly only.
2338 defm t2DMB : T2MemB<0b0101, "dmb">;
2340 // These DSB variants are for disassembly only.
2341 defm t2DSB : T2MemB<0b0100, "dsb">;
2343 // ISB has only full system option -- for disassembly only
2344 def t2ISBsy : T2I_memb<"isb", ""> {
2345 let Inst{7-4} = 0b0110;
2346 let Inst{3-0} = 0b1111;
2349 class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2350 InstrItinClass itin, string opc, string asm, string cstr,
2351 list<dag> pattern, bits<4> rt2 = 0b1111>
2352 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2353 let Inst{31-27} = 0b11101;
2354 let Inst{26-20} = 0b0001101;
2355 let Inst{11-8} = rt2;
2356 let Inst{7-6} = 0b01;
2357 let Inst{5-4} = opcod;
2358 let Inst{3-0} = 0b1111;
2360 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2361 InstrItinClass itin, string opc, string asm, string cstr,
2362 list<dag> pattern, bits<4> rt2 = 0b1111>
2363 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2364 let Inst{31-27} = 0b11101;
2365 let Inst{26-20} = 0b0001100;
2366 let Inst{11-8} = rt2;
2367 let Inst{7-6} = 0b01;
2368 let Inst{5-4} = opcod;
2371 let mayLoad = 1 in {
2372 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2373 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2375 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2376 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2378 def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
2379 Size4Bytes, NoItinerary,
2380 "ldrex", "\t$dest, [$ptr]", "",
2382 let Inst{31-27} = 0b11101;
2383 let Inst{26-20} = 0b0000101;
2384 let Inst{11-8} = 0b1111;
2385 let Inst{7-0} = 0b00000000; // imm8 = 0
2387 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
2388 AddrModeNone, Size4Bytes, NoItinerary,
2389 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
2393 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2394 def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2395 AddrModeNone, Size4Bytes, NoItinerary,
2396 "strexb", "\t$success, $src, [$ptr]", "", []>;
2397 def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2398 AddrModeNone, Size4Bytes, NoItinerary,
2399 "strexh", "\t$success, $src, [$ptr]", "", []>;
2400 def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
2401 AddrModeNone, Size4Bytes, NoItinerary,
2402 "strex", "\t$success, $src, [$ptr]", "",
2404 let Inst{31-27} = 0b11101;
2405 let Inst{26-20} = 0b0000100;
2406 let Inst{7-0} = 0b00000000; // imm8 = 0
2408 def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
2409 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
2410 AddrModeNone, Size4Bytes, NoItinerary,
2411 "strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2415 // Clear-Exclusive is for disassembly only.
2416 def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2417 [/* For disassembly only; pattern left blank */]>,
2418 Requires<[IsARM, HasV7]> {
2419 let Inst{31-20} = 0xf3b;
2420 let Inst{15-14} = 0b10;
2422 let Inst{7-4} = 0b0010;
2425 //===----------------------------------------------------------------------===//
2429 // __aeabi_read_tp preserves the registers r1-r3.
2431 Defs = [R0, R12, LR, CPSR] in {
2432 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2433 "bl\t__aeabi_read_tp",
2434 [(set R0, ARMthread_pointer)]> {
2435 let Inst{31-27} = 0b11110;
2436 let Inst{15-14} = 0b11;
2441 //===----------------------------------------------------------------------===//
2442 // SJLJ Exception handling intrinsics
2443 // eh_sjlj_setjmp() is an instruction sequence to store the return
2444 // address and save #0 in R0 for the non-longjmp case.
2445 // Since by its nature we may be coming from some other function to get
2446 // here, and we're using the stack frame for the containing function to
2447 // save/restore registers, we can't keep anything live in regs across
2448 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2449 // when we get here from a longjmp(). We force everthing out of registers
2450 // except for our own input by listing the relevant registers in Defs. By
2451 // doing so, we also cause the prologue/epilogue code to actively preserve
2452 // all of the callee-saved resgisters, which is exactly what we want.
2453 // $val is a scratch register for our use.
2455 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2456 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2457 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2458 D31 ], hasSideEffects = 1, isBarrier = 1 in {
2459 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2460 AddrModeNone, SizeSpecial, NoItinerary,
2461 "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t"
2462 "adds\t$val, #7\n\t"
2463 "str\t$val, [$src, #4]\n\t"
2466 "movs\tr0, #1\t${:comment} end eh.setjmp\n\t"
2468 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2469 Requires<[IsThumb2, HasVFP2]>;
2473 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
2474 hasSideEffects = 1, isBarrier = 1 in {
2475 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
2476 AddrModeNone, SizeSpecial, NoItinerary,
2477 "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t"
2478 "adds\t$val, #7\n\t"
2479 "str\t$val, [$src, #4]\n\t"
2482 "movs\tr0, #1\t${:comment} end eh.setjmp\n\t"
2484 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
2485 Requires<[IsThumb2, NoVFP]>;
2489 //===----------------------------------------------------------------------===//
2490 // Control-Flow Instructions
2493 // FIXME: remove when we have a way to marking a MI with these properties.
2494 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2496 // FIXME: Should pc be an implicit operand like PICADD, etc?
2497 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2498 hasExtraDefRegAllocReq = 1 in
2499 def t2LDM_RET : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
2500 reglist:$dsts, variable_ops), IIC_Br,
2501 "ldm${addr:submode}${p}${addr:wide}\t$addr!, $dsts",
2502 "$addr.addr = $wb", []> {
2503 let Inst{31-27} = 0b11101;
2504 let Inst{26-25} = 0b00;
2505 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2507 let Inst{21} = 1; // The W bit.
2508 let Inst{20} = 1; // Load
2511 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2512 let isPredicable = 1 in
2513 def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2515 [(br bb:$target)]> {
2516 let Inst{31-27} = 0b11110;
2517 let Inst{15-14} = 0b10;
2521 let isNotDuplicable = 1, isIndirectBranch = 1 in {
2524 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2525 IIC_Br, "mov\tpc, $target$jt",
2526 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2527 let Inst{31-27} = 0b11101;
2528 let Inst{26-20} = 0b0100100;
2529 let Inst{19-16} = 0b1111;
2530 let Inst{14-12} = 0b000;
2531 let Inst{11-8} = 0b1111; // Rd = pc
2532 let Inst{7-4} = 0b0000;
2535 // FIXME: Add a non-pc based case that can be predicated.
2538 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2539 IIC_Br, "tbb\t$index$jt", []> {
2540 let Inst{31-27} = 0b11101;
2541 let Inst{26-20} = 0b0001101;
2542 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2543 let Inst{15-8} = 0b11110000;
2544 let Inst{7-4} = 0b0000; // B form
2549 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2550 IIC_Br, "tbh\t$index$jt", []> {
2551 let Inst{31-27} = 0b11101;
2552 let Inst{26-20} = 0b0001101;
2553 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2554 let Inst{15-8} = 0b11110000;
2555 let Inst{7-4} = 0b0001; // H form
2558 // Generic versions of the above two instructions, for disassembly only
2560 def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2561 "tbb", "\t[$a, $b]", []>{
2562 let Inst{31-27} = 0b11101;
2563 let Inst{26-20} = 0b0001101;
2564 let Inst{15-8} = 0b11110000;
2565 let Inst{7-4} = 0b0000; // B form
2568 def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2569 "tbh", "\t[$a, $b, lsl #1]", []> {
2570 let Inst{31-27} = 0b11101;
2571 let Inst{26-20} = 0b0001101;
2572 let Inst{15-8} = 0b11110000;
2573 let Inst{7-4} = 0b0001; // H form
2575 } // isNotDuplicable, isIndirectBranch
2577 } // isBranch, isTerminator, isBarrier
2579 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
2580 // a two-value operand where a dag node expects two operands. :(
2581 let isBranch = 1, isTerminator = 1 in
2582 def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2584 [/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2585 let Inst{31-27} = 0b11110;
2586 let Inst{15-14} = 0b10;
2592 let Defs = [ITSTATE] in
2593 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2594 AddrModeNone, Size2Bytes, IIC_iALUx,
2595 "it$mask\t$cc", "", []> {
2596 // 16-bit instruction.
2597 let Inst{31-16} = 0x0000;
2598 let Inst{15-8} = 0b10111111;
2601 // Branch and Exchange Jazelle -- for disassembly only
2603 def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
2604 [/* For disassembly only; pattern left blank */]> {
2605 let Inst{31-27} = 0b11110;
2607 let Inst{25-20} = 0b111100;
2608 let Inst{15-14} = 0b10;
2612 // Change Processor State is a system instruction -- for disassembly only.
2613 // The singleton $opt operand contains the following information:
2614 // opt{4-0} = mode from Inst{4-0}
2615 // opt{5} = changemode from Inst{17}
2616 // opt{8-6} = AIF from Inst{8-6}
2617 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2618 def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
2619 [/* For disassembly only; pattern left blank */]> {
2620 let Inst{31-27} = 0b11110;
2622 let Inst{25-20} = 0b111010;
2623 let Inst{15-14} = 0b10;
2627 // A6.3.4 Branches and miscellaneous control
2628 // Table A6-14 Change Processor State, and hint instructions
2629 // Helper class for disassembly only.
2630 class T2I_hint<bits<8> op7_0, string opc, string asm>
2631 : T2I<(outs), (ins), NoItinerary, opc, asm,
2632 [/* For disassembly only; pattern left blank */]> {
2633 let Inst{31-20} = 0xf3a;
2634 let Inst{15-14} = 0b10;
2636 let Inst{10-8} = 0b000;
2637 let Inst{7-0} = op7_0;
2640 def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2641 def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2642 def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2643 def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2644 def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2646 def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2647 [/* For disassembly only; pattern left blank */]> {
2648 let Inst{31-20} = 0xf3a;
2649 let Inst{15-14} = 0b10;
2651 let Inst{10-8} = 0b000;
2652 let Inst{7-4} = 0b1111;
2655 // Secure Monitor Call is a system instruction -- for disassembly only
2656 // Option = Inst{19-16}
2657 def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2658 [/* For disassembly only; pattern left blank */]> {
2659 let Inst{31-27} = 0b11110;
2660 let Inst{26-20} = 0b1111111;
2661 let Inst{15-12} = 0b1000;
2664 // Store Return State is a system instruction -- for disassembly only
2665 def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2666 [/* For disassembly only; pattern left blank */]> {
2667 let Inst{31-27} = 0b11101;
2668 let Inst{26-20} = 0b0000010; // W = 1
2671 def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2672 [/* For disassembly only; pattern left blank */]> {
2673 let Inst{31-27} = 0b11101;
2674 let Inst{26-20} = 0b0000000; // W = 0
2677 def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2678 [/* For disassembly only; pattern left blank */]> {
2679 let Inst{31-27} = 0b11101;
2680 let Inst{26-20} = 0b0011010; // W = 1
2683 def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2684 [/* For disassembly only; pattern left blank */]> {
2685 let Inst{31-27} = 0b11101;
2686 let Inst{26-20} = 0b0011000; // W = 0
2689 // Return From Exception is a system instruction -- for disassembly only
2690 def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
2691 [/* For disassembly only; pattern left blank */]> {
2692 let Inst{31-27} = 0b11101;
2693 let Inst{26-20} = 0b0000011; // W = 1
2696 def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
2697 [/* For disassembly only; pattern left blank */]> {
2698 let Inst{31-27} = 0b11101;
2699 let Inst{26-20} = 0b0000001; // W = 0
2702 def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
2703 [/* For disassembly only; pattern left blank */]> {
2704 let Inst{31-27} = 0b11101;
2705 let Inst{26-20} = 0b0011011; // W = 1
2708 def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
2709 [/* For disassembly only; pattern left blank */]> {
2710 let Inst{31-27} = 0b11101;
2711 let Inst{26-20} = 0b0011001; // W = 0
2714 //===----------------------------------------------------------------------===//
2715 // Non-Instruction Patterns
2718 // Two piece so_imms.
2719 def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
2720 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2721 (t2_so_imm2part_2 imm:$RHS))>;
2722 def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
2723 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2724 (t2_so_imm2part_2 imm:$RHS))>;
2725 def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
2726 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2727 (t2_so_imm2part_2 imm:$RHS))>;
2728 def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
2729 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2730 (t2_so_neg_imm2part_2 imm:$RHS))>;
2732 // 32-bit immediate using movw + movt.
2733 // This is a single pseudo instruction to make it re-materializable. Remove
2734 // when we can do generalized remat.
2735 let isReMaterializable = 1 in
2736 def t2MOVi32imm : T2Ix2<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
2737 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2738 [(set rGPR:$dst, (i32 imm:$src))]>;
2740 // ConstantPool, GlobalAddress, and JumpTable
2741 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2742 Requires<[IsThumb2, DontUseMovt]>;
2743 def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2744 def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2745 Requires<[IsThumb2, UseMovt]>;
2747 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2748 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2750 // Pseudo instruction that combines ldr from constpool and add pc. This should
2751 // be expanded into two instructions late to allow if-conversion and
2753 let canFoldAsLoad = 1, isReMaterializable = 1 in
2754 def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2756 "${:comment} ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
2757 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2759 Requires<[IsThumb2]>;
2761 //===----------------------------------------------------------------------===//
2762 // Move between special register and ARM core register -- for disassembly only
2766 def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2767 [/* For disassembly only; pattern left blank */]> {
2768 let Inst{31-27} = 0b11110;
2770 let Inst{25-21} = 0b11111;
2771 let Inst{20} = 0; // The R bit.
2772 let Inst{15-14} = 0b10;
2777 def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2778 [/* For disassembly only; pattern left blank */]> {
2779 let Inst{31-27} = 0b11110;
2781 let Inst{25-21} = 0b11111;
2782 let Inst{20} = 1; // The R bit.
2783 let Inst{15-14} = 0b10;
2788 def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2789 "\tcpsr$mask, $src",
2790 [/* For disassembly only; pattern left blank */]> {
2791 let Inst{31-27} = 0b11110;
2793 let Inst{25-21} = 0b11100;
2794 let Inst{20} = 0; // The R bit.
2795 let Inst{15-14} = 0b10;
2800 def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
2801 "\tspsr$mask, $src",
2802 [/* For disassembly only; pattern left blank */]> {
2803 let Inst{31-27} = 0b11110;
2805 let Inst{25-21} = 0b11100;
2806 let Inst{20} = 1; // The R bit.
2807 let Inst{15-14} = 0b10;