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_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>;
64 def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
65 def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
66 def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
68 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
70 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
71 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
74 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
75 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
77 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
78 [SDNPHasChain, SDNPOutFlag]>;
79 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
80 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
82 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
85 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
88 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
89 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
92 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
93 [SDNPHasChain, SDNPOptInFlag]>;
95 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
97 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
100 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
101 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
103 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
105 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
108 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
111 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
114 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
115 [SDNPOutFlag, SDNPCommutative]>;
117 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
119 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
120 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
121 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
123 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
124 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
125 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
126 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
127 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
128 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
129 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
132 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
134 def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
136 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR,
138 def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR,
141 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
143 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
144 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
147 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
149 //===----------------------------------------------------------------------===//
150 // ARM Instruction Predicate Definitions.
152 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
153 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
154 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
155 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
156 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
157 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
158 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
159 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
160 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
161 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
162 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
163 def HasNEON : Predicate<"Subtarget->hasNEON()">;
164 def HasDivide : Predicate<"Subtarget->hasDivide()">;
165 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
166 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
167 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
168 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
169 def IsThumb : Predicate<"Subtarget->isThumb()">;
170 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
171 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
172 def IsARM : Predicate<"!Subtarget->isThumb()">;
173 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
174 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
176 // FIXME: Eventually this will be just "hasV6T2Ops".
177 def UseMovt : Predicate<"Subtarget->useMovt()">;
178 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
179 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
181 //===----------------------------------------------------------------------===//
182 // ARM Flag Definitions.
184 class RegConstraint<string C> {
185 string Constraints = C;
188 //===----------------------------------------------------------------------===//
189 // ARM specific transformation functions and pattern fragments.
192 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
193 // so_imm_neg def below.
194 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
195 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
198 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
199 // so_imm_not def below.
200 def so_imm_not_XFORM : SDNodeXForm<imm, [{
201 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
204 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
205 def imm1_15 : PatLeaf<(i32 imm), [{
206 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
209 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
210 def imm16_31 : PatLeaf<(i32 imm), [{
211 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
216 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
217 }], so_imm_neg_XFORM>;
221 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
222 }], so_imm_not_XFORM>;
224 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
225 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
226 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
229 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
231 def bf_inv_mask_imm : Operand<i32>,
233 return ARM::isBitFieldInvertedMask(N->getZExtValue());
235 string EncoderMethod = "getBitfieldInvertedMaskOpValue";
236 let PrintMethod = "printBitfieldInvMaskImmOperand";
239 /// Split a 32-bit immediate into two 16 bit parts.
240 def hi16 : SDNodeXForm<imm, [{
241 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
244 def lo16AllZero : PatLeaf<(i32 imm), [{
245 // Returns true if all low 16-bits are 0.
246 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
249 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
251 def imm0_65535 : PatLeaf<(i32 imm), [{
252 return (uint32_t)N->getZExtValue() < 65536;
255 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
256 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
258 /// adde and sube predicates - True based on whether the carry flag output
259 /// will be needed or not.
260 def adde_dead_carry :
261 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
262 [{return !N->hasAnyUseOfValue(1);}]>;
263 def sube_dead_carry :
264 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
265 [{return !N->hasAnyUseOfValue(1);}]>;
266 def adde_live_carry :
267 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
268 [{return N->hasAnyUseOfValue(1);}]>;
269 def sube_live_carry :
270 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
271 [{return N->hasAnyUseOfValue(1);}]>;
273 //===----------------------------------------------------------------------===//
274 // Operand Definitions.
278 def brtarget : Operand<OtherVT>;
280 // A list of registers separated by comma. Used by load/store multiple.
281 def reglist : Operand<i32> {
282 let PrintMethod = "printRegisterList";
285 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
286 def cpinst_operand : Operand<i32> {
287 let PrintMethod = "printCPInstOperand";
290 def jtblock_operand : Operand<i32> {
291 let PrintMethod = "printJTBlockOperand";
293 def jt2block_operand : Operand<i32> {
294 let PrintMethod = "printJT2BlockOperand";
298 def pclabel : Operand<i32> {
299 let PrintMethod = "printPCLabel";
302 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
303 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
304 int32_t v = (int32_t)N->getZExtValue();
305 return v == 8 || v == 16 || v == 24; }]> {
306 string EncoderMethod = "getRotImmOpValue";
309 // shift_imm: An integer that encodes a shift amount and the type of shift
310 // (currently either asr or lsl) using the same encoding used for the
311 // immediates in so_reg operands.
312 def shift_imm : Operand<i32> {
313 let PrintMethod = "printShiftImmOperand";
316 // shifter_operand operands: so_reg and so_imm.
317 def so_reg : Operand<i32>, // reg reg imm
318 ComplexPattern<i32, 3, "SelectShifterOperandReg",
319 [shl,srl,sra,rotr]> {
320 string EncoderMethod = "getSORegOpValue";
321 let PrintMethod = "printSORegOperand";
322 let MIOperandInfo = (ops GPR, GPR, i32imm);
325 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
326 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
327 // represented in the imm field in the same 12-bit form that they are encoded
328 // into so_imm instructions: the 8-bit immediate is the least significant bits
329 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
330 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
331 string EncoderMethod = "getSOImmOpValue";
332 let PrintMethod = "printSOImmOperand";
335 // Break so_imm's up into two pieces. This handles immediates with up to 16
336 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
337 // get the first/second pieces.
338 def so_imm2part : Operand<i32>,
340 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
342 let PrintMethod = "printSOImm2PartOperand";
345 def so_imm2part_1 : SDNodeXForm<imm, [{
346 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
347 return CurDAG->getTargetConstant(V, MVT::i32);
350 def so_imm2part_2 : SDNodeXForm<imm, [{
351 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
352 return CurDAG->getTargetConstant(V, MVT::i32);
355 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
356 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
358 let PrintMethod = "printSOImm2PartOperand";
361 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
362 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
363 return CurDAG->getTargetConstant(V, MVT::i32);
366 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
367 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
368 return CurDAG->getTargetConstant(V, MVT::i32);
371 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
372 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
373 return (int32_t)N->getZExtValue() < 32;
376 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
377 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
378 return (int32_t)N->getZExtValue() < 32;
380 string EncoderMethod = "getImmMinusOneOpValue";
383 // Define ARM specific addressing modes.
386 // addrmode_imm12 := reg +/- imm12
388 def addrmode_imm12 : Operand<i32>,
389 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
391 string EncoderMethod = "getAddrModeImm12OpValue";
392 let PrintMethod = "printAddrModeImm12Operand";
393 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
395 // ldst_so_reg := reg +/- reg shop imm
397 def ldst_so_reg : Operand<i32>,
398 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
399 // FIXME: Simplify the printer
400 let PrintMethod = "printAddrMode2Operand";
401 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
404 // addrmode2 := reg +/- imm12
405 // := reg +/- reg shop imm
407 def addrmode2 : Operand<i32>,
408 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
409 let PrintMethod = "printAddrMode2Operand";
410 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
413 def am2offset : Operand<i32>,
414 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
415 [], [SDNPWantRoot]> {
416 let PrintMethod = "printAddrMode2OffsetOperand";
417 let MIOperandInfo = (ops GPR, i32imm);
420 // addrmode3 := reg +/- reg
421 // addrmode3 := reg +/- imm8
423 def addrmode3 : Operand<i32>,
424 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
425 let PrintMethod = "printAddrMode3Operand";
426 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
429 def am3offset : Operand<i32>,
430 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
431 [], [SDNPWantRoot]> {
432 let PrintMethod = "printAddrMode3OffsetOperand";
433 let MIOperandInfo = (ops GPR, i32imm);
436 // addrmode4 := reg, <mode|W>
438 def addrmode4 : Operand<i32>,
439 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
440 let PrintMethod = "printAddrMode4Operand";
441 let MIOperandInfo = (ops GPR:$addr, i32imm);
444 // addrmode5 := reg +/- imm8*4
446 def addrmode5 : Operand<i32>,
447 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
448 let PrintMethod = "printAddrMode5Operand";
449 let MIOperandInfo = (ops GPR:$base, i32imm);
452 // addrmode6 := reg with optional writeback
454 def addrmode6 : Operand<i32>,
455 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
456 let PrintMethod = "printAddrMode6Operand";
457 let MIOperandInfo = (ops GPR:$addr, i32imm);
460 def am6offset : Operand<i32> {
461 let PrintMethod = "printAddrMode6OffsetOperand";
462 let MIOperandInfo = (ops GPR);
465 // addrmodepc := pc + reg
467 def addrmodepc : Operand<i32>,
468 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
469 let PrintMethod = "printAddrModePCOperand";
470 let MIOperandInfo = (ops GPR, i32imm);
473 def nohash_imm : Operand<i32> {
474 let PrintMethod = "printNoHashImmediate";
477 //===----------------------------------------------------------------------===//
479 include "ARMInstrFormats.td"
481 //===----------------------------------------------------------------------===//
482 // Multiclass helpers...
485 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
486 /// binop that produces a value.
487 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
488 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
489 PatFrag opnode, bit Commutable = 0> {
490 // The register-immediate version is re-materializable. This is useful
491 // in particular for taking the address of a local.
492 let isReMaterializable = 1 in {
493 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
494 iii, opc, "\t$Rd, $Rn, $imm",
495 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
500 let Inst{15-12} = Rd;
501 let Inst{19-16} = Rn;
502 let Inst{11-0} = imm;
505 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
506 iir, opc, "\t$Rd, $Rn, $Rm",
507 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
511 let Inst{11-4} = 0b00000000;
513 let isCommutable = Commutable;
515 let Inst{15-12} = Rd;
516 let Inst{19-16} = Rn;
518 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
519 iis, opc, "\t$Rd, $Rn, $shift",
520 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
525 let Inst{11-0} = shift;
526 let Inst{15-12} = Rd;
527 let Inst{19-16} = Rn;
531 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
532 /// instruction modifies the CPSR register.
533 let Defs = [CPSR] in {
534 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
535 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
536 PatFrag opnode, bit Commutable = 0> {
537 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
538 iii, opc, "\t$Rd, $Rn, $imm",
539 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
544 let Inst{15-12} = Rd;
545 let Inst{19-16} = Rn;
546 let Inst{11-0} = imm;
549 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
550 iir, opc, "\t$Rd, $Rn, $Rm",
551 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
555 let Inst{11-4} = 0b00000000;
557 let isCommutable = Commutable;
559 let Inst{15-12} = Rd;
560 let Inst{19-16} = Rn;
563 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
564 iis, opc, "\t$Rd, $Rn, $shift",
565 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
570 let Inst{11-0} = shift;
571 let Inst{15-12} = Rd;
572 let Inst{19-16} = Rn;
578 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
579 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
580 /// a explicit result, only implicitly set CPSR.
581 let isCompare = 1, Defs = [CPSR] in {
582 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
583 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
584 PatFrag opnode, bit Commutable = 0> {
585 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
587 [(opnode GPR:$Rn, so_imm:$imm)]> {
591 let Inst{15-12} = 0b0000;
592 let Inst{19-16} = Rn;
593 let Inst{11-0} = imm;
597 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
599 [(opnode GPR:$Rn, GPR:$Rm)]> {
602 let Inst{11-4} = 0b00000000;
604 let isCommutable = Commutable;
606 let Inst{15-12} = 0b0000;
607 let Inst{19-16} = Rn;
610 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
611 opc, "\t$Rn, $shift",
612 [(opnode GPR:$Rn, so_reg:$shift)]> {
616 let Inst{11-0} = shift;
617 let Inst{15-12} = 0b0000;
618 let Inst{19-16} = Rn;
624 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
625 /// register and one whose operand is a register rotated by 8/16/24.
626 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
627 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
628 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
629 IIC_iEXTr, opc, "\t$Rd, $Rm",
630 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
631 Requires<[IsARM, HasV6]> {
634 let Inst{15-12} = Rd;
636 let Inst{11-10} = 0b00;
637 let Inst{19-16} = 0b1111;
639 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
640 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
641 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
642 Requires<[IsARM, HasV6]> {
646 let Inst{15-12} = Rd;
647 let Inst{11-10} = rot;
649 let Inst{19-16} = 0b1111;
653 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
654 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
655 IIC_iEXTr, opc, "\t$Rd, $Rm",
656 [/* For disassembly only; pattern left blank */]>,
657 Requires<[IsARM, HasV6]> {
658 let Inst{11-10} = 0b00;
659 let Inst{19-16} = 0b1111;
661 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
662 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
663 [/* For disassembly only; pattern left blank */]>,
664 Requires<[IsARM, HasV6]> {
666 let Inst{11-10} = rot;
667 let Inst{19-16} = 0b1111;
671 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
672 /// register and one whose operand is a register rotated by 8/16/24.
673 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
674 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
675 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
676 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
677 Requires<[IsARM, HasV6]> {
678 let Inst{11-10} = 0b00;
680 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
682 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
683 [(set GPR:$Rd, (opnode GPR:$Rn,
684 (rotr GPR:$Rm, rot_imm:$rot)))]>,
685 Requires<[IsARM, HasV6]> {
688 let Inst{19-16} = Rn;
689 let Inst{11-10} = rot;
693 // For disassembly only.
694 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
695 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
696 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
697 [/* For disassembly only; pattern left blank */]>,
698 Requires<[IsARM, HasV6]> {
699 let Inst{11-10} = 0b00;
701 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
703 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
704 [/* For disassembly only; pattern left blank */]>,
705 Requires<[IsARM, HasV6]> {
708 let Inst{19-16} = Rn;
709 let Inst{11-10} = rot;
713 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
714 let Uses = [CPSR] in {
715 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
716 bit Commutable = 0> {
717 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
718 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
719 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
725 let Inst{15-12} = Rd;
726 let Inst{19-16} = Rn;
727 let Inst{11-0} = imm;
729 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
730 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
731 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
736 let Inst{11-4} = 0b00000000;
738 let isCommutable = Commutable;
740 let Inst{15-12} = Rd;
741 let Inst{19-16} = Rn;
743 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
744 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
745 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
751 let Inst{11-0} = shift;
752 let Inst{15-12} = Rd;
753 let Inst{19-16} = Rn;
756 // Carry setting variants
757 let Defs = [CPSR] in {
758 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
759 bit Commutable = 0> {
760 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
761 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
762 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
767 let Inst{15-12} = Rd;
768 let Inst{19-16} = Rn;
769 let Inst{11-0} = imm;
773 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
774 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
775 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
780 let Inst{11-4} = 0b00000000;
781 let isCommutable = Commutable;
783 let Inst{15-12} = Rd;
784 let Inst{19-16} = Rn;
788 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
789 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
790 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
795 let Inst{11-0} = shift;
796 let Inst{15-12} = Rd;
797 let Inst{19-16} = Rn;
805 let canFoldAsLoad = 1, isReMaterializable = 1 in {
806 multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
807 InstrItinClass iir, PatFrag opnode> {
808 // Note: We use the complex addrmode_imm12 rather than just an input
809 // GPR and a constrained immediate so that we can use this to match
810 // frame index references and avoid matching constant pool references.
811 def i12 : AIldr1<0b010, opc22, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
812 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
813 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
816 let Inst{23} = addr{12}; // U (add = ('U' == 1))
817 let Inst{19-16} = addr{16-13}; // Rn
818 let Inst{15-12} = Rt;
819 let Inst{11-0} = addr{11-0}; // imm12
821 def rs : AIldr1<0b011, opc22, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
822 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
823 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
826 let Inst{23} = shift{12}; // U (add = ('U' == 1))
827 let Inst{19-16} = shift{16-13}; // Rn
828 let Inst{11-0} = shift{11-0};
833 //===----------------------------------------------------------------------===//
835 //===----------------------------------------------------------------------===//
837 //===----------------------------------------------------------------------===//
838 // Miscellaneous Instructions.
841 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
842 /// the function. The first operand is the ID# for this instruction, the second
843 /// is the index into the MachineConstantPool that this is, the third is the
844 /// size in bytes of this constant pool entry.
845 let neverHasSideEffects = 1, isNotDuplicable = 1 in
846 def CONSTPOOL_ENTRY :
847 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
848 i32imm:$size), NoItinerary, "", []>;
850 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
851 // from removing one half of the matched pairs. That breaks PEI, which assumes
852 // these will always be in pairs, and asserts if it finds otherwise. Better way?
853 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
855 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
856 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
858 def ADJCALLSTACKDOWN :
859 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
860 [(ARMcallseq_start timm:$amt)]>;
863 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
864 [/* For disassembly only; pattern left blank */]>,
865 Requires<[IsARM, HasV6T2]> {
866 let Inst{27-16} = 0b001100100000;
867 let Inst{15-8} = 0b11110000;
868 let Inst{7-0} = 0b00000000;
871 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
872 [/* For disassembly only; pattern left blank */]>,
873 Requires<[IsARM, HasV6T2]> {
874 let Inst{27-16} = 0b001100100000;
875 let Inst{15-8} = 0b11110000;
876 let Inst{7-0} = 0b00000001;
879 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
880 [/* For disassembly only; pattern left blank */]>,
881 Requires<[IsARM, HasV6T2]> {
882 let Inst{27-16} = 0b001100100000;
883 let Inst{15-8} = 0b11110000;
884 let Inst{7-0} = 0b00000010;
887 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
888 [/* For disassembly only; pattern left blank */]>,
889 Requires<[IsARM, HasV6T2]> {
890 let Inst{27-16} = 0b001100100000;
891 let Inst{15-8} = 0b11110000;
892 let Inst{7-0} = 0b00000011;
895 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
897 [/* For disassembly only; pattern left blank */]>,
898 Requires<[IsARM, HasV6]> {
903 let Inst{15-12} = Rd;
904 let Inst{19-16} = Rn;
905 let Inst{27-20} = 0b01101000;
906 let Inst{7-4} = 0b1011;
907 let Inst{11-8} = 0b1111;
910 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
911 [/* For disassembly only; pattern left blank */]>,
912 Requires<[IsARM, HasV6T2]> {
913 let Inst{27-16} = 0b001100100000;
914 let Inst{15-8} = 0b11110000;
915 let Inst{7-0} = 0b00000100;
918 // The i32imm operand $val can be used by a debugger to store more information
919 // about the breakpoint.
920 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
921 [/* For disassembly only; pattern left blank */]>,
924 let Inst{3-0} = val{3-0};
925 let Inst{19-8} = val{15-4};
926 let Inst{27-20} = 0b00010010;
927 let Inst{7-4} = 0b0111;
930 // Change Processor State is a system instruction -- for disassembly only.
931 // The singleton $opt operand contains the following information:
932 // opt{4-0} = mode from Inst{4-0}
933 // opt{5} = changemode from Inst{17}
934 // opt{8-6} = AIF from Inst{8-6}
935 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
936 // FIXME: Integrated assembler will need these split out.
937 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
938 [/* For disassembly only; pattern left blank */]>,
940 let Inst{31-28} = 0b1111;
941 let Inst{27-20} = 0b00010000;
946 // Preload signals the memory system of possible future data/instruction access.
947 // These are for disassembly only.
949 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
950 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
951 multiclass APreLoad<bit data, bit read, string opc> {
953 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
954 !strconcat(opc, "\t[$base, $imm]"), []> {
955 let Inst{31-26} = 0b111101;
956 let Inst{25} = 0; // 0 for immediate form
959 let Inst{21-20} = 0b01;
962 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
963 !strconcat(opc, "\t$addr"), []> {
964 let Inst{31-26} = 0b111101;
965 let Inst{25} = 1; // 1 for register form
968 let Inst{21-20} = 0b01;
973 defm PLD : APreLoad<1, 1, "pld">;
974 defm PLDW : APreLoad<1, 0, "pldw">;
975 defm PLI : APreLoad<0, 1, "pli">;
977 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
979 [/* For disassembly only; pattern left blank */]>,
982 let Inst{31-10} = 0b1111000100000001000000;
987 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
988 [/* For disassembly only; pattern left blank */]>,
989 Requires<[IsARM, HasV7]> {
991 let Inst{27-4} = 0b001100100000111100001111;
995 // A5.4 Permanently UNDEFINED instructions.
996 let isBarrier = 1, isTerminator = 1 in
997 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1000 let Inst{27-25} = 0b011;
1001 let Inst{24-20} = 0b11111;
1002 let Inst{7-5} = 0b111;
1006 // Address computation and loads and stores in PIC mode.
1007 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1008 // classes (AXI1, et.al.) and so have encoding information and such,
1009 // which is suboptimal. Once the rest of the code emitter (including
1010 // JIT) is MC-ized we should look at refactoring these into true
1012 let isNotDuplicable = 1 in {
1013 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1014 Pseudo, IIC_iALUr, "",
1015 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1017 let AddedComplexity = 10 in {
1018 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1019 Pseudo, IIC_iLoad_r, "",
1020 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1022 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1023 Pseudo, IIC_iLoad_bh_r, "",
1024 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1026 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1027 Pseudo, IIC_iLoad_bh_r, "",
1028 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1030 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1031 Pseudo, IIC_iLoad_bh_r, "",
1032 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1034 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1035 Pseudo, IIC_iLoad_bh_r, "",
1036 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1038 let AddedComplexity = 10 in {
1039 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1040 Pseudo, IIC_iStore_r, "",
1041 [(store GPR:$src, addrmodepc:$addr)]>;
1043 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1044 Pseudo, IIC_iStore_bh_r, "",
1045 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1047 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1048 Pseudo, IIC_iStore_bh_r, "",
1049 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1051 } // isNotDuplicable = 1
1054 // LEApcrel - Load a pc-relative address into a register without offending the
1056 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1057 // the ADR instruction. Is this the right way to handle that? They need
1058 // encoding information regardless.
1059 let neverHasSideEffects = 1 in {
1060 let isReMaterializable = 1 in
1061 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1063 "adr$p\t$dst, #$label", []>;
1065 } // neverHasSideEffects
1066 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1067 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1069 "adr$p\t$dst, #${label}_${id}", []> {
1073 //===----------------------------------------------------------------------===//
1074 // Control Flow Instructions.
1077 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1079 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1080 "bx", "\tlr", [(ARMretflag)]>,
1081 Requires<[IsARM, HasV4T]> {
1082 let Inst{27-0} = 0b0001001011111111111100011110;
1086 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1087 "mov", "\tpc, lr", [(ARMretflag)]>,
1088 Requires<[IsARM, NoV4T]> {
1089 let Inst{27-0} = 0b0001101000001111000000001110;
1093 // Indirect branches
1094 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1096 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1097 [(brind GPR:$dst)]>,
1098 Requires<[IsARM, HasV4T]> {
1100 let Inst{31-4} = 0b1110000100101111111111110001;
1101 let Inst{3-0} = dst;
1105 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1106 [(brind GPR:$dst)]>,
1107 Requires<[IsARM, NoV4T]> {
1109 let Inst{31-4} = 0b1110000110100000111100000000;
1110 let Inst{3-0} = dst;
1114 // FIXME: remove when we have a way to marking a MI with these properties.
1115 // FIXME: Should pc be an implicit operand like PICADD, etc?
1116 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1117 hasExtraDefRegAllocReq = 1 in
1118 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1119 reglist:$dsts, variable_ops),
1120 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1121 "ldm${addr:submode}${p}\t$addr!, $dsts",
1122 "$addr.addr = $wb", []>;
1124 // On non-Darwin platforms R9 is callee-saved.
1126 Defs = [R0, R1, R2, R3, R12, LR,
1127 D0, D1, D2, D3, D4, D5, D6, D7,
1128 D16, D17, D18, D19, D20, D21, D22, D23,
1129 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1130 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1131 IIC_Br, "bl\t$func",
1132 [(ARMcall tglobaladdr:$func)]>,
1133 Requires<[IsARM, IsNotDarwin]> {
1134 let Inst{31-28} = 0b1110;
1135 // FIXME: Encoding info for $func. Needs fixups bits.
1138 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1139 IIC_Br, "bl", "\t$func",
1140 [(ARMcall_pred tglobaladdr:$func)]>,
1141 Requires<[IsARM, IsNotDarwin]>;
1144 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1145 IIC_Br, "blx\t$func",
1146 [(ARMcall GPR:$func)]>,
1147 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1149 let Inst{27-4} = 0b000100101111111111110011;
1150 let Inst{3-0} = func;
1154 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1155 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1156 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1157 [(ARMcall_nolink tGPR:$func)]>,
1158 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1160 let Inst{27-4} = 0b000100101111111111110001;
1161 let Inst{3-0} = func;
1165 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1166 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1167 [(ARMcall_nolink tGPR:$func)]>,
1168 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1170 let Inst{27-4} = 0b000110100000111100000000;
1171 let Inst{3-0} = func;
1175 // On Darwin R9 is call-clobbered.
1177 Defs = [R0, R1, R2, R3, R9, R12, LR,
1178 D0, D1, D2, D3, D4, D5, D6, D7,
1179 D16, D17, D18, D19, D20, D21, D22, D23,
1180 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1181 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1182 IIC_Br, "bl\t$func",
1183 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1184 let Inst{31-28} = 0b1110;
1185 // FIXME: Encoding info for $func. Needs fixups bits.
1188 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1189 IIC_Br, "bl", "\t$func",
1190 [(ARMcall_pred tglobaladdr:$func)]>,
1191 Requires<[IsARM, IsDarwin]>;
1194 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1195 IIC_Br, "blx\t$func",
1196 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1198 let Inst{27-4} = 0b000100101111111111110011;
1199 let Inst{3-0} = func;
1203 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1204 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1205 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1206 [(ARMcall_nolink tGPR:$func)]>,
1207 Requires<[IsARM, HasV4T, IsDarwin]> {
1209 let Inst{27-4} = 0b000100101111111111110001;
1210 let Inst{3-0} = func;
1214 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1215 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1216 [(ARMcall_nolink tGPR:$func)]>,
1217 Requires<[IsARM, NoV4T, IsDarwin]> {
1219 let Inst{27-4} = 0b000110100000111100000000;
1220 let Inst{3-0} = func;
1226 // FIXME: These should probably be xformed into the non-TC versions of the
1227 // instructions as part of MC lowering.
1228 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1230 let Defs = [R0, R1, R2, R3, R9, R12,
1231 D0, D1, D2, D3, D4, D5, D6, D7,
1232 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1233 D27, D28, D29, D30, D31, PC],
1235 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1237 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1239 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1241 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1243 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1244 IIC_Br, "b\t$dst @ TAILCALL",
1245 []>, Requires<[IsDarwin]>;
1247 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1248 IIC_Br, "b.w\t$dst @ TAILCALL",
1249 []>, Requires<[IsDarwin]>;
1251 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1252 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1253 []>, Requires<[IsDarwin]> {
1255 let Inst{31-4} = 0b1110000100101111111111110001;
1256 let Inst{3-0} = dst;
1260 // Non-Darwin versions (the difference is R9).
1261 let Defs = [R0, R1, R2, R3, R12,
1262 D0, D1, D2, D3, D4, D5, D6, D7,
1263 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1264 D27, D28, D29, D30, D31, PC],
1266 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1268 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1270 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1272 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1274 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1275 IIC_Br, "b\t$dst @ TAILCALL",
1276 []>, Requires<[IsARM, IsNotDarwin]>;
1278 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1279 IIC_Br, "b.w\t$dst @ TAILCALL",
1280 []>, Requires<[IsThumb, IsNotDarwin]>;
1282 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1283 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1284 []>, Requires<[IsNotDarwin]> {
1286 let Inst{31-4} = 0b1110000100101111111111110001;
1287 let Inst{3-0} = dst;
1292 let isBranch = 1, isTerminator = 1 in {
1293 // B is "predicable" since it can be xformed into a Bcc.
1294 let isBarrier = 1 in {
1295 let isPredicable = 1 in
1296 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1297 "b\t$target", [(br bb:$target)]>;
1299 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1300 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1301 IIC_Br, "mov\tpc, $target$jt",
1302 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1303 let Inst{11-4} = 0b00000000;
1304 let Inst{15-12} = 0b1111;
1305 let Inst{20} = 0; // S Bit
1306 let Inst{24-21} = 0b1101;
1307 let Inst{27-25} = 0b000;
1309 def BR_JTm : JTI<(outs),
1310 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1311 IIC_Br, "ldr\tpc, $target$jt",
1312 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1314 let Inst{15-12} = 0b1111;
1315 let Inst{20} = 1; // L bit
1316 let Inst{21} = 0; // W bit
1317 let Inst{22} = 0; // B bit
1318 let Inst{24} = 1; // P bit
1319 let Inst{27-25} = 0b011;
1321 def BR_JTadd : JTI<(outs),
1322 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1323 IIC_Br, "add\tpc, $target, $idx$jt",
1324 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1326 let Inst{15-12} = 0b1111;
1327 let Inst{20} = 0; // S bit
1328 let Inst{24-21} = 0b0100;
1329 let Inst{27-25} = 0b000;
1331 } // isNotDuplicable = 1, isIndirectBranch = 1
1334 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1335 // a two-value operand where a dag node expects two operands. :(
1336 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1337 IIC_Br, "b", "\t$target",
1338 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1341 // Branch and Exchange Jazelle -- for disassembly only
1342 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1343 [/* For disassembly only; pattern left blank */]> {
1344 let Inst{23-20} = 0b0010;
1345 //let Inst{19-8} = 0xfff;
1346 let Inst{7-4} = 0b0010;
1349 // Secure Monitor Call is a system instruction -- for disassembly only
1350 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1351 [/* For disassembly only; pattern left blank */]> {
1353 let Inst{23-4} = 0b01100000000000000111;
1354 let Inst{3-0} = opt;
1357 // Supervisor Call (Software Interrupt) -- for disassembly only
1359 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1360 [/* For disassembly only; pattern left blank */]> {
1362 let Inst{23-0} = svc;
1366 // Store Return State is a system instruction -- for disassembly only
1367 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1368 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1369 [/* For disassembly only; pattern left blank */]> {
1370 let Inst{31-28} = 0b1111;
1371 let Inst{22-20} = 0b110; // W = 1
1374 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1375 NoItinerary, "srs${addr:submode}\tsp, $mode",
1376 [/* For disassembly only; pattern left blank */]> {
1377 let Inst{31-28} = 0b1111;
1378 let Inst{22-20} = 0b100; // W = 0
1381 // Return From Exception is a system instruction -- for disassembly only
1382 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1383 NoItinerary, "rfe${addr:submode}\t$base!",
1384 [/* For disassembly only; pattern left blank */]> {
1385 let Inst{31-28} = 0b1111;
1386 let Inst{22-20} = 0b011; // W = 1
1389 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1390 NoItinerary, "rfe${addr:submode}\t$base",
1391 [/* For disassembly only; pattern left blank */]> {
1392 let Inst{31-28} = 0b1111;
1393 let Inst{22-20} = 0b001; // W = 0
1396 //===----------------------------------------------------------------------===//
1397 // Load / store Instructions.
1403 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_i, IIC_iLoad_r,
1404 UnOpFrag<(load node:$Src)>>;
1406 // Special LDR for loads from non-pc-relative constpools.
1407 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1408 isReMaterializable = 1 in
1409 def LDRcp : AIldr1<0b010, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1410 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> {
1413 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1414 let Inst{19-16} = 0b1111;
1415 let Inst{15-12} = Rt;
1416 let Inst{11-0} = addr{11-0}; // imm12
1419 // Loads with zero extension
1420 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1421 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1422 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1424 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1425 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr",
1426 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1428 // Loads with sign extension
1429 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1430 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1431 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1433 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1434 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1435 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1437 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1439 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1440 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1441 []>, Requires<[IsARM, HasV5TE]>;
1444 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1445 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1446 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1448 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1449 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1450 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1452 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1453 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1454 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1456 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1457 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1458 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1460 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1461 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1462 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1464 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1465 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1466 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1468 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1469 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1470 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1472 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1473 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1474 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1476 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1477 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1478 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1480 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1481 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1482 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1484 // For disassembly only
1485 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1486 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1487 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1488 Requires<[IsARM, HasV5TE]>;
1490 // For disassembly only
1491 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1492 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1493 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1494 Requires<[IsARM, HasV5TE]>;
1496 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1498 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1500 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1501 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1502 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1503 let Inst{21} = 1; // overwrite
1506 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1507 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1508 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1509 let Inst{21} = 1; // overwrite
1512 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1513 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1514 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1515 let Inst{21} = 1; // overwrite
1518 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1519 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1520 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1521 let Inst{21} = 1; // overwrite
1524 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1525 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1526 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1527 let Inst{21} = 1; // overwrite
1531 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1532 "str", "\t$src, $addr",
1533 [(store GPR:$src, addrmode2:$addr)]>;
1535 // Stores with truncate
1536 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1537 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1538 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1540 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1541 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1542 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1545 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1546 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1547 StMiscFrm, IIC_iStore_d_r,
1548 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1551 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1552 (ins GPR:$src, GPR:$base, am2offset:$offset),
1553 StFrm, IIC_iStore_ru,
1554 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1556 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1558 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1559 (ins GPR:$src, GPR:$base,am2offset:$offset),
1560 StFrm, IIC_iStore_ru,
1561 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1563 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1565 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1566 (ins GPR:$src, GPR:$base,am3offset:$offset),
1567 StMiscFrm, IIC_iStore_ru,
1568 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1570 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1572 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1573 (ins GPR:$src, GPR:$base,am3offset:$offset),
1574 StMiscFrm, IIC_iStore_bh_ru,
1575 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1576 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1577 GPR:$base, am3offset:$offset))]>;
1579 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1580 (ins GPR:$src, GPR:$base,am2offset:$offset),
1581 StFrm, IIC_iStore_bh_ru,
1582 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1583 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1584 GPR:$base, am2offset:$offset))]>;
1586 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1587 (ins GPR:$src, GPR:$base,am2offset:$offset),
1588 StFrm, IIC_iStore_bh_ru,
1589 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1590 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1591 GPR:$base, am2offset:$offset))]>;
1593 // For disassembly only
1594 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1595 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1596 StMiscFrm, IIC_iStore_d_ru,
1597 "strd", "\t$src1, $src2, [$base, $offset]!",
1598 "$base = $base_wb", []>;
1600 // For disassembly only
1601 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1602 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1603 StMiscFrm, IIC_iStore_d_ru,
1604 "strd", "\t$src1, $src2, [$base], $offset",
1605 "$base = $base_wb", []>;
1607 // STRT, STRBT, and STRHT are for disassembly only.
1609 def STRT : AI2stwpo<(outs GPR:$base_wb),
1610 (ins GPR:$src, GPR:$base,am2offset:$offset),
1611 StFrm, IIC_iStore_ru,
1612 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1613 [/* For disassembly only; pattern left blank */]> {
1614 let Inst{21} = 1; // overwrite
1617 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1618 (ins GPR:$src, GPR:$base,am2offset:$offset),
1619 StFrm, IIC_iStore_bh_ru,
1620 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1621 [/* For disassembly only; pattern left blank */]> {
1622 let Inst{21} = 1; // overwrite
1625 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1626 (ins GPR:$src, GPR:$base,am3offset:$offset),
1627 StMiscFrm, IIC_iStore_bh_ru,
1628 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1629 [/* For disassembly only; pattern left blank */]> {
1630 let Inst{21} = 1; // overwrite
1633 //===----------------------------------------------------------------------===//
1634 // Load / store multiple Instructions.
1637 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1638 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1639 reglist:$dsts, variable_ops),
1640 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1641 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1643 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1644 reglist:$dsts, variable_ops),
1645 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1646 "ldm${addr:submode}${p}\t$addr!, $dsts",
1647 "$addr.addr = $wb", []>;
1648 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1650 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1651 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1652 reglist:$srcs, variable_ops),
1653 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1654 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1656 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1657 reglist:$srcs, variable_ops),
1658 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1659 "stm${addr:submode}${p}\t$addr!, $srcs",
1660 "$addr.addr = $wb", []>;
1661 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1663 //===----------------------------------------------------------------------===//
1664 // Move Instructions.
1667 let neverHasSideEffects = 1 in
1668 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1669 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1673 let Inst{11-4} = 0b00000000;
1676 let Inst{15-12} = Rd;
1679 // A version for the smaller set of tail call registers.
1680 let neverHasSideEffects = 1 in
1681 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1682 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1686 let Inst{11-4} = 0b00000000;
1689 let Inst{15-12} = Rd;
1692 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins so_reg:$src),
1693 DPSoRegFrm, IIC_iMOVsr,
1694 "mov", "\t$Rd, $src", [(set GPR:$Rd, so_reg:$src)]>, UnaryDP {
1697 let Inst{15-12} = Rd;
1698 let Inst{11-0} = src;
1702 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1703 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1704 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1708 let Inst{15-12} = Rd;
1709 let Inst{19-16} = 0b0000;
1710 let Inst{11-0} = imm;
1713 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1714 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1716 "movw", "\t$Rd, $imm",
1717 [(set GPR:$Rd, imm0_65535:$imm)]>,
1718 Requires<[IsARM, HasV6T2]>, UnaryDP {
1721 let Inst{15-12} = Rd;
1722 let Inst{11-0} = imm{11-0};
1723 let Inst{19-16} = imm{15-12};
1728 let Constraints = "$src = $Rd" in
1729 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1731 "movt", "\t$Rd, $imm",
1733 (or (and GPR:$src, 0xffff),
1734 lo16AllZero:$imm))]>, UnaryDP,
1735 Requires<[IsARM, HasV6T2]> {
1738 let Inst{15-12} = Rd;
1739 let Inst{11-0} = imm{11-0};
1740 let Inst{19-16} = imm{15-12};
1745 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1746 Requires<[IsARM, HasV6T2]>;
1748 let Uses = [CPSR] in
1749 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1750 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1753 // These aren't really mov instructions, but we have to define them this way
1754 // due to flag operands.
1756 let Defs = [CPSR] in {
1757 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1758 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1760 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1761 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1765 //===----------------------------------------------------------------------===//
1766 // Extend Instructions.
1771 defm SXTB : AI_ext_rrot<0b01101010,
1772 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1773 defm SXTH : AI_ext_rrot<0b01101011,
1774 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1776 defm SXTAB : AI_exta_rrot<0b01101010,
1777 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1778 defm SXTAH : AI_exta_rrot<0b01101011,
1779 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1781 // For disassembly only
1782 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1784 // For disassembly only
1785 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1789 let AddedComplexity = 16 in {
1790 defm UXTB : AI_ext_rrot<0b01101110,
1791 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1792 defm UXTH : AI_ext_rrot<0b01101111,
1793 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1794 defm UXTB16 : AI_ext_rrot<0b01101100,
1795 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1797 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1798 // The transformation should probably be done as a combiner action
1799 // instead so we can include a check for masking back in the upper
1800 // eight bits of the source into the lower eight bits of the result.
1801 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1802 // (UXTB16r_rot GPR:$Src, 24)>;
1803 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1804 (UXTB16r_rot GPR:$Src, 8)>;
1806 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1807 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1808 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1809 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1812 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1813 // For disassembly only
1814 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1817 def SBFX : I<(outs GPR:$Rd),
1818 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1819 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1820 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1821 Requires<[IsARM, HasV6T2]> {
1826 let Inst{27-21} = 0b0111101;
1827 let Inst{6-4} = 0b101;
1828 let Inst{20-16} = width;
1829 let Inst{15-12} = Rd;
1830 let Inst{11-7} = lsb;
1834 def UBFX : I<(outs GPR:$Rd),
1835 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1836 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1837 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1838 Requires<[IsARM, HasV6T2]> {
1843 let Inst{27-21} = 0b0111111;
1844 let Inst{6-4} = 0b101;
1845 let Inst{20-16} = width;
1846 let Inst{15-12} = Rd;
1847 let Inst{11-7} = lsb;
1851 //===----------------------------------------------------------------------===//
1852 // Arithmetic Instructions.
1855 defm ADD : AsI1_bin_irs<0b0100, "add",
1856 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1857 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1858 defm SUB : AsI1_bin_irs<0b0010, "sub",
1859 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1860 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1862 // ADD and SUB with 's' bit set.
1863 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1864 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1865 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1866 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1867 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1868 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1870 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1871 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1872 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1873 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1874 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1875 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1876 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1877 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1879 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1880 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
1881 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
1886 let Inst{15-12} = Rd;
1887 let Inst{19-16} = Rn;
1888 let Inst{11-0} = imm;
1891 // The reg/reg form is only defined for the disassembler; for codegen it is
1892 // equivalent to SUBrr.
1893 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1894 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
1895 [/* For disassembly only; pattern left blank */]> {
1899 let Inst{11-4} = 0b00000000;
1902 let Inst{15-12} = Rd;
1903 let Inst{19-16} = Rn;
1906 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1907 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
1908 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
1913 let Inst{11-0} = shift;
1914 let Inst{15-12} = Rd;
1915 let Inst{19-16} = Rn;
1918 // RSB with 's' bit set.
1919 let Defs = [CPSR] in {
1920 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1921 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
1922 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
1928 let Inst{15-12} = Rd;
1929 let Inst{19-16} = Rn;
1930 let Inst{11-0} = imm;
1932 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1933 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
1934 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
1940 let Inst{11-0} = shift;
1941 let Inst{15-12} = Rd;
1942 let Inst{19-16} = Rn;
1946 let Uses = [CPSR] in {
1947 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1948 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
1949 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
1955 let Inst{15-12} = Rd;
1956 let Inst{19-16} = Rn;
1957 let Inst{11-0} = imm;
1959 // The reg/reg form is only defined for the disassembler; for codegen it is
1960 // equivalent to SUBrr.
1961 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1962 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
1963 [/* For disassembly only; pattern left blank */]> {
1967 let Inst{11-4} = 0b00000000;
1970 let Inst{15-12} = Rd;
1971 let Inst{19-16} = Rn;
1973 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1974 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
1975 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
1981 let Inst{11-0} = shift;
1982 let Inst{15-12} = Rd;
1983 let Inst{19-16} = Rn;
1987 // FIXME: Allow these to be predicated.
1988 let Defs = [CPSR], Uses = [CPSR] in {
1989 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1990 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
1991 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
1998 let Inst{15-12} = Rd;
1999 let Inst{19-16} = Rn;
2000 let Inst{11-0} = imm;
2002 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2003 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2004 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2011 let Inst{11-0} = shift;
2012 let Inst{15-12} = Rd;
2013 let Inst{19-16} = Rn;
2017 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2018 // The assume-no-carry-in form uses the negation of the input since add/sub
2019 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2020 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2022 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2023 (SUBri GPR:$src, so_imm_neg:$imm)>;
2024 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2025 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2026 // The with-carry-in form matches bitwise not instead of the negation.
2027 // Effectively, the inverse interpretation of the carry flag already accounts
2028 // for part of the negation.
2029 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2030 (SBCri GPR:$src, so_imm_not:$imm)>;
2032 // Note: These are implemented in C++ code, because they have to generate
2033 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2035 // (mul X, 2^n+1) -> (add (X << n), X)
2036 // (mul X, 2^n-1) -> (rsb X, (X << n))
2038 // ARM Arithmetic Instruction -- for disassembly only
2039 // GPR:$dst = GPR:$a op GPR:$b
2040 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2041 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2042 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2043 opc, "\t$Rd, $Rn, $Rm", pattern> {
2047 let Inst{27-20} = op27_20;
2048 let Inst{11-4} = op11_4;
2049 let Inst{19-16} = Rn;
2050 let Inst{15-12} = Rd;
2054 // Saturating add/subtract -- for disassembly only
2056 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2057 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2058 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2059 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2060 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2061 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2063 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2064 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2065 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2066 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2067 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2068 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2069 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2070 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2071 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2072 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2073 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2074 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2076 // Signed/Unsigned add/subtract -- for disassembly only
2078 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2079 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2080 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2081 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2082 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2083 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2084 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2085 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2086 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2087 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2088 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2089 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2091 // Signed/Unsigned halving add/subtract -- for disassembly only
2093 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2094 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2095 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2096 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2097 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2098 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2099 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2100 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2101 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2102 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2103 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2104 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2106 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2108 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2109 MulFrm /* for convenience */, NoItinerary, "usad8",
2110 "\t$Rd, $Rn, $Rm", []>,
2111 Requires<[IsARM, HasV6]> {
2115 let Inst{27-20} = 0b01111000;
2116 let Inst{15-12} = 0b1111;
2117 let Inst{7-4} = 0b0001;
2118 let Inst{19-16} = Rd;
2119 let Inst{11-8} = Rm;
2122 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2123 MulFrm /* for convenience */, NoItinerary, "usada8",
2124 "\t$Rd, $Rn, $Rm, $Ra", []>,
2125 Requires<[IsARM, HasV6]> {
2130 let Inst{27-20} = 0b01111000;
2131 let Inst{7-4} = 0b0001;
2132 let Inst{19-16} = Rd;
2133 let Inst{15-12} = Ra;
2134 let Inst{11-8} = Rm;
2138 // Signed/Unsigned saturate -- for disassembly only
2140 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2141 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2142 [/* For disassembly only; pattern left blank */]> {
2147 let Inst{27-21} = 0b0110101;
2148 let Inst{5-4} = 0b01;
2149 let Inst{20-16} = sat_imm;
2150 let Inst{15-12} = Rd;
2151 let Inst{11-7} = sh{7-3};
2152 let Inst{6} = sh{0};
2156 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2157 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2158 [/* For disassembly only; pattern left blank */]> {
2162 let Inst{27-20} = 0b01101010;
2163 let Inst{11-4} = 0b11110011;
2164 let Inst{15-12} = Rd;
2165 let Inst{19-16} = sat_imm;
2169 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2170 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2171 [/* For disassembly only; pattern left blank */]> {
2176 let Inst{27-21} = 0b0110111;
2177 let Inst{5-4} = 0b01;
2178 let Inst{15-12} = Rd;
2179 let Inst{11-7} = sh{7-3};
2180 let Inst{6} = sh{0};
2181 let Inst{20-16} = sat_imm;
2185 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2186 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2187 [/* For disassembly only; pattern left blank */]> {
2191 let Inst{27-20} = 0b01101110;
2192 let Inst{11-4} = 0b11110011;
2193 let Inst{15-12} = Rd;
2194 let Inst{19-16} = sat_imm;
2198 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2199 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2201 //===----------------------------------------------------------------------===//
2202 // Bitwise Instructions.
2205 defm AND : AsI1_bin_irs<0b0000, "and",
2206 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2207 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2208 defm ORR : AsI1_bin_irs<0b1100, "orr",
2209 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2210 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2211 defm EOR : AsI1_bin_irs<0b0001, "eor",
2212 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2213 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2214 defm BIC : AsI1_bin_irs<0b1110, "bic",
2215 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2216 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2218 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2219 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2220 "bfc", "\t$Rd, $imm", "$src = $Rd",
2221 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2222 Requires<[IsARM, HasV6T2]> {
2225 let Inst{27-21} = 0b0111110;
2226 let Inst{6-0} = 0b0011111;
2227 let Inst{15-12} = Rd;
2228 let Inst{11-7} = imm{4-0}; // lsb
2229 let Inst{20-16} = imm{9-5}; // width
2232 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2233 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2234 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2235 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2236 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2237 bf_inv_mask_imm:$imm))]>,
2238 Requires<[IsARM, HasV6T2]> {
2242 let Inst{27-21} = 0b0111110;
2243 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2244 let Inst{15-12} = Rd;
2245 let Inst{11-7} = imm{4-0}; // lsb
2246 let Inst{20-16} = imm{9-5}; // width
2250 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2251 "mvn", "\t$Rd, $Rm",
2252 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2256 let Inst{19-16} = 0b0000;
2257 let Inst{11-4} = 0b00000000;
2258 let Inst{15-12} = Rd;
2261 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2262 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2263 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2268 let Inst{19-16} = 0b0000;
2269 let Inst{15-12} = Rd;
2270 let Inst{11-0} = shift;
2272 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2273 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2274 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2275 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2280 let Inst{19-16} = 0b0000;
2281 let Inst{15-12} = Rd;
2282 let Inst{11-0} = imm;
2285 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2286 (BICri GPR:$src, so_imm_not:$imm)>;
2288 //===----------------------------------------------------------------------===//
2289 // Multiply Instructions.
2291 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2292 string opc, string asm, list<dag> pattern>
2293 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2297 let Inst{19-16} = Rd;
2298 let Inst{11-8} = Rm;
2301 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2302 string opc, string asm, list<dag> pattern>
2303 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2308 let Inst{19-16} = RdHi;
2309 let Inst{15-12} = RdLo;
2310 let Inst{11-8} = Rm;
2314 let isCommutable = 1 in
2315 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2316 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2317 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2319 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2320 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2321 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2323 let Inst{15-12} = Ra;
2326 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2327 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2328 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2329 Requires<[IsARM, HasV6T2]> {
2333 let Inst{19-16} = Rd;
2334 let Inst{11-8} = Rm;
2338 // Extra precision multiplies with low / high results
2340 let neverHasSideEffects = 1 in {
2341 let isCommutable = 1 in {
2342 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2343 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2344 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2346 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2347 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2348 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2351 // Multiply + accumulate
2352 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2353 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2354 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2356 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2357 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2358 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2360 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2361 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2362 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2363 Requires<[IsARM, HasV6]> {
2368 let Inst{19-16} = RdLo;
2369 let Inst{15-12} = RdHi;
2370 let Inst{11-8} = Rm;
2373 } // neverHasSideEffects
2375 // Most significant word multiply
2376 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2377 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2378 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2379 Requires<[IsARM, HasV6]> {
2380 let Inst{15-12} = 0b1111;
2383 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2384 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2385 [/* For disassembly only; pattern left blank */]>,
2386 Requires<[IsARM, HasV6]> {
2387 let Inst{15-12} = 0b1111;
2390 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2391 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2392 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2393 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2394 Requires<[IsARM, HasV6]>;
2396 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2397 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2398 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2399 [/* For disassembly only; pattern left blank */]>,
2400 Requires<[IsARM, HasV6]>;
2402 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2403 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2404 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2405 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2406 Requires<[IsARM, HasV6]>;
2408 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2409 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2410 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2411 [/* For disassembly only; pattern left blank */]>,
2412 Requires<[IsARM, HasV6]>;
2414 multiclass AI_smul<string opc, PatFrag opnode> {
2415 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2416 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2417 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2418 (sext_inreg GPR:$Rm, i16)))]>,
2419 Requires<[IsARM, HasV5TE]>;
2421 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2422 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2423 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2424 (sra GPR:$Rm, (i32 16))))]>,
2425 Requires<[IsARM, HasV5TE]>;
2427 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2428 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2429 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2430 (sext_inreg GPR:$Rm, i16)))]>,
2431 Requires<[IsARM, HasV5TE]>;
2433 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2434 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2435 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2436 (sra GPR:$Rm, (i32 16))))]>,
2437 Requires<[IsARM, HasV5TE]>;
2439 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2440 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2441 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2442 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2443 Requires<[IsARM, HasV5TE]>;
2445 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2446 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2447 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2448 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2449 Requires<[IsARM, HasV5TE]>;
2453 multiclass AI_smla<string opc, PatFrag opnode> {
2454 def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$Rd),
2455 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2456 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2457 [(set GPR:$Rd, (add GPR:$Ra,
2458 (opnode (sext_inreg GPR:$Rn, i16),
2459 (sext_inreg GPR:$Rm, i16))))]>,
2460 Requires<[IsARM, HasV5TE]>;
2462 def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$Rd),
2463 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2464 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2465 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2466 (sra GPR:$Rm, (i32 16)))))]>,
2467 Requires<[IsARM, HasV5TE]>;
2469 def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$Rd),
2470 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2471 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2472 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2473 (sext_inreg GPR:$Rm, i16))))]>,
2474 Requires<[IsARM, HasV5TE]>;
2476 def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$Rd),
2477 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2478 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2479 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2480 (sra GPR:$Rm, (i32 16)))))]>,
2481 Requires<[IsARM, HasV5TE]>;
2483 def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$Rd),
2484 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2485 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2486 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2487 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2488 Requires<[IsARM, HasV5TE]>;
2490 def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$Rd),
2491 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2492 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2493 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2494 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2495 Requires<[IsARM, HasV5TE]>;
2498 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2499 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2501 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2502 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2503 (ins GPR:$Rn, GPR:$Rm),
2504 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2505 [/* For disassembly only; pattern left blank */]>,
2506 Requires<[IsARM, HasV5TE]>;
2508 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2509 (ins GPR:$Rn, GPR:$Rm),
2510 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2511 [/* For disassembly only; pattern left blank */]>,
2512 Requires<[IsARM, HasV5TE]>;
2514 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2515 (ins GPR:$Rn, GPR:$Rm),
2516 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2517 [/* For disassembly only; pattern left blank */]>,
2518 Requires<[IsARM, HasV5TE]>;
2520 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2521 (ins GPR:$Rn, GPR:$Rm),
2522 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2523 [/* For disassembly only; pattern left blank */]>,
2524 Requires<[IsARM, HasV5TE]>;
2526 // Helper class for AI_smld -- for disassembly only
2527 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2528 InstrItinClass itin, string opc, string asm>
2529 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2536 let Inst{21-20} = 0b00;
2537 let Inst{22} = long;
2538 let Inst{27-23} = 0b01110;
2539 let Inst{11-8} = Rm;
2542 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2543 InstrItinClass itin, string opc, string asm>
2544 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2546 let Inst{15-12} = 0b1111;
2547 let Inst{19-16} = Rd;
2549 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2550 InstrItinClass itin, string opc, string asm>
2551 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2553 let Inst{15-12} = Ra;
2555 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2556 InstrItinClass itin, string opc, string asm>
2557 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2560 let Inst{19-16} = RdHi;
2561 let Inst{15-12} = RdLo;
2564 multiclass AI_smld<bit sub, string opc> {
2566 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2567 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2569 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2570 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2572 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2573 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2574 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2576 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2577 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2578 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2582 defm SMLA : AI_smld<0, "smla">;
2583 defm SMLS : AI_smld<1, "smls">;
2585 multiclass AI_sdml<bit sub, string opc> {
2587 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2588 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2589 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2590 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2593 defm SMUA : AI_sdml<0, "smua">;
2594 defm SMUS : AI_sdml<1, "smus">;
2596 //===----------------------------------------------------------------------===//
2597 // Misc. Arithmetic Instructions.
2600 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2601 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2602 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2604 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2605 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2606 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2607 Requires<[IsARM, HasV6T2]>;
2609 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2610 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2611 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2613 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2614 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2616 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2617 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2618 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2619 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2620 Requires<[IsARM, HasV6]>;
2622 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2623 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2626 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2627 (shl GPR:$Rm, (i32 8))), i16))]>,
2628 Requires<[IsARM, HasV6]>;
2630 def lsl_shift_imm : SDNodeXForm<imm, [{
2631 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2632 return CurDAG->getTargetConstant(Sh, MVT::i32);
2635 def lsl_amt : PatLeaf<(i32 imm), [{
2636 return (N->getZExtValue() < 32);
2639 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2640 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2641 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2642 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2643 (and (shl GPR:$Rm, lsl_amt:$sh),
2645 Requires<[IsARM, HasV6]>;
2647 // Alternate cases for PKHBT where identities eliminate some nodes.
2648 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2649 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2650 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2651 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2653 def asr_shift_imm : SDNodeXForm<imm, [{
2654 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2655 return CurDAG->getTargetConstant(Sh, MVT::i32);
2658 def asr_amt : PatLeaf<(i32 imm), [{
2659 return (N->getZExtValue() <= 32);
2662 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2663 // will match the pattern below.
2664 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2665 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2666 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2667 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2668 (and (sra GPR:$Rm, asr_amt:$sh),
2670 Requires<[IsARM, HasV6]>;
2672 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2673 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2674 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2675 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2676 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2677 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2678 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2680 //===----------------------------------------------------------------------===//
2681 // Comparison Instructions...
2684 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2685 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2686 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2688 // FIXME: We have to be careful when using the CMN instruction and comparison
2689 // with 0. One would expect these two pieces of code should give identical
2705 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2706 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2707 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2708 // value of r0 and the carry bit (because the "carry bit" parameter to
2709 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2710 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2711 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2712 // parameter to AddWithCarry is defined as 0).
2714 // When x is 0 and unsigned:
2718 // ~x + 1 = 0x1 0000 0000
2719 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2721 // Therefore, we should disable CMN when comparing against zero, until we can
2722 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2723 // when it's a comparison which doesn't look at the 'carry' flag).
2725 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2727 // This is related to <rdar://problem/7569620>.
2729 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2730 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2732 // Note that TST/TEQ don't set all the same flags that CMP does!
2733 defm TST : AI1_cmp_irs<0b1000, "tst",
2734 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2735 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2736 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2737 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2738 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2740 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2741 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2742 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2743 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2744 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2745 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2747 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2748 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2750 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2751 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2753 // Pseudo i64 compares for some floating point compares.
2754 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2756 def BCCi64 : PseudoInst<(outs),
2757 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2759 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2761 def BCCZi64 : PseudoInst<(outs),
2762 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2763 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2764 } // usesCustomInserter
2767 // Conditional moves
2768 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2769 // a two-value operand where a dag node expects two operands. :(
2770 // FIXME: These should all be pseudo-instructions that get expanded to
2771 // the normal MOV instructions. That would fix the dependency on
2772 // special casing them in tblgen.
2773 let neverHasSideEffects = 1 in {
2774 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2775 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2776 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2777 RegConstraint<"$false = $Rd">, UnaryDP {
2781 let Inst{11-4} = 0b00000000;
2784 let Inst{15-12} = Rd;
2785 let Inst{11-4} = 0b00000000;
2789 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2790 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2791 "mov", "\t$dst, $true",
2792 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2793 RegConstraint<"$false = $dst">, UnaryDP {
2797 def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src),
2799 "movw", "\t$dst, $src",
2801 RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>,
2807 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2808 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2809 "mov", "\t$dst, $true",
2810 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2811 RegConstraint<"$false = $dst">, UnaryDP {
2814 } // neverHasSideEffects
2816 //===----------------------------------------------------------------------===//
2817 // Atomic operations intrinsics
2820 // memory barriers protect the atomic sequences
2821 let hasSideEffects = 1 in {
2822 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2823 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2824 let Inst{31-4} = 0xf57ff05;
2825 // FIXME: add support for options other than a full system DMB
2826 // See DMB disassembly-only variants below.
2827 let Inst{3-0} = 0b1111;
2830 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2831 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2832 let Inst{31-4} = 0xf57ff04;
2833 // FIXME: add support for options other than a full system DSB
2834 // See DSB disassembly-only variants below.
2835 let Inst{3-0} = 0b1111;
2838 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2839 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2840 [(ARMMemBarrierMCR GPR:$zero)]>,
2841 Requires<[IsARM, HasV6]> {
2842 // FIXME: add support for options other than a full system DMB
2843 // FIXME: add encoding
2846 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2847 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2848 [(ARMSyncBarrierMCR GPR:$zero)]>,
2849 Requires<[IsARM, HasV6]> {
2850 // FIXME: add support for options other than a full system DSB
2851 // FIXME: add encoding
2855 // Memory Barrier Operations Variants -- for disassembly only
2857 def memb_opt : Operand<i32> {
2858 let PrintMethod = "printMemBOption";
2861 class AMBI<bits<4> op7_4, string opc>
2862 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2863 [/* For disassembly only; pattern left blank */]>,
2864 Requires<[IsARM, HasDB]> {
2865 let Inst{31-8} = 0xf57ff0;
2866 let Inst{7-4} = op7_4;
2869 // These DMB variants are for disassembly only.
2870 def DMBvar : AMBI<0b0101, "dmb">;
2872 // These DSB variants are for disassembly only.
2873 def DSBvar : AMBI<0b0100, "dsb">;
2875 // ISB has only full system option -- for disassembly only
2876 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2877 Requires<[IsARM, HasDB]> {
2878 let Inst{31-4} = 0xf57ff06;
2879 let Inst{3-0} = 0b1111;
2882 let usesCustomInserter = 1 in {
2883 let Uses = [CPSR] in {
2884 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2885 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2886 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2887 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2888 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2889 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2890 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2891 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2892 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2893 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2894 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2895 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2896 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2897 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2898 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2899 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2900 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2901 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2902 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2903 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2904 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2905 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2906 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2907 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2908 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2909 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2910 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2911 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2912 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2913 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2914 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2915 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2916 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2917 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2918 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2919 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2920 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2921 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2922 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2923 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2924 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2925 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2926 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2927 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2928 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2929 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2930 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2931 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2932 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2933 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2934 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2935 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2936 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2937 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2939 def ATOMIC_SWAP_I8 : PseudoInst<
2940 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2941 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2942 def ATOMIC_SWAP_I16 : PseudoInst<
2943 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2944 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2945 def ATOMIC_SWAP_I32 : PseudoInst<
2946 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2947 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2949 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2950 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2951 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2952 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2953 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2954 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2955 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2956 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2957 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2961 let mayLoad = 1 in {
2962 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2963 "ldrexb", "\t$dest, [$ptr]",
2965 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2966 "ldrexh", "\t$dest, [$ptr]",
2968 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2969 "ldrex", "\t$dest, [$ptr]",
2971 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2973 "ldrexd", "\t$dest, $dest2, [$ptr]",
2977 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2978 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2980 "strexb", "\t$success, $src, [$ptr]",
2982 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2984 "strexh", "\t$success, $src, [$ptr]",
2986 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2988 "strex", "\t$success, $src, [$ptr]",
2990 def STREXD : AIstrex<0b01, (outs GPR:$success),
2991 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2993 "strexd", "\t$success, $src, $src2, [$ptr]",
2997 // Clear-Exclusive is for disassembly only.
2998 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2999 [/* For disassembly only; pattern left blank */]>,
3000 Requires<[IsARM, HasV7]> {
3001 let Inst{31-20} = 0xf57;
3002 let Inst{7-4} = 0b0001;
3005 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3006 let mayLoad = 1 in {
3007 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
3008 "swp", "\t$dst, $src, [$ptr]",
3009 [/* For disassembly only; pattern left blank */]> {
3010 let Inst{27-23} = 0b00010;
3011 let Inst{22} = 0; // B = 0
3012 let Inst{21-20} = 0b00;
3013 let Inst{7-4} = 0b1001;
3016 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
3017 "swpb", "\t$dst, $src, [$ptr]",
3018 [/* For disassembly only; pattern left blank */]> {
3019 let Inst{27-23} = 0b00010;
3020 let Inst{22} = 1; // B = 1
3021 let Inst{21-20} = 0b00;
3022 let Inst{7-4} = 0b1001;
3026 //===----------------------------------------------------------------------===//
3030 // __aeabi_read_tp preserves the registers r1-r3.
3032 Defs = [R0, R12, LR, CPSR] in {
3033 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3034 "bl\t__aeabi_read_tp",
3035 [(set R0, ARMthread_pointer)]>;
3038 //===----------------------------------------------------------------------===//
3039 // SJLJ Exception handling intrinsics
3040 // eh_sjlj_setjmp() is an instruction sequence to store the return
3041 // address and save #0 in R0 for the non-longjmp case.
3042 // Since by its nature we may be coming from some other function to get
3043 // here, and we're using the stack frame for the containing function to
3044 // save/restore registers, we can't keep anything live in regs across
3045 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3046 // when we get here from a longjmp(). We force everthing out of registers
3047 // except for our own input by listing the relevant registers in Defs. By
3048 // doing so, we also cause the prologue/epilogue code to actively preserve
3049 // all of the callee-saved resgisters, which is exactly what we want.
3050 // A constant value is passed in $val, and we use the location as a scratch.
3052 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3053 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3054 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3055 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3056 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3057 AddrModeNone, SizeSpecial, IndexModeNone,
3058 Pseudo, NoItinerary, "", "",
3059 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3060 Requires<[IsARM, HasVFP2]>;
3064 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3065 hasSideEffects = 1, isBarrier = 1 in {
3066 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3067 AddrModeNone, SizeSpecial, IndexModeNone,
3068 Pseudo, NoItinerary, "", "",
3069 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3070 Requires<[IsARM, NoVFP]>;
3073 // FIXME: Non-Darwin version(s)
3074 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3075 Defs = [ R7, LR, SP ] in {
3076 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3077 AddrModeNone, SizeSpecial, IndexModeNone,
3078 Pseudo, NoItinerary, "", "",
3079 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3080 Requires<[IsARM, IsDarwin]>;
3083 // eh.sjlj.dispatchsetup pseudo-instruction.
3084 // This pseudo is usef for ARM, Thumb1 and Thumb2. Any differences are
3085 // handled when the pseudo is expanded (which happens before any passes
3086 // that need the instruction size).
3087 let isBarrier = 1, hasSideEffects = 1 in
3088 def Int_eh_sjlj_dispatchsetup :
3089 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3090 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3091 Requires<[IsDarwin]>;
3093 //===----------------------------------------------------------------------===//
3094 // Non-Instruction Patterns
3097 // Large immediate handling.
3099 // Two piece so_imms.
3100 // FIXME: Expand this in ARMExpandPseudoInsts.
3101 // FIXME: Remove this when we can do generalized remat.
3102 let isReMaterializable = 1 in
3103 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
3104 Pseudo, IIC_iMOVix2,
3105 "mov", "\t$dst, $src",
3106 [(set GPR:$dst, so_imm2part:$src)]>,
3107 Requires<[IsARM, NoV6T2]>;
3109 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3110 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3111 (so_imm2part_2 imm:$RHS))>;
3112 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3113 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3114 (so_imm2part_2 imm:$RHS))>;
3115 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3116 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3117 (so_imm2part_2 imm:$RHS))>;
3118 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3119 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3120 (so_neg_imm2part_2 imm:$RHS))>;
3122 // 32-bit immediate using movw + movt.
3123 // This is a single pseudo instruction, the benefit is that it can be remat'd
3124 // as a single unit instead of having to handle reg inputs.
3125 // FIXME: Remove this when we can do generalized remat.
3126 let isReMaterializable = 1 in
3127 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3128 [(set GPR:$dst, (i32 imm:$src))]>,
3129 Requires<[IsARM, HasV6T2]>;
3131 // ConstantPool, GlobalAddress, and JumpTable
3132 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3133 Requires<[IsARM, DontUseMovt]>;
3134 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3135 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3136 Requires<[IsARM, UseMovt]>;
3137 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3138 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3140 // TODO: add,sub,and, 3-instr forms?
3143 def : ARMPat<(ARMtcret tcGPR:$dst),
3144 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3146 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3147 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3149 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3150 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3152 def : ARMPat<(ARMtcret tcGPR:$dst),
3153 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3155 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3156 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3158 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3159 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3162 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3163 Requires<[IsARM, IsNotDarwin]>;
3164 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3165 Requires<[IsARM, IsDarwin]>;
3167 // zextload i1 -> zextload i8
3168 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
3170 // extload -> zextload
3171 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
3172 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
3173 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3175 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3176 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3179 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3180 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3181 (SMULBB GPR:$a, GPR:$b)>;
3182 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3183 (SMULBB GPR:$a, GPR:$b)>;
3184 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3185 (sra GPR:$b, (i32 16))),
3186 (SMULBT GPR:$a, GPR:$b)>;
3187 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3188 (SMULBT GPR:$a, GPR:$b)>;
3189 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3190 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3191 (SMULTB GPR:$a, GPR:$b)>;
3192 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3193 (SMULTB GPR:$a, GPR:$b)>;
3194 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3196 (SMULWB GPR:$a, GPR:$b)>;
3197 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3198 (SMULWB GPR:$a, GPR:$b)>;
3200 def : ARMV5TEPat<(add GPR:$acc,
3201 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3202 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3203 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3204 def : ARMV5TEPat<(add GPR:$acc,
3205 (mul sext_16_node:$a, sext_16_node:$b)),
3206 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3207 def : ARMV5TEPat<(add GPR:$acc,
3208 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3209 (sra GPR:$b, (i32 16)))),
3210 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3211 def : ARMV5TEPat<(add GPR:$acc,
3212 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3213 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3214 def : ARMV5TEPat<(add GPR:$acc,
3215 (mul (sra GPR:$a, (i32 16)),
3216 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3217 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3218 def : ARMV5TEPat<(add GPR:$acc,
3219 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3220 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3221 def : ARMV5TEPat<(add GPR:$acc,
3222 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3224 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3225 def : ARMV5TEPat<(add GPR:$acc,
3226 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3227 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3229 //===----------------------------------------------------------------------===//
3233 include "ARMInstrThumb.td"
3235 //===----------------------------------------------------------------------===//
3239 include "ARMInstrThumb2.td"
3241 //===----------------------------------------------------------------------===//
3242 // Floating Point Support
3245 include "ARMInstrVFP.td"
3247 //===----------------------------------------------------------------------===//
3248 // Advanced SIMD (NEON) Support
3251 include "ARMInstrNEON.td"
3253 //===----------------------------------------------------------------------===//
3254 // Coprocessor Instructions. For disassembly only.
3257 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3258 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3259 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3260 [/* For disassembly only; pattern left blank */]> {
3264 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3265 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3266 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3267 [/* For disassembly only; pattern left blank */]> {
3268 let Inst{31-28} = 0b1111;
3272 class ACI<dag oops, dag iops, string opc, string asm>
3273 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3274 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3275 let Inst{27-25} = 0b110;
3278 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3280 def _OFFSET : ACI<(outs),
3281 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3282 opc, "\tp$cop, cr$CRd, $addr"> {
3283 let Inst{31-28} = op31_28;
3284 let Inst{24} = 1; // P = 1
3285 let Inst{21} = 0; // W = 0
3286 let Inst{22} = 0; // D = 0
3287 let Inst{20} = load;
3290 def _PRE : ACI<(outs),
3291 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3292 opc, "\tp$cop, cr$CRd, $addr!"> {
3293 let Inst{31-28} = op31_28;
3294 let Inst{24} = 1; // P = 1
3295 let Inst{21} = 1; // W = 1
3296 let Inst{22} = 0; // D = 0
3297 let Inst{20} = load;
3300 def _POST : ACI<(outs),
3301 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3302 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3303 let Inst{31-28} = op31_28;
3304 let Inst{24} = 0; // P = 0
3305 let Inst{21} = 1; // W = 1
3306 let Inst{22} = 0; // D = 0
3307 let Inst{20} = load;
3310 def _OPTION : ACI<(outs),
3311 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3312 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3313 let Inst{31-28} = op31_28;
3314 let Inst{24} = 0; // P = 0
3315 let Inst{23} = 1; // U = 1
3316 let Inst{21} = 0; // W = 0
3317 let Inst{22} = 0; // D = 0
3318 let Inst{20} = load;
3321 def L_OFFSET : ACI<(outs),
3322 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3323 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3324 let Inst{31-28} = op31_28;
3325 let Inst{24} = 1; // P = 1
3326 let Inst{21} = 0; // W = 0
3327 let Inst{22} = 1; // D = 1
3328 let Inst{20} = load;
3331 def L_PRE : ACI<(outs),
3332 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3333 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3334 let Inst{31-28} = op31_28;
3335 let Inst{24} = 1; // P = 1
3336 let Inst{21} = 1; // W = 1
3337 let Inst{22} = 1; // D = 1
3338 let Inst{20} = load;
3341 def L_POST : ACI<(outs),
3342 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3343 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3344 let Inst{31-28} = op31_28;
3345 let Inst{24} = 0; // P = 0
3346 let Inst{21} = 1; // W = 1
3347 let Inst{22} = 1; // D = 1
3348 let Inst{20} = load;
3351 def L_OPTION : ACI<(outs),
3352 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3353 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3354 let Inst{31-28} = op31_28;
3355 let Inst{24} = 0; // P = 0
3356 let Inst{23} = 1; // U = 1
3357 let Inst{21} = 0; // W = 0
3358 let Inst{22} = 1; // D = 1
3359 let Inst{20} = load;
3363 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3364 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3365 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3366 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3368 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3369 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3370 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3371 [/* For disassembly only; pattern left blank */]> {
3376 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3377 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3378 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3379 [/* For disassembly only; pattern left blank */]> {
3380 let Inst{31-28} = 0b1111;
3385 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3386 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3387 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3388 [/* For disassembly only; pattern left blank */]> {
3393 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3394 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3395 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3396 [/* For disassembly only; pattern left blank */]> {
3397 let Inst{31-28} = 0b1111;
3402 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3403 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3404 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3405 [/* For disassembly only; pattern left blank */]> {
3406 let Inst{23-20} = 0b0100;
3409 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3410 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3411 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3412 [/* For disassembly only; pattern left blank */]> {
3413 let Inst{31-28} = 0b1111;
3414 let Inst{23-20} = 0b0100;
3417 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3418 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3419 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3420 [/* For disassembly only; pattern left blank */]> {
3421 let Inst{23-20} = 0b0101;
3424 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3425 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3426 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3427 [/* For disassembly only; pattern left blank */]> {
3428 let Inst{31-28} = 0b1111;
3429 let Inst{23-20} = 0b0101;
3432 //===----------------------------------------------------------------------===//
3433 // Move between special register and ARM core register -- for disassembly only
3436 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3437 [/* For disassembly only; pattern left blank */]> {
3438 let Inst{23-20} = 0b0000;
3439 let Inst{7-4} = 0b0000;
3442 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3443 [/* For disassembly only; pattern left blank */]> {
3444 let Inst{23-20} = 0b0100;
3445 let Inst{7-4} = 0b0000;
3448 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3449 "msr", "\tcpsr$mask, $src",
3450 [/* For disassembly only; pattern left blank */]> {
3451 let Inst{23-20} = 0b0010;
3452 let Inst{7-4} = 0b0000;
3455 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3456 "msr", "\tcpsr$mask, $a",
3457 [/* For disassembly only; pattern left blank */]> {
3458 let Inst{23-20} = 0b0010;
3459 let Inst{7-4} = 0b0000;
3462 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3463 "msr", "\tspsr$mask, $src",
3464 [/* For disassembly only; pattern left blank */]> {
3465 let Inst{23-20} = 0b0110;
3466 let Inst{7-4} = 0b0000;
3469 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3470 "msr", "\tspsr$mask, $a",
3471 [/* For disassembly only; pattern left blank */]> {
3472 let Inst{23-20} = 0b0110;
3473 let Inst{7-4} = 0b0000;