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;