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:$addr, 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:$base, 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 cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
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.
725 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
726 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
727 multiclass APreLoad<bit data, bit read, string opc> {
729 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
730 !strconcat(opc, "\t[$base, $imm]"), []> {
731 let Inst{31-26} = 0b111101;
732 let Inst{25} = 0; // 0 for immediate form
735 let Inst{21-20} = 0b01;
738 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
739 !strconcat(opc, "\t$addr"), []> {
740 let Inst{31-26} = 0b111101;
741 let Inst{25} = 1; // 1 for register form
744 let Inst{21-20} = 0b01;
749 defm PLD : APreLoad<1, 1, "pld">;
750 defm PLDW : APreLoad<1, 0, "pldw">;
751 defm PLI : APreLoad<0, 1, "pli">;
753 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
754 [/* For disassembly only; pattern left blank */]>,
756 let Inst{31-28} = 0b1111;
757 let Inst{27-20} = 0b00010000;
760 let Inst{7-4} = 0b0000;
763 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
764 [/* For disassembly only; pattern left blank */]>,
766 let Inst{31-28} = 0b1111;
767 let Inst{27-20} = 0b00010000;
770 let Inst{7-4} = 0b0000;
773 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
774 [/* For disassembly only; pattern left blank */]>,
775 Requires<[IsARM, HasV7]> {
776 let Inst{27-16} = 0b001100100000;
777 let Inst{7-4} = 0b1111;
780 // A5.4 Permanently UNDEFINED instructions.
781 def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
782 [/* For disassembly only; pattern left blank */]>,
784 let Inst{27-25} = 0b011;
785 let Inst{24-20} = 0b11111;
786 let Inst{7-5} = 0b111;
790 // Address computation and loads and stores in PIC mode.
791 let isNotDuplicable = 1 in {
792 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
793 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
794 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
796 let AddedComplexity = 10 in {
797 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
798 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
799 [(set GPR:$dst, (load addrmodepc:$addr))]>;
801 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
802 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
803 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
805 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
806 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
807 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
809 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
810 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
811 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
813 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
814 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
815 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
817 let AddedComplexity = 10 in {
818 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
819 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
820 [(store GPR:$src, addrmodepc:$addr)]>;
822 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
823 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
824 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
826 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
827 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
828 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
830 } // isNotDuplicable = 1
833 // LEApcrel - Load a pc-relative address into a register without offending the
835 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
837 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
838 "${:private}PCRELL${:uid}+8))\n"),
839 !strconcat("${:private}PCRELL${:uid}:\n\t",
840 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
843 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
844 (ins i32imm:$label, nohash_imm:$id, pred:$p),
846 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
848 "${:private}PCRELL${:uid}+8))\n"),
849 !strconcat("${:private}PCRELL${:uid}:\n\t",
850 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
855 //===----------------------------------------------------------------------===//
856 // Control Flow Instructions.
859 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
861 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
862 "bx", "\tlr", [(ARMretflag)]>,
863 Requires<[IsARM, HasV4T]> {
864 let Inst{3-0} = 0b1110;
865 let Inst{7-4} = 0b0001;
866 let Inst{19-8} = 0b111111111111;
867 let Inst{27-20} = 0b00010010;
871 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
872 "mov", "\tpc, lr", [(ARMretflag)]>,
873 Requires<[IsARM, NoV4T]> {
874 let Inst{11-0} = 0b000000001110;
875 let Inst{15-12} = 0b1111;
876 let Inst{19-16} = 0b0000;
877 let Inst{27-20} = 0b00011010;
882 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
884 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
886 Requires<[IsARM, HasV4T]> {
887 let Inst{7-4} = 0b0001;
888 let Inst{19-8} = 0b111111111111;
889 let Inst{27-20} = 0b00010010;
890 let Inst{31-28} = 0b1110;
894 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
896 Requires<[IsARM, NoV4T]> {
897 let Inst{11-4} = 0b00000000;
898 let Inst{15-12} = 0b1111;
899 let Inst{19-16} = 0b0000;
900 let Inst{27-20} = 0b00011010;
901 let Inst{31-28} = 0b1110;
905 // FIXME: remove when we have a way to marking a MI with these properties.
906 // FIXME: Should pc be an implicit operand like PICADD, etc?
907 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
908 hasExtraDefRegAllocReq = 1 in
909 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
910 reglist:$dsts, variable_ops),
911 IndexModeUpd, LdStMulFrm, IIC_Br,
912 "ldm${addr:submode}${p}\t$addr, $dsts",
913 "$addr.addr = $wb", []>;
915 // On non-Darwin platforms R9 is callee-saved.
917 Defs = [R0, R1, R2, R3, R12, LR,
918 D0, D1, D2, D3, D4, D5, D6, D7,
919 D16, D17, D18, D19, D20, D21, D22, D23,
920 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
921 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
922 IIC_Br, "bl\t${func:call}",
923 [(ARMcall tglobaladdr:$func)]>,
924 Requires<[IsARM, IsNotDarwin]> {
925 let Inst{31-28} = 0b1110;
928 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
929 IIC_Br, "bl", "\t${func:call}",
930 [(ARMcall_pred tglobaladdr:$func)]>,
931 Requires<[IsARM, IsNotDarwin]>;
934 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
935 IIC_Br, "blx\t$func",
936 [(ARMcall GPR:$func)]>,
937 Requires<[IsARM, HasV5T, IsNotDarwin]> {
938 let Inst{7-4} = 0b0011;
939 let Inst{19-8} = 0b111111111111;
940 let Inst{27-20} = 0b00010010;
944 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
945 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
946 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
947 [(ARMcall_nolink tGPR:$func)]>,
948 Requires<[IsARM, HasV4T, IsNotDarwin]> {
949 let Inst{7-4} = 0b0001;
950 let Inst{19-8} = 0b111111111111;
951 let Inst{27-20} = 0b00010010;
955 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
956 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
957 [(ARMcall_nolink tGPR:$func)]>,
958 Requires<[IsARM, NoV4T, IsNotDarwin]> {
959 let Inst{11-4} = 0b00000000;
960 let Inst{15-12} = 0b1111;
961 let Inst{19-16} = 0b0000;
962 let Inst{27-20} = 0b00011010;
966 // On Darwin R9 is call-clobbered.
968 Defs = [R0, R1, R2, R3, R9, R12, LR,
969 D0, D1, D2, D3, D4, D5, D6, D7,
970 D16, D17, D18, D19, D20, D21, D22, D23,
971 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
972 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
973 IIC_Br, "bl\t${func:call}",
974 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
975 let Inst{31-28} = 0b1110;
978 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
979 IIC_Br, "bl", "\t${func:call}",
980 [(ARMcall_pred tglobaladdr:$func)]>,
981 Requires<[IsARM, IsDarwin]>;
984 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
985 IIC_Br, "blx\t$func",
986 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
987 let Inst{7-4} = 0b0011;
988 let Inst{19-8} = 0b111111111111;
989 let Inst{27-20} = 0b00010010;
993 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
994 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
995 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
996 [(ARMcall_nolink tGPR:$func)]>,
997 Requires<[IsARM, HasV4T, IsDarwin]> {
998 let Inst{7-4} = 0b0001;
999 let Inst{19-8} = 0b111111111111;
1000 let Inst{27-20} = 0b00010010;
1004 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1005 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1006 [(ARMcall_nolink tGPR:$func)]>,
1007 Requires<[IsARM, NoV4T, IsDarwin]> {
1008 let Inst{11-4} = 0b00000000;
1009 let Inst{15-12} = 0b1111;
1010 let Inst{19-16} = 0b0000;
1011 let Inst{27-20} = 0b00011010;
1015 let isBranch = 1, isTerminator = 1 in {
1016 // B is "predicable" since it can be xformed into a Bcc.
1017 let isBarrier = 1 in {
1018 let isPredicable = 1 in
1019 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1020 "b\t$target", [(br bb:$target)]>;
1022 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1023 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1024 IIC_Br, "mov\tpc, $target \n$jt",
1025 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1026 let Inst{11-4} = 0b00000000;
1027 let Inst{15-12} = 0b1111;
1028 let Inst{20} = 0; // S Bit
1029 let Inst{24-21} = 0b1101;
1030 let Inst{27-25} = 0b000;
1032 def BR_JTm : JTI<(outs),
1033 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1034 IIC_Br, "ldr\tpc, $target \n$jt",
1035 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1037 let Inst{15-12} = 0b1111;
1038 let Inst{20} = 1; // L bit
1039 let Inst{21} = 0; // W bit
1040 let Inst{22} = 0; // B bit
1041 let Inst{24} = 1; // P bit
1042 let Inst{27-25} = 0b011;
1044 def BR_JTadd : JTI<(outs),
1045 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1046 IIC_Br, "add\tpc, $target, $idx \n$jt",
1047 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1049 let Inst{15-12} = 0b1111;
1050 let Inst{20} = 0; // S bit
1051 let Inst{24-21} = 0b0100;
1052 let Inst{27-25} = 0b000;
1054 } // isNotDuplicable = 1, isIndirectBranch = 1
1057 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1058 // a two-value operand where a dag node expects two operands. :(
1059 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1060 IIC_Br, "b", "\t$target",
1061 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1064 // Branch and Exchange Jazelle -- for disassembly only
1065 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1066 [/* For disassembly only; pattern left blank */]> {
1067 let Inst{23-20} = 0b0010;
1068 //let Inst{19-8} = 0xfff;
1069 let Inst{7-4} = 0b0010;
1072 // Secure Monitor Call is a system instruction -- for disassembly only
1073 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1074 [/* For disassembly only; pattern left blank */]> {
1075 let Inst{23-20} = 0b0110;
1076 let Inst{7-4} = 0b0111;
1079 // Supervisor Call (Software Interrupt) -- for disassembly only
1081 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1082 [/* For disassembly only; pattern left blank */]>;
1085 // Store Return State is a system instruction -- for disassembly only
1086 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1087 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1088 [/* For disassembly only; pattern left blank */]> {
1089 let Inst{31-28} = 0b1111;
1090 let Inst{22-20} = 0b110; // W = 1
1093 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1094 NoItinerary, "srs${addr:submode}\tsp, $mode",
1095 [/* For disassembly only; pattern left blank */]> {
1096 let Inst{31-28} = 0b1111;
1097 let Inst{22-20} = 0b100; // W = 0
1100 // Return From Exception is a system instruction -- for disassembly only
1101 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1102 NoItinerary, "rfe${addr:submode}\t$base!",
1103 [/* For disassembly only; pattern left blank */]> {
1104 let Inst{31-28} = 0b1111;
1105 let Inst{22-20} = 0b011; // W = 1
1108 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1109 NoItinerary, "rfe${addr:submode}\t$base",
1110 [/* For disassembly only; pattern left blank */]> {
1111 let Inst{31-28} = 0b1111;
1112 let Inst{22-20} = 0b001; // W = 0
1115 //===----------------------------------------------------------------------===//
1116 // Load / store Instructions.
1120 let canFoldAsLoad = 1, isReMaterializable = 1 in
1121 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1122 "ldr", "\t$dst, $addr",
1123 [(set GPR:$dst, (load addrmode2:$addr))]>;
1125 // Special LDR for loads from non-pc-relative constpools.
1126 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
1127 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1128 "ldr", "\t$dst, $addr", []>;
1130 // Loads with zero extension
1131 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1132 IIC_iLoadr, "ldrh", "\t$dst, $addr",
1133 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1135 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1136 IIC_iLoadr, "ldrb", "\t$dst, $addr",
1137 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1139 // Loads with sign extension
1140 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1141 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1142 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1144 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1145 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1146 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1148 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1150 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1151 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1152 []>, Requires<[IsARM, HasV5TE]>;
1155 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1156 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1157 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1159 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1160 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1161 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1163 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1164 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1165 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1167 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1168 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1169 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1171 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1172 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1173 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1175 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1176 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1177 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1179 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1180 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1181 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1183 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1184 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1185 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1187 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1188 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1189 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1191 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1192 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1193 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1195 // For disassembly only
1196 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1197 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1198 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1199 Requires<[IsARM, HasV5TE]>;
1201 // For disassembly only
1202 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1203 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1204 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1205 Requires<[IsARM, HasV5TE]>;
1209 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1211 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1212 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1213 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1214 let Inst{21} = 1; // overwrite
1217 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1218 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1219 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1220 let Inst{21} = 1; // overwrite
1223 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1224 (ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
1225 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1226 let Inst{21} = 1; // overwrite
1229 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1230 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1231 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1232 let Inst{21} = 1; // overwrite
1235 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1236 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1237 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1238 let Inst{21} = 1; // overwrite
1242 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1243 "str", "\t$src, $addr",
1244 [(store GPR:$src, addrmode2:$addr)]>;
1246 // Stores with truncate
1247 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1248 IIC_iStorer, "strh", "\t$src, $addr",
1249 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1251 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1252 "strb", "\t$src, $addr",
1253 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1256 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1257 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1258 StMiscFrm, IIC_iStorer,
1259 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1262 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1263 (ins GPR:$src, GPR:$base, am2offset:$offset),
1264 StFrm, IIC_iStoreru,
1265 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1267 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1269 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1270 (ins GPR:$src, GPR:$base,am2offset:$offset),
1271 StFrm, IIC_iStoreru,
1272 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1274 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1276 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1277 (ins GPR:$src, GPR:$base,am3offset:$offset),
1278 StMiscFrm, IIC_iStoreru,
1279 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1281 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1283 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1284 (ins GPR:$src, GPR:$base,am3offset:$offset),
1285 StMiscFrm, IIC_iStoreru,
1286 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1287 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1288 GPR:$base, am3offset:$offset))]>;
1290 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1291 (ins GPR:$src, GPR:$base,am2offset:$offset),
1292 StFrm, IIC_iStoreru,
1293 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1294 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1295 GPR:$base, am2offset:$offset))]>;
1297 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1298 (ins GPR:$src, GPR:$base,am2offset:$offset),
1299 StFrm, IIC_iStoreru,
1300 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1301 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1302 GPR:$base, am2offset:$offset))]>;
1304 // For disassembly only
1305 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1306 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1307 StMiscFrm, IIC_iStoreru,
1308 "strd", "\t$src1, $src2, [$base, $offset]!",
1309 "$base = $base_wb", []>;
1311 // For disassembly only
1312 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1313 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1314 StMiscFrm, IIC_iStoreru,
1315 "strd", "\t$src1, $src2, [$base], $offset",
1316 "$base = $base_wb", []>;
1318 // STRT, STRBT, and STRHT are for disassembly only.
1320 def STRT : AI2stwpo<(outs GPR:$base_wb),
1321 (ins GPR:$src, GPR:$base,am2offset:$offset),
1322 StFrm, IIC_iStoreru,
1323 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1324 [/* For disassembly only; pattern left blank */]> {
1325 let Inst{21} = 1; // overwrite
1328 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1329 (ins GPR:$src, GPR:$base,am2offset:$offset),
1330 StFrm, IIC_iStoreru,
1331 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1332 [/* For disassembly only; pattern left blank */]> {
1333 let Inst{21} = 1; // overwrite
1336 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1337 (ins GPR:$src, GPR:$base,am3offset:$offset),
1338 StMiscFrm, IIC_iStoreru,
1339 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1340 [/* For disassembly only; pattern left blank */]> {
1341 let Inst{21} = 1; // overwrite
1344 //===----------------------------------------------------------------------===//
1345 // Load / store multiple Instructions.
1348 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1349 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1350 reglist:$dsts, variable_ops),
1351 IndexModeNone, LdStMulFrm, IIC_iLoadm,
1352 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1354 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1355 reglist:$dsts, variable_ops),
1356 IndexModeUpd, LdStMulFrm, IIC_iLoadm,
1357 "ldm${addr:submode}${p}\t$addr, $dsts",
1358 "$addr.addr = $wb", []>;
1359 } // mayLoad, hasExtraDefRegAllocReq
1361 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
1362 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1363 reglist:$srcs, variable_ops),
1364 IndexModeNone, LdStMulFrm, IIC_iStorem,
1365 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1367 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1368 reglist:$srcs, variable_ops),
1369 IndexModeUpd, LdStMulFrm, IIC_iStorem,
1370 "stm${addr:submode}${p}\t$addr, $srcs",
1371 "$addr.addr = $wb", []>;
1372 } // mayStore, hasExtraSrcRegAllocReq
1374 //===----------------------------------------------------------------------===//
1375 // Move Instructions.
1378 let neverHasSideEffects = 1 in
1379 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1380 "mov", "\t$dst, $src", []>, UnaryDP {
1381 let Inst{11-4} = 0b00000000;
1385 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1386 DPSoRegFrm, IIC_iMOVsr,
1387 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1391 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1392 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1393 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1397 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1398 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1400 "movw", "\t$dst, $src",
1401 [(set GPR:$dst, imm0_65535:$src)]>,
1402 Requires<[IsARM, HasV6T2]>, UnaryDP {
1407 let Constraints = "$src = $dst" in
1408 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1410 "movt", "\t$dst, $imm",
1412 (or (and GPR:$src, 0xffff),
1413 lo16AllZero:$imm))]>, UnaryDP,
1414 Requires<[IsARM, HasV6T2]> {
1419 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1420 Requires<[IsARM, HasV6T2]>;
1422 let Uses = [CPSR] in
1423 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1424 "mov", "\t$dst, $src, rrx",
1425 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1427 // These aren't really mov instructions, but we have to define them this way
1428 // due to flag operands.
1430 let Defs = [CPSR] in {
1431 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1432 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1433 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1434 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1435 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1436 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1439 //===----------------------------------------------------------------------===//
1440 // Extend Instructions.
1445 defm SXTB : AI_unary_rrot<0b01101010,
1446 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1447 defm SXTH : AI_unary_rrot<0b01101011,
1448 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1450 defm SXTAB : AI_bin_rrot<0b01101010,
1451 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1452 defm SXTAH : AI_bin_rrot<0b01101011,
1453 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1455 // For disassembly only
1456 defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
1458 // For disassembly only
1459 defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1463 let AddedComplexity = 16 in {
1464 defm UXTB : AI_unary_rrot<0b01101110,
1465 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1466 defm UXTH : AI_unary_rrot<0b01101111,
1467 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1468 defm UXTB16 : AI_unary_rrot<0b01101100,
1469 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1471 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1472 (UXTB16r_rot GPR:$Src, 24)>;
1473 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1474 (UXTB16r_rot GPR:$Src, 8)>;
1476 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1477 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1478 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1479 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1482 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1483 // For disassembly only
1484 defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1487 def SBFX : I<(outs GPR:$dst),
1488 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1489 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1490 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1491 Requires<[IsARM, HasV6T2]> {
1492 let Inst{27-21} = 0b0111101;
1493 let Inst{6-4} = 0b101;
1496 def UBFX : I<(outs GPR:$dst),
1497 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1498 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1499 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1500 Requires<[IsARM, HasV6T2]> {
1501 let Inst{27-21} = 0b0111111;
1502 let Inst{6-4} = 0b101;
1505 //===----------------------------------------------------------------------===//
1506 // Arithmetic Instructions.
1509 defm ADD : AsI1_bin_irs<0b0100, "add",
1510 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1511 defm SUB : AsI1_bin_irs<0b0010, "sub",
1512 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1514 // ADD and SUB with 's' bit set.
1515 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1516 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1517 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1518 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1520 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1521 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1522 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1523 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1524 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1525 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1526 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1527 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1529 // These don't define reg/reg forms, because they are handled above.
1530 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1531 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1532 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1536 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1537 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1538 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1542 // RSB with 's' bit set.
1543 let Defs = [CPSR] in {
1544 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1545 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1546 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1550 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1551 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1552 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1558 let Uses = [CPSR] in {
1559 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1560 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1561 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1565 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1566 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1567 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1573 // FIXME: Allow these to be predicated.
1574 let Defs = [CPSR], Uses = [CPSR] in {
1575 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1576 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1577 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1582 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1583 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1584 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1591 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1592 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1593 (SUBri GPR:$src, so_imm_neg:$imm)>;
1595 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1596 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1597 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1598 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1600 // Note: These are implemented in C++ code, because they have to generate
1601 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1603 // (mul X, 2^n+1) -> (add (X << n), X)
1604 // (mul X, 2^n-1) -> (rsb X, (X << n))
1606 // ARM Arithmetic Instruction -- for disassembly only
1607 // GPR:$dst = GPR:$a op GPR:$b
1608 class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
1609 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1610 opc, "\t$dst, $a, $b",
1611 [/* For disassembly only; pattern left blank */]> {
1612 let Inst{27-20} = op27_20;
1613 let Inst{7-4} = op7_4;
1616 // Saturating add/subtract -- for disassembly only
1618 def QADD : AAI<0b00010000, 0b0101, "qadd">;
1619 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1620 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1621 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1622 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1623 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1624 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1625 def QSUB : AAI<0b00010010, 0b0101, "qsub">;
1626 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1627 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1628 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1629 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1630 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1631 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1632 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1633 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1635 // Signed/Unsigned add/subtract -- for disassembly only
1637 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1638 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1639 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1640 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1641 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1642 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1643 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1644 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1645 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1646 def USAX : AAI<0b01100101, 0b0101, "usax">;
1647 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1648 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1650 // Signed/Unsigned halving add/subtract -- for disassembly only
1652 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1653 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1654 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1655 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1656 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1657 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1658 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1659 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1660 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1661 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1662 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1663 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1665 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1667 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1668 MulFrm /* for convenience */, NoItinerary, "usad8",
1669 "\t$dst, $a, $b", []>,
1670 Requires<[IsARM, HasV6]> {
1671 let Inst{27-20} = 0b01111000;
1672 let Inst{15-12} = 0b1111;
1673 let Inst{7-4} = 0b0001;
1675 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1676 MulFrm /* for convenience */, NoItinerary, "usada8",
1677 "\t$dst, $a, $b, $acc", []>,
1678 Requires<[IsARM, HasV6]> {
1679 let Inst{27-20} = 0b01111000;
1680 let Inst{7-4} = 0b0001;
1683 // Signed/Unsigned saturate -- for disassembly only
1685 def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1686 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1687 [/* For disassembly only; pattern left blank */]> {
1688 let Inst{27-21} = 0b0110101;
1689 let Inst{6-4} = 0b001;
1692 def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1693 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1694 [/* For disassembly only; pattern left blank */]> {
1695 let Inst{27-21} = 0b0110101;
1696 let Inst{6-4} = 0b101;
1699 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1700 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1701 [/* For disassembly only; pattern left blank */]> {
1702 let Inst{27-20} = 0b01101010;
1703 let Inst{7-4} = 0b0011;
1706 def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1707 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1708 [/* For disassembly only; pattern left blank */]> {
1709 let Inst{27-21} = 0b0110111;
1710 let Inst{6-4} = 0b001;
1713 def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1714 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1715 [/* For disassembly only; pattern left blank */]> {
1716 let Inst{27-21} = 0b0110111;
1717 let Inst{6-4} = 0b101;
1720 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1721 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1722 [/* For disassembly only; pattern left blank */]> {
1723 let Inst{27-20} = 0b01101110;
1724 let Inst{7-4} = 0b0011;
1727 //===----------------------------------------------------------------------===//
1728 // Bitwise Instructions.
1731 defm AND : AsI1_bin_irs<0b0000, "and",
1732 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1733 defm ORR : AsI1_bin_irs<0b1100, "orr",
1734 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1735 defm EOR : AsI1_bin_irs<0b0001, "eor",
1736 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1737 defm BIC : AsI1_bin_irs<0b1110, "bic",
1738 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1740 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1741 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1742 "bfc", "\t$dst, $imm", "$src = $dst",
1743 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1744 Requires<[IsARM, HasV6T2]> {
1745 let Inst{27-21} = 0b0111110;
1746 let Inst{6-0} = 0b0011111;
1749 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1750 // Added for disassembler with the pattern field purposely left blank.
1751 def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1752 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1753 "bfi", "\t$dst, $src, $imm", "",
1754 [/* For disassembly only; pattern left blank */]>,
1755 Requires<[IsARM, HasV6T2]> {
1756 let Inst{27-21} = 0b0111110;
1757 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1760 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1761 "mvn", "\t$dst, $src",
1762 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1764 let Inst{11-4} = 0b00000000;
1766 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1767 IIC_iMOVsr, "mvn", "\t$dst, $src",
1768 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1771 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1772 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1773 IIC_iMOVi, "mvn", "\t$dst, $imm",
1774 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1778 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1779 (BICri GPR:$src, so_imm_not:$imm)>;
1781 //===----------------------------------------------------------------------===//
1782 // Multiply Instructions.
1785 let isCommutable = 1 in
1786 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1787 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1788 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1790 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1791 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1792 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1794 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1795 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1796 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1797 Requires<[IsARM, HasV6T2]>;
1799 // Extra precision multiplies with low / high results
1800 let neverHasSideEffects = 1 in {
1801 let isCommutable = 1 in {
1802 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1803 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1804 "smull", "\t$ldst, $hdst, $a, $b", []>;
1806 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1807 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1808 "umull", "\t$ldst, $hdst, $a, $b", []>;
1811 // Multiply + accumulate
1812 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1813 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1814 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1816 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1817 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1818 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1820 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1821 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1822 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1823 Requires<[IsARM, HasV6]>;
1824 } // neverHasSideEffects
1826 // Most significant word multiply
1827 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1828 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1829 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1830 Requires<[IsARM, HasV6]> {
1831 let Inst{7-4} = 0b0001;
1832 let Inst{15-12} = 0b1111;
1835 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1836 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1837 [/* For disassembly only; pattern left blank */]>,
1838 Requires<[IsARM, HasV6]> {
1839 let Inst{7-4} = 0b0011; // R = 1
1840 let Inst{15-12} = 0b1111;
1843 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1844 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1845 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1846 Requires<[IsARM, HasV6]> {
1847 let Inst{7-4} = 0b0001;
1850 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1851 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1852 [/* For disassembly only; pattern left blank */]>,
1853 Requires<[IsARM, HasV6]> {
1854 let Inst{7-4} = 0b0011; // R = 1
1857 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1858 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1859 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1860 Requires<[IsARM, HasV6]> {
1861 let Inst{7-4} = 0b1101;
1864 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1865 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1866 [/* For disassembly only; pattern left blank */]>,
1867 Requires<[IsARM, HasV6]> {
1868 let Inst{7-4} = 0b1111; // R = 1
1871 multiclass AI_smul<string opc, PatFrag opnode> {
1872 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1873 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1874 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1875 (sext_inreg GPR:$b, i16)))]>,
1876 Requires<[IsARM, HasV5TE]> {
1881 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1882 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1883 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1884 (sra GPR:$b, (i32 16))))]>,
1885 Requires<[IsARM, HasV5TE]> {
1890 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1891 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1892 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1893 (sext_inreg GPR:$b, i16)))]>,
1894 Requires<[IsARM, HasV5TE]> {
1899 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1900 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1901 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1902 (sra GPR:$b, (i32 16))))]>,
1903 Requires<[IsARM, HasV5TE]> {
1908 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1909 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1910 [(set GPR:$dst, (sra (opnode GPR:$a,
1911 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1912 Requires<[IsARM, HasV5TE]> {
1917 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1918 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1919 [(set GPR:$dst, (sra (opnode GPR:$a,
1920 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1921 Requires<[IsARM, HasV5TE]> {
1928 multiclass AI_smla<string opc, PatFrag opnode> {
1929 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1930 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1931 [(set GPR:$dst, (add GPR:$acc,
1932 (opnode (sext_inreg GPR:$a, i16),
1933 (sext_inreg GPR:$b, i16))))]>,
1934 Requires<[IsARM, HasV5TE]> {
1939 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1940 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1941 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1942 (sra GPR:$b, (i32 16)))))]>,
1943 Requires<[IsARM, HasV5TE]> {
1948 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1949 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1950 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1951 (sext_inreg GPR:$b, i16))))]>,
1952 Requires<[IsARM, HasV5TE]> {
1957 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1958 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1959 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1960 (sra GPR:$b, (i32 16)))))]>,
1961 Requires<[IsARM, HasV5TE]> {
1966 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1967 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1968 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1969 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1970 Requires<[IsARM, HasV5TE]> {
1975 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1976 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1977 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1978 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1979 Requires<[IsARM, HasV5TE]> {
1985 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1986 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1988 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1989 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1990 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1991 [/* For disassembly only; pattern left blank */]>,
1992 Requires<[IsARM, HasV5TE]> {
1997 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1998 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1999 [/* For disassembly only; pattern left blank */]>,
2000 Requires<[IsARM, HasV5TE]> {
2005 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2006 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2007 [/* For disassembly only; pattern left blank */]>,
2008 Requires<[IsARM, HasV5TE]> {
2013 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2014 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2015 [/* For disassembly only; pattern left blank */]>,
2016 Requires<[IsARM, HasV5TE]> {
2021 // Helper class for AI_smld -- for disassembly only
2022 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2023 InstrItinClass itin, string opc, string asm>
2024 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2029 let Inst{21-20} = 0b00;
2030 let Inst{22} = long;
2031 let Inst{27-23} = 0b01110;
2034 multiclass AI_smld<bit sub, string opc> {
2036 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2037 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2039 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2040 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2042 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2043 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2045 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2046 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2050 defm SMLA : AI_smld<0, "smla">;
2051 defm SMLS : AI_smld<1, "smls">;
2053 multiclass AI_sdml<bit sub, string opc> {
2055 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2056 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2057 let Inst{15-12} = 0b1111;
2060 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2061 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2062 let Inst{15-12} = 0b1111;
2067 defm SMUA : AI_sdml<0, "smua">;
2068 defm SMUS : AI_sdml<1, "smus">;
2070 //===----------------------------------------------------------------------===//
2071 // Misc. Arithmetic Instructions.
2074 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2075 "clz", "\t$dst, $src",
2076 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2077 let Inst{7-4} = 0b0001;
2078 let Inst{11-8} = 0b1111;
2079 let Inst{19-16} = 0b1111;
2082 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2083 "rbit", "\t$dst, $src",
2084 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2085 Requires<[IsARM, HasV6T2]> {
2086 let Inst{7-4} = 0b0011;
2087 let Inst{11-8} = 0b1111;
2088 let Inst{19-16} = 0b1111;
2091 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2092 "rev", "\t$dst, $src",
2093 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2094 let Inst{7-4} = 0b0011;
2095 let Inst{11-8} = 0b1111;
2096 let Inst{19-16} = 0b1111;
2099 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2100 "rev16", "\t$dst, $src",
2102 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2103 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2104 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2105 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2106 Requires<[IsARM, HasV6]> {
2107 let Inst{7-4} = 0b1011;
2108 let Inst{11-8} = 0b1111;
2109 let Inst{19-16} = 0b1111;
2112 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2113 "revsh", "\t$dst, $src",
2116 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2117 (shl GPR:$src, (i32 8))), i16))]>,
2118 Requires<[IsARM, HasV6]> {
2119 let Inst{7-4} = 0b1011;
2120 let Inst{11-8} = 0b1111;
2121 let Inst{19-16} = 0b1111;
2124 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2125 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2126 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2127 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2128 (and (shl GPR:$src2, (i32 imm:$shamt)),
2130 Requires<[IsARM, HasV6]> {
2131 let Inst{6-4} = 0b001;
2134 // Alternate cases for PKHBT where identities eliminate some nodes.
2135 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2136 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2137 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2138 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2141 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2142 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2143 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2144 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2145 (and (sra GPR:$src2, imm16_31:$shamt),
2146 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
2147 let Inst{6-4} = 0b101;
2150 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2151 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2152 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2153 (PKHTB GPR:$src1, GPR:$src2, 16)>;
2154 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2155 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2156 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2158 //===----------------------------------------------------------------------===//
2159 // Comparison Instructions...
2162 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2163 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2164 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2165 // Compare-to-zero still works out, just not the relationals
2166 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2167 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2169 // Note that TST/TEQ don't set all the same flags that CMP does!
2170 defm TST : AI1_cmp_irs<0b1000, "tst",
2171 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2172 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2173 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2175 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2176 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2177 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2178 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2180 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2181 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2183 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2184 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2187 // Conditional moves
2188 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2189 // a two-value operand where a dag node expects two operands. :(
2190 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2191 IIC_iCMOVr, "mov", "\t$dst, $true",
2192 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2193 RegConstraint<"$false = $dst">, UnaryDP {
2194 let Inst{11-4} = 0b00000000;
2198 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2199 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2200 "mov", "\t$dst, $true",
2201 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2202 RegConstraint<"$false = $dst">, UnaryDP {
2206 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2207 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2208 "mov", "\t$dst, $true",
2209 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2210 RegConstraint<"$false = $dst">, UnaryDP {
2214 //===----------------------------------------------------------------------===//
2215 // Atomic operations intrinsics
2218 // memory barriers protect the atomic sequences
2219 let hasSideEffects = 1 in {
2220 def Int_MemBarrierV7 : AInoP<(outs), (ins),
2221 Pseudo, NoItinerary,
2223 [(ARMMemBarrierV7)]>,
2224 Requires<[IsARM, HasV7]> {
2225 let Inst{31-4} = 0xf57ff05;
2226 // FIXME: add support for options other than a full system DMB
2227 // See DMB disassembly-only variants below.
2228 let Inst{3-0} = 0b1111;
2231 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
2232 Pseudo, NoItinerary,
2234 [(ARMSyncBarrierV7)]>,
2235 Requires<[IsARM, HasV7]> {
2236 let Inst{31-4} = 0xf57ff04;
2237 // FIXME: add support for options other than a full system DSB
2238 // See DSB disassembly-only variants below.
2239 let Inst{3-0} = 0b1111;
2242 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2243 Pseudo, NoItinerary,
2244 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2245 [(ARMMemBarrierV6 GPR:$zero)]>,
2246 Requires<[IsARM, HasV6]> {
2247 // FIXME: add support for options other than a full system DMB
2248 // FIXME: add encoding
2251 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2252 Pseudo, NoItinerary,
2253 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2254 [(ARMSyncBarrierV6 GPR:$zero)]>,
2255 Requires<[IsARM, HasV6]> {
2256 // FIXME: add support for options other than a full system DSB
2257 // FIXME: add encoding
2261 // Helper class for multiclass MemB -- for disassembly only
2262 class AMBI<string opc, string asm>
2263 : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
2264 [/* For disassembly only; pattern left blank */]>,
2265 Requires<[IsARM, HasV7]> {
2266 let Inst{31-20} = 0xf57;
2269 multiclass MemB<bits<4> op7_4, string opc> {
2271 def st : AMBI<opc, "\tst"> {
2272 let Inst{7-4} = op7_4;
2273 let Inst{3-0} = 0b1110;
2276 def ish : AMBI<opc, "\tish"> {
2277 let Inst{7-4} = op7_4;
2278 let Inst{3-0} = 0b1011;
2281 def ishst : AMBI<opc, "\tishst"> {
2282 let Inst{7-4} = op7_4;
2283 let Inst{3-0} = 0b1010;
2286 def nsh : AMBI<opc, "\tnsh"> {
2287 let Inst{7-4} = op7_4;
2288 let Inst{3-0} = 0b0111;
2291 def nshst : AMBI<opc, "\tnshst"> {
2292 let Inst{7-4} = op7_4;
2293 let Inst{3-0} = 0b0110;
2296 def osh : AMBI<opc, "\tosh"> {
2297 let Inst{7-4} = op7_4;
2298 let Inst{3-0} = 0b0011;
2301 def oshst : AMBI<opc, "\toshst"> {
2302 let Inst{7-4} = op7_4;
2303 let Inst{3-0} = 0b0010;
2307 // These DMB variants are for disassembly only.
2308 defm DMB : MemB<0b0101, "dmb">;
2310 // These DSB variants are for disassembly only.
2311 defm DSB : MemB<0b0100, "dsb">;
2313 // ISB has only full system option -- for disassembly only
2314 def ISBsy : AMBI<"isb", ""> {
2315 let Inst{7-4} = 0b0110;
2316 let Inst{3-0} = 0b1111;
2319 let usesCustomInserter = 1 in {
2320 let Uses = [CPSR] in {
2321 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2322 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2323 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2324 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2325 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2326 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2327 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2328 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2329 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2330 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2331 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2332 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2333 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2334 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2335 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2336 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2337 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2338 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2339 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2340 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2341 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2342 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2343 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2344 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2345 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2346 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2347 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2348 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2349 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2350 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2351 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2352 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2353 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2354 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2355 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2356 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2357 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2358 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2359 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2360 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2361 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2362 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2363 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2364 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2365 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2366 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2367 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2368 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2369 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2370 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2371 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2372 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2373 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2374 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2375 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2376 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2377 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2378 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2379 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2380 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2381 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2382 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2383 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2384 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2385 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2386 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2387 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2388 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2389 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2390 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2391 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2392 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2394 def ATOMIC_SWAP_I8 : PseudoInst<
2395 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2396 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2397 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2398 def ATOMIC_SWAP_I16 : PseudoInst<
2399 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2400 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2401 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2402 def ATOMIC_SWAP_I32 : PseudoInst<
2403 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2404 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2405 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2407 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2408 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2409 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2410 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2411 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2412 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2413 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2414 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2415 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2416 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2417 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2418 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2422 let mayLoad = 1 in {
2423 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2424 "ldrexb", "\t$dest, [$ptr]",
2426 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2427 "ldrexh", "\t$dest, [$ptr]",
2429 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2430 "ldrex", "\t$dest, [$ptr]",
2432 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2434 "ldrexd", "\t$dest, $dest2, [$ptr]",
2438 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2439 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2441 "strexb", "\t$success, $src, [$ptr]",
2443 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2445 "strexh", "\t$success, $src, [$ptr]",
2447 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2449 "strex", "\t$success, $src, [$ptr]",
2451 def STREXD : AIstrex<0b01, (outs GPR:$success),
2452 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2454 "strexd", "\t$success, $src, $src2, [$ptr]",
2458 // Clear-Exclusive is for disassembly only.
2459 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2460 [/* For disassembly only; pattern left blank */]>,
2461 Requires<[IsARM, HasV7]> {
2462 let Inst{31-20} = 0xf57;
2463 let Inst{7-4} = 0b0001;
2466 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2467 let mayLoad = 1 in {
2468 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2469 "swp", "\t$dst, $src, [$ptr]",
2470 [/* For disassembly only; pattern left blank */]> {
2471 let Inst{27-23} = 0b00010;
2472 let Inst{22} = 0; // B = 0
2473 let Inst{21-20} = 0b00;
2474 let Inst{7-4} = 0b1001;
2477 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2478 "swpb", "\t$dst, $src, [$ptr]",
2479 [/* For disassembly only; pattern left blank */]> {
2480 let Inst{27-23} = 0b00010;
2481 let Inst{22} = 1; // B = 1
2482 let Inst{21-20} = 0b00;
2483 let Inst{7-4} = 0b1001;
2487 //===----------------------------------------------------------------------===//
2491 // __aeabi_read_tp preserves the registers r1-r3.
2493 Defs = [R0, R12, LR, CPSR] in {
2494 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2495 "bl\t__aeabi_read_tp",
2496 [(set R0, ARMthread_pointer)]>;
2499 //===----------------------------------------------------------------------===//
2500 // SJLJ Exception handling intrinsics
2501 // eh_sjlj_setjmp() is an instruction sequence to store the return
2502 // address and save #0 in R0 for the non-longjmp case.
2503 // Since by its nature we may be coming from some other function to get
2504 // here, and we're using the stack frame for the containing function to
2505 // save/restore registers, we can't keep anything live in regs across
2506 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2507 // when we get here from a longjmp(). We force everthing out of registers
2508 // except for our own input by listing the relevant registers in Defs. By
2509 // doing so, we also cause the prologue/epilogue code to actively preserve
2510 // all of the callee-saved resgisters, which is exactly what we want.
2511 // A constant value is passed in $val, and we use the location as a scratch.
2513 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2514 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2515 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2517 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2518 AddrModeNone, SizeSpecial, IndexModeNone,
2519 Pseudo, NoItinerary,
2520 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2521 "add\t$val, pc, #8\n\t"
2522 "str\t$val, [$src, #+4]\n\t"
2524 "add\tpc, pc, #0\n\t"
2525 "mov\tr0, #1 @ eh_setjmp end", "",
2526 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2529 //===----------------------------------------------------------------------===//
2530 // Non-Instruction Patterns
2533 // Large immediate handling.
2535 // Two piece so_imms.
2536 let isReMaterializable = 1 in
2537 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2539 "mov", "\t$dst, $src",
2540 [(set GPR:$dst, so_imm2part:$src)]>,
2541 Requires<[IsARM, NoV6T2]>;
2543 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2544 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2545 (so_imm2part_2 imm:$RHS))>;
2546 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2547 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2548 (so_imm2part_2 imm:$RHS))>;
2549 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2550 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2551 (so_imm2part_2 imm:$RHS))>;
2552 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2553 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2554 (so_neg_imm2part_2 imm:$RHS))>;
2556 // 32-bit immediate using movw + movt.
2557 // This is a single pseudo instruction, the benefit is that it can be remat'd
2558 // as a single unit instead of having to handle reg inputs.
2559 // FIXME: Remove this when we can do generalized remat.
2560 let isReMaterializable = 1 in
2561 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2562 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2563 [(set GPR:$dst, (i32 imm:$src))]>,
2564 Requires<[IsARM, HasV6T2]>;
2566 // ConstantPool, GlobalAddress, and JumpTable
2567 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2568 Requires<[IsARM, DontUseMovt]>;
2569 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2570 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2571 Requires<[IsARM, UseMovt]>;
2572 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2573 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2575 // TODO: add,sub,and, 3-instr forms?
2579 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2580 Requires<[IsARM, IsNotDarwin]>;
2581 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2582 Requires<[IsARM, IsDarwin]>;
2584 // zextload i1 -> zextload i8
2585 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2587 // extload -> zextload
2588 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2589 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2590 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2592 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2593 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2596 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2597 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2598 (SMULBB GPR:$a, GPR:$b)>;
2599 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2600 (SMULBB GPR:$a, GPR:$b)>;
2601 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2602 (sra GPR:$b, (i32 16))),
2603 (SMULBT GPR:$a, GPR:$b)>;
2604 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2605 (SMULBT GPR:$a, GPR:$b)>;
2606 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2607 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2608 (SMULTB GPR:$a, GPR:$b)>;
2609 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2610 (SMULTB GPR:$a, GPR:$b)>;
2611 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2613 (SMULWB GPR:$a, GPR:$b)>;
2614 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2615 (SMULWB GPR:$a, GPR:$b)>;
2617 def : ARMV5TEPat<(add GPR:$acc,
2618 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2619 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2620 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2621 def : ARMV5TEPat<(add GPR:$acc,
2622 (mul sext_16_node:$a, sext_16_node:$b)),
2623 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2624 def : ARMV5TEPat<(add GPR:$acc,
2625 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2626 (sra GPR:$b, (i32 16)))),
2627 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2628 def : ARMV5TEPat<(add GPR:$acc,
2629 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2630 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2631 def : ARMV5TEPat<(add GPR:$acc,
2632 (mul (sra GPR:$a, (i32 16)),
2633 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2634 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2635 def : ARMV5TEPat<(add GPR:$acc,
2636 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2637 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2638 def : ARMV5TEPat<(add GPR:$acc,
2639 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2641 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2642 def : ARMV5TEPat<(add GPR:$acc,
2643 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2644 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2646 //===----------------------------------------------------------------------===//
2650 include "ARMInstrThumb.td"
2652 //===----------------------------------------------------------------------===//
2656 include "ARMInstrThumb2.td"
2658 //===----------------------------------------------------------------------===//
2659 // Floating Point Support
2662 include "ARMInstrVFP.td"
2664 //===----------------------------------------------------------------------===//
2665 // Advanced SIMD (NEON) Support
2668 include "ARMInstrNEON.td"
2670 //===----------------------------------------------------------------------===//
2671 // Coprocessor Instructions. For disassembly only.
2674 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2675 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2676 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2677 [/* For disassembly only; pattern left blank */]> {
2681 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2682 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2683 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2684 [/* For disassembly only; pattern left blank */]> {
2685 let Inst{31-28} = 0b1111;
2689 class ACI<dag oops, dag iops, string opc, string asm>
2690 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2691 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2692 let Inst{27-25} = 0b110;
2695 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2697 def _OFFSET : ACI<(outs),
2698 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2699 opc, "\tp$cop, cr$CRd, $addr"> {
2700 let Inst{31-28} = op31_28;
2701 let Inst{24} = 1; // P = 1
2702 let Inst{21} = 0; // W = 0
2703 let Inst{22} = 0; // D = 0
2704 let Inst{20} = load;
2707 def _PRE : ACI<(outs),
2708 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2709 opc, "\tp$cop, cr$CRd, $addr!"> {
2710 let Inst{31-28} = op31_28;
2711 let Inst{24} = 1; // P = 1
2712 let Inst{21} = 1; // W = 1
2713 let Inst{22} = 0; // D = 0
2714 let Inst{20} = load;
2717 def _POST : ACI<(outs),
2718 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2719 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2720 let Inst{31-28} = op31_28;
2721 let Inst{24} = 0; // P = 0
2722 let Inst{21} = 1; // W = 1
2723 let Inst{22} = 0; // D = 0
2724 let Inst{20} = load;
2727 def _OPTION : ACI<(outs),
2728 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2729 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2730 let Inst{31-28} = op31_28;
2731 let Inst{24} = 0; // P = 0
2732 let Inst{23} = 1; // U = 1
2733 let Inst{21} = 0; // W = 0
2734 let Inst{22} = 0; // D = 0
2735 let Inst{20} = load;
2738 def L_OFFSET : ACI<(outs),
2739 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2740 opc, "l\tp$cop, cr$CRd, $addr"> {
2741 let Inst{31-28} = op31_28;
2742 let Inst{24} = 1; // P = 1
2743 let Inst{21} = 0; // W = 0
2744 let Inst{22} = 1; // D = 1
2745 let Inst{20} = load;
2748 def L_PRE : ACI<(outs),
2749 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2750 opc, "l\tp$cop, cr$CRd, $addr!"> {
2751 let Inst{31-28} = op31_28;
2752 let Inst{24} = 1; // P = 1
2753 let Inst{21} = 1; // W = 1
2754 let Inst{22} = 1; // D = 1
2755 let Inst{20} = load;
2758 def L_POST : ACI<(outs),
2759 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2760 opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
2761 let Inst{31-28} = op31_28;
2762 let Inst{24} = 0; // P = 0
2763 let Inst{21} = 1; // W = 1
2764 let Inst{22} = 1; // D = 1
2765 let Inst{20} = load;
2768 def L_OPTION : ACI<(outs),
2769 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2770 opc, "l\tp$cop, cr$CRd, [$base], $option"> {
2771 let Inst{31-28} = op31_28;
2772 let Inst{24} = 0; // P = 0
2773 let Inst{23} = 1; // U = 1
2774 let Inst{21} = 0; // W = 0
2775 let Inst{22} = 1; // D = 1
2776 let Inst{20} = load;
2780 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2781 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2782 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2783 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2785 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2786 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2787 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2788 [/* For disassembly only; pattern left blank */]> {
2793 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2794 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2795 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2796 [/* For disassembly only; pattern left blank */]> {
2797 let Inst{31-28} = 0b1111;
2802 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2803 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2804 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2805 [/* For disassembly only; pattern left blank */]> {
2810 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2811 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2812 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2813 [/* For disassembly only; pattern left blank */]> {
2814 let Inst{31-28} = 0b1111;
2819 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2820 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2821 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2822 [/* For disassembly only; pattern left blank */]> {
2823 let Inst{23-20} = 0b0100;
2826 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2827 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2828 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2829 [/* For disassembly only; pattern left blank */]> {
2830 let Inst{31-28} = 0b1111;
2831 let Inst{23-20} = 0b0100;
2834 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2835 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2836 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2837 [/* For disassembly only; pattern left blank */]> {
2838 let Inst{23-20} = 0b0101;
2841 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2842 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2843 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2844 [/* For disassembly only; pattern left blank */]> {
2845 let Inst{31-28} = 0b1111;
2846 let Inst{23-20} = 0b0101;
2849 //===----------------------------------------------------------------------===//
2850 // Move between special register and ARM core register -- for disassembly only
2853 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2854 [/* For disassembly only; pattern left blank */]> {
2855 let Inst{23-20} = 0b0000;
2856 let Inst{7-4} = 0b0000;
2859 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2860 [/* For disassembly only; pattern left blank */]> {
2861 let Inst{23-20} = 0b0100;
2862 let Inst{7-4} = 0b0000;
2865 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
2866 "msr", "\tcpsr$mask, $src",
2867 [/* For disassembly only; pattern left blank */]> {
2868 let Inst{23-20} = 0b0010;
2869 let Inst{7-4} = 0b0000;
2872 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
2873 "msr", "\tcpsr$mask, $a",
2874 [/* For disassembly only; pattern left blank */]> {
2875 let Inst{23-20} = 0b0010;
2876 let Inst{7-4} = 0b0000;
2879 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
2880 "msr", "\tspsr$mask, $src",
2881 [/* For disassembly only; pattern left blank */]> {
2882 let Inst{23-20} = 0b0110;
2883 let Inst{7-4} = 0b0000;
2886 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
2887 "msr", "\tspsr$mask, $a",
2888 [/* For disassembly only; pattern left blank */]> {
2889 let Inst{23-20} = 0b0110;
2890 let Inst{7-4} = 0b0000;