1
//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
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 ARM instructions in TableGen format.
12
//===----------------------------------------------------------------------===//
14
//===----------------------------------------------------------------------===//
15
// ARM specific DAG Nodes.
19
def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20
def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22
def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24
def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
26
def SDT_ARMCMov : SDTypeProfile<1, 3,
27
[SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30
def SDT_ARMBrcond : SDTypeProfile<0, 2,
31
[SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33
def SDT_ARMBrJT : SDTypeProfile<0, 3,
34
[SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37
def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38
[SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39
SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41
def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
43
def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44
SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
46
def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47
def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
50
def SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>;
51
def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
52
def SDT_ARMMEMBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
53
def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
56
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
57
def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
59
def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
60
[SDNPHasChain, SDNPOutFlag]>;
61
def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
62
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
64
def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
65
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
66
def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
67
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
68
def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
69
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
71
def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
72
[SDNPHasChain, SDNPOptInFlag]>;
74
def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
76
def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
79
def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
80
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
82
def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
84
def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
87
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
90
def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
91
[SDNPOutFlag,SDNPCommutative]>;
93
def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
95
def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96
def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
97
def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
99
def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
100
def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
102
def ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
104
def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
106
def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
108
def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
111
def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
113
//===----------------------------------------------------------------------===//
114
// ARM Instruction Predicate Definitions.
116
def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
117
def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
118
def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
119
def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
120
def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
121
def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
122
def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
123
def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
124
def HasNEON : Predicate<"Subtarget->hasNEON()">;
125
def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
126
def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
127
def IsThumb : Predicate<"Subtarget->isThumb()">;
128
def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
129
def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
130
def IsARM : Predicate<"!Subtarget->isThumb()">;
131
def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
132
def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
134
// FIXME: Eventually this will be just "hasV6T2Ops".
135
def UseMovt : Predicate<"Subtarget->useMovt()">;
136
def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
138
//===----------------------------------------------------------------------===//
139
// ARM Flag Definitions.
141
class RegConstraint<string C> {
142
string Constraints = C;
145
//===----------------------------------------------------------------------===//
146
// ARM specific transformation functions and pattern fragments.
149
// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
150
// so_imm_neg def below.
151
def so_imm_neg_XFORM : SDNodeXForm<imm, [{
152
return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
155
// so_imm_not_XFORM - Return a so_imm value packed into the format described for
156
// so_imm_not def below.
157
def so_imm_not_XFORM : SDNodeXForm<imm, [{
158
return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
161
// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
162
def rot_imm : PatLeaf<(i32 imm), [{
163
int32_t v = (int32_t)N->getZExtValue();
164
return v == 8 || v == 16 || v == 24;
167
/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
168
def imm1_15 : PatLeaf<(i32 imm), [{
169
return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
172
/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
173
def imm16_31 : PatLeaf<(i32 imm), [{
174
return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
179
return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
180
}], so_imm_neg_XFORM>;
184
return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
185
}], so_imm_not_XFORM>;
187
// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
188
def sext_16_node : PatLeaf<(i32 GPR:$a), [{
189
return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
192
/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
194
def bf_inv_mask_imm : Operand<i32>,
196
uint32_t v = (uint32_t)N->getZExtValue();
199
// there can be 1's on either or both "outsides", all the "inside"
201
unsigned int lsb = 0, msb = 31;
202
while (v & (1 << msb)) --msb;
203
while (v & (1 << lsb)) ++lsb;
204
for (unsigned int i = lsb; i <= msb; ++i) {
210
let PrintMethod = "printBitfieldInvMaskImmOperand";
213
/// Split a 32-bit immediate into two 16 bit parts.
214
def lo16 : SDNodeXForm<imm, [{
215
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
219
def hi16 : SDNodeXForm<imm, [{
220
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
223
def lo16AllZero : PatLeaf<(i32 imm), [{
224
// Returns true if all low 16-bits are 0.
225
return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
228
/// imm0_65535 predicate - True if the 32-bit immediate is in the range
230
def imm0_65535 : PatLeaf<(i32 imm), [{
231
return (uint32_t)N->getZExtValue() < 65536;
234
class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
235
class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
237
/// adde and sube predicates - True based on whether the carry flag output
238
/// will be needed or not.
239
def adde_dead_carry :
240
PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
241
[{return !N->hasAnyUseOfValue(1);}]>;
242
def sube_dead_carry :
243
PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
244
[{return !N->hasAnyUseOfValue(1);}]>;
245
def adde_live_carry :
246
PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
247
[{return N->hasAnyUseOfValue(1);}]>;
248
def sube_live_carry :
249
PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
250
[{return N->hasAnyUseOfValue(1);}]>;
252
//===----------------------------------------------------------------------===//
253
// Operand Definitions.
257
def brtarget : Operand<OtherVT>;
259
// A list of registers separated by comma. Used by load/store multiple.
260
def reglist : Operand<i32> {
261
let PrintMethod = "printRegisterList";
264
// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
265
def cpinst_operand : Operand<i32> {
266
let PrintMethod = "printCPInstOperand";
269
def jtblock_operand : Operand<i32> {
270
let PrintMethod = "printJTBlockOperand";
272
def jt2block_operand : Operand<i32> {
273
let PrintMethod = "printJT2BlockOperand";
277
def pclabel : Operand<i32> {
278
let PrintMethod = "printPCLabel";
281
// shifter_operand operands: so_reg and so_imm.
282
def so_reg : Operand<i32>, // reg reg imm
283
ComplexPattern<i32, 3, "SelectShifterOperandReg",
284
[shl,srl,sra,rotr]> {
285
let PrintMethod = "printSORegOperand";
286
let MIOperandInfo = (ops GPR, GPR, i32imm);
289
// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
290
// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
291
// represented in the imm field in the same 12-bit form that they are encoded
292
// into so_imm instructions: the 8-bit immediate is the least significant bits
293
// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
294
def so_imm : Operand<i32>,
296
return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
298
let PrintMethod = "printSOImmOperand";
301
// Break so_imm's up into two pieces. This handles immediates with up to 16
302
// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
303
// get the first/second pieces.
304
def so_imm2part : Operand<i32>,
306
return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
308
let PrintMethod = "printSOImm2PartOperand";
311
def so_imm2part_1 : SDNodeXForm<imm, [{
312
unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
313
return CurDAG->getTargetConstant(V, MVT::i32);
316
def so_imm2part_2 : SDNodeXForm<imm, [{
317
unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
318
return CurDAG->getTargetConstant(V, MVT::i32);
321
def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
322
return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
324
let PrintMethod = "printSOImm2PartOperand";
327
def so_neg_imm2part_1 : SDNodeXForm<imm, [{
328
unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
329
return CurDAG->getTargetConstant(V, MVT::i32);
332
def so_neg_imm2part_2 : SDNodeXForm<imm, [{
333
unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
334
return CurDAG->getTargetConstant(V, MVT::i32);
337
/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
338
def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
339
return (int32_t)N->getZExtValue() < 32;
342
// Define ARM specific addressing modes.
344
// addrmode2 := reg +/- reg shop imm
345
// addrmode2 := reg +/- imm12
347
def addrmode2 : Operand<i32>,
348
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
349
let PrintMethod = "printAddrMode2Operand";
350
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
353
def am2offset : Operand<i32>,
354
ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
355
let PrintMethod = "printAddrMode2OffsetOperand";
356
let MIOperandInfo = (ops GPR, i32imm);
359
// addrmode3 := reg +/- reg
360
// addrmode3 := reg +/- imm8
362
def addrmode3 : Operand<i32>,
363
ComplexPattern<i32, 3, "SelectAddrMode3", []> {
364
let PrintMethod = "printAddrMode3Operand";
365
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
368
def am3offset : Operand<i32>,
369
ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
370
let PrintMethod = "printAddrMode3OffsetOperand";
371
let MIOperandInfo = (ops GPR, i32imm);
374
// addrmode4 := reg, <mode|W>
376
def addrmode4 : Operand<i32>,
377
ComplexPattern<i32, 2, "SelectAddrMode4", []> {
378
let PrintMethod = "printAddrMode4Operand";
379
let MIOperandInfo = (ops GPR, i32imm);
382
// addrmode5 := reg +/- imm8*4
384
def addrmode5 : Operand<i32>,
385
ComplexPattern<i32, 2, "SelectAddrMode5", []> {
386
let PrintMethod = "printAddrMode5Operand";
387
let MIOperandInfo = (ops GPR, i32imm);
390
// addrmode6 := reg with optional writeback
392
def addrmode6 : Operand<i32>,
393
ComplexPattern<i32, 4, "SelectAddrMode6", []> {
394
let PrintMethod = "printAddrMode6Operand";
395
let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
398
// addrmodepc := pc + reg
400
def addrmodepc : Operand<i32>,
401
ComplexPattern<i32, 2, "SelectAddrModePC", []> {
402
let PrintMethod = "printAddrModePCOperand";
403
let MIOperandInfo = (ops GPR, i32imm);
406
def nohash_imm : Operand<i32> {
407
let PrintMethod = "printNoHashImmediate";
410
//===----------------------------------------------------------------------===//
412
include "ARMInstrFormats.td"
414
//===----------------------------------------------------------------------===//
415
// Multiclass helpers...
418
/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
419
/// binop that produces a value.
420
multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
421
bit Commutable = 0> {
422
def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
423
IIC_iALUi, opc, "\t$dst, $a, $b",
424
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
427
def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
428
IIC_iALUr, opc, "\t$dst, $a, $b",
429
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
430
let Inst{11-4} = 0b00000000;
432
let isCommutable = Commutable;
434
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
435
IIC_iALUsr, opc, "\t$dst, $a, $b",
436
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
441
/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
442
/// instruction modifies the CPSR register.
443
let Defs = [CPSR] in {
444
multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
445
bit Commutable = 0> {
446
def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
447
IIC_iALUi, opc, "\t$dst, $a, $b",
448
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
452
def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
453
IIC_iALUr, opc, "\t$dst, $a, $b",
454
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
455
let isCommutable = Commutable;
456
let Inst{11-4} = 0b00000000;
460
def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
461
IIC_iALUsr, opc, "\t$dst, $a, $b",
462
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
469
/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
470
/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
471
/// a explicit result, only implicitly set CPSR.
472
let Defs = [CPSR] in {
473
multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
474
bit Commutable = 0> {
475
def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
477
[(opnode GPR:$a, so_imm:$b)]> {
481
def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
483
[(opnode GPR:$a, GPR:$b)]> {
484
let Inst{11-4} = 0b00000000;
487
let isCommutable = Commutable;
489
def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
491
[(opnode GPR:$a, so_reg:$b)]> {
498
/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
499
/// register and one whose operand is a register rotated by 8/16/24.
500
/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
501
multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
502
def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
503
IIC_iUNAr, opc, "\t$dst, $src",
504
[(set GPR:$dst, (opnode GPR:$src))]>,
505
Requires<[IsARM, HasV6]> {
506
let Inst{11-10} = 0b00;
507
let Inst{19-16} = 0b1111;
509
def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
510
IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
511
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
512
Requires<[IsARM, HasV6]> {
513
let Inst{19-16} = 0b1111;
517
multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
518
def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
519
IIC_iUNAr, opc, "\t$dst, $src",
520
[/* For disassembly only; pattern left blank */]>,
521
Requires<[IsARM, HasV6]> {
522
let Inst{11-10} = 0b00;
523
let Inst{19-16} = 0b1111;
525
def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
526
IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
527
[/* For disassembly only; pattern left blank */]>,
528
Requires<[IsARM, HasV6]> {
529
let Inst{19-16} = 0b1111;
533
/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
534
/// register and one whose operand is a register rotated by 8/16/24.
535
multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
536
def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
537
IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
538
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
539
Requires<[IsARM, HasV6]> {
540
let Inst{11-10} = 0b00;
542
def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
544
IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
545
[(set GPR:$dst, (opnode GPR:$LHS,
546
(rotr GPR:$RHS, rot_imm:$rot)))]>,
547
Requires<[IsARM, HasV6]>;
550
// For disassembly only.
551
multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
552
def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
553
IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
554
[/* For disassembly only; pattern left blank */]>,
555
Requires<[IsARM, HasV6]> {
556
let Inst{11-10} = 0b00;
558
def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
560
IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
561
[/* For disassembly only; pattern left blank */]>,
562
Requires<[IsARM, HasV6]>;
565
/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
566
let Uses = [CPSR] in {
567
multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
568
bit Commutable = 0> {
569
def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
570
DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
571
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
575
def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
576
DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
577
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
579
let isCommutable = Commutable;
580
let Inst{11-4} = 0b00000000;
583
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
584
DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
585
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
590
// Carry setting variants
591
let Defs = [CPSR] in {
592
multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
593
bit Commutable = 0> {
594
def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
595
DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
596
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
601
def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
602
DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
603
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
605
let Inst{11-4} = 0b00000000;
609
def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
610
DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
611
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
620
//===----------------------------------------------------------------------===//
622
//===----------------------------------------------------------------------===//
624
//===----------------------------------------------------------------------===//
625
// Miscellaneous Instructions.
628
/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
629
/// the function. The first operand is the ID# for this instruction, the second
630
/// is the index into the MachineConstantPool that this is, the third is the
631
/// size in bytes of this constant pool entry.
632
let neverHasSideEffects = 1, isNotDuplicable = 1 in
633
def CONSTPOOL_ENTRY :
634
PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
635
i32imm:$size), NoItinerary,
636
"${instid:label} ${cpidx:cpentry}", []>;
638
// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
639
// from removing one half of the matched pairs. That breaks PEI, which assumes
640
// these will always be in pairs, and asserts if it finds otherwise. Better way?
641
let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
643
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
644
"@ ADJCALLSTACKUP $amt1",
645
[(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
647
def ADJCALLSTACKDOWN :
648
PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
649
"@ ADJCALLSTACKDOWN $amt",
650
[(ARMcallseq_start timm:$amt)]>;
653
def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
654
[/* For disassembly only; pattern left blank */]>,
655
Requires<[IsARM, HasV6T2]> {
656
let Inst{27-16} = 0b001100100000;
657
let Inst{7-0} = 0b00000000;
660
def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
661
[/* For disassembly only; pattern left blank */]>,
662
Requires<[IsARM, HasV6T2]> {
663
let Inst{27-16} = 0b001100100000;
664
let Inst{7-0} = 0b00000001;
667
def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
668
[/* For disassembly only; pattern left blank */]>,
669
Requires<[IsARM, HasV6T2]> {
670
let Inst{27-16} = 0b001100100000;
671
let Inst{7-0} = 0b00000010;
674
def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
675
[/* For disassembly only; pattern left blank */]>,
676
Requires<[IsARM, HasV6T2]> {
677
let Inst{27-16} = 0b001100100000;
678
let Inst{7-0} = 0b00000011;
681
def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
683
[/* For disassembly only; pattern left blank */]>,
684
Requires<[IsARM, HasV6]> {
685
let Inst{27-20} = 0b01101000;
686
let Inst{7-4} = 0b1011;
689
def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
690
[/* For disassembly only; pattern left blank */]>,
691
Requires<[IsARM, HasV6T2]> {
692
let Inst{27-16} = 0b001100100000;
693
let Inst{7-0} = 0b00000100;
696
// The i32imm operand $val can be used by a debugger to store more information
697
// about the breakpoint.
698
def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
699
[/* For disassembly only; pattern left blank */]>,
701
let Inst{27-20} = 0b00010010;
702
let Inst{7-4} = 0b0111;
705
// Change Processor State is a system instruction -- for disassembly only.
706
// The singleton $opt operand contains the following information:
707
// opt{4-0} = mode from Inst{4-0}
708
// opt{5} = changemode from Inst{17}
709
// opt{8-6} = AIF from Inst{8-6}
710
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
711
def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
712
[/* For disassembly only; pattern left blank */]>,
714
let Inst{31-28} = 0b1111;
715
let Inst{27-20} = 0b00010000;
720
// Preload signals the memory system of possible future data/instruction access.
721
// These are for disassembly only.
722
multiclass APreLoad<bit data, bit read, string opc> {
724
def i : AXI<(outs), (ins GPR:$base, i32imm:$imm), MiscFrm, NoItinerary,
725
!strconcat(opc, "\t[$base, $imm]"), []> {
726
let Inst{31-26} = 0b111101;
727
let Inst{25} = 0; // 0 for immediate form
730
let Inst{21-20} = 0b01;
733
def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
734
!strconcat(opc, "\t$addr"), []> {
735
let Inst{31-26} = 0b111101;
736
let Inst{25} = 1; // 1 for register form
739
let Inst{21-20} = 0b01;
744
defm PLD : APreLoad<1, 1, "pld">;
745
defm PLDW : APreLoad<1, 0, "pldw">;
746
defm PLI : APreLoad<0, 1, "pli">;
748
def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
749
[/* For disassembly only; pattern left blank */]>,
751
let Inst{31-28} = 0b1111;
752
let Inst{27-20} = 0b00010000;
755
let Inst{7-4} = 0b0000;
758
def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
759
[/* For disassembly only; pattern left blank */]>,
761
let Inst{31-28} = 0b1111;
762
let Inst{27-20} = 0b00010000;
765
let Inst{7-4} = 0b0000;
768
def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
769
[/* For disassembly only; pattern left blank */]>,
770
Requires<[IsARM, HasV7]> {
771
let Inst{27-16} = 0b001100100000;
772
let Inst{7-4} = 0b1111;
775
// A5.4 Permanently UNDEFINED instructions.
776
def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
777
[/* For disassembly only; pattern left blank */]>,
779
let Inst{27-25} = 0b011;
780
let Inst{24-20} = 0b11111;
781
let Inst{7-5} = 0b111;
785
// Address computation and loads and stores in PIC mode.
786
let isNotDuplicable = 1 in {
787
def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
788
Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
789
[(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
791
let AddedComplexity = 10 in {
792
def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
793
Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
794
[(set GPR:$dst, (load addrmodepc:$addr))]>;
796
def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
797
Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
798
[(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
800
def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
801
Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
802
[(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
804
def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
805
Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
806
[(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
808
def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
809
Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
810
[(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
812
let AddedComplexity = 10 in {
813
def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
814
Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
815
[(store GPR:$src, addrmodepc:$addr)]>;
817
def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
818
Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
819
[(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
821
def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
822
Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
823
[(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
825
} // isNotDuplicable = 1
828
// LEApcrel - Load a pc-relative address into a register without offending the
830
def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
832
!strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
833
"${:private}PCRELL${:uid}+8))\n"),
834
!strconcat("${:private}PCRELL${:uid}:\n\t",
835
"add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
838
def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
839
(ins i32imm:$label, nohash_imm:$id, pred:$p),
841
!strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
843
"${:private}PCRELL${:uid}+8))\n"),
844
!strconcat("${:private}PCRELL${:uid}:\n\t",
845
"add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
850
//===----------------------------------------------------------------------===//
851
// Control Flow Instructions.
854
let isReturn = 1, isTerminator = 1, isBarrier = 1 in
855
def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
856
"bx", "\tlr", [(ARMretflag)]> {
857
let Inst{3-0} = 0b1110;
858
let Inst{7-4} = 0b0001;
859
let Inst{19-8} = 0b111111111111;
860
let Inst{27-20} = 0b00010010;
864
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
865
def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
866
[(brind GPR:$dst)]> {
867
let Inst{7-4} = 0b0001;
868
let Inst{19-8} = 0b111111111111;
869
let Inst{27-20} = 0b00010010;
870
let Inst{31-28} = 0b1110;
874
// FIXME: remove when we have a way to marking a MI with these properties.
875
// FIXME: Should pc be an implicit operand like PICADD, etc?
876
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
877
hasExtraDefRegAllocReq = 1 in
878
def LDM_RET : AXI4ld<(outs),
879
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
880
LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
883
// On non-Darwin platforms R9 is callee-saved.
885
Defs = [R0, R1, R2, R3, R12, LR,
886
D0, D1, D2, D3, D4, D5, D6, D7,
887
D16, D17, D18, D19, D20, D21, D22, D23,
888
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
889
def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
890
IIC_Br, "bl\t${func:call}",
891
[(ARMcall tglobaladdr:$func)]>,
892
Requires<[IsARM, IsNotDarwin]> {
893
let Inst{31-28} = 0b1110;
896
def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
897
IIC_Br, "bl", "\t${func:call}",
898
[(ARMcall_pred tglobaladdr:$func)]>,
899
Requires<[IsARM, IsNotDarwin]>;
902
def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
903
IIC_Br, "blx\t$func",
904
[(ARMcall GPR:$func)]>,
905
Requires<[IsARM, HasV5T, IsNotDarwin]> {
906
let Inst{7-4} = 0b0011;
907
let Inst{19-8} = 0b111111111111;
908
let Inst{27-20} = 0b00010010;
912
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
913
def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
914
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
915
[(ARMcall_nolink tGPR:$func)]>,
916
Requires<[IsARM, IsNotDarwin]> {
917
let Inst{7-4} = 0b0001;
918
let Inst{19-8} = 0b111111111111;
919
let Inst{27-20} = 0b00010010;
923
// On Darwin R9 is call-clobbered.
925
Defs = [R0, R1, R2, R3, R9, R12, LR,
926
D0, D1, D2, D3, D4, D5, D6, D7,
927
D16, D17, D18, D19, D20, D21, D22, D23,
928
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
929
def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
930
IIC_Br, "bl\t${func:call}",
931
[(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
932
let Inst{31-28} = 0b1110;
935
def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
936
IIC_Br, "bl", "\t${func:call}",
937
[(ARMcall_pred tglobaladdr:$func)]>,
938
Requires<[IsARM, IsDarwin]>;
941
def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
942
IIC_Br, "blx\t$func",
943
[(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
944
let Inst{7-4} = 0b0011;
945
let Inst{19-8} = 0b111111111111;
946
let Inst{27-20} = 0b00010010;
950
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
951
def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
952
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
953
[(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
954
let Inst{7-4} = 0b0001;
955
let Inst{19-8} = 0b111111111111;
956
let Inst{27-20} = 0b00010010;
960
let isBranch = 1, isTerminator = 1 in {
961
// B is "predicable" since it can be xformed into a Bcc.
962
let isBarrier = 1 in {
963
let isPredicable = 1 in
964
def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
965
"b\t$target", [(br bb:$target)]>;
967
let isNotDuplicable = 1, isIndirectBranch = 1 in {
968
def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
969
IIC_Br, "mov\tpc, $target \n$jt",
970
[(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
971
let Inst{11-4} = 0b00000000;
972
let Inst{15-12} = 0b1111;
973
let Inst{20} = 0; // S Bit
974
let Inst{24-21} = 0b1101;
975
let Inst{27-25} = 0b000;
977
def BR_JTm : JTI<(outs),
978
(ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
979
IIC_Br, "ldr\tpc, $target \n$jt",
980
[(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
982
let Inst{15-12} = 0b1111;
983
let Inst{20} = 1; // L bit
984
let Inst{21} = 0; // W bit
985
let Inst{22} = 0; // B bit
986
let Inst{24} = 1; // P bit
987
let Inst{27-25} = 0b011;
989
def BR_JTadd : JTI<(outs),
990
(ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
991
IIC_Br, "add\tpc, $target, $idx \n$jt",
992
[(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
994
let Inst{15-12} = 0b1111;
995
let Inst{20} = 0; // S bit
996
let Inst{24-21} = 0b0100;
997
let Inst{27-25} = 0b000;
999
} // isNotDuplicable = 1, isIndirectBranch = 1
1002
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
1003
// a two-value operand where a dag node expects two operands. :(
1004
def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1005
IIC_Br, "b", "\t$target",
1006
[/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1009
// Branch and Exchange Jazelle -- for disassembly only
1010
def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1011
[/* For disassembly only; pattern left blank */]> {
1012
let Inst{23-20} = 0b0010;
1013
//let Inst{19-8} = 0xfff;
1014
let Inst{7-4} = 0b0010;
1017
// Secure Monitor Call is a system instruction -- for disassembly only
1018
def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1019
[/* For disassembly only; pattern left blank */]> {
1020
let Inst{23-20} = 0b0110;
1021
let Inst{7-4} = 0b0111;
1024
// Supervisor Call (Software Interrupt) -- for disassembly only
1026
def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1027
[/* For disassembly only; pattern left blank */]>;
1030
// Store Return State is a system instruction -- for disassembly only
1031
def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1032
NoItinerary, "srs${addr:submode}\tsp!, $mode",
1033
[/* For disassembly only; pattern left blank */]> {
1034
let Inst{31-28} = 0b1111;
1035
let Inst{22-20} = 0b110; // W = 1
1038
def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1039
NoItinerary, "srs${addr:submode}\tsp, $mode",
1040
[/* For disassembly only; pattern left blank */]> {
1041
let Inst{31-28} = 0b1111;
1042
let Inst{22-20} = 0b100; // W = 0
1045
// Return From Exception is a system instruction -- for disassembly only
1046
def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1047
NoItinerary, "rfe${addr:submode}\t$base!",
1048
[/* For disassembly only; pattern left blank */]> {
1049
let Inst{31-28} = 0b1111;
1050
let Inst{22-20} = 0b011; // W = 1
1053
def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1054
NoItinerary, "rfe${addr:submode}\t$base",
1055
[/* For disassembly only; pattern left blank */]> {
1056
let Inst{31-28} = 0b1111;
1057
let Inst{22-20} = 0b001; // W = 0
1060
//===----------------------------------------------------------------------===//
1061
// Load / store Instructions.
1065
let canFoldAsLoad = 1, isReMaterializable = 1 in
1066
def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1067
"ldr", "\t$dst, $addr",
1068
[(set GPR:$dst, (load addrmode2:$addr))]>;
1070
// Special LDR for loads from non-pc-relative constpools.
1071
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
1072
def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1073
"ldr", "\t$dst, $addr", []>;
1075
// Loads with zero extension
1076
def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1077
IIC_iLoadr, "ldrh", "\t$dst, $addr",
1078
[(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1080
def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1081
IIC_iLoadr, "ldrb", "\t$dst, $addr",
1082
[(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1084
// Loads with sign extension
1085
def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1086
IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1087
[(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1089
def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1090
IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1091
[(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1093
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1095
def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1096
IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1097
[]>, Requires<[IsARM, HasV5TE]>;
1100
def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1101
(ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1102
"ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1104
def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1105
(ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1106
"ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1108
def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1109
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1110
"ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1112
def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1113
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1114
"ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1116
def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1117
(ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1118
"ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1120
def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1121
(ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1122
"ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1124
def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1125
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1126
"ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1128
def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1129
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1130
"ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1132
def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1133
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1134
"ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1136
def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1137
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1138
"ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1140
// For disassembly only
1141
def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1142
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1143
"ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1144
Requires<[IsARM, HasV5TE]>;
1146
// For disassembly only
1147
def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1148
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1149
"ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1150
Requires<[IsARM, HasV5TE]>;
1154
// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1156
def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1157
(ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1158
"ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1159
let Inst{21} = 1; // overwrite
1162
def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1163
(ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1164
"ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1165
let Inst{21} = 1; // overwrite
1168
def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1169
(ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
1170
"ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1171
let Inst{21} = 1; // overwrite
1174
def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1175
(ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1176
"ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1177
let Inst{21} = 1; // overwrite
1180
def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1181
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1182
"ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1183
let Inst{21} = 1; // overwrite
1187
def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1188
"str", "\t$src, $addr",
1189
[(store GPR:$src, addrmode2:$addr)]>;
1191
// Stores with truncate
1192
def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1193
IIC_iStorer, "strh", "\t$src, $addr",
1194
[(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1196
def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1197
"strb", "\t$src, $addr",
1198
[(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1201
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1202
def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1203
StMiscFrm, IIC_iStorer,
1204
"strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1207
def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1208
(ins GPR:$src, GPR:$base, am2offset:$offset),
1209
StFrm, IIC_iStoreru,
1210
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1212
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1214
def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1215
(ins GPR:$src, GPR:$base,am2offset:$offset),
1216
StFrm, IIC_iStoreru,
1217
"str", "\t$src, [$base], $offset", "$base = $base_wb",
1219
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1221
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1222
(ins GPR:$src, GPR:$base,am3offset:$offset),
1223
StMiscFrm, IIC_iStoreru,
1224
"strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1226
(pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1228
def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1229
(ins GPR:$src, GPR:$base,am3offset:$offset),
1230
StMiscFrm, IIC_iStoreru,
1231
"strh", "\t$src, [$base], $offset", "$base = $base_wb",
1232
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1233
GPR:$base, am3offset:$offset))]>;
1235
def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1236
(ins GPR:$src, GPR:$base,am2offset:$offset),
1237
StFrm, IIC_iStoreru,
1238
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1239
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1240
GPR:$base, am2offset:$offset))]>;
1242
def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1243
(ins GPR:$src, GPR:$base,am2offset:$offset),
1244
StFrm, IIC_iStoreru,
1245
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
1246
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1247
GPR:$base, am2offset:$offset))]>;
1249
// For disassembly only
1250
def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1251
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1252
StMiscFrm, IIC_iStoreru,
1253
"strd", "\t$src1, $src2, [$base, $offset]!",
1254
"$base = $base_wb", []>;
1256
// For disassembly only
1257
def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1258
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1259
StMiscFrm, IIC_iStoreru,
1260
"strd", "\t$src1, $src2, [$base], $offset",
1261
"$base = $base_wb", []>;
1263
// STRT, STRBT, and STRHT are for disassembly only.
1265
def STRT : AI2stwpo<(outs GPR:$base_wb),
1266
(ins GPR:$src, GPR:$base,am2offset:$offset),
1267
StFrm, IIC_iStoreru,
1268
"strt", "\t$src, [$base], $offset", "$base = $base_wb",
1269
[/* For disassembly only; pattern left blank */]> {
1270
let Inst{21} = 1; // overwrite
1273
def STRBT : AI2stbpo<(outs GPR:$base_wb),
1274
(ins GPR:$src, GPR:$base,am2offset:$offset),
1275
StFrm, IIC_iStoreru,
1276
"strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1277
[/* For disassembly only; pattern left blank */]> {
1278
let Inst{21} = 1; // overwrite
1281
def STRHT: AI3sthpo<(outs GPR:$base_wb),
1282
(ins GPR:$src, GPR:$base,am3offset:$offset),
1283
StMiscFrm, IIC_iStoreru,
1284
"strht", "\t$src, [$base], $offset", "$base = $base_wb",
1285
[/* For disassembly only; pattern left blank */]> {
1286
let Inst{21} = 1; // overwrite
1289
//===----------------------------------------------------------------------===//
1290
// Load / store multiple Instructions.
1293
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1294
def LDM : AXI4ld<(outs),
1295
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1296
LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1299
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1300
def STM : AXI4st<(outs),
1301
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1302
LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1305
//===----------------------------------------------------------------------===//
1306
// Move Instructions.
1309
let neverHasSideEffects = 1 in
1310
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1311
"mov", "\t$dst, $src", []>, UnaryDP {
1312
let Inst{11-4} = 0b00000000;
1316
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1317
DPSoRegFrm, IIC_iMOVsr,
1318
"mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1322
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1323
def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1324
"mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1328
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1329
def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1331
"movw", "\t$dst, $src",
1332
[(set GPR:$dst, imm0_65535:$src)]>,
1333
Requires<[IsARM, HasV6T2]>, UnaryDP {
1338
let Constraints = "$src = $dst" in
1339
def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1341
"movt", "\t$dst, $imm",
1343
(or (and GPR:$src, 0xffff),
1344
lo16AllZero:$imm))]>, UnaryDP,
1345
Requires<[IsARM, HasV6T2]> {
1350
def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1351
Requires<[IsARM, HasV6T2]>;
1353
let Uses = [CPSR] in
1354
def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1355
"mov", "\t$dst, $src, rrx",
1356
[(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1358
// These aren't really mov instructions, but we have to define them this way
1359
// due to flag operands.
1361
let Defs = [CPSR] in {
1362
def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1363
IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1364
[(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1365
def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1366
IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1367
[(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1370
//===----------------------------------------------------------------------===//
1371
// Extend Instructions.
1376
defm SXTB : AI_unary_rrot<0b01101010,
1377
"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1378
defm SXTH : AI_unary_rrot<0b01101011,
1379
"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1381
defm SXTAB : AI_bin_rrot<0b01101010,
1382
"sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1383
defm SXTAH : AI_bin_rrot<0b01101011,
1384
"sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1386
// For disassembly only
1387
defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
1389
// For disassembly only
1390
defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1394
let AddedComplexity = 16 in {
1395
defm UXTB : AI_unary_rrot<0b01101110,
1396
"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1397
defm UXTH : AI_unary_rrot<0b01101111,
1398
"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1399
defm UXTB16 : AI_unary_rrot<0b01101100,
1400
"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1402
def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1403
(UXTB16r_rot GPR:$Src, 24)>;
1404
def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1405
(UXTB16r_rot GPR:$Src, 8)>;
1407
defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1408
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1409
defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1410
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1413
// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1414
// For disassembly only
1415
defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1418
def SBFX : I<(outs GPR:$dst),
1419
(ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1420
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1421
"sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1422
Requires<[IsARM, HasV6T2]> {
1423
let Inst{27-21} = 0b0111101;
1424
let Inst{6-4} = 0b101;
1427
def UBFX : I<(outs GPR:$dst),
1428
(ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1429
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1430
"ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1431
Requires<[IsARM, HasV6T2]> {
1432
let Inst{27-21} = 0b0111111;
1433
let Inst{6-4} = 0b101;
1436
//===----------------------------------------------------------------------===//
1437
// Arithmetic Instructions.
1440
defm ADD : AsI1_bin_irs<0b0100, "add",
1441
BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1442
defm SUB : AsI1_bin_irs<0b0010, "sub",
1443
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1445
// ADD and SUB with 's' bit set.
1446
defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1447
BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1448
defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1449
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1451
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1452
BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1453
defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1454
BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1455
defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1456
BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1457
defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1458
BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1460
// These don't define reg/reg forms, because they are handled above.
1461
def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1462
IIC_iALUi, "rsb", "\t$dst, $a, $b",
1463
[(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1467
def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1468
IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1469
[(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1473
// RSB with 's' bit set.
1474
let Defs = [CPSR] in {
1475
def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1476
IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1477
[(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1481
def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1482
IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1483
[(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1489
let Uses = [CPSR] in {
1490
def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1491
DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1492
[(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1496
def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1497
DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1498
[(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1504
// FIXME: Allow these to be predicated.
1505
let Defs = [CPSR], Uses = [CPSR] in {
1506
def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1507
DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1508
[(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1513
def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1514
DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1515
[(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1522
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1523
def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1524
(SUBri GPR:$src, so_imm_neg:$imm)>;
1526
//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1527
// (SUBSri GPR:$src, so_imm_neg:$imm)>;
1528
//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1529
// (SBCri GPR:$src, so_imm_neg:$imm)>;
1531
// Note: These are implemented in C++ code, because they have to generate
1532
// ADD/SUBrs instructions, which use a complex pattern that a xform function
1534
// (mul X, 2^n+1) -> (add (X << n), X)
1535
// (mul X, 2^n-1) -> (rsb X, (X << n))
1537
// ARM Arithmetic Instruction -- for disassembly only
1538
// GPR:$dst = GPR:$a op GPR:$b
1539
class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
1540
: AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1541
opc, "\t$dst, $a, $b",
1542
[/* For disassembly only; pattern left blank */]> {
1543
let Inst{27-20} = op27_20;
1544
let Inst{7-4} = op7_4;
1547
// Saturating add/subtract -- for disassembly only
1549
def QADD : AAI<0b00010000, 0b0101, "qadd">;
1550
def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1551
def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1552
def QASX : AAI<0b01100010, 0b0011, "qasx">;
1553
def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1554
def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1555
def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1556
def QSUB : AAI<0b00010010, 0b0101, "qsub">;
1557
def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1558
def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1559
def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1560
def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1561
def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1562
def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1563
def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1564
def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1566
// Signed/Unsigned add/subtract -- for disassembly only
1568
def SASX : AAI<0b01100001, 0b0011, "sasx">;
1569
def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1570
def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1571
def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1572
def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1573
def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1574
def UASX : AAI<0b01100101, 0b0011, "uasx">;
1575
def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1576
def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1577
def USAX : AAI<0b01100101, 0b0101, "usax">;
1578
def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1579
def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1581
// Signed/Unsigned halving add/subtract -- for disassembly only
1583
def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1584
def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1585
def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1586
def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1587
def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1588
def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1589
def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1590
def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1591
def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1592
def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1593
def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1594
def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1596
// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1598
def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1599
MulFrm /* for convenience */, NoItinerary, "usad8",
1600
"\t$dst, $a, $b", []>,
1601
Requires<[IsARM, HasV6]> {
1602
let Inst{27-20} = 0b01111000;
1603
let Inst{15-12} = 0b1111;
1604
let Inst{7-4} = 0b0001;
1606
def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1607
MulFrm /* for convenience */, NoItinerary, "usada8",
1608
"\t$dst, $a, $b, $acc", []>,
1609
Requires<[IsARM, HasV6]> {
1610
let Inst{27-20} = 0b01111000;
1611
let Inst{7-4} = 0b0001;
1614
// Signed/Unsigned saturate -- for disassembly only
1616
def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1617
DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1618
[/* For disassembly only; pattern left blank */]> {
1619
let Inst{27-21} = 0b0110101;
1620
let Inst{6-4} = 0b001;
1623
def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1624
DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1625
[/* For disassembly only; pattern left blank */]> {
1626
let Inst{27-21} = 0b0110101;
1627
let Inst{6-4} = 0b101;
1630
def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1631
NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1632
[/* For disassembly only; pattern left blank */]> {
1633
let Inst{27-20} = 0b01101010;
1634
let Inst{7-4} = 0b0011;
1637
def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1638
DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1639
[/* For disassembly only; pattern left blank */]> {
1640
let Inst{27-21} = 0b0110111;
1641
let Inst{6-4} = 0b001;
1644
def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1645
DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1646
[/* For disassembly only; pattern left blank */]> {
1647
let Inst{27-21} = 0b0110111;
1648
let Inst{6-4} = 0b101;
1651
def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1652
NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1653
[/* For disassembly only; pattern left blank */]> {
1654
let Inst{27-20} = 0b01101110;
1655
let Inst{7-4} = 0b0011;
1658
//===----------------------------------------------------------------------===//
1659
// Bitwise Instructions.
1662
defm AND : AsI1_bin_irs<0b0000, "and",
1663
BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1664
defm ORR : AsI1_bin_irs<0b1100, "orr",
1665
BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1666
defm EOR : AsI1_bin_irs<0b0001, "eor",
1667
BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1668
defm BIC : AsI1_bin_irs<0b1110, "bic",
1669
BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1671
def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1672
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1673
"bfc", "\t$dst, $imm", "$src = $dst",
1674
[(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1675
Requires<[IsARM, HasV6T2]> {
1676
let Inst{27-21} = 0b0111110;
1677
let Inst{6-0} = 0b0011111;
1680
// A8.6.18 BFI - Bitfield insert (Encoding A1)
1681
// Added for disassembler with the pattern field purposely left blank.
1682
def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1683
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1684
"bfi", "\t$dst, $src, $imm", "",
1685
[/* For disassembly only; pattern left blank */]>,
1686
Requires<[IsARM, HasV6T2]> {
1687
let Inst{27-21} = 0b0111110;
1688
let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1691
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1692
"mvn", "\t$dst, $src",
1693
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1695
let Inst{11-4} = 0b00000000;
1697
def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1698
IIC_iMOVsr, "mvn", "\t$dst, $src",
1699
[(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1702
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1703
def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1704
IIC_iMOVi, "mvn", "\t$dst, $imm",
1705
[(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1709
def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1710
(BICri GPR:$src, so_imm_not:$imm)>;
1712
//===----------------------------------------------------------------------===//
1713
// Multiply Instructions.
1716
let isCommutable = 1 in
1717
def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1718
IIC_iMUL32, "mul", "\t$dst, $a, $b",
1719
[(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1721
def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1722
IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1723
[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1725
def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1726
IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1727
[(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1728
Requires<[IsARM, HasV6T2]>;
1730
// Extra precision multiplies with low / high results
1731
let neverHasSideEffects = 1 in {
1732
let isCommutable = 1 in {
1733
def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1734
(ins GPR:$a, GPR:$b), IIC_iMUL64,
1735
"smull", "\t$ldst, $hdst, $a, $b", []>;
1737
def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1738
(ins GPR:$a, GPR:$b), IIC_iMUL64,
1739
"umull", "\t$ldst, $hdst, $a, $b", []>;
1742
// Multiply + accumulate
1743
def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1744
(ins GPR:$a, GPR:$b), IIC_iMAC64,
1745
"smlal", "\t$ldst, $hdst, $a, $b", []>;
1747
def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1748
(ins GPR:$a, GPR:$b), IIC_iMAC64,
1749
"umlal", "\t$ldst, $hdst, $a, $b", []>;
1751
def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1752
(ins GPR:$a, GPR:$b), IIC_iMAC64,
1753
"umaal", "\t$ldst, $hdst, $a, $b", []>,
1754
Requires<[IsARM, HasV6]>;
1755
} // neverHasSideEffects
1757
// Most significant word multiply
1758
def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1759
IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1760
[(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1761
Requires<[IsARM, HasV6]> {
1762
let Inst{7-4} = 0b0001;
1763
let Inst{15-12} = 0b1111;
1766
def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1767
IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1768
[/* For disassembly only; pattern left blank */]>,
1769
Requires<[IsARM, HasV6]> {
1770
let Inst{7-4} = 0b0011; // R = 1
1771
let Inst{15-12} = 0b1111;
1774
def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1775
IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1776
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1777
Requires<[IsARM, HasV6]> {
1778
let Inst{7-4} = 0b0001;
1781
def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1782
IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1783
[/* For disassembly only; pattern left blank */]>,
1784
Requires<[IsARM, HasV6]> {
1785
let Inst{7-4} = 0b0011; // R = 1
1788
def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1789
IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1790
[(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1791
Requires<[IsARM, HasV6]> {
1792
let Inst{7-4} = 0b1101;
1795
def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1796
IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1797
[/* For disassembly only; pattern left blank */]>,
1798
Requires<[IsARM, HasV6]> {
1799
let Inst{7-4} = 0b1111; // R = 1
1802
multiclass AI_smul<string opc, PatFrag opnode> {
1803
def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1804
IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1805
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1806
(sext_inreg GPR:$b, i16)))]>,
1807
Requires<[IsARM, HasV5TE]> {
1812
def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1813
IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1814
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1815
(sra GPR:$b, (i32 16))))]>,
1816
Requires<[IsARM, HasV5TE]> {
1821
def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1822
IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1823
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1824
(sext_inreg GPR:$b, i16)))]>,
1825
Requires<[IsARM, HasV5TE]> {
1830
def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1831
IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1832
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1833
(sra GPR:$b, (i32 16))))]>,
1834
Requires<[IsARM, HasV5TE]> {
1839
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1840
IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1841
[(set GPR:$dst, (sra (opnode GPR:$a,
1842
(sext_inreg GPR:$b, i16)), (i32 16)))]>,
1843
Requires<[IsARM, HasV5TE]> {
1848
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1849
IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1850
[(set GPR:$dst, (sra (opnode GPR:$a,
1851
(sra GPR:$b, (i32 16))), (i32 16)))]>,
1852
Requires<[IsARM, HasV5TE]> {
1859
multiclass AI_smla<string opc, PatFrag opnode> {
1860
def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1861
IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1862
[(set GPR:$dst, (add GPR:$acc,
1863
(opnode (sext_inreg GPR:$a, i16),
1864
(sext_inreg GPR:$b, i16))))]>,
1865
Requires<[IsARM, HasV5TE]> {
1870
def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1871
IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1872
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1873
(sra GPR:$b, (i32 16)))))]>,
1874
Requires<[IsARM, HasV5TE]> {
1879
def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1880
IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1881
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1882
(sext_inreg GPR:$b, i16))))]>,
1883
Requires<[IsARM, HasV5TE]> {
1888
def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1889
IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1890
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1891
(sra GPR:$b, (i32 16)))))]>,
1892
Requires<[IsARM, HasV5TE]> {
1897
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1898
IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1899
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1900
(sext_inreg GPR:$b, i16)), (i32 16))))]>,
1901
Requires<[IsARM, HasV5TE]> {
1906
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1907
IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1908
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1909
(sra GPR:$b, (i32 16))), (i32 16))))]>,
1910
Requires<[IsARM, HasV5TE]> {
1916
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1917
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1919
// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1920
def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1921
IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1922
[/* For disassembly only; pattern left blank */]>,
1923
Requires<[IsARM, HasV5TE]> {
1928
def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1929
IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1930
[/* For disassembly only; pattern left blank */]>,
1931
Requires<[IsARM, HasV5TE]> {
1936
def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1937
IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1938
[/* For disassembly only; pattern left blank */]>,
1939
Requires<[IsARM, HasV5TE]> {
1944
def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1945
IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1946
[/* For disassembly only; pattern left blank */]>,
1947
Requires<[IsARM, HasV5TE]> {
1952
// Helper class for AI_smld -- for disassembly only
1953
class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
1954
InstrItinClass itin, string opc, string asm>
1955
: AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
1960
let Inst{21-20} = 0b00;
1961
let Inst{22} = long;
1962
let Inst{27-23} = 0b01110;
1965
multiclass AI_smld<bit sub, string opc> {
1967
def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1968
NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
1970
def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1971
NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
1973
def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
1974
NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
1976
def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1977
NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
1981
defm SMLA : AI_smld<0, "smla">;
1982
defm SMLS : AI_smld<1, "smls">;
1984
multiclass AI_sdml<bit sub, string opc> {
1986
def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1987
NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
1988
let Inst{15-12} = 0b1111;
1991
def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1992
NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
1993
let Inst{15-12} = 0b1111;
1998
defm SMUA : AI_sdml<0, "smua">;
1999
defm SMUS : AI_sdml<1, "smus">;
2001
//===----------------------------------------------------------------------===//
2002
// Misc. Arithmetic Instructions.
2005
def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2006
"clz", "\t$dst, $src",
2007
[(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2008
let Inst{7-4} = 0b0001;
2009
let Inst{11-8} = 0b1111;
2010
let Inst{19-16} = 0b1111;
2013
def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2014
"rbit", "\t$dst, $src",
2015
[(set GPR:$dst, (ARMrbit GPR:$src))]>,
2016
Requires<[IsARM, HasV6T2]> {
2017
let Inst{7-4} = 0b0011;
2018
let Inst{11-8} = 0b1111;
2019
let Inst{19-16} = 0b1111;
2022
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2023
"rev", "\t$dst, $src",
2024
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2025
let Inst{7-4} = 0b0011;
2026
let Inst{11-8} = 0b1111;
2027
let Inst{19-16} = 0b1111;
2030
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2031
"rev16", "\t$dst, $src",
2033
(or (and (srl GPR:$src, (i32 8)), 0xFF),
2034
(or (and (shl GPR:$src, (i32 8)), 0xFF00),
2035
(or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2036
(and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2037
Requires<[IsARM, HasV6]> {
2038
let Inst{7-4} = 0b1011;
2039
let Inst{11-8} = 0b1111;
2040
let Inst{19-16} = 0b1111;
2043
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2044
"revsh", "\t$dst, $src",
2047
(or (srl (and GPR:$src, 0xFF00), (i32 8)),
2048
(shl GPR:$src, (i32 8))), i16))]>,
2049
Requires<[IsARM, HasV6]> {
2050
let Inst{7-4} = 0b1011;
2051
let Inst{11-8} = 0b1111;
2052
let Inst{19-16} = 0b1111;
2055
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2056
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2057
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2058
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2059
(and (shl GPR:$src2, (i32 imm:$shamt)),
2061
Requires<[IsARM, HasV6]> {
2062
let Inst{6-4} = 0b001;
2065
// Alternate cases for PKHBT where identities eliminate some nodes.
2066
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2067
(PKHBT GPR:$src1, GPR:$src2, 0)>;
2068
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2069
(PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2072
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2073
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2074
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2075
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2076
(and (sra GPR:$src2, imm16_31:$shamt),
2077
0xFFFF)))]>, Requires<[IsARM, HasV6]> {
2078
let Inst{6-4} = 0b101;
2081
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
2082
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
2083
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2084
(PKHTB GPR:$src1, GPR:$src2, 16)>;
2085
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2086
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2087
(PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2089
//===----------------------------------------------------------------------===//
2090
// Comparison Instructions...
2093
defm CMP : AI1_cmp_irs<0b1010, "cmp",
2094
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2095
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
2096
// Compare-to-zero still works out, just not the relationals
2097
//defm CMN : AI1_cmp_irs<0b1011, "cmn",
2098
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2100
// Note that TST/TEQ don't set all the same flags that CMP does!
2101
defm TST : AI1_cmp_irs<0b1000, "tst",
2102
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2103
defm TEQ : AI1_cmp_irs<0b1001, "teq",
2104
BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2106
defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2107
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2108
defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2109
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2111
//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2112
// (CMNri GPR:$src, so_imm_neg:$imm)>;
2114
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2115
(CMNzri GPR:$src, so_imm_neg:$imm)>;
2118
// Conditional moves
2119
// FIXME: should be able to write a pattern for ARMcmov, but can't use
2120
// a two-value operand where a dag node expects two operands. :(
2121
def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2122
IIC_iCMOVr, "mov", "\t$dst, $true",
2123
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2124
RegConstraint<"$false = $dst">, UnaryDP {
2125
let Inst{11-4} = 0b00000000;
2129
def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2130
(ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2131
"mov", "\t$dst, $true",
2132
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2133
RegConstraint<"$false = $dst">, UnaryDP {
2137
def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2138
(ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2139
"mov", "\t$dst, $true",
2140
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2141
RegConstraint<"$false = $dst">, UnaryDP {
2145
//===----------------------------------------------------------------------===//
2146
// Atomic operations intrinsics
2149
// memory barriers protect the atomic sequences
2150
let hasSideEffects = 1 in {
2151
def Int_MemBarrierV7 : AInoP<(outs), (ins),
2152
Pseudo, NoItinerary,
2154
[(ARMMemBarrierV7)]>,
2155
Requires<[IsARM, HasV7]> {
2156
let Inst{31-4} = 0xf57ff05;
2157
// FIXME: add support for options other than a full system DMB
2158
// See DMB disassembly-only variants below.
2159
let Inst{3-0} = 0b1111;
2162
def Int_SyncBarrierV7 : AInoP<(outs), (ins),
2163
Pseudo, NoItinerary,
2165
[(ARMSyncBarrierV7)]>,
2166
Requires<[IsARM, HasV7]> {
2167
let Inst{31-4} = 0xf57ff04;
2168
// FIXME: add support for options other than a full system DSB
2169
// See DSB disassembly-only variants below.
2170
let Inst{3-0} = 0b1111;
2173
def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2174
Pseudo, NoItinerary,
2175
"mcr", "\tp15, 0, $zero, c7, c10, 5",
2176
[(ARMMemBarrierV6 GPR:$zero)]>,
2177
Requires<[IsARM, HasV6]> {
2178
// FIXME: add support for options other than a full system DMB
2179
// FIXME: add encoding
2182
def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2183
Pseudo, NoItinerary,
2184
"mcr", "\tp15, 0, $zero, c7, c10, 4",
2185
[(ARMSyncBarrierV6 GPR:$zero)]>,
2186
Requires<[IsARM, HasV6]> {
2187
// FIXME: add support for options other than a full system DSB
2188
// FIXME: add encoding
2192
// Helper class for multiclass MemB -- for disassembly only
2193
class AMBI<string opc, string asm>
2194
: AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
2195
[/* For disassembly only; pattern left blank */]>,
2196
Requires<[IsARM, HasV7]> {
2197
let Inst{31-20} = 0xf57;
2200
multiclass MemB<bits<4> op7_4, string opc> {
2202
def st : AMBI<opc, "\tst"> {
2203
let Inst{7-4} = op7_4;
2204
let Inst{3-0} = 0b1110;
2207
def ish : AMBI<opc, "\tish"> {
2208
let Inst{7-4} = op7_4;
2209
let Inst{3-0} = 0b1011;
2212
def ishst : AMBI<opc, "\tishst"> {
2213
let Inst{7-4} = op7_4;
2214
let Inst{3-0} = 0b1010;
2217
def nsh : AMBI<opc, "\tnsh"> {
2218
let Inst{7-4} = op7_4;
2219
let Inst{3-0} = 0b0111;
2222
def nshst : AMBI<opc, "\tnshst"> {
2223
let Inst{7-4} = op7_4;
2224
let Inst{3-0} = 0b0110;
2227
def osh : AMBI<opc, "\tosh"> {
2228
let Inst{7-4} = op7_4;
2229
let Inst{3-0} = 0b0011;
2232
def oshst : AMBI<opc, "\toshst"> {
2233
let Inst{7-4} = op7_4;
2234
let Inst{3-0} = 0b0010;
2238
// These DMB variants are for disassembly only.
2239
defm DMB : MemB<0b0101, "dmb">;
2241
// These DSB variants are for disassembly only.
2242
defm DSB : MemB<0b0100, "dsb">;
2244
// ISB has only full system option -- for disassembly only
2245
def ISBsy : AMBI<"isb", ""> {
2246
let Inst{7-4} = 0b0110;
2247
let Inst{3-0} = 0b1111;
2250
let usesCustomInserter = 1 in {
2251
let Uses = [CPSR] in {
2252
def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2253
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2254
"${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2255
[(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2256
def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2257
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2258
"${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2259
[(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2260
def ATOMIC_LOAD_AND_I8 : PseudoInst<
2261
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2262
"${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2263
[(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2264
def ATOMIC_LOAD_OR_I8 : PseudoInst<
2265
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2266
"${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2267
[(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2268
def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2269
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2270
"${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2271
[(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2272
def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2273
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2274
"${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2275
[(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2276
def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2277
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2278
"${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2279
[(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2280
def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2281
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2282
"${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2283
[(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2284
def ATOMIC_LOAD_AND_I16 : PseudoInst<
2285
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2286
"${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2287
[(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2288
def ATOMIC_LOAD_OR_I16 : PseudoInst<
2289
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2290
"${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2291
[(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2292
def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2293
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2294
"${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2295
[(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2296
def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2297
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2298
"${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2299
[(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2300
def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2301
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2302
"${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2303
[(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2304
def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2305
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2306
"${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2307
[(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2308
def ATOMIC_LOAD_AND_I32 : PseudoInst<
2309
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2310
"${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2311
[(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2312
def ATOMIC_LOAD_OR_I32 : PseudoInst<
2313
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2314
"${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2315
[(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2316
def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2317
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2318
"${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2319
[(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2320
def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2321
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2322
"${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2323
[(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2325
def ATOMIC_SWAP_I8 : PseudoInst<
2326
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2327
"${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2328
[(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2329
def ATOMIC_SWAP_I16 : PseudoInst<
2330
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2331
"${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2332
[(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2333
def ATOMIC_SWAP_I32 : PseudoInst<
2334
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2335
"${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2336
[(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2338
def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2339
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2340
"${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2341
[(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2342
def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2343
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2344
"${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2345
[(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2346
def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2347
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2348
"${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2349
[(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2353
let mayLoad = 1 in {
2354
def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2355
"ldrexb", "\t$dest, [$ptr]",
2357
def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2358
"ldrexh", "\t$dest, [$ptr]",
2360
def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2361
"ldrex", "\t$dest, [$ptr]",
2363
def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2365
"ldrexd", "\t$dest, $dest2, [$ptr]",
2369
let mayStore = 1, Constraints = "@earlyclobber $success" in {
2370
def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2372
"strexb", "\t$success, $src, [$ptr]",
2374
def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2376
"strexh", "\t$success, $src, [$ptr]",
2378
def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2380
"strex", "\t$success, $src, [$ptr]",
2382
def STREXD : AIstrex<0b01, (outs GPR:$success),
2383
(ins GPR:$src, GPR:$src2, GPR:$ptr),
2385
"strexd", "\t$success, $src, $src2, [$ptr]",
2389
// Clear-Exclusive is for disassembly only.
2390
def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2391
[/* For disassembly only; pattern left blank */]>,
2392
Requires<[IsARM, HasV7]> {
2393
let Inst{31-20} = 0xf57;
2394
let Inst{7-4} = 0b0001;
2397
// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2398
let mayLoad = 1 in {
2399
def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2400
"swp", "\t$dst, $src, [$ptr]",
2401
[/* For disassembly only; pattern left blank */]> {
2402
let Inst{27-23} = 0b00010;
2403
let Inst{22} = 0; // B = 0
2404
let Inst{21-20} = 0b00;
2405
let Inst{7-4} = 0b1001;
2408
def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2409
"swpb", "\t$dst, $src, [$ptr]",
2410
[/* For disassembly only; pattern left blank */]> {
2411
let Inst{27-23} = 0b00010;
2412
let Inst{22} = 1; // B = 1
2413
let Inst{21-20} = 0b00;
2414
let Inst{7-4} = 0b1001;
2418
//===----------------------------------------------------------------------===//
2422
// __aeabi_read_tp preserves the registers r1-r3.
2424
Defs = [R0, R12, LR, CPSR] in {
2425
def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2426
"bl\t__aeabi_read_tp",
2427
[(set R0, ARMthread_pointer)]>;
2430
//===----------------------------------------------------------------------===//
2431
// SJLJ Exception handling intrinsics
2432
// eh_sjlj_setjmp() is an instruction sequence to store the return
2433
// address and save #0 in R0 for the non-longjmp case.
2434
// Since by its nature we may be coming from some other function to get
2435
// here, and we're using the stack frame for the containing function to
2436
// save/restore registers, we can't keep anything live in regs across
2437
// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2438
// when we get here from a longjmp(). We force everthing out of registers
2439
// except for our own input by listing the relevant registers in Defs. By
2440
// doing so, we also cause the prologue/epilogue code to actively preserve
2441
// all of the callee-saved resgisters, which is exactly what we want.
2442
// A constant value is passed in $val, and we use the location as a scratch.
2444
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2445
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2446
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2448
def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2449
AddrModeNone, SizeSpecial, IndexModeNone,
2450
Pseudo, NoItinerary,
2451
"str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2452
"add\t$val, pc, #8\n\t"
2453
"str\t$val, [$src, #+4]\n\t"
2455
"add\tpc, pc, #0\n\t"
2456
"mov\tr0, #1 @ eh_setjmp end", "",
2457
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2460
//===----------------------------------------------------------------------===//
2461
// Non-Instruction Patterns
2464
// Large immediate handling.
2466
// Two piece so_imms.
2467
let isReMaterializable = 1 in
2468
def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2470
"mov", "\t$dst, $src",
2471
[(set GPR:$dst, so_imm2part:$src)]>,
2472
Requires<[IsARM, NoV6T2]>;
2474
def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2475
(ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2476
(so_imm2part_2 imm:$RHS))>;
2477
def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2478
(EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2479
(so_imm2part_2 imm:$RHS))>;
2480
def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2481
(ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2482
(so_imm2part_2 imm:$RHS))>;
2483
def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2484
(SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2485
(so_neg_imm2part_2 imm:$RHS))>;
2487
// 32-bit immediate using movw + movt.
2488
// This is a single pseudo instruction, the benefit is that it can be remat'd
2489
// as a single unit instead of having to handle reg inputs.
2490
// FIXME: Remove this when we can do generalized remat.
2491
let isReMaterializable = 1 in
2492
def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2493
"movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2494
[(set GPR:$dst, (i32 imm:$src))]>,
2495
Requires<[IsARM, HasV6T2]>;
2497
// ConstantPool, GlobalAddress, and JumpTable
2498
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2499
Requires<[IsARM, DontUseMovt]>;
2500
def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2501
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2502
Requires<[IsARM, UseMovt]>;
2503
def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2504
(LEApcrelJT tjumptable:$dst, imm:$id)>;
2506
// TODO: add,sub,and, 3-instr forms?
2510
def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2511
Requires<[IsARM, IsNotDarwin]>;
2512
def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2513
Requires<[IsARM, IsDarwin]>;
2515
// zextload i1 -> zextload i8
2516
def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2518
// extload -> zextload
2519
def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2520
def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2521
def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2523
def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2524
def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2527
def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2528
(sra (shl GPR:$b, (i32 16)), (i32 16))),
2529
(SMULBB GPR:$a, GPR:$b)>;
2530
def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2531
(SMULBB GPR:$a, GPR:$b)>;
2532
def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2533
(sra GPR:$b, (i32 16))),
2534
(SMULBT GPR:$a, GPR:$b)>;
2535
def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2536
(SMULBT GPR:$a, GPR:$b)>;
2537
def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2538
(sra (shl GPR:$b, (i32 16)), (i32 16))),
2539
(SMULTB GPR:$a, GPR:$b)>;
2540
def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2541
(SMULTB GPR:$a, GPR:$b)>;
2542
def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2544
(SMULWB GPR:$a, GPR:$b)>;
2545
def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2546
(SMULWB GPR:$a, GPR:$b)>;
2548
def : ARMV5TEPat<(add GPR:$acc,
2549
(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2550
(sra (shl GPR:$b, (i32 16)), (i32 16)))),
2551
(SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2552
def : ARMV5TEPat<(add GPR:$acc,
2553
(mul sext_16_node:$a, sext_16_node:$b)),
2554
(SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2555
def : ARMV5TEPat<(add GPR:$acc,
2556
(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2557
(sra GPR:$b, (i32 16)))),
2558
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2559
def : ARMV5TEPat<(add GPR:$acc,
2560
(mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2561
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2562
def : ARMV5TEPat<(add GPR:$acc,
2563
(mul (sra GPR:$a, (i32 16)),
2564
(sra (shl GPR:$b, (i32 16)), (i32 16)))),
2565
(SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2566
def : ARMV5TEPat<(add GPR:$acc,
2567
(mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2568
(SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2569
def : ARMV5TEPat<(add GPR:$acc,
2570
(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2572
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2573
def : ARMV5TEPat<(add GPR:$acc,
2574
(sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2575
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2577
//===----------------------------------------------------------------------===//
2581
include "ARMInstrThumb.td"
2583
//===----------------------------------------------------------------------===//
2587
include "ARMInstrThumb2.td"
2589
//===----------------------------------------------------------------------===//
2590
// Floating Point Support
2593
include "ARMInstrVFP.td"
2595
//===----------------------------------------------------------------------===//
2596
// Advanced SIMD (NEON) Support
2599
include "ARMInstrNEON.td"
2601
//===----------------------------------------------------------------------===//
2602
// Coprocessor Instructions. For disassembly only.
2605
def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2606
nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2607
NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2608
[/* For disassembly only; pattern left blank */]> {
2612
def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2613
nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2614
NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2615
[/* For disassembly only; pattern left blank */]> {
2616
let Inst{31-28} = 0b1111;
2620
class ACI<dag oops, dag iops, string opc, string asm>
2621
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2622
opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2623
let Inst{27-25} = 0b110;
2626
multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2628
def _OFFSET : ACI<(outs),
2629
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2630
opc, "\tp$cop, cr$CRd, $addr"> {
2631
let Inst{31-28} = op31_28;
2632
let Inst{24} = 1; // P = 1
2633
let Inst{21} = 0; // W = 0
2634
let Inst{22} = 0; // D = 0
2635
let Inst{20} = load;
2638
def _PRE : ACI<(outs),
2639
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2640
opc, "\tp$cop, cr$CRd, $addr!"> {
2641
let Inst{31-28} = op31_28;
2642
let Inst{24} = 1; // P = 1
2643
let Inst{21} = 1; // W = 1
2644
let Inst{22} = 0; // D = 0
2645
let Inst{20} = load;
2648
def _POST : ACI<(outs),
2649
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2650
opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2651
let Inst{31-28} = op31_28;
2652
let Inst{24} = 0; // P = 0
2653
let Inst{21} = 1; // W = 1
2654
let Inst{22} = 0; // D = 0
2655
let Inst{20} = load;
2658
def _OPTION : ACI<(outs),
2659
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2660
opc, "\tp$cop, cr$CRd, [$base], $option"> {
2661
let Inst{31-28} = op31_28;
2662
let Inst{24} = 0; // P = 0
2663
let Inst{23} = 1; // U = 1
2664
let Inst{21} = 0; // W = 0
2665
let Inst{22} = 0; // D = 0
2666
let Inst{20} = load;
2669
def L_OFFSET : ACI<(outs),
2670
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2671
opc, "l\tp$cop, cr$CRd, $addr"> {
2672
let Inst{31-28} = op31_28;
2673
let Inst{24} = 1; // P = 1
2674
let Inst{21} = 0; // W = 0
2675
let Inst{22} = 1; // D = 1
2676
let Inst{20} = load;
2679
def L_PRE : ACI<(outs),
2680
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2681
opc, "l\tp$cop, cr$CRd, $addr!"> {
2682
let Inst{31-28} = op31_28;
2683
let Inst{24} = 1; // P = 1
2684
let Inst{21} = 1; // W = 1
2685
let Inst{22} = 1; // D = 1
2686
let Inst{20} = load;
2689
def L_POST : ACI<(outs),
2690
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2691
opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
2692
let Inst{31-28} = op31_28;
2693
let Inst{24} = 0; // P = 0
2694
let Inst{21} = 1; // W = 1
2695
let Inst{22} = 1; // D = 1
2696
let Inst{20} = load;
2699
def L_OPTION : ACI<(outs),
2700
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2701
opc, "l\tp$cop, cr$CRd, [$base], $option"> {
2702
let Inst{31-28} = op31_28;
2703
let Inst{24} = 0; // P = 0
2704
let Inst{23} = 1; // U = 1
2705
let Inst{21} = 0; // W = 0
2706
let Inst{22} = 1; // D = 1
2707
let Inst{20} = load;
2711
defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2712
defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2713
defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2714
defm STC2 : LdStCop<0b1111, 0, "stc2">;
2716
def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2717
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2718
NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2719
[/* For disassembly only; pattern left blank */]> {
2724
def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2725
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2726
NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2727
[/* For disassembly only; pattern left blank */]> {
2728
let Inst{31-28} = 0b1111;
2733
def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2734
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2735
NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2736
[/* For disassembly only; pattern left blank */]> {
2741
def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2742
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2743
NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2744
[/* For disassembly only; pattern left blank */]> {
2745
let Inst{31-28} = 0b1111;
2750
def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2751
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2752
NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2753
[/* For disassembly only; pattern left blank */]> {
2754
let Inst{23-20} = 0b0100;
2757
def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2758
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2759
NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2760
[/* For disassembly only; pattern left blank */]> {
2761
let Inst{31-28} = 0b1111;
2762
let Inst{23-20} = 0b0100;
2765
def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2766
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2767
NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2768
[/* For disassembly only; pattern left blank */]> {
2769
let Inst{23-20} = 0b0101;
2772
def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2773
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2774
NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2775
[/* For disassembly only; pattern left blank */]> {
2776
let Inst{31-28} = 0b1111;
2777
let Inst{23-20} = 0b0101;
2780
//===----------------------------------------------------------------------===//
2781
// Move between special register and ARM core register -- for disassembly only
2784
def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2785
[/* For disassembly only; pattern left blank */]> {
2786
let Inst{23-20} = 0b0000;
2787
let Inst{7-4} = 0b0000;
2790
def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2791
[/* For disassembly only; pattern left blank */]> {
2792
let Inst{23-20} = 0b0100;
2793
let Inst{7-4} = 0b0000;
2796
// FIXME: mask is ignored for the time being.
2797
def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2798
[/* For disassembly only; pattern left blank */]> {
2799
let Inst{23-20} = 0b0010;
2800
let Inst{7-4} = 0b0000;
2803
// FIXME: mask is ignored for the time being.
2804
def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
2805
[/* For disassembly only; pattern left blank */]> {
2806
let Inst{23-20} = 0b0010;
2807
let Inst{7-4} = 0b0000;
2810
// FIXME: mask is ignored for the time being.
2811
def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
2812
[/* For disassembly only; pattern left blank */]> {
2813
let Inst{23-20} = 0b0110;
2814
let Inst{7-4} = 0b0000;
2817
// FIXME: mask is ignored for the time being.
2818
def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
2819
[/* For disassembly only; pattern left blank */]> {
2820
let Inst{23-20} = 0b0110;
2821
let Inst{7-4} = 0b0000;