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, [SDTCisPtrTy<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 HasV4T : Predicate<"Subtarget->hasV4TOps()">;
117 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
118 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
119 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
120 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
121 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
122 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
123 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
124 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
125 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
126 def HasNEON : Predicate<"Subtarget->hasNEON()">;
127 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
128 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
129 def IsThumb : Predicate<"Subtarget->isThumb()">;
130 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
131 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
132 def IsARM : Predicate<"!Subtarget->isThumb()">;
133 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
134 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
136 // FIXME: Eventually this will be just "hasV6T2Ops".
137 def UseMovt : Predicate<"Subtarget->useMovt()">;
138 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
140 //===----------------------------------------------------------------------===//
141 // ARM Flag Definitions.
143 class RegConstraint<string C> {
144 string Constraints = C;
147 //===----------------------------------------------------------------------===//
148 // ARM specific transformation functions and pattern fragments.
151 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
152 // so_imm_neg def below.
153 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
154 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
157 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
158 // so_imm_not def below.
159 def so_imm_not_XFORM : SDNodeXForm<imm, [{
160 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
163 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
164 def rot_imm : PatLeaf<(i32 imm), [{
165 int32_t v = (int32_t)N->getZExtValue();
166 return v == 8 || v == 16 || v == 24;
169 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
170 def imm1_15 : PatLeaf<(i32 imm), [{
171 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
174 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
175 def imm16_31 : PatLeaf<(i32 imm), [{
176 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
181 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
182 }], so_imm_neg_XFORM>;
186 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
187 }], so_imm_not_XFORM>;
189 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
190 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
191 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
194 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
196 def bf_inv_mask_imm : Operand<i32>,
198 uint32_t v = (uint32_t)N->getZExtValue();
201 // there can be 1's on either or both "outsides", all the "inside"
203 unsigned int lsb = 0, msb = 31;
204 while (v & (1 << msb)) --msb;
205 while (v & (1 << lsb)) ++lsb;
206 for (unsigned int i = lsb; i <= msb; ++i) {
212 let PrintMethod = "printBitfieldInvMaskImmOperand";
215 /// Split a 32-bit immediate into two 16 bit parts.
216 def lo16 : SDNodeXForm<imm, [{
217 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
221 def hi16 : SDNodeXForm<imm, [{
222 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
225 def lo16AllZero : PatLeaf<(i32 imm), [{
226 // Returns true if all low 16-bits are 0.
227 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
230 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
232 def imm0_65535 : PatLeaf<(i32 imm), [{
233 return (uint32_t)N->getZExtValue() < 65536;
236 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
237 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
239 /// adde and sube predicates - True based on whether the carry flag output
240 /// will be needed or not.
241 def adde_dead_carry :
242 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
243 [{return !N->hasAnyUseOfValue(1);}]>;
244 def sube_dead_carry :
245 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
246 [{return !N->hasAnyUseOfValue(1);}]>;
247 def adde_live_carry :
248 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
249 [{return N->hasAnyUseOfValue(1);}]>;
250 def sube_live_carry :
251 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
252 [{return N->hasAnyUseOfValue(1);}]>;
254 //===----------------------------------------------------------------------===//
255 // Operand Definitions.
259 def brtarget : Operand<OtherVT>;
261 // A list of registers separated by comma. Used by load/store multiple.
262 def reglist : Operand<i32> {
263 let PrintMethod = "printRegisterList";
266 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
267 def cpinst_operand : Operand<i32> {
268 let PrintMethod = "printCPInstOperand";
271 def jtblock_operand : Operand<i32> {
272 let PrintMethod = "printJTBlockOperand";
274 def jt2block_operand : Operand<i32> {
275 let PrintMethod = "printJT2BlockOperand";
279 def pclabel : Operand<i32> {
280 let PrintMethod = "printPCLabel";
283 // shifter_operand operands: so_reg and so_imm.
284 def so_reg : Operand<i32>, // reg reg imm
285 ComplexPattern<i32, 3, "SelectShifterOperandReg",
286 [shl,srl,sra,rotr]> {
287 let PrintMethod = "printSORegOperand";
288 let MIOperandInfo = (ops GPR, GPR, i32imm);
291 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
292 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
293 // represented in the imm field in the same 12-bit form that they are encoded
294 // into so_imm instructions: the 8-bit immediate is the least significant bits
295 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
296 def so_imm : Operand<i32>,
298 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
300 let PrintMethod = "printSOImmOperand";
303 // Break so_imm's up into two pieces. This handles immediates with up to 16
304 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
305 // get the first/second pieces.
306 def so_imm2part : Operand<i32>,
308 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
310 let PrintMethod = "printSOImm2PartOperand";
313 def so_imm2part_1 : SDNodeXForm<imm, [{
314 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
315 return CurDAG->getTargetConstant(V, MVT::i32);
318 def so_imm2part_2 : SDNodeXForm<imm, [{
319 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
320 return CurDAG->getTargetConstant(V, MVT::i32);
323 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
324 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
326 let PrintMethod = "printSOImm2PartOperand";
329 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
330 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
331 return CurDAG->getTargetConstant(V, MVT::i32);
334 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
335 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
336 return CurDAG->getTargetConstant(V, MVT::i32);
339 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
340 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
341 return (int32_t)N->getZExtValue() < 32;
344 // Define ARM specific addressing modes.
346 // addrmode2 := reg +/- reg shop imm
347 // addrmode2 := reg +/- imm12
349 def addrmode2 : Operand<i32>,
350 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
351 let PrintMethod = "printAddrMode2Operand";
352 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
355 def am2offset : Operand<i32>,
356 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
357 let PrintMethod = "printAddrMode2OffsetOperand";
358 let MIOperandInfo = (ops GPR, i32imm);
361 // addrmode3 := reg +/- reg
362 // addrmode3 := reg +/- imm8
364 def addrmode3 : Operand<i32>,
365 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
366 let PrintMethod = "printAddrMode3Operand";
367 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
370 def am3offset : Operand<i32>,
371 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
372 let PrintMethod = "printAddrMode3OffsetOperand";
373 let MIOperandInfo = (ops GPR, i32imm);
376 // addrmode4 := reg, <mode|W>
378 def addrmode4 : Operand<i32>,
379 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
380 let PrintMethod = "printAddrMode4Operand";
381 let MIOperandInfo = (ops GPR, i32imm);
384 // addrmode5 := reg +/- imm8*4
386 def addrmode5 : Operand<i32>,
387 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
388 let PrintMethod = "printAddrMode5Operand";
389 let MIOperandInfo = (ops GPR, i32imm);
392 // addrmode6 := reg with optional writeback
394 def addrmode6 : Operand<i32>,
395 ComplexPattern<i32, 4, "SelectAddrMode6", []> {
396 let PrintMethod = "printAddrMode6Operand";
397 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
400 // addrmodepc := pc + reg
402 def addrmodepc : Operand<i32>,
403 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
404 let PrintMethod = "printAddrModePCOperand";
405 let MIOperandInfo = (ops GPR, i32imm);
408 def nohash_imm : Operand<i32> {
409 let PrintMethod = "printNoHashImmediate";
412 //===----------------------------------------------------------------------===//
414 include "ARMInstrFormats.td"
416 //===----------------------------------------------------------------------===//
417 // Multiclass helpers...
420 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
421 /// binop that produces a value.
422 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
423 bit Commutable = 0> {
424 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
425 IIC_iALUi, opc, "\t$dst, $a, $b",
426 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
429 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
430 IIC_iALUr, opc, "\t$dst, $a, $b",
431 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
432 let Inst{11-4} = 0b00000000;
434 let isCommutable = Commutable;
436 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
437 IIC_iALUsr, opc, "\t$dst, $a, $b",
438 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
443 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
444 /// instruction modifies the CPSR register.
445 let Defs = [CPSR] in {
446 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
447 bit Commutable = 0> {
448 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
449 IIC_iALUi, opc, "\t$dst, $a, $b",
450 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
454 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
455 IIC_iALUr, opc, "\t$dst, $a, $b",
456 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
457 let isCommutable = Commutable;
458 let Inst{11-4} = 0b00000000;
462 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
463 IIC_iALUsr, opc, "\t$dst, $a, $b",
464 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
471 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
472 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
473 /// a explicit result, only implicitly set CPSR.
474 let Defs = [CPSR] in {
475 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
476 bit Commutable = 0> {
477 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
479 [(opnode GPR:$a, so_imm:$b)]> {
483 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
485 [(opnode GPR:$a, GPR:$b)]> {
486 let Inst{11-4} = 0b00000000;
489 let isCommutable = Commutable;
491 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
493 [(opnode GPR:$a, so_reg:$b)]> {
500 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
501 /// register and one whose operand is a register rotated by 8/16/24.
502 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
503 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
504 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
505 IIC_iUNAr, opc, "\t$dst, $src",
506 [(set GPR:$dst, (opnode GPR:$src))]>,
507 Requires<[IsARM, HasV6]> {
508 let Inst{11-10} = 0b00;
509 let Inst{19-16} = 0b1111;
511 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
512 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
513 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
514 Requires<[IsARM, HasV6]> {
515 let Inst{19-16} = 0b1111;
519 multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
520 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
521 IIC_iUNAr, opc, "\t$dst, $src",
522 [/* For disassembly only; pattern left blank */]>,
523 Requires<[IsARM, HasV6]> {
524 let Inst{11-10} = 0b00;
525 let Inst{19-16} = 0b1111;
527 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
528 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
529 [/* For disassembly only; pattern left blank */]>,
530 Requires<[IsARM, HasV6]> {
531 let Inst{19-16} = 0b1111;
535 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
536 /// register and one whose operand is a register rotated by 8/16/24.
537 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
538 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
539 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
540 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
541 Requires<[IsARM, HasV6]> {
542 let Inst{11-10} = 0b00;
544 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
546 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
547 [(set GPR:$dst, (opnode GPR:$LHS,
548 (rotr GPR:$RHS, rot_imm:$rot)))]>,
549 Requires<[IsARM, HasV6]>;
552 // For disassembly only.
553 multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
554 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
555 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
556 [/* For disassembly only; pattern left blank */]>,
557 Requires<[IsARM, HasV6]> {
558 let Inst{11-10} = 0b00;
560 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
562 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
563 [/* For disassembly only; pattern left blank */]>,
564 Requires<[IsARM, HasV6]>;
567 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
568 let Uses = [CPSR] in {
569 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
570 bit Commutable = 0> {
571 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
572 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
573 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
577 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
578 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
579 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
581 let isCommutable = Commutable;
582 let Inst{11-4} = 0b00000000;
585 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
586 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
587 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
592 // Carry setting variants
593 let Defs = [CPSR] in {
594 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
595 bit Commutable = 0> {
596 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
597 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
598 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
603 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
604 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
605 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
607 let Inst{11-4} = 0b00000000;
611 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
612 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
613 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
622 //===----------------------------------------------------------------------===//
624 //===----------------------------------------------------------------------===//
626 //===----------------------------------------------------------------------===//
627 // Miscellaneous Instructions.
630 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
631 /// the function. The first operand is the ID# for this instruction, the second
632 /// is the index into the MachineConstantPool that this is, the third is the
633 /// size in bytes of this constant pool entry.
634 let neverHasSideEffects = 1, isNotDuplicable = 1 in
635 def CONSTPOOL_ENTRY :
636 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
637 i32imm:$size), NoItinerary,
638 "${instid:label} ${cpidx:cpentry}", []>;
640 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
641 // from removing one half of the matched pairs. That breaks PEI, which assumes
642 // these will always be in pairs, and asserts if it finds otherwise. Better way?
643 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
645 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
646 "@ ADJCALLSTACKUP $amt1",
647 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
649 def ADJCALLSTACKDOWN :
650 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
651 "@ ADJCALLSTACKDOWN $amt",
652 [(ARMcallseq_start timm:$amt)]>;
655 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
656 [/* For disassembly only; pattern left blank */]>,
657 Requires<[IsARM, HasV6T2]> {
658 let Inst{27-16} = 0b001100100000;
659 let Inst{7-0} = 0b00000000;
662 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
663 [/* For disassembly only; pattern left blank */]>,
664 Requires<[IsARM, HasV6T2]> {
665 let Inst{27-16} = 0b001100100000;
666 let Inst{7-0} = 0b00000001;
669 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
670 [/* For disassembly only; pattern left blank */]>,
671 Requires<[IsARM, HasV6T2]> {
672 let Inst{27-16} = 0b001100100000;
673 let Inst{7-0} = 0b00000010;
676 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
677 [/* For disassembly only; pattern left blank */]>,
678 Requires<[IsARM, HasV6T2]> {
679 let Inst{27-16} = 0b001100100000;
680 let Inst{7-0} = 0b00000011;
683 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
685 [/* For disassembly only; pattern left blank */]>,
686 Requires<[IsARM, HasV6]> {
687 let Inst{27-20} = 0b01101000;
688 let Inst{7-4} = 0b1011;
691 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
692 [/* For disassembly only; pattern left blank */]>,
693 Requires<[IsARM, HasV6T2]> {
694 let Inst{27-16} = 0b001100100000;
695 let Inst{7-0} = 0b00000100;
698 // The i32imm operand $val can be used by a debugger to store more information
699 // about the breakpoint.
700 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
701 [/* For disassembly only; pattern left blank */]>,
703 let Inst{27-20} = 0b00010010;
704 let Inst{7-4} = 0b0111;
707 // Change Processor State is a system instruction -- for disassembly only.
708 // The singleton $opt operand contains the following information:
709 // opt{4-0} = mode from Inst{4-0}
710 // opt{5} = changemode from Inst{17}
711 // opt{8-6} = AIF from Inst{8-6}
712 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
713 def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
714 [/* For disassembly only; pattern left blank */]>,
716 let Inst{31-28} = 0b1111;
717 let Inst{27-20} = 0b00010000;
722 // Preload signals the memory system of possible future data/instruction access.
723 // These are for disassembly only.
724 multiclass APreLoad<bit data, bit read, string opc> {
726 def i : AXI<(outs), (ins GPR:$base, i32imm:$imm), MiscFrm, NoItinerary,
727 !strconcat(opc, "\t[$base, $imm]"), []> {
728 let Inst{31-26} = 0b111101;
729 let Inst{25} = 0; // 0 for immediate form
732 let Inst{21-20} = 0b01;
735 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
736 !strconcat(opc, "\t$addr"), []> {
737 let Inst{31-26} = 0b111101;
738 let Inst{25} = 1; // 1 for register form
741 let Inst{21-20} = 0b01;
746 defm PLD : APreLoad<1, 1, "pld">;
747 defm PLDW : APreLoad<1, 0, "pldw">;
748 defm PLI : APreLoad<0, 1, "pli">;
750 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
751 [/* For disassembly only; pattern left blank */]>,
753 let Inst{31-28} = 0b1111;
754 let Inst{27-20} = 0b00010000;
757 let Inst{7-4} = 0b0000;
760 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
761 [/* For disassembly only; pattern left blank */]>,
763 let Inst{31-28} = 0b1111;
764 let Inst{27-20} = 0b00010000;
767 let Inst{7-4} = 0b0000;
770 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
771 [/* For disassembly only; pattern left blank */]>,
772 Requires<[IsARM, HasV7]> {
773 let Inst{27-16} = 0b001100100000;
774 let Inst{7-4} = 0b1111;
777 // A5.4 Permanently UNDEFINED instructions.
778 def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
779 [/* For disassembly only; pattern left blank */]>,
781 let Inst{27-25} = 0b011;
782 let Inst{24-20} = 0b11111;
783 let Inst{7-5} = 0b111;
787 // Address computation and loads and stores in PIC mode.
788 let isNotDuplicable = 1 in {
789 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
790 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
791 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
793 let AddedComplexity = 10 in {
794 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
795 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
796 [(set GPR:$dst, (load addrmodepc:$addr))]>;
798 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
799 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
800 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
802 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
803 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
804 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
806 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
807 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
808 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
810 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
811 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
812 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
814 let AddedComplexity = 10 in {
815 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
816 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
817 [(store GPR:$src, addrmodepc:$addr)]>;
819 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
820 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
821 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
823 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
824 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
825 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
827 } // isNotDuplicable = 1
830 // LEApcrel - Load a pc-relative address into a register without offending the
832 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
834 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
835 "${:private}PCRELL${:uid}+8))\n"),
836 !strconcat("${:private}PCRELL${:uid}:\n\t",
837 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
840 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
841 (ins i32imm:$label, nohash_imm:$id, pred:$p),
843 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
845 "${:private}PCRELL${:uid}+8))\n"),
846 !strconcat("${:private}PCRELL${:uid}:\n\t",
847 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
852 //===----------------------------------------------------------------------===//
853 // Control Flow Instructions.
856 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
858 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
859 "bx", "\tlr", [(ARMretflag)]>,
860 Requires<[IsARM, HasV4T]> {
861 let Inst{3-0} = 0b1110;
862 let Inst{7-4} = 0b0001;
863 let Inst{19-8} = 0b111111111111;
864 let Inst{27-20} = 0b00010010;
868 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
869 "mov", "\tpc, lr", [(ARMretflag)]>,
870 Requires<[IsARM, NoV4T]> {
871 let Inst{11-0} = 0b000000001110;
872 let Inst{15-12} = 0b1111;
873 let Inst{19-16} = 0b0000;
874 let Inst{27-20} = 0b00011010;
879 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
881 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
883 Requires<[IsARM, HasV4T]> {
884 let Inst{7-4} = 0b0001;
885 let Inst{19-8} = 0b111111111111;
886 let Inst{27-20} = 0b00010010;
887 let Inst{31-28} = 0b1110;
891 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
893 Requires<[IsARM, NoV4T]> {
894 let Inst{11-4} = 0b00000000;
895 let Inst{15-12} = 0b1111;
896 let Inst{19-16} = 0b0000;
897 let Inst{27-20} = 0b00011010;
898 let Inst{31-28} = 0b1110;
902 // FIXME: remove when we have a way to marking a MI with these properties.
903 // FIXME: Should pc be an implicit operand like PICADD, etc?
904 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
905 hasExtraDefRegAllocReq = 1 in
906 def LDM_RET : AXI4ld<(outs),
907 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
908 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
911 // On non-Darwin platforms R9 is callee-saved.
913 Defs = [R0, R1, R2, R3, R12, LR,
914 D0, D1, D2, D3, D4, D5, D6, D7,
915 D16, D17, D18, D19, D20, D21, D22, D23,
916 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
917 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
918 IIC_Br, "bl\t${func:call}",
919 [(ARMcall tglobaladdr:$func)]>,
920 Requires<[IsARM, IsNotDarwin]> {
921 let Inst{31-28} = 0b1110;
924 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
925 IIC_Br, "bl", "\t${func:call}",
926 [(ARMcall_pred tglobaladdr:$func)]>,
927 Requires<[IsARM, IsNotDarwin]>;
930 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
931 IIC_Br, "blx\t$func",
932 [(ARMcall GPR:$func)]>,
933 Requires<[IsARM, HasV5T, IsNotDarwin]> {
934 let Inst{7-4} = 0b0011;
935 let Inst{19-8} = 0b111111111111;
936 let Inst{27-20} = 0b00010010;
940 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
941 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
942 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
943 [(ARMcall_nolink tGPR:$func)]>,
944 Requires<[IsARM, HasV4T, IsNotDarwin]> {
945 let Inst{7-4} = 0b0001;
946 let Inst{19-8} = 0b111111111111;
947 let Inst{27-20} = 0b00010010;
951 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
952 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
953 [(ARMcall_nolink tGPR:$func)]>,
954 Requires<[IsARM, NoV4T, IsNotDarwin]> {
955 let Inst{11-4} = 0b00000000;
956 let Inst{15-12} = 0b1111;
957 let Inst{19-16} = 0b0000;
958 let Inst{27-20} = 0b00011010;
962 // On Darwin R9 is call-clobbered.
964 Defs = [R0, R1, R2, R3, R9, R12, LR,
965 D0, D1, D2, D3, D4, D5, D6, D7,
966 D16, D17, D18, D19, D20, D21, D22, D23,
967 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
968 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
969 IIC_Br, "bl\t${func:call}",
970 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
971 let Inst{31-28} = 0b1110;
974 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
975 IIC_Br, "bl", "\t${func:call}",
976 [(ARMcall_pred tglobaladdr:$func)]>,
977 Requires<[IsARM, IsDarwin]>;
980 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
981 IIC_Br, "blx\t$func",
982 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
983 let Inst{7-4} = 0b0011;
984 let Inst{19-8} = 0b111111111111;
985 let Inst{27-20} = 0b00010010;
989 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
990 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
991 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
992 [(ARMcall_nolink tGPR:$func)]>,
993 Requires<[IsARM, HasV4T, IsDarwin]> {
994 let Inst{7-4} = 0b0001;
995 let Inst{19-8} = 0b111111111111;
996 let Inst{27-20} = 0b00010010;
1000 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1001 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1002 [(ARMcall_nolink tGPR:$func)]>,
1003 Requires<[IsARM, NoV4T, IsDarwin]> {
1004 let Inst{11-4} = 0b00000000;
1005 let Inst{15-12} = 0b1111;
1006 let Inst{19-16} = 0b0000;
1007 let Inst{27-20} = 0b00011010;
1011 let isBranch = 1, isTerminator = 1 in {
1012 // B is "predicable" since it can be xformed into a Bcc.
1013 let isBarrier = 1 in {
1014 let isPredicable = 1 in
1015 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1016 "b\t$target", [(br bb:$target)]>;
1018 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1019 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1020 IIC_Br, "mov\tpc, $target \n$jt",
1021 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1022 let Inst{11-4} = 0b00000000;
1023 let Inst{15-12} = 0b1111;
1024 let Inst{20} = 0; // S Bit
1025 let Inst{24-21} = 0b1101;
1026 let Inst{27-25} = 0b000;
1028 def BR_JTm : JTI<(outs),
1029 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1030 IIC_Br, "ldr\tpc, $target \n$jt",
1031 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1033 let Inst{15-12} = 0b1111;
1034 let Inst{20} = 1; // L bit
1035 let Inst{21} = 0; // W bit
1036 let Inst{22} = 0; // B bit
1037 let Inst{24} = 1; // P bit
1038 let Inst{27-25} = 0b011;
1040 def BR_JTadd : JTI<(outs),
1041 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1042 IIC_Br, "add\tpc, $target, $idx \n$jt",
1043 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1045 let Inst{15-12} = 0b1111;
1046 let Inst{20} = 0; // S bit
1047 let Inst{24-21} = 0b0100;
1048 let Inst{27-25} = 0b000;
1050 } // isNotDuplicable = 1, isIndirectBranch = 1
1053 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1054 // a two-value operand where a dag node expects two operands. :(
1055 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1056 IIC_Br, "b", "\t$target",
1057 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1060 // Branch and Exchange Jazelle -- for disassembly only
1061 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1062 [/* For disassembly only; pattern left blank */]> {
1063 let Inst{23-20} = 0b0010;
1064 //let Inst{19-8} = 0xfff;
1065 let Inst{7-4} = 0b0010;
1068 // Secure Monitor Call is a system instruction -- for disassembly only
1069 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1070 [/* For disassembly only; pattern left blank */]> {
1071 let Inst{23-20} = 0b0110;
1072 let Inst{7-4} = 0b0111;
1075 // Supervisor Call (Software Interrupt) -- for disassembly only
1077 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1078 [/* For disassembly only; pattern left blank */]>;
1081 // Store Return State is a system instruction -- for disassembly only
1082 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1083 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1084 [/* For disassembly only; pattern left blank */]> {
1085 let Inst{31-28} = 0b1111;
1086 let Inst{22-20} = 0b110; // W = 1
1089 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1090 NoItinerary, "srs${addr:submode}\tsp, $mode",
1091 [/* For disassembly only; pattern left blank */]> {
1092 let Inst{31-28} = 0b1111;
1093 let Inst{22-20} = 0b100; // W = 0
1096 // Return From Exception is a system instruction -- for disassembly only
1097 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1098 NoItinerary, "rfe${addr:submode}\t$base!",
1099 [/* For disassembly only; pattern left blank */]> {
1100 let Inst{31-28} = 0b1111;
1101 let Inst{22-20} = 0b011; // W = 1
1104 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1105 NoItinerary, "rfe${addr:submode}\t$base",
1106 [/* For disassembly only; pattern left blank */]> {
1107 let Inst{31-28} = 0b1111;
1108 let Inst{22-20} = 0b001; // W = 0
1111 //===----------------------------------------------------------------------===//
1112 // Load / store Instructions.
1116 let canFoldAsLoad = 1, isReMaterializable = 1 in
1117 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1118 "ldr", "\t$dst, $addr",
1119 [(set GPR:$dst, (load addrmode2:$addr))]>;
1121 // Special LDR for loads from non-pc-relative constpools.
1122 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
1123 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1124 "ldr", "\t$dst, $addr", []>;
1126 // Loads with zero extension
1127 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1128 IIC_iLoadr, "ldrh", "\t$dst, $addr",
1129 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1131 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1132 IIC_iLoadr, "ldrb", "\t$dst, $addr",
1133 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1135 // Loads with sign extension
1136 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1137 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1138 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1140 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1141 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1142 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1144 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1146 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1147 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1148 []>, Requires<[IsARM, HasV5TE]>;
1151 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1152 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1153 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1155 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1156 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1157 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1159 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1160 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1161 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1163 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1164 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1165 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1167 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1168 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1169 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1171 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1172 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1173 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1175 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1176 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1177 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1179 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1180 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1181 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1183 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1184 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1185 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1187 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1188 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1189 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1191 // For disassembly only
1192 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1193 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1194 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1195 Requires<[IsARM, HasV5TE]>;
1197 // For disassembly only
1198 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1199 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1200 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1201 Requires<[IsARM, HasV5TE]>;
1205 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1207 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1208 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1209 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1210 let Inst{21} = 1; // overwrite
1213 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1214 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1215 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1216 let Inst{21} = 1; // overwrite
1219 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1220 (ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
1221 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1222 let Inst{21} = 1; // overwrite
1225 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1226 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1227 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1228 let Inst{21} = 1; // overwrite
1231 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1232 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1233 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1234 let Inst{21} = 1; // overwrite
1238 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1239 "str", "\t$src, $addr",
1240 [(store GPR:$src, addrmode2:$addr)]>;
1242 // Stores with truncate
1243 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1244 IIC_iStorer, "strh", "\t$src, $addr",
1245 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1247 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1248 "strb", "\t$src, $addr",
1249 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1252 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1253 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1254 StMiscFrm, IIC_iStorer,
1255 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1258 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1259 (ins GPR:$src, GPR:$base, am2offset:$offset),
1260 StFrm, IIC_iStoreru,
1261 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1263 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1265 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1266 (ins GPR:$src, GPR:$base,am2offset:$offset),
1267 StFrm, IIC_iStoreru,
1268 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1270 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1272 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1273 (ins GPR:$src, GPR:$base,am3offset:$offset),
1274 StMiscFrm, IIC_iStoreru,
1275 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1277 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1279 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1280 (ins GPR:$src, GPR:$base,am3offset:$offset),
1281 StMiscFrm, IIC_iStoreru,
1282 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1283 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1284 GPR:$base, am3offset:$offset))]>;
1286 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1287 (ins GPR:$src, GPR:$base,am2offset:$offset),
1288 StFrm, IIC_iStoreru,
1289 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1290 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1291 GPR:$base, am2offset:$offset))]>;
1293 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1294 (ins GPR:$src, GPR:$base,am2offset:$offset),
1295 StFrm, IIC_iStoreru,
1296 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1297 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1298 GPR:$base, am2offset:$offset))]>;
1300 // For disassembly only
1301 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1302 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1303 StMiscFrm, IIC_iStoreru,
1304 "strd", "\t$src1, $src2, [$base, $offset]!",
1305 "$base = $base_wb", []>;
1307 // For disassembly only
1308 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1309 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1310 StMiscFrm, IIC_iStoreru,
1311 "strd", "\t$src1, $src2, [$base], $offset",
1312 "$base = $base_wb", []>;
1314 // STRT, STRBT, and STRHT are for disassembly only.
1316 def STRT : AI2stwpo<(outs GPR:$base_wb),
1317 (ins GPR:$src, GPR:$base,am2offset:$offset),
1318 StFrm, IIC_iStoreru,
1319 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1320 [/* For disassembly only; pattern left blank */]> {
1321 let Inst{21} = 1; // overwrite
1324 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1325 (ins GPR:$src, GPR:$base,am2offset:$offset),
1326 StFrm, IIC_iStoreru,
1327 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1328 [/* For disassembly only; pattern left blank */]> {
1329 let Inst{21} = 1; // overwrite
1332 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1333 (ins GPR:$src, GPR:$base,am3offset:$offset),
1334 StMiscFrm, IIC_iStoreru,
1335 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1336 [/* For disassembly only; pattern left blank */]> {
1337 let Inst{21} = 1; // overwrite
1340 //===----------------------------------------------------------------------===//
1341 // Load / store multiple Instructions.
1344 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1345 def LDM : AXI4ld<(outs),
1346 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1347 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1350 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1351 def STM : AXI4st<(outs),
1352 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1353 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1356 //===----------------------------------------------------------------------===//
1357 // Move Instructions.
1360 let neverHasSideEffects = 1 in
1361 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1362 "mov", "\t$dst, $src", []>, UnaryDP {
1363 let Inst{11-4} = 0b00000000;
1367 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1368 DPSoRegFrm, IIC_iMOVsr,
1369 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1373 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1374 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1375 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1379 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1380 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1382 "movw", "\t$dst, $src",
1383 [(set GPR:$dst, imm0_65535:$src)]>,
1384 Requires<[IsARM, HasV6T2]>, UnaryDP {
1389 let Constraints = "$src = $dst" in
1390 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1392 "movt", "\t$dst, $imm",
1394 (or (and GPR:$src, 0xffff),
1395 lo16AllZero:$imm))]>, UnaryDP,
1396 Requires<[IsARM, HasV6T2]> {
1401 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1402 Requires<[IsARM, HasV6T2]>;
1404 let Uses = [CPSR] in
1405 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1406 "mov", "\t$dst, $src, rrx",
1407 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1409 // These aren't really mov instructions, but we have to define them this way
1410 // due to flag operands.
1412 let Defs = [CPSR] in {
1413 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1414 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1415 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1416 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1417 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1418 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1421 //===----------------------------------------------------------------------===//
1422 // Extend Instructions.
1427 defm SXTB : AI_unary_rrot<0b01101010,
1428 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1429 defm SXTH : AI_unary_rrot<0b01101011,
1430 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1432 defm SXTAB : AI_bin_rrot<0b01101010,
1433 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1434 defm SXTAH : AI_bin_rrot<0b01101011,
1435 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1437 // For disassembly only
1438 defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
1440 // For disassembly only
1441 defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1445 let AddedComplexity = 16 in {
1446 defm UXTB : AI_unary_rrot<0b01101110,
1447 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1448 defm UXTH : AI_unary_rrot<0b01101111,
1449 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1450 defm UXTB16 : AI_unary_rrot<0b01101100,
1451 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1453 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1454 (UXTB16r_rot GPR:$Src, 24)>;
1455 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1456 (UXTB16r_rot GPR:$Src, 8)>;
1458 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1459 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1460 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1461 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1464 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1465 // For disassembly only
1466 defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1469 def SBFX : I<(outs GPR:$dst),
1470 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1471 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1472 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1473 Requires<[IsARM, HasV6T2]> {
1474 let Inst{27-21} = 0b0111101;
1475 let Inst{6-4} = 0b101;
1478 def UBFX : I<(outs GPR:$dst),
1479 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1480 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1481 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1482 Requires<[IsARM, HasV6T2]> {
1483 let Inst{27-21} = 0b0111111;
1484 let Inst{6-4} = 0b101;
1487 //===----------------------------------------------------------------------===//
1488 // Arithmetic Instructions.
1491 defm ADD : AsI1_bin_irs<0b0100, "add",
1492 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1493 defm SUB : AsI1_bin_irs<0b0010, "sub",
1494 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1496 // ADD and SUB with 's' bit set.
1497 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1498 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1499 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1500 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1502 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1503 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1504 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1505 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1506 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1507 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1508 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1509 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1511 // These don't define reg/reg forms, because they are handled above.
1512 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1513 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1514 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1518 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1519 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1520 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1524 // RSB with 's' bit set.
1525 let Defs = [CPSR] in {
1526 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1527 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1528 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1532 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1533 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1534 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1540 let Uses = [CPSR] in {
1541 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1542 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1543 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1547 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1548 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1549 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1555 // FIXME: Allow these to be predicated.
1556 let Defs = [CPSR], Uses = [CPSR] in {
1557 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1558 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1559 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1564 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1565 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1566 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1573 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1574 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1575 (SUBri GPR:$src, so_imm_neg:$imm)>;
1577 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1578 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1579 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1580 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1582 // Note: These are implemented in C++ code, because they have to generate
1583 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1585 // (mul X, 2^n+1) -> (add (X << n), X)
1586 // (mul X, 2^n-1) -> (rsb X, (X << n))
1588 // ARM Arithmetic Instruction -- for disassembly only
1589 // GPR:$dst = GPR:$a op GPR:$b
1590 class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
1591 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1592 opc, "\t$dst, $a, $b",
1593 [/* For disassembly only; pattern left blank */]> {
1594 let Inst{27-20} = op27_20;
1595 let Inst{7-4} = op7_4;
1598 // Saturating add/subtract -- for disassembly only
1600 def QADD : AAI<0b00010000, 0b0101, "qadd">;
1601 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1602 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1603 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1604 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1605 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1606 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1607 def QSUB : AAI<0b00010010, 0b0101, "qsub">;
1608 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1609 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1610 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1611 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1612 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1613 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1614 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1615 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1617 // Signed/Unsigned add/subtract -- for disassembly only
1619 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1620 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1621 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1622 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1623 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1624 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1625 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1626 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1627 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1628 def USAX : AAI<0b01100101, 0b0101, "usax">;
1629 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1630 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1632 // Signed/Unsigned halving add/subtract -- for disassembly only
1634 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1635 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1636 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1637 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1638 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1639 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1640 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1641 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1642 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1643 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1644 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1645 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1647 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1649 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1650 MulFrm /* for convenience */, NoItinerary, "usad8",
1651 "\t$dst, $a, $b", []>,
1652 Requires<[IsARM, HasV6]> {
1653 let Inst{27-20} = 0b01111000;
1654 let Inst{15-12} = 0b1111;
1655 let Inst{7-4} = 0b0001;
1657 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1658 MulFrm /* for convenience */, NoItinerary, "usada8",
1659 "\t$dst, $a, $b, $acc", []>,
1660 Requires<[IsARM, HasV6]> {
1661 let Inst{27-20} = 0b01111000;
1662 let Inst{7-4} = 0b0001;
1665 // Signed/Unsigned saturate -- for disassembly only
1667 def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1668 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1669 [/* For disassembly only; pattern left blank */]> {
1670 let Inst{27-21} = 0b0110101;
1671 let Inst{6-4} = 0b001;
1674 def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1675 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1676 [/* For disassembly only; pattern left blank */]> {
1677 let Inst{27-21} = 0b0110101;
1678 let Inst{6-4} = 0b101;
1681 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1682 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1683 [/* For disassembly only; pattern left blank */]> {
1684 let Inst{27-20} = 0b01101010;
1685 let Inst{7-4} = 0b0011;
1688 def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1689 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1690 [/* For disassembly only; pattern left blank */]> {
1691 let Inst{27-21} = 0b0110111;
1692 let Inst{6-4} = 0b001;
1695 def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1696 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1697 [/* For disassembly only; pattern left blank */]> {
1698 let Inst{27-21} = 0b0110111;
1699 let Inst{6-4} = 0b101;
1702 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1703 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1704 [/* For disassembly only; pattern left blank */]> {
1705 let Inst{27-20} = 0b01101110;
1706 let Inst{7-4} = 0b0011;
1709 //===----------------------------------------------------------------------===//
1710 // Bitwise Instructions.
1713 defm AND : AsI1_bin_irs<0b0000, "and",
1714 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1715 defm ORR : AsI1_bin_irs<0b1100, "orr",
1716 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1717 defm EOR : AsI1_bin_irs<0b0001, "eor",
1718 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1719 defm BIC : AsI1_bin_irs<0b1110, "bic",
1720 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1722 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1723 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1724 "bfc", "\t$dst, $imm", "$src = $dst",
1725 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1726 Requires<[IsARM, HasV6T2]> {
1727 let Inst{27-21} = 0b0111110;
1728 let Inst{6-0} = 0b0011111;
1731 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1732 // Added for disassembler with the pattern field purposely left blank.
1733 def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1734 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1735 "bfi", "\t$dst, $src, $imm", "",
1736 [/* For disassembly only; pattern left blank */]>,
1737 Requires<[IsARM, HasV6T2]> {
1738 let Inst{27-21} = 0b0111110;
1739 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1742 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1743 "mvn", "\t$dst, $src",
1744 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1746 let Inst{11-4} = 0b00000000;
1748 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1749 IIC_iMOVsr, "mvn", "\t$dst, $src",
1750 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1753 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1754 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1755 IIC_iMOVi, "mvn", "\t$dst, $imm",
1756 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1760 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1761 (BICri GPR:$src, so_imm_not:$imm)>;
1763 //===----------------------------------------------------------------------===//
1764 // Multiply Instructions.
1767 let isCommutable = 1 in
1768 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1769 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1770 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1772 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1773 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1774 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1776 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1777 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1778 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1779 Requires<[IsARM, HasV6T2]>;
1781 // Extra precision multiplies with low / high results
1782 let neverHasSideEffects = 1 in {
1783 let isCommutable = 1 in {
1784 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1785 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1786 "smull", "\t$ldst, $hdst, $a, $b", []>;
1788 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1789 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1790 "umull", "\t$ldst, $hdst, $a, $b", []>;
1793 // Multiply + accumulate
1794 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1795 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1796 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1798 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1799 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1800 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1802 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1803 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1804 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1805 Requires<[IsARM, HasV6]>;
1806 } // neverHasSideEffects
1808 // Most significant word multiply
1809 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1810 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1811 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1812 Requires<[IsARM, HasV6]> {
1813 let Inst{7-4} = 0b0001;
1814 let Inst{15-12} = 0b1111;
1817 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1818 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1819 [/* For disassembly only; pattern left blank */]>,
1820 Requires<[IsARM, HasV6]> {
1821 let Inst{7-4} = 0b0011; // R = 1
1822 let Inst{15-12} = 0b1111;
1825 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1826 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1827 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1828 Requires<[IsARM, HasV6]> {
1829 let Inst{7-4} = 0b0001;
1832 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1833 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1834 [/* For disassembly only; pattern left blank */]>,
1835 Requires<[IsARM, HasV6]> {
1836 let Inst{7-4} = 0b0011; // R = 1
1839 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1840 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1841 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1842 Requires<[IsARM, HasV6]> {
1843 let Inst{7-4} = 0b1101;
1846 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1847 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1848 [/* For disassembly only; pattern left blank */]>,
1849 Requires<[IsARM, HasV6]> {
1850 let Inst{7-4} = 0b1111; // R = 1
1853 multiclass AI_smul<string opc, PatFrag opnode> {
1854 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1855 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1856 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1857 (sext_inreg GPR:$b, i16)))]>,
1858 Requires<[IsARM, HasV5TE]> {
1863 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1864 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1865 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1866 (sra GPR:$b, (i32 16))))]>,
1867 Requires<[IsARM, HasV5TE]> {
1872 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1873 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1874 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1875 (sext_inreg GPR:$b, i16)))]>,
1876 Requires<[IsARM, HasV5TE]> {
1881 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1882 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1883 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1884 (sra GPR:$b, (i32 16))))]>,
1885 Requires<[IsARM, HasV5TE]> {
1890 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1891 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1892 [(set GPR:$dst, (sra (opnode GPR:$a,
1893 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1894 Requires<[IsARM, HasV5TE]> {
1899 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1900 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1901 [(set GPR:$dst, (sra (opnode GPR:$a,
1902 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1903 Requires<[IsARM, HasV5TE]> {
1910 multiclass AI_smla<string opc, PatFrag opnode> {
1911 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1912 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1913 [(set GPR:$dst, (add GPR:$acc,
1914 (opnode (sext_inreg GPR:$a, i16),
1915 (sext_inreg GPR:$b, i16))))]>,
1916 Requires<[IsARM, HasV5TE]> {
1921 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1922 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1923 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1924 (sra GPR:$b, (i32 16)))))]>,
1925 Requires<[IsARM, HasV5TE]> {
1930 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1931 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1932 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1933 (sext_inreg GPR:$b, i16))))]>,
1934 Requires<[IsARM, HasV5TE]> {
1939 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1940 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1941 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1942 (sra GPR:$b, (i32 16)))))]>,
1943 Requires<[IsARM, HasV5TE]> {
1948 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1949 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1950 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1951 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1952 Requires<[IsARM, HasV5TE]> {
1957 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1958 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1959 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1960 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1961 Requires<[IsARM, HasV5TE]> {
1967 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1968 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1970 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1971 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1972 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1973 [/* For disassembly only; pattern left blank */]>,
1974 Requires<[IsARM, HasV5TE]> {
1979 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1980 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1981 [/* For disassembly only; pattern left blank */]>,
1982 Requires<[IsARM, HasV5TE]> {
1987 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1988 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1989 [/* For disassembly only; pattern left blank */]>,
1990 Requires<[IsARM, HasV5TE]> {
1995 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1996 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1997 [/* For disassembly only; pattern left blank */]>,
1998 Requires<[IsARM, HasV5TE]> {
2003 // Helper class for AI_smld -- for disassembly only
2004 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2005 InstrItinClass itin, string opc, string asm>
2006 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2011 let Inst{21-20} = 0b00;
2012 let Inst{22} = long;
2013 let Inst{27-23} = 0b01110;
2016 multiclass AI_smld<bit sub, string opc> {
2018 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2019 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2021 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2022 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2024 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2025 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2027 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2028 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2032 defm SMLA : AI_smld<0, "smla">;
2033 defm SMLS : AI_smld<1, "smls">;
2035 multiclass AI_sdml<bit sub, string opc> {
2037 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2038 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2039 let Inst{15-12} = 0b1111;
2042 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2043 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2044 let Inst{15-12} = 0b1111;
2049 defm SMUA : AI_sdml<0, "smua">;
2050 defm SMUS : AI_sdml<1, "smus">;
2052 //===----------------------------------------------------------------------===//
2053 // Misc. Arithmetic Instructions.
2056 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2057 "clz", "\t$dst, $src",
2058 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2059 let Inst{7-4} = 0b0001;
2060 let Inst{11-8} = 0b1111;
2061 let Inst{19-16} = 0b1111;
2064 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2065 "rbit", "\t$dst, $src",
2066 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2067 Requires<[IsARM, HasV6T2]> {
2068 let Inst{7-4} = 0b0011;
2069 let Inst{11-8} = 0b1111;
2070 let Inst{19-16} = 0b1111;
2073 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2074 "rev", "\t$dst, $src",
2075 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2076 let Inst{7-4} = 0b0011;
2077 let Inst{11-8} = 0b1111;
2078 let Inst{19-16} = 0b1111;
2081 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2082 "rev16", "\t$dst, $src",
2084 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2085 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2086 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2087 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2088 Requires<[IsARM, HasV6]> {
2089 let Inst{7-4} = 0b1011;
2090 let Inst{11-8} = 0b1111;
2091 let Inst{19-16} = 0b1111;
2094 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2095 "revsh", "\t$dst, $src",
2098 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2099 (shl GPR:$src, (i32 8))), i16))]>,
2100 Requires<[IsARM, HasV6]> {
2101 let Inst{7-4} = 0b1011;
2102 let Inst{11-8} = 0b1111;
2103 let Inst{19-16} = 0b1111;
2106 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2107 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2108 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2109 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2110 (and (shl GPR:$src2, (i32 imm:$shamt)),
2112 Requires<[IsARM, HasV6]> {
2113 let Inst{6-4} = 0b001;
2116 // Alternate cases for PKHBT where identities eliminate some nodes.
2117 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2118 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2119 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2120 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2123 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2124 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2125 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2126 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2127 (and (sra GPR:$src2, imm16_31:$shamt),
2128 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
2129 let Inst{6-4} = 0b101;
2132 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2133 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2134 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2135 (PKHTB GPR:$src1, GPR:$src2, 16)>;
2136 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2137 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2138 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2140 //===----------------------------------------------------------------------===//
2141 // Comparison Instructions...
2144 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2145 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2146 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2147 // Compare-to-zero still works out, just not the relationals
2148 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2149 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2151 // Note that TST/TEQ don't set all the same flags that CMP does!
2152 defm TST : AI1_cmp_irs<0b1000, "tst",
2153 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2154 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2155 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2157 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2158 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2159 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2160 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2162 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2163 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2165 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2166 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2169 // Conditional moves
2170 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2171 // a two-value operand where a dag node expects two operands. :(
2172 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2173 IIC_iCMOVr, "mov", "\t$dst, $true",
2174 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2175 RegConstraint<"$false = $dst">, UnaryDP {
2176 let Inst{11-4} = 0b00000000;
2180 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2181 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2182 "mov", "\t$dst, $true",
2183 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2184 RegConstraint<"$false = $dst">, UnaryDP {
2188 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2189 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2190 "mov", "\t$dst, $true",
2191 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2192 RegConstraint<"$false = $dst">, UnaryDP {
2196 //===----------------------------------------------------------------------===//
2197 // Atomic operations intrinsics
2200 // memory barriers protect the atomic sequences
2201 let hasSideEffects = 1 in {
2202 def Int_MemBarrierV7 : AInoP<(outs), (ins),
2203 Pseudo, NoItinerary,
2205 [(ARMMemBarrierV7)]>,
2206 Requires<[IsARM, HasV7]> {
2207 let Inst{31-4} = 0xf57ff05;
2208 // FIXME: add support for options other than a full system DMB
2209 // See DMB disassembly-only variants below.
2210 let Inst{3-0} = 0b1111;
2213 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
2214 Pseudo, NoItinerary,
2216 [(ARMSyncBarrierV7)]>,
2217 Requires<[IsARM, HasV7]> {
2218 let Inst{31-4} = 0xf57ff04;
2219 // FIXME: add support for options other than a full system DSB
2220 // See DSB disassembly-only variants below.
2221 let Inst{3-0} = 0b1111;
2224 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2225 Pseudo, NoItinerary,
2226 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2227 [(ARMMemBarrierV6 GPR:$zero)]>,
2228 Requires<[IsARM, HasV6]> {
2229 // FIXME: add support for options other than a full system DMB
2230 // FIXME: add encoding
2233 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2234 Pseudo, NoItinerary,
2235 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2236 [(ARMSyncBarrierV6 GPR:$zero)]>,
2237 Requires<[IsARM, HasV6]> {
2238 // FIXME: add support for options other than a full system DSB
2239 // FIXME: add encoding
2243 // Helper class for multiclass MemB -- for disassembly only
2244 class AMBI<string opc, string asm>
2245 : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
2246 [/* For disassembly only; pattern left blank */]>,
2247 Requires<[IsARM, HasV7]> {
2248 let Inst{31-20} = 0xf57;
2251 multiclass MemB<bits<4> op7_4, string opc> {
2253 def st : AMBI<opc, "\tst"> {
2254 let Inst{7-4} = op7_4;
2255 let Inst{3-0} = 0b1110;
2258 def ish : AMBI<opc, "\tish"> {
2259 let Inst{7-4} = op7_4;
2260 let Inst{3-0} = 0b1011;
2263 def ishst : AMBI<opc, "\tishst"> {
2264 let Inst{7-4} = op7_4;
2265 let Inst{3-0} = 0b1010;
2268 def nsh : AMBI<opc, "\tnsh"> {
2269 let Inst{7-4} = op7_4;
2270 let Inst{3-0} = 0b0111;
2273 def nshst : AMBI<opc, "\tnshst"> {
2274 let Inst{7-4} = op7_4;
2275 let Inst{3-0} = 0b0110;
2278 def osh : AMBI<opc, "\tosh"> {
2279 let Inst{7-4} = op7_4;
2280 let Inst{3-0} = 0b0011;
2283 def oshst : AMBI<opc, "\toshst"> {
2284 let Inst{7-4} = op7_4;
2285 let Inst{3-0} = 0b0010;
2289 // These DMB variants are for disassembly only.
2290 defm DMB : MemB<0b0101, "dmb">;
2292 // These DSB variants are for disassembly only.
2293 defm DSB : MemB<0b0100, "dsb">;
2295 // ISB has only full system option -- for disassembly only
2296 def ISBsy : AMBI<"isb", ""> {
2297 let Inst{7-4} = 0b0110;
2298 let Inst{3-0} = 0b1111;
2301 let usesCustomInserter = 1 in {
2302 let Uses = [CPSR] in {
2303 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2304 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2305 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2306 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2307 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2308 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2309 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2310 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2311 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2312 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2313 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2314 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2315 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2316 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2317 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2318 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2319 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2320 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2321 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2322 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2323 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2324 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2325 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2326 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2327 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2328 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2329 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2330 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2331 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2332 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2333 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2334 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2335 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2336 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2337 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2338 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2339 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2340 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2341 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2342 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2343 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2344 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2345 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2346 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2347 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2348 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2349 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2350 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2351 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2352 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2353 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2354 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2355 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2356 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2357 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2358 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2359 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2360 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2361 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2362 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2363 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2364 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2365 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2366 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2367 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2368 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2369 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2370 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2371 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2372 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2373 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2374 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2376 def ATOMIC_SWAP_I8 : PseudoInst<
2377 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2378 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2379 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2380 def ATOMIC_SWAP_I16 : PseudoInst<
2381 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2382 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2383 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2384 def ATOMIC_SWAP_I32 : PseudoInst<
2385 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2386 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2387 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2389 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2390 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2391 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2392 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2393 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2394 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2395 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2396 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2397 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2398 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2399 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2400 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2404 let mayLoad = 1 in {
2405 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2406 "ldrexb", "\t$dest, [$ptr]",
2408 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2409 "ldrexh", "\t$dest, [$ptr]",
2411 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2412 "ldrex", "\t$dest, [$ptr]",
2414 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2416 "ldrexd", "\t$dest, $dest2, [$ptr]",
2420 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2421 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2423 "strexb", "\t$success, $src, [$ptr]",
2425 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2427 "strexh", "\t$success, $src, [$ptr]",
2429 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2431 "strex", "\t$success, $src, [$ptr]",
2433 def STREXD : AIstrex<0b01, (outs GPR:$success),
2434 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2436 "strexd", "\t$success, $src, $src2, [$ptr]",
2440 // Clear-Exclusive is for disassembly only.
2441 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2442 [/* For disassembly only; pattern left blank */]>,
2443 Requires<[IsARM, HasV7]> {
2444 let Inst{31-20} = 0xf57;
2445 let Inst{7-4} = 0b0001;
2448 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2449 let mayLoad = 1 in {
2450 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2451 "swp", "\t$dst, $src, [$ptr]",
2452 [/* For disassembly only; pattern left blank */]> {
2453 let Inst{27-23} = 0b00010;
2454 let Inst{22} = 0; // B = 0
2455 let Inst{21-20} = 0b00;
2456 let Inst{7-4} = 0b1001;
2459 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2460 "swpb", "\t$dst, $src, [$ptr]",
2461 [/* For disassembly only; pattern left blank */]> {
2462 let Inst{27-23} = 0b00010;
2463 let Inst{22} = 1; // B = 1
2464 let Inst{21-20} = 0b00;
2465 let Inst{7-4} = 0b1001;
2469 //===----------------------------------------------------------------------===//
2473 // __aeabi_read_tp preserves the registers r1-r3.
2475 Defs = [R0, R12, LR, CPSR] in {
2476 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2477 "bl\t__aeabi_read_tp",
2478 [(set R0, ARMthread_pointer)]>;
2481 //===----------------------------------------------------------------------===//
2482 // SJLJ Exception handling intrinsics
2483 // eh_sjlj_setjmp() is an instruction sequence to store the return
2484 // address and save #0 in R0 for the non-longjmp case.
2485 // Since by its nature we may be coming from some other function to get
2486 // here, and we're using the stack frame for the containing function to
2487 // save/restore registers, we can't keep anything live in regs across
2488 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2489 // when we get here from a longjmp(). We force everthing out of registers
2490 // except for our own input by listing the relevant registers in Defs. By
2491 // doing so, we also cause the prologue/epilogue code to actively preserve
2492 // all of the callee-saved resgisters, which is exactly what we want.
2493 // A constant value is passed in $val, and we use the location as a scratch.
2495 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2496 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2497 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2499 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2500 AddrModeNone, SizeSpecial, IndexModeNone,
2501 Pseudo, NoItinerary,
2502 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2503 "add\t$val, pc, #8\n\t"
2504 "str\t$val, [$src, #+4]\n\t"
2506 "add\tpc, pc, #0\n\t"
2507 "mov\tr0, #1 @ eh_setjmp end", "",
2508 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2511 //===----------------------------------------------------------------------===//
2512 // Non-Instruction Patterns
2515 // Large immediate handling.
2517 // Two piece so_imms.
2518 let isReMaterializable = 1 in
2519 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2521 "mov", "\t$dst, $src",
2522 [(set GPR:$dst, so_imm2part:$src)]>,
2523 Requires<[IsARM, NoV6T2]>;
2525 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2526 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2527 (so_imm2part_2 imm:$RHS))>;
2528 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2529 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2530 (so_imm2part_2 imm:$RHS))>;
2531 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2532 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2533 (so_imm2part_2 imm:$RHS))>;
2534 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2535 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2536 (so_neg_imm2part_2 imm:$RHS))>;
2538 // 32-bit immediate using movw + movt.
2539 // This is a single pseudo instruction, the benefit is that it can be remat'd
2540 // as a single unit instead of having to handle reg inputs.
2541 // FIXME: Remove this when we can do generalized remat.
2542 let isReMaterializable = 1 in
2543 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2544 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2545 [(set GPR:$dst, (i32 imm:$src))]>,
2546 Requires<[IsARM, HasV6T2]>;
2548 // ConstantPool, GlobalAddress, and JumpTable
2549 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2550 Requires<[IsARM, DontUseMovt]>;
2551 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2552 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2553 Requires<[IsARM, UseMovt]>;
2554 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2555 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2557 // TODO: add,sub,and, 3-instr forms?
2561 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2562 Requires<[IsARM, IsNotDarwin]>;
2563 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2564 Requires<[IsARM, IsDarwin]>;
2566 // zextload i1 -> zextload i8
2567 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2569 // extload -> zextload
2570 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2571 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2572 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2574 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2575 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2578 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2579 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2580 (SMULBB GPR:$a, GPR:$b)>;
2581 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2582 (SMULBB GPR:$a, GPR:$b)>;
2583 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2584 (sra GPR:$b, (i32 16))),
2585 (SMULBT GPR:$a, GPR:$b)>;
2586 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2587 (SMULBT GPR:$a, GPR:$b)>;
2588 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2589 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2590 (SMULTB GPR:$a, GPR:$b)>;
2591 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2592 (SMULTB GPR:$a, GPR:$b)>;
2593 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2595 (SMULWB GPR:$a, GPR:$b)>;
2596 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2597 (SMULWB GPR:$a, GPR:$b)>;
2599 def : ARMV5TEPat<(add GPR:$acc,
2600 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2601 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2602 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2603 def : ARMV5TEPat<(add GPR:$acc,
2604 (mul sext_16_node:$a, sext_16_node:$b)),
2605 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2606 def : ARMV5TEPat<(add GPR:$acc,
2607 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2608 (sra GPR:$b, (i32 16)))),
2609 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2610 def : ARMV5TEPat<(add GPR:$acc,
2611 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2612 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2613 def : ARMV5TEPat<(add GPR:$acc,
2614 (mul (sra GPR:$a, (i32 16)),
2615 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2616 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2617 def : ARMV5TEPat<(add GPR:$acc,
2618 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2619 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2620 def : ARMV5TEPat<(add GPR:$acc,
2621 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2623 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2624 def : ARMV5TEPat<(add GPR:$acc,
2625 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2626 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2628 //===----------------------------------------------------------------------===//
2632 include "ARMInstrThumb.td"
2634 //===----------------------------------------------------------------------===//
2638 include "ARMInstrThumb2.td"
2640 //===----------------------------------------------------------------------===//
2641 // Floating Point Support
2644 include "ARMInstrVFP.td"
2646 //===----------------------------------------------------------------------===//
2647 // Advanced SIMD (NEON) Support
2650 include "ARMInstrNEON.td"
2652 //===----------------------------------------------------------------------===//
2653 // Coprocessor Instructions. For disassembly only.
2656 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2657 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2658 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2659 [/* For disassembly only; pattern left blank */]> {
2663 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2664 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2665 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2666 [/* For disassembly only; pattern left blank */]> {
2667 let Inst{31-28} = 0b1111;
2671 class ACI<dag oops, dag iops, string opc, string asm>
2672 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2673 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2674 let Inst{27-25} = 0b110;
2677 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2679 def _OFFSET : ACI<(outs),
2680 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2681 opc, "\tp$cop, cr$CRd, $addr"> {
2682 let Inst{31-28} = op31_28;
2683 let Inst{24} = 1; // P = 1
2684 let Inst{21} = 0; // W = 0
2685 let Inst{22} = 0; // D = 0
2686 let Inst{20} = load;
2689 def _PRE : ACI<(outs),
2690 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2691 opc, "\tp$cop, cr$CRd, $addr!"> {
2692 let Inst{31-28} = op31_28;
2693 let Inst{24} = 1; // P = 1
2694 let Inst{21} = 1; // W = 1
2695 let Inst{22} = 0; // D = 0
2696 let Inst{20} = load;
2699 def _POST : ACI<(outs),
2700 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2701 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2702 let Inst{31-28} = op31_28;
2703 let Inst{24} = 0; // P = 0
2704 let Inst{21} = 1; // W = 1
2705 let Inst{22} = 0; // D = 0
2706 let Inst{20} = load;
2709 def _OPTION : ACI<(outs),
2710 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2711 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2712 let Inst{31-28} = op31_28;
2713 let Inst{24} = 0; // P = 0
2714 let Inst{23} = 1; // U = 1
2715 let Inst{21} = 0; // W = 0
2716 let Inst{22} = 0; // D = 0
2717 let Inst{20} = load;
2720 def L_OFFSET : ACI<(outs),
2721 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2722 opc, "l\tp$cop, cr$CRd, $addr"> {
2723 let Inst{31-28} = op31_28;
2724 let Inst{24} = 1; // P = 1
2725 let Inst{21} = 0; // W = 0
2726 let Inst{22} = 1; // D = 1
2727 let Inst{20} = load;
2730 def L_PRE : ACI<(outs),
2731 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2732 opc, "l\tp$cop, cr$CRd, $addr!"> {
2733 let Inst{31-28} = op31_28;
2734 let Inst{24} = 1; // P = 1
2735 let Inst{21} = 1; // W = 1
2736 let Inst{22} = 1; // D = 1
2737 let Inst{20} = load;
2740 def L_POST : ACI<(outs),
2741 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2742 opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
2743 let Inst{31-28} = op31_28;
2744 let Inst{24} = 0; // P = 0
2745 let Inst{21} = 1; // W = 1
2746 let Inst{22} = 1; // D = 1
2747 let Inst{20} = load;
2750 def L_OPTION : ACI<(outs),
2751 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2752 opc, "l\tp$cop, cr$CRd, [$base], $option"> {
2753 let Inst{31-28} = op31_28;
2754 let Inst{24} = 0; // P = 0
2755 let Inst{23} = 1; // U = 1
2756 let Inst{21} = 0; // W = 0
2757 let Inst{22} = 1; // D = 1
2758 let Inst{20} = load;
2762 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2763 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2764 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2765 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2767 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2768 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2769 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2770 [/* For disassembly only; pattern left blank */]> {
2775 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2776 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2777 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2778 [/* For disassembly only; pattern left blank */]> {
2779 let Inst{31-28} = 0b1111;
2784 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2785 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2786 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2787 [/* For disassembly only; pattern left blank */]> {
2792 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2793 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2794 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2795 [/* For disassembly only; pattern left blank */]> {
2796 let Inst{31-28} = 0b1111;
2801 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2802 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2803 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2804 [/* For disassembly only; pattern left blank */]> {
2805 let Inst{23-20} = 0b0100;
2808 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2809 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2810 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2811 [/* For disassembly only; pattern left blank */]> {
2812 let Inst{31-28} = 0b1111;
2813 let Inst{23-20} = 0b0100;
2816 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2817 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2818 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2819 [/* For disassembly only; pattern left blank */]> {
2820 let Inst{23-20} = 0b0101;
2823 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2824 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2825 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2826 [/* For disassembly only; pattern left blank */]> {
2827 let Inst{31-28} = 0b1111;
2828 let Inst{23-20} = 0b0101;
2831 //===----------------------------------------------------------------------===//
2832 // Move between special register and ARM core register -- for disassembly only
2835 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2836 [/* For disassembly only; pattern left blank */]> {
2837 let Inst{23-20} = 0b0000;
2838 let Inst{7-4} = 0b0000;
2841 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2842 [/* For disassembly only; pattern left blank */]> {
2843 let Inst{23-20} = 0b0100;
2844 let Inst{7-4} = 0b0000;
2847 // FIXME: mask is ignored for the time being.
2848 def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2849 [/* For disassembly only; pattern left blank */]> {
2850 let Inst{23-20} = 0b0010;
2851 let Inst{7-4} = 0b0000;
2854 // FIXME: mask is ignored for the time being.
2855 def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
2856 [/* For disassembly only; pattern left blank */]> {
2857 let Inst{23-20} = 0b0010;
2858 let Inst{7-4} = 0b0000;
2861 // FIXME: mask is ignored for the time being.
2862 def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
2863 [/* For disassembly only; pattern left blank */]> {
2864 let Inst{23-20} = 0b0110;
2865 let Inst{7-4} = 0b0000;
2868 // FIXME: mask is ignored for the time being.
2869 def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
2870 [/* For disassembly only; pattern left blank */]> {
2871 let Inst{23-20} = 0b0110;
2872 let Inst{7-4} = 0b0000;