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 GPR, 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>,
56
return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
59
// t2_so_imm_not - Match an immediate that is a complement
61
def t2_so_imm_not : Operand<i32>,
63
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64
}], t2_so_imm_not_XFORM>;
66
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67
def t2_so_imm_neg : Operand<i32>,
69
return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
70
}], t2_so_imm_neg_XFORM>;
72
// Break t2_so_imm's up into two pieces. This handles immediates with up to 16
73
// bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74
// to get the first/second pieces.
75
def t2_so_imm2part : Operand<i32>,
77
return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
81
def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82
unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83
return CurDAG->getTargetConstant(V, MVT::i32);
86
def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87
unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88
return CurDAG->getTargetConstant(V, MVT::i32);
91
def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92
return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
96
def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97
unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98
return CurDAG->getTargetConstant(V, MVT::i32);
101
def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102
unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103
return CurDAG->getTargetConstant(V, MVT::i32);
106
/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107
def imm1_31 : PatLeaf<(i32 imm), [{
108
return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
111
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
112
def imm0_4095 : Operand<i32>,
113
PatLeaf<(i32 imm), [{
114
return (uint32_t)N->getZExtValue() < 4096;
117
def imm0_4095_neg : PatLeaf<(i32 imm), [{
118
return (uint32_t)(-N->getZExtValue()) < 4096;
121
def imm0_255_neg : PatLeaf<(i32 imm), [{
122
return (uint32_t)(-N->getZExtValue()) < 255;
125
// Define Thumb2 specific addressing modes.
127
// t2addrmode_imm12 := reg + imm12
128
def t2addrmode_imm12 : Operand<i32>,
129
ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
130
let PrintMethod = "printT2AddrModeImm12Operand";
131
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
134
// t2addrmode_imm8 := reg +/- imm8
135
def t2addrmode_imm8 : Operand<i32>,
136
ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
137
let PrintMethod = "printT2AddrModeImm8Operand";
138
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
141
def t2am_imm8_offset : Operand<i32>,
142
ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
143
let PrintMethod = "printT2AddrModeImm8OffsetOperand";
146
// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
147
def t2addrmode_imm8s4 : Operand<i32>,
148
ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
149
let PrintMethod = "printT2AddrModeImm8s4Operand";
150
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
153
// t2addrmode_so_reg := reg + (reg << imm2)
154
def t2addrmode_so_reg : Operand<i32>,
155
ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
156
let PrintMethod = "printT2AddrModeSoRegOperand";
157
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
161
//===----------------------------------------------------------------------===//
162
// Multiclass helpers...
165
/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
166
/// unary operation that produces a value. These are predicable and can be
167
/// changed to modify CPSR.
168
multiclass T2I_un_irs<bits<4> opcod, string opc, PatFrag opnode,
169
bit Cheap = 0, bit ReMat = 0> {
171
def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
173
[(set GPR:$dst, (opnode t2_so_imm:$src))]> {
174
let isAsCheapAsAMove = Cheap;
175
let isReMaterializable = ReMat;
176
let Inst{31-27} = 0b11110;
178
let Inst{24-21} = opcod;
179
let Inst{20} = ?; // The S bit.
180
let Inst{19-16} = 0b1111; // Rn
184
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
185
opc, ".w\t$dst, $src",
186
[(set GPR:$dst, (opnode GPR:$src))]> {
187
let Inst{31-27} = 0b11101;
188
let Inst{26-25} = 0b01;
189
let Inst{24-21} = opcod;
190
let Inst{20} = ?; // The S bit.
191
let Inst{19-16} = 0b1111; // Rn
192
let Inst{14-12} = 0b000; // imm3
193
let Inst{7-6} = 0b00; // imm2
194
let Inst{5-4} = 0b00; // type
197
def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
198
opc, ".w\t$dst, $src",
199
[(set GPR:$dst, (opnode t2_so_reg:$src))]> {
200
let Inst{31-27} = 0b11101;
201
let Inst{26-25} = 0b01;
202
let Inst{24-21} = opcod;
203
let Inst{20} = ?; // The S bit.
204
let Inst{19-16} = 0b1111; // Rn
208
/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
209
// binary operation that produces a value. These are predicable and can be
210
/// changed to modify CPSR.
211
multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
212
bit Commutable = 0, string wide =""> {
214
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
215
opc, "\t$dst, $lhs, $rhs",
216
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
217
let Inst{31-27} = 0b11110;
219
let Inst{24-21} = opcod;
220
let Inst{20} = ?; // The S bit.
224
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
225
opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
226
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
227
let isCommutable = Commutable;
228
let Inst{31-27} = 0b11101;
229
let Inst{26-25} = 0b01;
230
let Inst{24-21} = opcod;
231
let Inst{20} = ?; // The S bit.
232
let Inst{14-12} = 0b000; // imm3
233
let Inst{7-6} = 0b00; // imm2
234
let Inst{5-4} = 0b00; // type
237
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
238
opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
239
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
240
let Inst{31-27} = 0b11101;
241
let Inst{26-25} = 0b01;
242
let Inst{24-21} = opcod;
243
let Inst{20} = ?; // The S bit.
247
/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
248
// the ".w" prefix to indicate that they are wide.
249
multiclass T2I_bin_w_irs<bits<4> opcod, string opc, PatFrag opnode,
250
bit Commutable = 0> :
251
T2I_bin_irs<opcod, opc, opnode, Commutable, ".w">;
253
/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
254
/// reversed. It doesn't define the 'rr' form since it's handled by its
255
/// T2I_bin_irs counterpart.
256
multiclass T2I_rbin_is<bits<4> opcod, string opc, PatFrag opnode> {
258
def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
259
opc, ".w\t$dst, $rhs, $lhs",
260
[(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
261
let Inst{31-27} = 0b11110;
263
let Inst{24-21} = opcod;
264
let Inst{20} = 0; // The S bit.
268
def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
269
opc, "\t$dst, $rhs, $lhs",
270
[(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
271
let Inst{31-27} = 0b11101;
272
let Inst{26-25} = 0b01;
273
let Inst{24-21} = opcod;
274
let Inst{20} = 0; // The S bit.
278
/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
279
/// instruction modifies the CPSR register.
280
let Defs = [CPSR] in {
281
multiclass T2I_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
282
bit Commutable = 0> {
284
def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
285
!strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
286
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
287
let Inst{31-27} = 0b11110;
289
let Inst{24-21} = opcod;
290
let Inst{20} = 1; // The S bit.
294
def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
295
!strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
296
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
297
let isCommutable = Commutable;
298
let Inst{31-27} = 0b11101;
299
let Inst{26-25} = 0b01;
300
let Inst{24-21} = opcod;
301
let Inst{20} = 1; // The S bit.
302
let Inst{14-12} = 0b000; // imm3
303
let Inst{7-6} = 0b00; // imm2
304
let Inst{5-4} = 0b00; // type
307
def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
308
!strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
309
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
310
let Inst{31-27} = 0b11101;
311
let Inst{26-25} = 0b01;
312
let Inst{24-21} = opcod;
313
let Inst{20} = 1; // The S bit.
318
/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
319
/// patterns for a binary operation that produces a value.
320
multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
321
bit Commutable = 0> {
323
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
324
opc, ".w\t$dst, $lhs, $rhs",
325
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]> {
326
let Inst{31-27} = 0b11110;
329
let Inst{23-21} = op23_21;
330
let Inst{20} = 0; // The S bit.
334
def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
335
!strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
336
[(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
337
let Inst{31-27} = 0b11110;
340
let Inst{23-21} = op23_21;
341
let Inst{20} = 0; // The S bit.
345
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
346
opc, ".w\t$dst, $lhs, $rhs",
347
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
348
let isCommutable = Commutable;
349
let Inst{31-27} = 0b11101;
350
let Inst{26-25} = 0b01;
352
let Inst{23-21} = op23_21;
353
let Inst{20} = 0; // The S bit.
354
let Inst{14-12} = 0b000; // imm3
355
let Inst{7-6} = 0b00; // imm2
356
let Inst{5-4} = 0b00; // type
359
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
360
opc, ".w\t$dst, $lhs, $rhs",
361
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
362
let Inst{31-27} = 0b11101;
363
let Inst{26-25} = 0b01;
365
let Inst{23-21} = op23_21;
366
let Inst{20} = 0; // The S bit.
370
/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
371
/// for a binary operation that produces a value and use the carry
372
/// bit. It's not predicable.
373
let Uses = [CPSR] in {
374
multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
375
bit Commutable = 0> {
377
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
378
opc, "\t$dst, $lhs, $rhs",
379
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
380
Requires<[IsThumb2]> {
381
let Inst{31-27} = 0b11110;
383
let Inst{24-21} = opcod;
384
let Inst{20} = 0; // The S bit.
388
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
389
opc, ".w\t$dst, $lhs, $rhs",
390
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
391
Requires<[IsThumb2]> {
392
let isCommutable = Commutable;
393
let Inst{31-27} = 0b11101;
394
let Inst{26-25} = 0b01;
395
let Inst{24-21} = opcod;
396
let Inst{20} = 0; // The S bit.
397
let Inst{14-12} = 0b000; // imm3
398
let Inst{7-6} = 0b00; // imm2
399
let Inst{5-4} = 0b00; // type
402
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
403
opc, ".w\t$dst, $lhs, $rhs",
404
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
405
Requires<[IsThumb2]> {
406
let Inst{31-27} = 0b11101;
407
let Inst{26-25} = 0b01;
408
let Inst{24-21} = opcod;
409
let Inst{20} = 0; // The S bit.
413
// Carry setting variants
414
let Defs = [CPSR] in {
415
multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
416
bit Commutable = 0> {
418
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
419
opc, "\t$dst, $lhs, $rhs",
420
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
421
Requires<[IsThumb2]> {
422
let Inst{31-27} = 0b11110;
424
let Inst{24-21} = opcod;
425
let Inst{20} = 1; // The S bit.
429
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
430
opc, ".w\t$dst, $lhs, $rhs",
431
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
432
Requires<[IsThumb2]> {
433
let isCommutable = Commutable;
434
let Inst{31-27} = 0b11101;
435
let Inst{26-25} = 0b01;
436
let Inst{24-21} = opcod;
437
let Inst{20} = 1; // The S bit.
438
let Inst{14-12} = 0b000; // imm3
439
let Inst{7-6} = 0b00; // imm2
440
let Inst{5-4} = 0b00; // type
443
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
444
opc, ".w\t$dst, $lhs, $rhs",
445
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
446
Requires<[IsThumb2]> {
447
let Inst{31-27} = 0b11101;
448
let Inst{26-25} = 0b01;
449
let Inst{24-21} = opcod;
450
let Inst{20} = 1; // The S bit.
456
/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
457
let Defs = [CPSR] in {
458
multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
460
def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
462
!strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"),
463
[(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> {
464
let Inst{31-27} = 0b11110;
466
let Inst{24-21} = opcod;
467
let Inst{20} = 1; // The S bit.
471
def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
473
!strconcat(opc, "${s}\t$dst, $rhs, $lhs"),
474
[(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> {
475
let Inst{31-27} = 0b11101;
476
let Inst{26-25} = 0b01;
477
let Inst{24-21} = opcod;
478
let Inst{20} = 1; // The S bit.
483
/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
484
// rotate operation that produces a value.
485
multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> {
487
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
488
opc, ".w\t$dst, $lhs, $rhs",
489
[(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]> {
490
let Inst{31-27} = 0b11101;
491
let Inst{26-21} = 0b010010;
492
let Inst{19-16} = 0b1111; // Rn
493
let Inst{5-4} = opcod;
496
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr,
497
opc, ".w\t$dst, $lhs, $rhs",
498
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
499
let Inst{31-27} = 0b11111;
500
let Inst{26-23} = 0b0100;
501
let Inst{22-21} = opcod;
502
let Inst{15-12} = 0b1111;
503
let Inst{7-4} = 0b0000;
507
/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
508
/// patterns. Similar to T2I_bin_irs except the instruction does not produce
509
/// a explicit result, only implicitly set CPSR.
510
let Defs = [CPSR] in {
511
multiclass T2I_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
513
def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
514
opc, ".w\t$lhs, $rhs",
515
[(opnode GPR:$lhs, t2_so_imm:$rhs)]> {
516
let Inst{31-27} = 0b11110;
518
let Inst{24-21} = opcod;
519
let Inst{20} = 1; // The S bit.
521
let Inst{11-8} = 0b1111; // Rd
524
def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
525
opc, ".w\t$lhs, $rhs",
526
[(opnode GPR:$lhs, GPR:$rhs)]> {
527
let Inst{31-27} = 0b11101;
528
let Inst{26-25} = 0b01;
529
let Inst{24-21} = opcod;
530
let Inst{20} = 1; // The S bit.
531
let Inst{14-12} = 0b000; // imm3
532
let Inst{11-8} = 0b1111; // Rd
533
let Inst{7-6} = 0b00; // imm2
534
let Inst{5-4} = 0b00; // type
537
def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
538
opc, ".w\t$lhs, $rhs",
539
[(opnode GPR:$lhs, t2_so_reg:$rhs)]> {
540
let Inst{31-27} = 0b11101;
541
let Inst{26-25} = 0b01;
542
let Inst{24-21} = opcod;
543
let Inst{20} = 1; // The S bit.
544
let Inst{11-8} = 0b1111; // Rd
549
/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
550
multiclass T2I_ld<bit signed, bits<2> opcod, string opc, PatFrag opnode> {
551
def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
552
opc, ".w\t$dst, $addr",
553
[(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> {
554
let Inst{31-27} = 0b11111;
555
let Inst{26-25} = 0b00;
556
let Inst{24} = signed;
558
let Inst{22-21} = opcod;
559
let Inst{20} = 1; // load
561
def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
562
opc, "\t$dst, $addr",
563
[(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> {
564
let Inst{31-27} = 0b11111;
565
let Inst{26-25} = 0b00;
566
let Inst{24} = signed;
568
let Inst{22-21} = opcod;
569
let Inst{20} = 1; // load
571
// Offset: index==TRUE, wback==FALSE
572
let Inst{10} = 1; // The P bit.
573
let Inst{8} = 0; // The W bit.
575
def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
576
opc, ".w\t$dst, $addr",
577
[(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> {
578
let Inst{31-27} = 0b11111;
579
let Inst{26-25} = 0b00;
580
let Inst{24} = signed;
582
let Inst{22-21} = opcod;
583
let Inst{20} = 1; // load
584
let Inst{11-6} = 0b000000;
586
def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
587
opc, ".w\t$dst, $addr",
588
[(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
589
let isReMaterializable = 1;
590
let Inst{31-27} = 0b11111;
591
let Inst{26-25} = 0b00;
592
let Inst{24} = signed;
593
let Inst{23} = ?; // add = (U == '1')
594
let Inst{22-21} = opcod;
595
let Inst{20} = 1; // load
596
let Inst{19-16} = 0b1111; // Rn
600
/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
601
multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
602
def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
603
opc, ".w\t$src, $addr",
604
[(opnode GPR:$src, t2addrmode_imm12:$addr)]> {
605
let Inst{31-27} = 0b11111;
606
let Inst{26-23} = 0b0001;
607
let Inst{22-21} = opcod;
608
let Inst{20} = 0; // !load
610
def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
611
opc, "\t$src, $addr",
612
[(opnode GPR:$src, t2addrmode_imm8:$addr)]> {
613
let Inst{31-27} = 0b11111;
614
let Inst{26-23} = 0b0000;
615
let Inst{22-21} = opcod;
616
let Inst{20} = 0; // !load
618
// Offset: index==TRUE, wback==FALSE
619
let Inst{10} = 1; // The P bit.
620
let Inst{8} = 0; // The W bit.
622
def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
623
opc, ".w\t$src, $addr",
624
[(opnode GPR:$src, t2addrmode_so_reg:$addr)]> {
625
let Inst{31-27} = 0b11111;
626
let Inst{26-23} = 0b0000;
627
let Inst{22-21} = opcod;
628
let Inst{20} = 0; // !load
629
let Inst{11-6} = 0b000000;
633
/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
634
/// register and one whose operand is a register rotated by 8/16/24.
635
multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
636
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
637
opc, ".w\t$dst, $src",
638
[(set GPR:$dst, (opnode GPR:$src))]> {
639
let Inst{31-27} = 0b11111;
640
let Inst{26-23} = 0b0100;
641
let Inst{22-20} = opcod;
642
let Inst{19-16} = 0b1111; // Rn
643
let Inst{15-12} = 0b1111;
645
let Inst{5-4} = 0b00; // rotate
647
def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
648
opc, ".w\t$dst, $src, ror $rot",
649
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
650
let Inst{31-27} = 0b11111;
651
let Inst{26-23} = 0b0100;
652
let Inst{22-20} = opcod;
653
let Inst{19-16} = 0b1111; // Rn
654
let Inst{15-12} = 0b1111;
656
let Inst{5-4} = {?,?}; // rotate
660
// SXTB16 and UXTB16 do not need the .w qualifier.
661
multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
662
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
664
[(set GPR:$dst, (opnode GPR:$src))]> {
665
let Inst{31-27} = 0b11111;
666
let Inst{26-23} = 0b0100;
667
let Inst{22-20} = opcod;
668
let Inst{19-16} = 0b1111; // Rn
669
let Inst{15-12} = 0b1111;
671
let Inst{5-4} = 0b00; // rotate
673
def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
674
opc, "\t$dst, $src, ror $rot",
675
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
676
let Inst{31-27} = 0b11111;
677
let Inst{26-23} = 0b0100;
678
let Inst{22-20} = opcod;
679
let Inst{19-16} = 0b1111; // Rn
680
let Inst{15-12} = 0b1111;
682
let Inst{5-4} = {?,?}; // rotate
686
// DO variant - disassembly only, no pattern
688
multiclass T2I_unary_rrot_DO<bits<3> opcod, string opc> {
689
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
690
opc, "\t$dst, $src", []> {
691
let Inst{31-27} = 0b11111;
692
let Inst{26-23} = 0b0100;
693
let Inst{22-20} = opcod;
694
let Inst{19-16} = 0b1111; // Rn
695
let Inst{15-12} = 0b1111;
697
let Inst{5-4} = 0b00; // rotate
699
def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
700
opc, "\t$dst, $src, ror $rot", []> {
701
let Inst{31-27} = 0b11111;
702
let Inst{26-23} = 0b0100;
703
let Inst{22-20} = opcod;
704
let Inst{19-16} = 0b1111; // Rn
705
let Inst{15-12} = 0b1111;
707
let Inst{5-4} = {?,?}; // rotate
711
/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
712
/// register and one whose operand is a register rotated by 8/16/24.
713
multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
714
def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
715
opc, "\t$dst, $LHS, $RHS",
716
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]> {
717
let Inst{31-27} = 0b11111;
718
let Inst{26-23} = 0b0100;
719
let Inst{22-20} = opcod;
720
let Inst{15-12} = 0b1111;
722
let Inst{5-4} = 0b00; // rotate
724
def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
725
IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
726
[(set GPR:$dst, (opnode GPR:$LHS,
727
(rotr GPR:$RHS, rot_imm:$rot)))]> {
728
let Inst{31-27} = 0b11111;
729
let Inst{26-23} = 0b0100;
730
let Inst{22-20} = opcod;
731
let Inst{15-12} = 0b1111;
733
let Inst{5-4} = {?,?}; // rotate
737
// DO variant - disassembly only, no pattern
739
multiclass T2I_bin_rrot_DO<bits<3> opcod, string opc> {
740
def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
741
opc, "\t$dst, $LHS, $RHS", []> {
742
let Inst{31-27} = 0b11111;
743
let Inst{26-23} = 0b0100;
744
let Inst{22-20} = opcod;
745
let Inst{15-12} = 0b1111;
747
let Inst{5-4} = 0b00; // rotate
749
def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
750
IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
751
let Inst{31-27} = 0b11111;
752
let Inst{26-23} = 0b0100;
753
let Inst{22-20} = opcod;
754
let Inst{15-12} = 0b1111;
756
let Inst{5-4} = {?,?}; // rotate
760
//===----------------------------------------------------------------------===//
762
//===----------------------------------------------------------------------===//
764
//===----------------------------------------------------------------------===//
765
// Miscellaneous Instructions.
768
// LEApcrel - Load a pc-relative address into a register without offending the
770
def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
771
"adr$p.w\t$dst, #$label", []> {
772
let Inst{31-27} = 0b11110;
773
let Inst{25-24} = 0b10;
774
// Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
777
let Inst{19-16} = 0b1111; // Rn
780
def t2LEApcrelJT : T2XI<(outs GPR:$dst),
781
(ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
782
"adr$p.w\t$dst, #${label}_${id}", []> {
783
let Inst{31-27} = 0b11110;
784
let Inst{25-24} = 0b10;
785
// Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
788
let Inst{19-16} = 0b1111; // Rn
792
// ADD r, sp, {so_imm|i12}
793
def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
794
IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []> {
795
let Inst{31-27} = 0b11110;
797
let Inst{24-21} = 0b1000;
798
let Inst{20} = ?; // The S bit.
799
let Inst{19-16} = 0b1101; // Rn = sp
802
def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
803
IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
804
let Inst{31-27} = 0b11110;
806
let Inst{24-21} = 0b0000;
807
let Inst{20} = 0; // The S bit.
808
let Inst{19-16} = 0b1101; // Rn = sp
813
def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
814
IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []> {
815
let Inst{31-27} = 0b11101;
816
let Inst{26-25} = 0b01;
817
let Inst{24-21} = 0b1000;
818
let Inst{20} = ?; // The S bit.
819
let Inst{19-16} = 0b1101; // Rn = sp
823
// SUB r, sp, {so_imm|i12}
824
def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
825
IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []> {
826
let Inst{31-27} = 0b11110;
828
let Inst{24-21} = 0b1101;
829
let Inst{20} = ?; // The S bit.
830
let Inst{19-16} = 0b1101; // Rn = sp
833
def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
834
IIC_iALUi, "subw", "\t$dst, $sp, $imm", []> {
835
let Inst{31-27} = 0b11110;
837
let Inst{24-21} = 0b0101;
838
let Inst{20} = 0; // The S bit.
839
let Inst{19-16} = 0b1101; // Rn = sp
844
def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
846
"sub", "\t$dst, $sp, $rhs", []> {
847
let Inst{31-27} = 0b11101;
848
let Inst{26-25} = 0b01;
849
let Inst{24-21} = 0b1101;
850
let Inst{20} = ?; // The S bit.
851
let Inst{19-16} = 0b1101; // Rn = sp
855
// Signed and unsigned division, for disassembly only
856
def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
857
"sdiv", "\t$dst, $a, $b", []> {
858
let Inst{31-27} = 0b11111;
859
let Inst{26-21} = 0b011100;
861
let Inst{15-12} = 0b1111;
862
let Inst{7-4} = 0b1111;
865
def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
866
"udiv", "\t$dst, $a, $b", []> {
867
let Inst{31-27} = 0b11111;
868
let Inst{26-21} = 0b011101;
870
let Inst{15-12} = 0b1111;
871
let Inst{7-4} = 0b1111;
874
// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
875
let usesCustomInserter = 1 in { // Expanded after instruction selection.
876
def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
877
NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
878
def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
879
NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
880
def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
881
NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
882
} // usesCustomInserter
885
//===----------------------------------------------------------------------===//
886
// Load / store Instructions.
890
let canFoldAsLoad = 1, isReMaterializable = 1 in
891
defm t2LDR : T2I_ld<0, 0b10, "ldr", UnOpFrag<(load node:$Src)>>;
893
// Loads with zero extension
894
defm t2LDRH : T2I_ld<0, 0b01, "ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
895
defm t2LDRB : T2I_ld<0, 0b00, "ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
897
// Loads with sign extension
898
defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
899
defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
901
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
903
def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
904
(ins t2addrmode_imm8s4:$addr),
905
IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
906
def t2LDRDpci : T2Ii8s4<?, ?, 1, (outs GPR:$dst1, GPR:$dst2),
907
(ins i32imm:$addr), IIC_iLoadi,
908
"ldrd", "\t$dst1, $addr", []> {
909
let Inst{19-16} = 0b1111; // Rn
913
// zextload i1 -> zextload i8
914
def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
915
(t2LDRBi12 t2addrmode_imm12:$addr)>;
916
def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
917
(t2LDRBi8 t2addrmode_imm8:$addr)>;
918
def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
919
(t2LDRBs t2addrmode_so_reg:$addr)>;
920
def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
921
(t2LDRBpci tconstpool:$addr)>;
923
// extload -> zextload
924
// FIXME: Reduce the number of patterns by legalizing extload to zextload
926
def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
927
(t2LDRBi12 t2addrmode_imm12:$addr)>;
928
def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
929
(t2LDRBi8 t2addrmode_imm8:$addr)>;
930
def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
931
(t2LDRBs t2addrmode_so_reg:$addr)>;
932
def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
933
(t2LDRBpci tconstpool:$addr)>;
935
def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
936
(t2LDRBi12 t2addrmode_imm12:$addr)>;
937
def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
938
(t2LDRBi8 t2addrmode_imm8:$addr)>;
939
def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
940
(t2LDRBs t2addrmode_so_reg:$addr)>;
941
def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
942
(t2LDRBpci tconstpool:$addr)>;
944
def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
945
(t2LDRHi12 t2addrmode_imm12:$addr)>;
946
def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
947
(t2LDRHi8 t2addrmode_imm8:$addr)>;
948
def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
949
(t2LDRHs t2addrmode_so_reg:$addr)>;
950
def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
951
(t2LDRHpci tconstpool:$addr)>;
955
def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb),
956
(ins t2addrmode_imm8:$addr),
957
AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
958
"ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
961
def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb),
962
(ins GPR:$base, t2am_imm8_offset:$offset),
963
AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
964
"ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
967
def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
968
(ins t2addrmode_imm8:$addr),
969
AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
970
"ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
972
def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
973
(ins GPR:$base, t2am_imm8_offset:$offset),
974
AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
975
"ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
978
def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
979
(ins t2addrmode_imm8:$addr),
980
AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
981
"ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
983
def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
984
(ins GPR:$base, t2am_imm8_offset:$offset),
985
AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
986
"ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
989
def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb),
990
(ins t2addrmode_imm8:$addr),
991
AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
992
"ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
994
def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb),
995
(ins GPR:$base, t2am_imm8_offset:$offset),
996
AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
997
"ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
1000
def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb),
1001
(ins t2addrmode_imm8:$addr),
1002
AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
1003
"ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
1005
def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1006
(ins GPR:$base, t2am_imm8_offset:$offset),
1007
AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
1008
"ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
1012
// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
1013
// for disassembly only.
1014
// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1015
class T2IldT<bit signed, bits<2> type, string opc>
1016
: T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
1017
"\t$dst, $addr", []> {
1018
let Inst{31-27} = 0b11111;
1019
let Inst{26-25} = 0b00;
1020
let Inst{24} = signed;
1022
let Inst{22-21} = type;
1023
let Inst{20} = 1; // load
1025
let Inst{10-8} = 0b110; // PUW.
1028
def t2LDRT : T2IldT<0, 0b10, "ldrt">;
1029
def t2LDRBT : T2IldT<0, 0b00, "ldrbt">;
1030
def t2LDRHT : T2IldT<0, 0b01, "ldrht">;
1031
def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt">;
1032
def t2LDRSHT : T2IldT<1, 0b01, "ldrsht">;
1035
defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
1036
defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1037
defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
1040
let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
1041
def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1042
(ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
1043
IIC_iStorer, "strd", "\t$src1, $addr", []>;
1046
def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb),
1047
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1048
AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1049
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1051
(pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1053
def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb),
1054
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1055
AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1056
"str", "\t$src, [$base], $offset", "$base = $base_wb",
1058
(post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1060
def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb),
1061
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1062
AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1063
"strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1065
(pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1067
def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb),
1068
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1069
AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1070
"strh", "\t$src, [$base], $offset", "$base = $base_wb",
1072
(post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1074
def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb),
1075
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1076
AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
1077
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1079
(pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1081
def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
1082
(ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
1083
AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
1084
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
1086
(post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
1088
// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1090
// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1091
class T2IstT<bits<2> type, string opc>
1092
: T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), IIC_iStorei, opc,
1093
"\t$src, $addr", []> {
1094
let Inst{31-27} = 0b11111;
1095
let Inst{26-25} = 0b00;
1096
let Inst{24} = 0; // not signed
1098
let Inst{22-21} = type;
1099
let Inst{20} = 0; // store
1101
let Inst{10-8} = 0b110; // PUW
1104
def t2STRT : T2IstT<0b10, "strt">;
1105
def t2STRBT : T2IstT<0b00, "strbt">;
1106
def t2STRHT : T2IstT<0b01, "strht">;
1108
// FIXME: ldrd / strd pre / post variants
1110
// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1111
// data/instruction access. These are for disassembly only.
1112
multiclass T2Ipl<bit instr, bit write, string opc> {
1114
def i12 : T2I<(outs), (ins t2addrmode_imm12:$addr), IIC_iLoadi, opc,
1116
let Inst{31-25} = 0b1111100;
1117
let Inst{24} = instr;
1118
let Inst{23} = 1; // U = 1
1120
let Inst{21} = write;
1122
let Inst{15-12} = 0b1111;
1125
def i8 : T2I<(outs), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
1127
let Inst{31-25} = 0b1111100;
1128
let Inst{24} = instr;
1129
let Inst{23} = 0; // U = 0
1131
let Inst{21} = write;
1133
let Inst{15-12} = 0b1111;
1134
let Inst{11-8} = 0b1100;
1137
// A8.6.118 #0 and #-0 differs. Translates -0 to -1, -1 to -2, ..., etc.
1138
def pci : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
1139
"\t[pc, ${imm:negzero}]", []> {
1140
let Inst{31-25} = 0b1111100;
1141
let Inst{24} = instr;
1142
let Inst{23} = ?; // add = (U == 1)
1144
let Inst{21} = write;
1146
let Inst{19-16} = 0b1111; // Rn = 0b1111
1147
let Inst{15-12} = 0b1111;
1150
def r : T2I<(outs), (ins GPR:$base, GPR:$a), IIC_iLoadi, opc,
1151
"\t[$base, $a]", []> {
1152
let Inst{31-25} = 0b1111100;
1153
let Inst{24} = instr;
1154
let Inst{23} = 0; // add = TRUE for T1
1156
let Inst{21} = write;
1158
let Inst{15-12} = 0b1111;
1159
let Inst{11-6} = 0000000;
1160
let Inst{5-4} = 0b00; // no shift is applied
1163
def s : T2I<(outs), (ins GPR:$base, GPR:$a, i32imm:$shamt), IIC_iLoadi, opc,
1164
"\t[$base, $a, lsl $shamt]", []> {
1165
let Inst{31-25} = 0b1111100;
1166
let Inst{24} = instr;
1167
let Inst{23} = 0; // add = TRUE for T1
1169
let Inst{21} = write;
1171
let Inst{15-12} = 0b1111;
1172
let Inst{11-6} = 0000000;
1176
defm t2PLD : T2Ipl<0, 0, "pld">;
1177
defm t2PLDW : T2Ipl<0, 1, "pldw">;
1178
defm t2PLI : T2Ipl<1, 0, "pli">;
1180
//===----------------------------------------------------------------------===//
1181
// Load / store multiple Instructions.
1184
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1185
def t2LDM : T2XI<(outs),
1186
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1187
IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1188
let Inst{31-27} = 0b11101;
1189
let Inst{26-25} = 0b00;
1190
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1192
let Inst{21} = ?; // The W bit.
1193
let Inst{20} = 1; // Load
1196
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1197
def t2STM : T2XI<(outs),
1198
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1199
IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
1200
let Inst{31-27} = 0b11101;
1201
let Inst{26-25} = 0b00;
1202
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
1204
let Inst{21} = ?; // The W bit.
1205
let Inst{20} = 0; // Store
1208
//===----------------------------------------------------------------------===//
1209
// Move Instructions.
1212
let neverHasSideEffects = 1 in
1213
def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
1214
"mov", ".w\t$dst, $src", []> {
1215
let Inst{31-27} = 0b11101;
1216
let Inst{26-25} = 0b01;
1217
let Inst{24-21} = 0b0010;
1218
let Inst{20} = ?; // The S bit.
1219
let Inst{19-16} = 0b1111; // Rn
1220
let Inst{14-12} = 0b000;
1221
let Inst{7-4} = 0b0000;
1224
// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1225
let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
1226
def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
1227
"mov", ".w\t$dst, $src",
1228
[(set GPR:$dst, t2_so_imm:$src)]> {
1229
let Inst{31-27} = 0b11110;
1231
let Inst{24-21} = 0b0010;
1232
let Inst{20} = ?; // The S bit.
1233
let Inst{19-16} = 0b1111; // Rn
1237
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1238
def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
1239
"movw", "\t$dst, $src",
1240
[(set GPR:$dst, imm0_65535:$src)]> {
1241
let Inst{31-27} = 0b11110;
1243
let Inst{24-21} = 0b0010;
1244
let Inst{20} = 0; // The S bit.
1248
let Constraints = "$src = $dst" in
1249
def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
1250
"movt", "\t$dst, $imm",
1252
(or (and GPR:$src, 0xffff), lo16AllZero:$imm))]> {
1253
let Inst{31-27} = 0b11110;
1255
let Inst{24-21} = 0b0110;
1256
let Inst{20} = 0; // The S bit.
1260
def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
1262
//===----------------------------------------------------------------------===//
1263
// Extend Instructions.
1268
defm t2SXTB : T2I_unary_rrot<0b100, "sxtb",
1269
UnOpFrag<(sext_inreg node:$Src, i8)>>;
1270
defm t2SXTH : T2I_unary_rrot<0b000, "sxth",
1271
UnOpFrag<(sext_inreg node:$Src, i16)>>;
1272
defm t2SXTB16 : T2I_unary_rrot_DO<0b010, "sxtb16">;
1274
defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
1275
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1276
defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
1277
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1278
defm t2SXTAB16 : T2I_bin_rrot_DO<0b010, "sxtab16">;
1280
// TODO: SXT(A){B|H}16 - done for disassembly only
1284
let AddedComplexity = 16 in {
1285
defm t2UXTB : T2I_unary_rrot<0b101, "uxtb",
1286
UnOpFrag<(and node:$Src, 0x000000FF)>>;
1287
defm t2UXTH : T2I_unary_rrot<0b001, "uxth",
1288
UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1289
defm t2UXTB16 : T2I_unary_rrot_nw<0b011, "uxtb16",
1290
UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1292
def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1293
(t2UXTB16r_rot GPR:$Src, 24)>;
1294
def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1295
(t2UXTB16r_rot GPR:$Src, 8)>;
1297
defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
1298
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1299
defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
1300
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1301
defm t2UXTAB16 : T2I_bin_rrot_DO<0b011, "uxtab16">;
1304
//===----------------------------------------------------------------------===//
1305
// Arithmetic Instructions.
1308
defm t2ADD : T2I_bin_ii12rs<0b000, "add",
1309
BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1310
defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
1311
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1313
// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
1314
defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
1315
BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1316
defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
1317
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1319
defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
1320
BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1321
defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
1322
BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1323
defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
1324
BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1325
defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
1326
BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
1329
defm t2RSB : T2I_rbin_is <0b1110, "rsb",
1330
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1331
defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
1332
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1334
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1335
let AddedComplexity = 1 in
1336
def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1337
(t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1338
def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1339
(t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1340
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1341
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1343
// Select Bytes -- for disassembly only
1345
def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
1346
"\t$dst, $a, $b", []> {
1347
let Inst{31-27} = 0b11111;
1348
let Inst{26-24} = 0b010;
1350
let Inst{22-20} = 0b010;
1351
let Inst{15-12} = 0b1111;
1353
let Inst{6-4} = 0b000;
1356
// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
1357
// And Miscellaneous operations -- for disassembly only
1358
class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc>
1359
: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, opc,
1360
"\t$dst, $a, $b", [/* For disassembly only; pattern left blank */]> {
1361
let Inst{31-27} = 0b11111;
1362
let Inst{26-23} = 0b0101;
1363
let Inst{22-20} = op22_20;
1364
let Inst{15-12} = 0b1111;
1365
let Inst{7-4} = op7_4;
1368
// Saturating add/subtract -- for disassembly only
1370
def t2QADD : T2I_pam<0b000, 0b1000, "qadd">;
1371
def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
1372
def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
1373
def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
1374
def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
1375
def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
1376
def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
1377
def t2QSUB : T2I_pam<0b000, 0b1010, "qsub">;
1378
def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
1379
def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
1380
def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
1381
def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
1382
def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
1383
def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
1384
def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
1385
def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
1387
// Signed/Unsigned add/subtract -- for disassembly only
1389
def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
1390
def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
1391
def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
1392
def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
1393
def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
1394
def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
1395
def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
1396
def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
1397
def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
1398
def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
1399
def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
1400
def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
1402
// Signed/Unsigned halving add/subtract -- for disassembly only
1404
def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
1405
def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
1406
def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
1407
def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
1408
def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
1409
def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
1410
def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
1411
def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
1412
def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
1413
def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
1414
def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
1415
def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
1417
// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1419
def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1420
NoItinerary, "usad8", "\t$dst, $a, $b", []> {
1421
let Inst{15-12} = 0b1111;
1423
def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst),
1424
(ins GPR:$a, GPR:$b, GPR:$acc), NoItinerary, "usada8",
1425
"\t$dst, $a, $b, $acc", []>;
1427
// Signed/Unsigned saturate -- for disassembly only
1429
def t2SSATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1430
NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1431
[/* For disassembly only; pattern left blank */]> {
1432
let Inst{31-27} = 0b11110;
1433
let Inst{25-22} = 0b1100;
1436
let Inst{21} = 0; // sh = '0'
1439
def t2SSATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1440
NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1441
[/* For disassembly only; pattern left blank */]> {
1442
let Inst{31-27} = 0b11110;
1443
let Inst{25-22} = 0b1100;
1446
let Inst{21} = 1; // sh = '1'
1449
def t2SSAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1450
"ssat16", "\t$dst, $bit_pos, $a",
1451
[/* For disassembly only; pattern left blank */]> {
1452
let Inst{31-27} = 0b11110;
1453
let Inst{25-22} = 0b1100;
1456
let Inst{21} = 1; // sh = '1'
1457
let Inst{14-12} = 0b000; // imm3 = '000'
1458
let Inst{7-6} = 0b00; // imm2 = '00'
1461
def t2USATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1462
NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1463
[/* For disassembly only; pattern left blank */]> {
1464
let Inst{31-27} = 0b11110;
1465
let Inst{25-22} = 0b1110;
1468
let Inst{21} = 0; // sh = '0'
1471
def t2USATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
1472
NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1473
[/* For disassembly only; pattern left blank */]> {
1474
let Inst{31-27} = 0b11110;
1475
let Inst{25-22} = 0b1110;
1478
let Inst{21} = 1; // sh = '1'
1481
def t2USAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
1482
"usat16", "\t$dst, $bit_pos, $a",
1483
[/* For disassembly only; pattern left blank */]> {
1484
let Inst{31-27} = 0b11110;
1485
let Inst{25-22} = 0b1110;
1488
let Inst{21} = 1; // sh = '1'
1489
let Inst{14-12} = 0b000; // imm3 = '000'
1490
let Inst{7-6} = 0b00; // imm2 = '00'
1493
//===----------------------------------------------------------------------===//
1494
// Shift and rotate Instructions.
1497
defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
1498
defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
1499
defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
1500
defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
1502
let Uses = [CPSR] in {
1503
def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1504
"rrx", "\t$dst, $src",
1505
[(set GPR:$dst, (ARMrrx GPR:$src))]> {
1506
let Inst{31-27} = 0b11101;
1507
let Inst{26-25} = 0b01;
1508
let Inst{24-21} = 0b0010;
1509
let Inst{20} = ?; // The S bit.
1510
let Inst{19-16} = 0b1111; // Rn
1511
let Inst{14-12} = 0b000;
1512
let Inst{7-4} = 0b0011;
1516
let Defs = [CPSR] in {
1517
def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1518
"lsrs.w\t$dst, $src, #1",
1519
[(set GPR:$dst, (ARMsrl_flag GPR:$src))]> {
1520
let Inst{31-27} = 0b11101;
1521
let Inst{26-25} = 0b01;
1522
let Inst{24-21} = 0b0010;
1523
let Inst{20} = 1; // The S bit.
1524
let Inst{19-16} = 0b1111; // Rn
1525
let Inst{5-4} = 0b01; // Shift type.
1526
// Shift amount = Inst{14-12:7-6} = 1.
1527
let Inst{14-12} = 0b000;
1528
let Inst{7-6} = 0b01;
1530
def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1531
"asrs.w\t$dst, $src, #1",
1532
[(set GPR:$dst, (ARMsra_flag GPR:$src))]> {
1533
let Inst{31-27} = 0b11101;
1534
let Inst{26-25} = 0b01;
1535
let Inst{24-21} = 0b0010;
1536
let Inst{20} = 1; // The S bit.
1537
let Inst{19-16} = 0b1111; // Rn
1538
let Inst{5-4} = 0b10; // Shift type.
1539
// Shift amount = Inst{14-12:7-6} = 1.
1540
let Inst{14-12} = 0b000;
1541
let Inst{7-6} = 0b01;
1545
//===----------------------------------------------------------------------===//
1546
// Bitwise Instructions.
1549
defm t2AND : T2I_bin_w_irs<0b0000, "and",
1550
BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1551
defm t2ORR : T2I_bin_w_irs<0b0010, "orr",
1552
BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1553
defm t2EOR : T2I_bin_w_irs<0b0100, "eor",
1554
BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1556
defm t2BIC : T2I_bin_w_irs<0b0001, "bic",
1557
BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1559
let Constraints = "$src = $dst" in
1560
def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1561
IIC_iUNAsi, "bfc", "\t$dst, $imm",
1562
[(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]> {
1563
let Inst{31-27} = 0b11110;
1565
let Inst{24-20} = 0b10110;
1566
let Inst{19-16} = 0b1111; // Rn
1570
def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1571
IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []> {
1572
let Inst{31-27} = 0b11110;
1574
let Inst{24-20} = 0b10100;
1578
def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1579
IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []> {
1580
let Inst{31-27} = 0b11110;
1582
let Inst{24-20} = 0b11100;
1586
// A8.6.18 BFI - Bitfield insert (Encoding T1)
1587
// Added for disassembler with the pattern field purposely left blank.
1588
// FIXME: Utilize this instruction in codgen.
1589
def t2BFI : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1590
IIC_iALUi, "bfi", "\t$dst, $src, $lsb, $width", []> {
1591
let Inst{31-27} = 0b11110;
1593
let Inst{24-20} = 0b10110;
1597
defm t2ORN : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or node:$LHS,
1600
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
1601
let AddedComplexity = 1 in
1602
defm t2MVN : T2I_un_irs <0b0011, "mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
1605
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
1606
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
1608
// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
1609
def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
1610
(t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
1611
Requires<[IsThumb2]>;
1613
def : T2Pat<(t2_so_imm_not:$src),
1614
(t2MVNi t2_so_imm_not:$src)>;
1616
//===----------------------------------------------------------------------===//
1617
// Multiply Instructions.
1619
let isCommutable = 1 in
1620
def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1621
"mul", "\t$dst, $a, $b",
1622
[(set GPR:$dst, (mul GPR:$a, GPR:$b))]> {
1623
let Inst{31-27} = 0b11111;
1624
let Inst{26-23} = 0b0110;
1625
let Inst{22-20} = 0b000;
1626
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1627
let Inst{7-4} = 0b0000; // Multiply
1630
def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1631
"mla", "\t$dst, $a, $b, $c",
1632
[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]> {
1633
let Inst{31-27} = 0b11111;
1634
let Inst{26-23} = 0b0110;
1635
let Inst{22-20} = 0b000;
1636
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1637
let Inst{7-4} = 0b0000; // Multiply
1640
def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1641
"mls", "\t$dst, $a, $b, $c",
1642
[(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]> {
1643
let Inst{31-27} = 0b11111;
1644
let Inst{26-23} = 0b0110;
1645
let Inst{22-20} = 0b000;
1646
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1647
let Inst{7-4} = 0b0001; // Multiply and Subtract
1650
// Extra precision multiplies with low / high results
1651
let neverHasSideEffects = 1 in {
1652
let isCommutable = 1 in {
1653
def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1654
"smull", "\t$ldst, $hdst, $a, $b", []> {
1655
let Inst{31-27} = 0b11111;
1656
let Inst{26-23} = 0b0111;
1657
let Inst{22-20} = 0b000;
1658
let Inst{7-4} = 0b0000;
1661
def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
1662
"umull", "\t$ldst, $hdst, $a, $b", []> {
1663
let Inst{31-27} = 0b11111;
1664
let Inst{26-23} = 0b0111;
1665
let Inst{22-20} = 0b010;
1666
let Inst{7-4} = 0b0000;
1670
// Multiply + accumulate
1671
def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1672
"smlal", "\t$ldst, $hdst, $a, $b", []>{
1673
let Inst{31-27} = 0b11111;
1674
let Inst{26-23} = 0b0111;
1675
let Inst{22-20} = 0b100;
1676
let Inst{7-4} = 0b0000;
1679
def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1680
"umlal", "\t$ldst, $hdst, $a, $b", []>{
1681
let Inst{31-27} = 0b11111;
1682
let Inst{26-23} = 0b0111;
1683
let Inst{22-20} = 0b110;
1684
let Inst{7-4} = 0b0000;
1687
def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
1688
"umaal", "\t$ldst, $hdst, $a, $b", []>{
1689
let Inst{31-27} = 0b11111;
1690
let Inst{26-23} = 0b0111;
1691
let Inst{22-20} = 0b110;
1692
let Inst{7-4} = 0b0110;
1694
} // neverHasSideEffects
1696
// Rounding variants of the below included for disassembly only
1698
// Most significant word multiply
1699
def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1700
"smmul", "\t$dst, $a, $b",
1701
[(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]> {
1702
let Inst{31-27} = 0b11111;
1703
let Inst{26-23} = 0b0110;
1704
let Inst{22-20} = 0b101;
1705
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1706
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1709
def t2SMMULR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1710
"smmulr", "\t$dst, $a, $b", []> {
1711
let Inst{31-27} = 0b11111;
1712
let Inst{26-23} = 0b0110;
1713
let Inst{22-20} = 0b101;
1714
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1715
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1718
def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1719
"smmla", "\t$dst, $a, $b, $c",
1720
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]> {
1721
let Inst{31-27} = 0b11111;
1722
let Inst{26-23} = 0b0110;
1723
let Inst{22-20} = 0b101;
1724
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1725
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1728
def t2SMMLAR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1729
"smmlar", "\t$dst, $a, $b, $c", []> {
1730
let Inst{31-27} = 0b11111;
1731
let Inst{26-23} = 0b0110;
1732
let Inst{22-20} = 0b101;
1733
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1734
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1737
def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1738
"smmls", "\t$dst, $a, $b, $c",
1739
[(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]> {
1740
let Inst{31-27} = 0b11111;
1741
let Inst{26-23} = 0b0110;
1742
let Inst{22-20} = 0b110;
1743
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1744
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
1747
def t2SMMLSR : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
1748
"smmlsr", "\t$dst, $a, $b, $c", []> {
1749
let Inst{31-27} = 0b11111;
1750
let Inst{26-23} = 0b0110;
1751
let Inst{22-20} = 0b110;
1752
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1753
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
1756
multiclass T2I_smul<string opc, PatFrag opnode> {
1757
def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1758
!strconcat(opc, "bb"), "\t$dst, $a, $b",
1759
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1760
(sext_inreg GPR:$b, i16)))]> {
1761
let Inst{31-27} = 0b11111;
1762
let Inst{26-23} = 0b0110;
1763
let Inst{22-20} = 0b001;
1764
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1765
let Inst{7-6} = 0b00;
1766
let Inst{5-4} = 0b00;
1769
def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1770
!strconcat(opc, "bt"), "\t$dst, $a, $b",
1771
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1772
(sra GPR:$b, (i32 16))))]> {
1773
let Inst{31-27} = 0b11111;
1774
let Inst{26-23} = 0b0110;
1775
let Inst{22-20} = 0b001;
1776
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1777
let Inst{7-6} = 0b00;
1778
let Inst{5-4} = 0b01;
1781
def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1782
!strconcat(opc, "tb"), "\t$dst, $a, $b",
1783
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1784
(sext_inreg GPR:$b, i16)))]> {
1785
let Inst{31-27} = 0b11111;
1786
let Inst{26-23} = 0b0110;
1787
let Inst{22-20} = 0b001;
1788
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1789
let Inst{7-6} = 0b00;
1790
let Inst{5-4} = 0b10;
1793
def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
1794
!strconcat(opc, "tt"), "\t$dst, $a, $b",
1795
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1796
(sra GPR:$b, (i32 16))))]> {
1797
let Inst{31-27} = 0b11111;
1798
let Inst{26-23} = 0b0110;
1799
let Inst{22-20} = 0b001;
1800
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1801
let Inst{7-6} = 0b00;
1802
let Inst{5-4} = 0b11;
1805
def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1806
!strconcat(opc, "wb"), "\t$dst, $a, $b",
1807
[(set GPR:$dst, (sra (opnode GPR:$a,
1808
(sext_inreg GPR:$b, i16)), (i32 16)))]> {
1809
let Inst{31-27} = 0b11111;
1810
let Inst{26-23} = 0b0110;
1811
let Inst{22-20} = 0b011;
1812
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1813
let Inst{7-6} = 0b00;
1814
let Inst{5-4} = 0b00;
1817
def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
1818
!strconcat(opc, "wt"), "\t$dst, $a, $b",
1819
[(set GPR:$dst, (sra (opnode GPR:$a,
1820
(sra GPR:$b, (i32 16))), (i32 16)))]> {
1821
let Inst{31-27} = 0b11111;
1822
let Inst{26-23} = 0b0110;
1823
let Inst{22-20} = 0b011;
1824
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
1825
let Inst{7-6} = 0b00;
1826
let Inst{5-4} = 0b01;
1831
multiclass T2I_smla<string opc, PatFrag opnode> {
1832
def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1833
!strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1834
[(set GPR:$dst, (add GPR:$acc,
1835
(opnode (sext_inreg GPR:$a, i16),
1836
(sext_inreg GPR:$b, i16))))]> {
1837
let Inst{31-27} = 0b11111;
1838
let Inst{26-23} = 0b0110;
1839
let Inst{22-20} = 0b001;
1840
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1841
let Inst{7-6} = 0b00;
1842
let Inst{5-4} = 0b00;
1845
def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1846
!strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1847
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1848
(sra GPR:$b, (i32 16)))))]> {
1849
let Inst{31-27} = 0b11111;
1850
let Inst{26-23} = 0b0110;
1851
let Inst{22-20} = 0b001;
1852
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1853
let Inst{7-6} = 0b00;
1854
let Inst{5-4} = 0b01;
1857
def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1858
!strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1859
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1860
(sext_inreg GPR:$b, i16))))]> {
1861
let Inst{31-27} = 0b11111;
1862
let Inst{26-23} = 0b0110;
1863
let Inst{22-20} = 0b001;
1864
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1865
let Inst{7-6} = 0b00;
1866
let Inst{5-4} = 0b10;
1869
def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1870
!strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1871
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1872
(sra GPR:$b, (i32 16)))))]> {
1873
let Inst{31-27} = 0b11111;
1874
let Inst{26-23} = 0b0110;
1875
let Inst{22-20} = 0b001;
1876
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1877
let Inst{7-6} = 0b00;
1878
let Inst{5-4} = 0b11;
1881
def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1882
!strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1883
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1884
(sext_inreg GPR:$b, i16)), (i32 16))))]> {
1885
let Inst{31-27} = 0b11111;
1886
let Inst{26-23} = 0b0110;
1887
let Inst{22-20} = 0b011;
1888
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1889
let Inst{7-6} = 0b00;
1890
let Inst{5-4} = 0b00;
1893
def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
1894
!strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1895
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1896
(sra GPR:$b, (i32 16))), (i32 16))))]> {
1897
let Inst{31-27} = 0b11111;
1898
let Inst{26-23} = 0b0110;
1899
let Inst{22-20} = 0b011;
1900
let Inst{15-12} = {?, ?, ?, ?}; // Ra
1901
let Inst{7-6} = 0b00;
1902
let Inst{5-4} = 0b01;
1906
defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1907
defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1909
// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
1910
def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs GPR:$ldst,GPR:$hdst),
1911
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1912
[/* For disassembly only; pattern left blank */]>;
1913
def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs GPR:$ldst,GPR:$hdst),
1914
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1915
[/* For disassembly only; pattern left blank */]>;
1916
def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs GPR:$ldst,GPR:$hdst),
1917
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1918
[/* For disassembly only; pattern left blank */]>;
1919
def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs GPR:$ldst,GPR:$hdst),
1920
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1921
[/* For disassembly only; pattern left blank */]>;
1923
// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1924
// These are for disassembly only.
1926
def t2SMUAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1927
IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
1928
let Inst{15-12} = 0b1111;
1930
def t2SMUADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1931
IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
1932
let Inst{15-12} = 0b1111;
1934
def t2SMUSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1935
IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
1936
let Inst{15-12} = 0b1111;
1938
def t2SMUSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1939
IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
1940
let Inst{15-12} = 0b1111;
1942
def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst),
1943
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlad",
1944
"\t$dst, $a, $b, $acc", []>;
1945
def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst),
1946
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smladx",
1947
"\t$dst, $a, $b, $acc", []>;
1948
def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst),
1949
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsd",
1950
"\t$dst, $a, $b, $acc", []>;
1951
def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst),
1952
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsdx",
1953
"\t$dst, $a, $b, $acc", []>;
1954
def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1955
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlald",
1956
"\t$ldst, $hdst, $a, $b", []>;
1957
def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1958
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaldx",
1959
"\t$ldst, $hdst, $a, $b", []>;
1960
def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs GPR:$ldst,GPR:$hdst),
1961
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsld",
1962
"\t$ldst, $hdst, $a, $b", []>;
1963
def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs GPR:$ldst,GPR:$hdst),
1964
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsldx",
1965
"\t$ldst, $hdst, $a, $b", []>;
1967
//===----------------------------------------------------------------------===//
1968
// Misc. Arithmetic Instructions.
1971
class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
1972
InstrItinClass itin, string opc, string asm, list<dag> pattern>
1973
: T2I<oops, iops, itin, opc, asm, pattern> {
1974
let Inst{31-27} = 0b11111;
1975
let Inst{26-22} = 0b01010;
1976
let Inst{21-20} = op1;
1977
let Inst{15-12} = 0b1111;
1978
let Inst{7-6} = 0b10;
1979
let Inst{5-4} = op2;
1982
def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1983
"clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
1985
def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1986
"rbit", "\t$dst, $src",
1987
[(set GPR:$dst, (ARMrbit GPR:$src))]>;
1989
def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1990
"rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
1992
def t2REV16 : T2I_misc<0b01, 0b01, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1993
"rev16", ".w\t$dst, $src",
1995
(or (and (srl GPR:$src, (i32 8)), 0xFF),
1996
(or (and (shl GPR:$src, (i32 8)), 0xFF00),
1997
(or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1998
(and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
2000
def t2REVSH : T2I_misc<0b01, 0b11, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2001
"revsh", ".w\t$dst, $src",
2004
(or (srl (and GPR:$src, 0xFF00), (i32 8)),
2005
(shl GPR:$src, (i32 8))), i16))]>;
2007
def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2008
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2009
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2010
(and (shl GPR:$src2, (i32 imm:$shamt)),
2012
let Inst{31-27} = 0b11101;
2013
let Inst{26-25} = 0b01;
2014
let Inst{24-20} = 0b01100;
2015
let Inst{5} = 0; // BT form
2019
// Alternate cases for PKHBT where identities eliminate some nodes.
2020
def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2021
(t2PKHBT GPR:$src1, GPR:$src2, 0)>;
2022
def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2023
(t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2025
def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2026
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2027
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2028
(and (sra GPR:$src2, imm16_31:$shamt),
2030
let Inst{31-27} = 0b11101;
2031
let Inst{26-25} = 0b01;
2032
let Inst{24-20} = 0b01100;
2033
let Inst{5} = 1; // TB form
2037
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
2038
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2039
def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2040
(t2PKHTB GPR:$src1, GPR:$src2, 16)>;
2041
def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
2042
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2043
(t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2045
//===----------------------------------------------------------------------===//
2046
// Comparison Instructions...
2049
defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
2050
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2051
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
2052
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2054
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
2055
// Compare-to-zero still works out, just not the relationals
2056
//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
2057
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2058
defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
2059
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2061
//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
2062
// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
2064
def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
2065
(t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
2067
defm t2TST : T2I_cmp_irs<0b0000, "tst",
2068
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
2069
defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
2070
BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
2072
// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
2073
// Short range conditional branch. Looks awesome for loops. Need to figure
2074
// out how to use this one.
2077
// Conditional moves
2078
// FIXME: should be able to write a pattern for ARMcmov, but can't use
2079
// a two-value operand where a dag node expects two operands. :(
2080
def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
2081
"mov", ".w\t$dst, $true",
2082
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2083
RegConstraint<"$false = $dst"> {
2084
let Inst{31-27} = 0b11101;
2085
let Inst{26-25} = 0b01;
2086
let Inst{24-21} = 0b0010;
2087
let Inst{20} = 0; // The S bit.
2088
let Inst{19-16} = 0b1111; // Rn
2089
let Inst{14-12} = 0b000;
2090
let Inst{7-4} = 0b0000;
2093
def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
2094
IIC_iCMOVi, "mov", ".w\t$dst, $true",
2095
[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2096
RegConstraint<"$false = $dst"> {
2097
let Inst{31-27} = 0b11110;
2099
let Inst{24-21} = 0b0010;
2100
let Inst{20} = 0; // The S bit.
2101
let Inst{19-16} = 0b1111; // Rn
2105
class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
2106
string opc, string asm, list<dag> pattern>
2107
: T2I<oops, iops, itin, opc, asm, pattern> {
2108
let Inst{31-27} = 0b11101;
2109
let Inst{26-25} = 0b01;
2110
let Inst{24-21} = 0b0010;
2111
let Inst{20} = 0; // The S bit.
2112
let Inst{19-16} = 0b1111; // Rn
2113
let Inst{5-4} = opcod; // Shift type.
2115
def t2MOVCClsl : T2I_movcc_sh<0b00, (outs GPR:$dst),
2116
(ins GPR:$false, GPR:$true, i32imm:$rhs),
2117
IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
2118
RegConstraint<"$false = $dst">;
2119
def t2MOVCClsr : T2I_movcc_sh<0b01, (outs GPR:$dst),
2120
(ins GPR:$false, GPR:$true, i32imm:$rhs),
2121
IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
2122
RegConstraint<"$false = $dst">;
2123
def t2MOVCCasr : T2I_movcc_sh<0b10, (outs GPR:$dst),
2124
(ins GPR:$false, GPR:$true, i32imm:$rhs),
2125
IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
2126
RegConstraint<"$false = $dst">;
2127
def t2MOVCCror : T2I_movcc_sh<0b11, (outs GPR:$dst),
2128
(ins GPR:$false, GPR:$true, i32imm:$rhs),
2129
IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
2130
RegConstraint<"$false = $dst">;
2132
//===----------------------------------------------------------------------===//
2133
// Atomic operations intrinsics
2136
// memory barriers protect the atomic sequences
2137
let hasSideEffects = 1 in {
2138
def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
2139
Pseudo, NoItinerary,
2141
[(ARMMemBarrierV7)]>,
2142
Requires<[IsThumb2]> {
2143
let Inst{31-4} = 0xF3BF8F5;
2144
// FIXME: add support for options other than a full system DMB
2145
let Inst{3-0} = 0b1111;
2148
def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
2149
Pseudo, NoItinerary,
2151
[(ARMSyncBarrierV7)]>,
2152
Requires<[IsThumb2]> {
2153
let Inst{31-4} = 0xF3BF8F4;
2154
// FIXME: add support for options other than a full system DSB
2155
let Inst{3-0} = 0b1111;
2159
// Helper class for multiclass T2MemB -- for disassembly only
2160
class T2I_memb<string opc, string asm>
2161
: T2I<(outs), (ins), NoItinerary, opc, asm,
2162
[/* For disassembly only; pattern left blank */]>,
2163
Requires<[IsThumb2, HasV7]> {
2164
let Inst{31-20} = 0xf3b;
2165
let Inst{15-14} = 0b10;
2169
multiclass T2MemB<bits<4> op7_4, string opc> {
2171
def st : T2I_memb<opc, "\tst"> {
2172
let Inst{7-4} = op7_4;
2173
let Inst{3-0} = 0b1110;
2176
def ish : T2I_memb<opc, "\tish"> {
2177
let Inst{7-4} = op7_4;
2178
let Inst{3-0} = 0b1011;
2181
def ishst : T2I_memb<opc, "\tishst"> {
2182
let Inst{7-4} = op7_4;
2183
let Inst{3-0} = 0b1010;
2186
def nsh : T2I_memb<opc, "\tnsh"> {
2187
let Inst{7-4} = op7_4;
2188
let Inst{3-0} = 0b0111;
2191
def nshst : T2I_memb<opc, "\tnshst"> {
2192
let Inst{7-4} = op7_4;
2193
let Inst{3-0} = 0b0110;
2196
def osh : T2I_memb<opc, "\tosh"> {
2197
let Inst{7-4} = op7_4;
2198
let Inst{3-0} = 0b0011;
2201
def oshst : T2I_memb<opc, "\toshst"> {
2202
let Inst{7-4} = op7_4;
2203
let Inst{3-0} = 0b0010;
2207
// These DMB variants are for disassembly only.
2208
defm t2DMB : T2MemB<0b0101, "dmb">;
2210
// These DSB variants are for disassembly only.
2211
defm t2DSB : T2MemB<0b0100, "dsb">;
2213
// ISB has only full system option -- for disassembly only
2214
def t2ISBsy : T2I_memb<"isb", ""> {
2215
let Inst{7-4} = 0b0110;
2216
let Inst{3-0} = 0b1111;
2219
class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2220
InstrItinClass itin, string opc, string asm, string cstr,
2221
list<dag> pattern, bits<4> rt2 = 0b1111>
2222
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2223
let Inst{31-27} = 0b11101;
2224
let Inst{26-20} = 0b0001101;
2225
let Inst{11-8} = rt2;
2226
let Inst{7-6} = 0b01;
2227
let Inst{5-4} = opcod;
2228
let Inst{3-0} = 0b1111;
2230
class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
2231
InstrItinClass itin, string opc, string asm, string cstr,
2232
list<dag> pattern, bits<4> rt2 = 0b1111>
2233
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
2234
let Inst{31-27} = 0b11101;
2235
let Inst{26-20} = 0b0001100;
2236
let Inst{11-8} = rt2;
2237
let Inst{7-6} = 0b01;
2238
let Inst{5-4} = opcod;
2241
let mayLoad = 1 in {
2242
def t2LDREXB : T2I_ldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2243
Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
2245
def t2LDREXH : T2I_ldrex<0b01, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2246
Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
2248
def t2LDREX : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
2249
Size4Bytes, NoItinerary,
2250
"ldrex", "\t$dest, [$ptr]", "",
2252
let Inst{31-27} = 0b11101;
2253
let Inst{26-20} = 0b0000101;
2254
let Inst{11-8} = 0b1111;
2255
let Inst{7-0} = 0b00000000; // imm8 = 0
2257
def t2LDREXD : T2I_ldrex<0b11, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2258
AddrModeNone, Size4Bytes, NoItinerary,
2259
"ldrexd", "\t$dest, $dest2, [$ptr]", "",
2263
let mayStore = 1, Constraints = "@earlyclobber $success" in {
2264
def t2STREXB : T2I_strex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2265
AddrModeNone, Size4Bytes, NoItinerary,
2266
"strexb", "\t$success, $src, [$ptr]", "", []>;
2267
def t2STREXH : T2I_strex<0b01, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2268
AddrModeNone, Size4Bytes, NoItinerary,
2269
"strexh", "\t$success, $src, [$ptr]", "", []>;
2270
def t2STREX : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2271
AddrModeNone, Size4Bytes, NoItinerary,
2272
"strex", "\t$success, $src, [$ptr]", "",
2274
let Inst{31-27} = 0b11101;
2275
let Inst{26-20} = 0b0000100;
2276
let Inst{7-0} = 0b00000000; // imm8 = 0
2278
def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
2279
(ins GPR:$src, GPR:$src2, GPR:$ptr),
2280
AddrModeNone, Size4Bytes, NoItinerary,
2281
"strexd", "\t$success, $src, $src2, [$ptr]", "", [],
2285
// Clear-Exclusive is for disassembly only.
2286
def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
2287
[/* For disassembly only; pattern left blank */]>,
2288
Requires<[IsARM, HasV7]> {
2289
let Inst{31-20} = 0xf3b;
2290
let Inst{15-14} = 0b10;
2292
let Inst{7-4} = 0b0010;
2295
//===----------------------------------------------------------------------===//
2299
// __aeabi_read_tp preserves the registers r1-r3.
2301
Defs = [R0, R12, LR, CPSR] in {
2302
def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
2303
"bl\t__aeabi_read_tp",
2304
[(set R0, ARMthread_pointer)]> {
2305
let Inst{31-27} = 0b11110;
2306
let Inst{15-14} = 0b11;
2311
//===----------------------------------------------------------------------===//
2312
// SJLJ Exception handling intrinsics
2313
// eh_sjlj_setjmp() is an instruction sequence to store the return
2314
// address and save #0 in R0 for the non-longjmp case.
2315
// Since by its nature we may be coming from some other function to get
2316
// here, and we're using the stack frame for the containing function to
2317
// save/restore registers, we can't keep anything live in regs across
2318
// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2319
// when we get here from a longjmp(). We force everthing out of registers
2320
// except for our own input by listing the relevant registers in Defs. By
2321
// doing so, we also cause the prologue/epilogue code to actively preserve
2322
// all of the callee-saved resgisters, which is exactly what we want.
2323
// The current SP is passed in $val, and we reuse the reg as a scratch.
2325
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2326
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2327
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2329
def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
2330
AddrModeNone, SizeSpecial, NoItinerary,
2331
"str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
2333
"\tadds\t$val, #9\n"
2334
"\tstr\t$val, [$src, #4]\n"
2337
"\tmovs\tr0, #1\t@ end eh.setjmp\n"
2339
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
2344
//===----------------------------------------------------------------------===//
2345
// Control-Flow Instructions
2348
// FIXME: remove when we have a way to marking a MI with these properties.
2349
// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
2351
// FIXME: Should pc be an implicit operand like PICADD, etc?
2352
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
2353
hasExtraDefRegAllocReq = 1 in
2354
def t2LDM_RET : T2XI<(outs),
2355
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
2356
IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
2358
let Inst{31-27} = 0b11101;
2359
let Inst{26-25} = 0b00;
2360
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
2362
let Inst{21} = ?; // The W bit.
2363
let Inst{20} = 1; // Load
2366
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2367
let isPredicable = 1 in
2368
def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
2370
[(br bb:$target)]> {
2371
let Inst{31-27} = 0b11110;
2372
let Inst{15-14} = 0b10;
2376
let isNotDuplicable = 1, isIndirectBranch = 1 in {
2379
(ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
2380
IIC_Br, "mov\tpc, $target\n$jt",
2381
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
2382
let Inst{31-27} = 0b11101;
2383
let Inst{26-20} = 0b0100100;
2384
let Inst{19-16} = 0b1111;
2385
let Inst{14-12} = 0b000;
2386
let Inst{11-8} = 0b1111; // Rd = pc
2387
let Inst{7-4} = 0b0000;
2390
// FIXME: Add a non-pc based case that can be predicated.
2393
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2394
IIC_Br, "tbb\t$index\n$jt", []> {
2395
let Inst{31-27} = 0b11101;
2396
let Inst{26-20} = 0b0001101;
2397
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2398
let Inst{15-8} = 0b11110000;
2399
let Inst{7-4} = 0b0000; // B form
2404
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
2405
IIC_Br, "tbh\t$index\n$jt", []> {
2406
let Inst{31-27} = 0b11101;
2407
let Inst{26-20} = 0b0001101;
2408
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
2409
let Inst{15-8} = 0b11110000;
2410
let Inst{7-4} = 0b0001; // H form
2413
// Generic versions of the above two instructions, for disassembly only
2415
def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2416
"tbb", "\t[$a, $b]", []>{
2417
let Inst{31-27} = 0b11101;
2418
let Inst{26-20} = 0b0001101;
2419
let Inst{15-8} = 0b11110000;
2420
let Inst{7-4} = 0b0000; // B form
2423
def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
2424
"tbh", "\t[$a, $b, lsl #1]", []> {
2425
let Inst{31-27} = 0b11101;
2426
let Inst{26-20} = 0b0001101;
2427
let Inst{15-8} = 0b11110000;
2428
let Inst{7-4} = 0b0001; // H form
2430
} // isNotDuplicable, isIndirectBranch
2432
} // isBranch, isTerminator, isBarrier
2434
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
2435
// a two-value operand where a dag node expects two operands. :(
2436
let isBranch = 1, isTerminator = 1 in
2437
def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
2439
[/*(ARMbrcond bb:$target, imm:$cc)*/]> {
2440
let Inst{31-27} = 0b11110;
2441
let Inst{15-14} = 0b10;
2447
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
2448
AddrModeNone, Size2Bytes, IIC_iALUx,
2449
"it$mask\t$cc", "", []> {
2450
// 16-bit instruction.
2451
let Inst{31-16} = 0x0000;
2452
let Inst{15-8} = 0b10111111;
2455
// Branch and Exchange Jazelle -- for disassembly only
2457
def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
2458
[/* For disassembly only; pattern left blank */]> {
2459
let Inst{31-27} = 0b11110;
2461
let Inst{25-20} = 0b111100;
2462
let Inst{15-14} = 0b10;
2466
// Change Processor State is a system instruction -- for disassembly only.
2467
// The singleton $opt operand contains the following information:
2468
// opt{4-0} = mode from Inst{4-0}
2469
// opt{5} = changemode from Inst{17}
2470
// opt{8-6} = AIF from Inst{8-6}
2471
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
2472
def t2CPS : T2XI<(outs),(ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
2473
[/* For disassembly only; pattern left blank */]> {
2474
let Inst{31-27} = 0b11110;
2476
let Inst{25-20} = 0b111010;
2477
let Inst{15-14} = 0b10;
2481
// A6.3.4 Branches and miscellaneous control
2482
// Table A6-14 Change Processor State, and hint instructions
2483
// Helper class for disassembly only.
2484
class T2I_hint<bits<8> op7_0, string opc, string asm>
2485
: T2I<(outs), (ins), NoItinerary, opc, asm,
2486
[/* For disassembly only; pattern left blank */]> {
2487
let Inst{31-20} = 0xf3a;
2488
let Inst{15-14} = 0b10;
2490
let Inst{10-8} = 0b000;
2491
let Inst{7-0} = op7_0;
2494
def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
2495
def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
2496
def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
2497
def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
2498
def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
2500
def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
2501
[/* For disassembly only; pattern left blank */]> {
2502
let Inst{31-20} = 0xf3a;
2503
let Inst{15-14} = 0b10;
2505
let Inst{10-8} = 0b000;
2506
let Inst{7-4} = 0b1111;
2509
// Secure Monitor Call is a system instruction -- for disassembly only
2510
// Option = Inst{19-16}
2511
def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
2512
[/* For disassembly only; pattern left blank */]> {
2513
let Inst{31-27} = 0b11110;
2514
let Inst{26-20} = 0b1111111;
2515
let Inst{15-12} = 0b1000;
2518
// Store Return State is a system instruction -- for disassembly only
2519
def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
2520
[/* For disassembly only; pattern left blank */]> {
2521
let Inst{31-27} = 0b11101;
2522
let Inst{26-20} = 0b0000010; // W = 1
2525
def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
2526
[/* For disassembly only; pattern left blank */]> {
2527
let Inst{31-27} = 0b11101;
2528
let Inst{26-20} = 0b0000000; // W = 0
2531
def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
2532
[/* For disassembly only; pattern left blank */]> {
2533
let Inst{31-27} = 0b11101;
2534
let Inst{26-20} = 0b0011010; // W = 1
2537
def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
2538
[/* For disassembly only; pattern left blank */]> {
2539
let Inst{31-27} = 0b11101;
2540
let Inst{26-20} = 0b0011000; // W = 0
2543
// Return From Exception is a system instruction -- for disassembly only
2544
def t2RFEDBW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfedb", "\t$base!",
2545
[/* For disassembly only; pattern left blank */]> {
2546
let Inst{31-27} = 0b11101;
2547
let Inst{26-20} = 0b0000011; // W = 1
2550
def t2RFEDB : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeab", "\t$base",
2551
[/* For disassembly only; pattern left blank */]> {
2552
let Inst{31-27} = 0b11101;
2553
let Inst{26-20} = 0b0000001; // W = 0
2556
def t2RFEIAW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base!",
2557
[/* For disassembly only; pattern left blank */]> {
2558
let Inst{31-27} = 0b11101;
2559
let Inst{26-20} = 0b0011011; // W = 1
2562
def t2RFEIA : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base",
2563
[/* For disassembly only; pattern left blank */]> {
2564
let Inst{31-27} = 0b11101;
2565
let Inst{26-20} = 0b0011001; // W = 0
2568
//===----------------------------------------------------------------------===//
2569
// Non-Instruction Patterns
2572
// Two piece so_imms.
2573
def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
2574
(t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2575
(t2_so_imm2part_2 imm:$RHS))>;
2576
def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
2577
(t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2578
(t2_so_imm2part_2 imm:$RHS))>;
2579
def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
2580
(t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
2581
(t2_so_imm2part_2 imm:$RHS))>;
2582
def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
2583
(t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
2584
(t2_so_neg_imm2part_2 imm:$RHS))>;
2586
// 32-bit immediate using movw + movt.
2587
// This is a single pseudo instruction to make it re-materializable. Remove
2588
// when we can do generalized remat.
2589
let isReMaterializable = 1 in
2590
def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
2591
"movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2592
[(set GPR:$dst, (i32 imm:$src))]>;
2594
// ConstantPool, GlobalAddress, and JumpTable
2595
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
2596
Requires<[IsThumb2, DontUseMovt]>;
2597
def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
2598
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
2599
Requires<[IsThumb2, UseMovt]>;
2601
def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2602
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
2604
// Pseudo instruction that combines ldr from constpool and add pc. This should
2605
// be expanded into two instructions late to allow if-conversion and
2607
let canFoldAsLoad = 1, isReMaterializable = 1 in
2608
def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
2609
NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
2610
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
2612
Requires<[IsThumb2]>;
2614
//===----------------------------------------------------------------------===//
2615
// Move between special register and ARM core register -- for disassembly only
2619
def t2MRS : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
2620
[/* For disassembly only; pattern left blank */]> {
2621
let Inst{31-27} = 0b11110;
2623
let Inst{25-21} = 0b11111;
2624
let Inst{20} = 0; // The R bit.
2625
let Inst{15-14} = 0b10;
2630
def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
2631
[/* For disassembly only; pattern left blank */]> {
2632
let Inst{31-27} = 0b11110;
2634
let Inst{25-21} = 0b11111;
2635
let Inst{20} = 1; // The R bit.
2636
let Inst{15-14} = 0b10;
2640
// FIXME: mask is ignored for the time being.
2642
def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2643
[/* For disassembly only; pattern left blank */]> {
2644
let Inst{31-27} = 0b11110;
2646
let Inst{25-21} = 0b11100;
2647
let Inst{20} = 0; // The R bit.
2648
let Inst{15-14} = 0b10;
2652
// FIXME: mask is ignored for the time being.
2654
def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src",
2655
[/* For disassembly only; pattern left blank */]> {
2656
let Inst{31-27} = 0b11110;
2658
let Inst{25-21} = 0b11100;
2659
let Inst{20} = 1; // The R bit.
2660
let Inst{15-14} = 0b10;