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, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>;
73 def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
74 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
76 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
77 [SDNPHasChain, SDNPOutGlue]>;
78 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
79 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
81 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
82 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
84 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
85 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
87 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
88 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
91 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
92 [SDNPHasChain, SDNPOptInGlue]>;
94 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
97 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
98 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
100 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
102 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
105 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
108 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
111 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
112 [SDNPOutGlue, SDNPCommutative]>;
114 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
117 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
118 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
120 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
121 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
122 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
123 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
124 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
126 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
129 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
131 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
133 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
134 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
136 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
138 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
139 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
142 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
144 //===----------------------------------------------------------------------===//
145 // ARM Instruction Predicate Definitions.
147 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
148 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
149 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
150 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
151 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
152 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
153 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
154 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
155 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
156 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
157 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
158 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
159 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
160 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
161 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
162 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
164 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
166 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
168 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
169 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
170 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
171 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
172 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
173 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
174 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
175 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
177 // FIXME: Eventually this will be just "hasV6T2Ops".
178 def UseMovt : Predicate<"Subtarget->useMovt()">;
179 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
180 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
182 //===----------------------------------------------------------------------===//
183 // ARM Flag Definitions.
185 class RegConstraint<string C> {
186 string Constraints = C;
189 //===----------------------------------------------------------------------===//
190 // ARM specific transformation functions and pattern fragments.
193 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
194 // so_imm_neg def below.
195 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
196 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
199 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
200 // so_imm_not def below.
201 def so_imm_not_XFORM : SDNodeXForm<imm, [{
202 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
205 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
206 def imm1_15 : PatLeaf<(i32 imm), [{
207 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
210 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
211 def imm16_31 : PatLeaf<(i32 imm), [{
212 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
217 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
218 }], so_imm_neg_XFORM>;
222 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
223 }], so_imm_not_XFORM>;
225 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
226 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
227 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
230 /// Split a 32-bit immediate into two 16 bit parts.
231 def hi16 : SDNodeXForm<imm, [{
232 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
235 def lo16AllZero : PatLeaf<(i32 imm), [{
236 // Returns true if all low 16-bits are 0.
237 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
240 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
242 def imm0_65535 : PatLeaf<(i32 imm), [{
243 return (uint32_t)N->getZExtValue() < 65536;
246 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
247 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
249 /// adde and sube predicates - True based on whether the carry flag output
250 /// will be needed or not.
251 def adde_dead_carry :
252 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
253 [{return !N->hasAnyUseOfValue(1);}]>;
254 def sube_dead_carry :
255 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
256 [{return !N->hasAnyUseOfValue(1);}]>;
257 def adde_live_carry :
258 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
259 [{return N->hasAnyUseOfValue(1);}]>;
260 def sube_live_carry :
261 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
262 [{return N->hasAnyUseOfValue(1);}]>;
264 // An 'and' node with a single use.
265 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
266 return N->hasOneUse();
269 // An 'xor' node with a single use.
270 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
271 return N->hasOneUse();
274 // An 'fmul' node with a single use.
275 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
276 return N->hasOneUse();
279 // An 'fadd' node which checks for single non-hazardous use.
280 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
281 return hasNoVMLxHazardUse(N);
284 // An 'fsub' node which checks for single non-hazardous use.
285 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
286 return hasNoVMLxHazardUse(N);
289 //===----------------------------------------------------------------------===//
290 // Operand Definitions.
294 // FIXME: rename brtarget to t2_brtarget
295 def brtarget : Operand<OtherVT> {
296 let EncoderMethod = "getBranchTargetOpValue";
299 // FIXME: get rid of this one?
300 def uncondbrtarget : Operand<OtherVT> {
301 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
304 // Branch target for ARM. Handles conditional/unconditional
305 def br_target : Operand<OtherVT> {
306 let EncoderMethod = "getARMBranchTargetOpValue";
310 // FIXME: rename bltarget to t2_bl_target?
311 def bltarget : Operand<i32> {
312 // Encoded the same as branch targets.
313 let EncoderMethod = "getBranchTargetOpValue";
316 // Call target for ARM. Handles conditional/unconditional
317 // FIXME: rename bl_target to t2_bltarget?
318 def bl_target : Operand<i32> {
319 // Encoded the same as branch targets.
320 let EncoderMethod = "getARMBranchTargetOpValue";
324 // A list of registers separated by comma. Used by load/store multiple.
325 def RegListAsmOperand : AsmOperandClass {
326 let Name = "RegList";
327 let SuperClasses = [];
330 def DPRRegListAsmOperand : AsmOperandClass {
331 let Name = "DPRRegList";
332 let SuperClasses = [];
335 def SPRRegListAsmOperand : AsmOperandClass {
336 let Name = "SPRRegList";
337 let SuperClasses = [];
340 def reglist : Operand<i32> {
341 let EncoderMethod = "getRegisterListOpValue";
342 let ParserMatchClass = RegListAsmOperand;
343 let PrintMethod = "printRegisterList";
346 def dpr_reglist : Operand<i32> {
347 let EncoderMethod = "getRegisterListOpValue";
348 let ParserMatchClass = DPRRegListAsmOperand;
349 let PrintMethod = "printRegisterList";
352 def spr_reglist : Operand<i32> {
353 let EncoderMethod = "getRegisterListOpValue";
354 let ParserMatchClass = SPRRegListAsmOperand;
355 let PrintMethod = "printRegisterList";
358 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
359 def cpinst_operand : Operand<i32> {
360 let PrintMethod = "printCPInstOperand";
364 def pclabel : Operand<i32> {
365 let PrintMethod = "printPCLabel";
368 // ADR instruction labels.
369 def adrlabel : Operand<i32> {
370 let EncoderMethod = "getAdrLabelOpValue";
373 def neon_vcvt_imm32 : Operand<i32> {
374 let EncoderMethod = "getNEONVcvtImm32OpValue";
377 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
378 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
379 int32_t v = (int32_t)N->getZExtValue();
380 return v == 8 || v == 16 || v == 24; }]> {
381 let EncoderMethod = "getRotImmOpValue";
384 // shift_imm: An integer that encodes a shift amount and the type of shift
385 // (currently either asr or lsl) using the same encoding used for the
386 // immediates in so_reg operands.
387 def shift_imm : Operand<i32> {
388 let PrintMethod = "printShiftImmOperand";
391 // shifter_operand operands: so_reg and so_imm.
392 def so_reg : Operand<i32>, // reg reg imm
393 ComplexPattern<i32, 3, "SelectShifterOperandReg",
394 [shl,srl,sra,rotr]> {
395 let EncoderMethod = "getSORegOpValue";
396 let PrintMethod = "printSORegOperand";
397 let MIOperandInfo = (ops GPR, GPR, i32imm);
399 def shift_so_reg : Operand<i32>, // reg reg imm
400 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
401 [shl,srl,sra,rotr]> {
402 let EncoderMethod = "getSORegOpValue";
403 let PrintMethod = "printSORegOperand";
404 let MIOperandInfo = (ops GPR, GPR, i32imm);
407 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
408 // 8-bit immediate rotated by an arbitrary number of bits.
409 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
410 let EncoderMethod = "getSOImmOpValue";
411 let PrintMethod = "printSOImmOperand";
414 // Break so_imm's up into two pieces. This handles immediates with up to 16
415 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
416 // get the first/second pieces.
417 def so_imm2part : PatLeaf<(imm), [{
418 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
421 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
423 def arm_i32imm : PatLeaf<(imm), [{
424 if (Subtarget->hasV6T2Ops())
426 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
429 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
430 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
431 return (int32_t)N->getZExtValue() < 32;
434 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
435 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
436 return (int32_t)N->getZExtValue() < 32;
438 let EncoderMethod = "getImmMinusOneOpValue";
441 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
442 // The imm is split into imm{15-12}, imm{11-0}
444 def i32imm_hilo16 : Operand<i32> {
445 let EncoderMethod = "getHiLo16ImmOpValue";
448 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
450 def bf_inv_mask_imm : Operand<i32>,
452 return ARM::isBitFieldInvertedMask(N->getZExtValue());
454 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
455 let PrintMethod = "printBitfieldInvMaskImmOperand";
458 /// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
459 def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
460 return isInt<5>(N->getSExtValue());
463 /// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
464 def width_imm : Operand<i32>, PatLeaf<(imm), [{
465 return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
467 let EncoderMethod = "getMsbOpValue";
470 // Define ARM specific addressing modes.
473 // addrmode_imm12 := reg +/- imm12
475 def addrmode_imm12 : Operand<i32>,
476 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
477 // 12-bit immediate operand. Note that instructions using this encode
478 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
479 // immediate values are as normal.
481 let EncoderMethod = "getAddrModeImm12OpValue";
482 let PrintMethod = "printAddrModeImm12Operand";
483 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
485 // ldst_so_reg := reg +/- reg shop imm
487 def ldst_so_reg : Operand<i32>,
488 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
489 let EncoderMethod = "getLdStSORegOpValue";
490 // FIXME: Simplify the printer
491 let PrintMethod = "printAddrMode2Operand";
492 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
495 // addrmode2 := reg +/- imm12
496 // := reg +/- reg shop imm
498 def addrmode2 : Operand<i32>,
499 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
500 let EncoderMethod = "getAddrMode2OpValue";
501 let PrintMethod = "printAddrMode2Operand";
502 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
505 def am2offset : Operand<i32>,
506 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
507 [], [SDNPWantRoot]> {
508 let EncoderMethod = "getAddrMode2OffsetOpValue";
509 let PrintMethod = "printAddrMode2OffsetOperand";
510 let MIOperandInfo = (ops GPR, i32imm);
513 // addrmode3 := reg +/- reg
514 // addrmode3 := reg +/- imm8
516 def addrmode3 : Operand<i32>,
517 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
518 let EncoderMethod = "getAddrMode3OpValue";
519 let PrintMethod = "printAddrMode3Operand";
520 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
523 def am3offset : Operand<i32>,
524 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
525 [], [SDNPWantRoot]> {
526 let EncoderMethod = "getAddrMode3OffsetOpValue";
527 let PrintMethod = "printAddrMode3OffsetOperand";
528 let MIOperandInfo = (ops GPR, i32imm);
531 // ldstm_mode := {ia, ib, da, db}
533 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
534 let EncoderMethod = "getLdStmModeOpValue";
535 let PrintMethod = "printLdStmModeOperand";
538 def MemMode5AsmOperand : AsmOperandClass {
539 let Name = "MemMode5";
540 let SuperClasses = [];
543 // addrmode5 := reg +/- imm8*4
545 def addrmode5 : Operand<i32>,
546 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
547 let PrintMethod = "printAddrMode5Operand";
548 let MIOperandInfo = (ops GPR:$base, i32imm);
549 let ParserMatchClass = MemMode5AsmOperand;
550 let EncoderMethod = "getAddrMode5OpValue";
553 // addrmode6 := reg with optional alignment
555 def addrmode6 : Operand<i32>,
556 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
557 let PrintMethod = "printAddrMode6Operand";
558 let MIOperandInfo = (ops GPR:$addr, i32imm);
559 let EncoderMethod = "getAddrMode6AddressOpValue";
562 def am6offset : Operand<i32>,
563 ComplexPattern<i32, 1, "SelectAddrMode6Offset",
564 [], [SDNPWantRoot]> {
565 let PrintMethod = "printAddrMode6OffsetOperand";
566 let MIOperandInfo = (ops GPR);
567 let EncoderMethod = "getAddrMode6OffsetOpValue";
570 // Special version of addrmode6 to handle alignment encoding for VLD-dup
571 // instructions, specifically VLD4-dup.
572 def addrmode6dup : Operand<i32>,
573 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
574 let PrintMethod = "printAddrMode6Operand";
575 let MIOperandInfo = (ops GPR:$addr, i32imm);
576 let EncoderMethod = "getAddrMode6DupAddressOpValue";
579 // addrmodepc := pc + reg
581 def addrmodepc : Operand<i32>,
582 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
583 let PrintMethod = "printAddrModePCOperand";
584 let MIOperandInfo = (ops GPR, i32imm);
587 def nohash_imm : Operand<i32> {
588 let PrintMethod = "printNoHashImmediate";
591 def CoprocNumAsmOperand : AsmOperandClass {
592 let Name = "CoprocNum";
593 let SuperClasses = [];
594 let ParserMethod = "tryParseCoprocNumOperand";
597 def CoprocRegAsmOperand : AsmOperandClass {
598 let Name = "CoprocReg";
599 let SuperClasses = [];
600 let ParserMethod = "tryParseCoprocRegOperand";
603 def p_imm : Operand<i32> {
604 let PrintMethod = "printPImmediate";
605 let ParserMatchClass = CoprocNumAsmOperand;
608 def c_imm : Operand<i32> {
609 let PrintMethod = "printCImmediate";
610 let ParserMatchClass = CoprocRegAsmOperand;
613 //===----------------------------------------------------------------------===//
615 include "ARMInstrFormats.td"
617 //===----------------------------------------------------------------------===//
618 // Multiclass helpers...
621 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
622 /// binop that produces a value.
623 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
624 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
625 PatFrag opnode, bit Commutable = 0> {
626 // The register-immediate version is re-materializable. This is useful
627 // in particular for taking the address of a local.
628 let isReMaterializable = 1 in {
629 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
630 iii, opc, "\t$Rd, $Rn, $imm",
631 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
636 let Inst{19-16} = Rn;
637 let Inst{15-12} = Rd;
638 let Inst{11-0} = imm;
641 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
642 iir, opc, "\t$Rd, $Rn, $Rm",
643 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
648 let isCommutable = Commutable;
649 let Inst{19-16} = Rn;
650 let Inst{15-12} = Rd;
651 let Inst{11-4} = 0b00000000;
654 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
655 iis, opc, "\t$Rd, $Rn, $shift",
656 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
661 let Inst{19-16} = Rn;
662 let Inst{15-12} = Rd;
663 let Inst{11-0} = shift;
667 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
668 /// instruction modifies the CPSR register.
669 let isCodeGenOnly = 1, Defs = [CPSR] in {
670 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
671 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
672 PatFrag opnode, bit Commutable = 0> {
673 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
674 iii, opc, "\t$Rd, $Rn, $imm",
675 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
681 let Inst{19-16} = Rn;
682 let Inst{15-12} = Rd;
683 let Inst{11-0} = imm;
685 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
686 iir, opc, "\t$Rd, $Rn, $Rm",
687 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
691 let isCommutable = Commutable;
694 let Inst{19-16} = Rn;
695 let Inst{15-12} = Rd;
696 let Inst{11-4} = 0b00000000;
699 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
700 iis, opc, "\t$Rd, $Rn, $shift",
701 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
707 let Inst{19-16} = Rn;
708 let Inst{15-12} = Rd;
709 let Inst{11-0} = shift;
714 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
715 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
716 /// a explicit result, only implicitly set CPSR.
717 let isCompare = 1, Defs = [CPSR] in {
718 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
719 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
720 PatFrag opnode, bit Commutable = 0> {
721 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
723 [(opnode GPR:$Rn, so_imm:$imm)]> {
728 let Inst{19-16} = Rn;
729 let Inst{15-12} = 0b0000;
730 let Inst{11-0} = imm;
732 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
734 [(opnode GPR:$Rn, GPR:$Rm)]> {
737 let isCommutable = Commutable;
740 let Inst{19-16} = Rn;
741 let Inst{15-12} = 0b0000;
742 let Inst{11-4} = 0b00000000;
745 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
746 opc, "\t$Rn, $shift",
747 [(opnode GPR:$Rn, so_reg:$shift)]> {
752 let Inst{19-16} = Rn;
753 let Inst{15-12} = 0b0000;
754 let Inst{11-0} = shift;
759 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
760 /// register and one whose operand is a register rotated by 8/16/24.
761 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
762 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
763 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
764 IIC_iEXTr, opc, "\t$Rd, $Rm",
765 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
766 Requires<[IsARM, HasV6]> {
769 let Inst{19-16} = 0b1111;
770 let Inst{15-12} = Rd;
771 let Inst{11-10} = 0b00;
774 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
775 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
776 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
777 Requires<[IsARM, HasV6]> {
781 let Inst{19-16} = 0b1111;
782 let Inst{15-12} = Rd;
783 let Inst{11-10} = rot;
788 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
789 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
790 IIC_iEXTr, opc, "\t$Rd, $Rm",
791 [/* For disassembly only; pattern left blank */]>,
792 Requires<[IsARM, HasV6]> {
793 let Inst{19-16} = 0b1111;
794 let Inst{11-10} = 0b00;
796 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
797 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
798 [/* For disassembly only; pattern left blank */]>,
799 Requires<[IsARM, HasV6]> {
801 let Inst{19-16} = 0b1111;
802 let Inst{11-10} = rot;
806 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
807 /// register and one whose operand is a register rotated by 8/16/24.
808 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
809 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
810 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
811 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
812 Requires<[IsARM, HasV6]> {
816 let Inst{19-16} = Rn;
817 let Inst{15-12} = Rd;
818 let Inst{11-10} = 0b00;
819 let Inst{9-4} = 0b000111;
822 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
824 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
825 [(set GPR:$Rd, (opnode GPR:$Rn,
826 (rotr GPR:$Rm, rot_imm:$rot)))]>,
827 Requires<[IsARM, HasV6]> {
832 let Inst{19-16} = Rn;
833 let Inst{15-12} = Rd;
834 let Inst{11-10} = rot;
835 let Inst{9-4} = 0b000111;
840 // For disassembly only.
841 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
842 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
843 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
844 [/* For disassembly only; pattern left blank */]>,
845 Requires<[IsARM, HasV6]> {
846 let Inst{11-10} = 0b00;
848 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
850 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
851 [/* For disassembly only; pattern left blank */]>,
852 Requires<[IsARM, HasV6]> {
855 let Inst{19-16} = Rn;
856 let Inst{11-10} = rot;
860 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
861 let Uses = [CPSR] in {
862 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
863 bit Commutable = 0> {
864 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
865 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
866 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
872 let Inst{15-12} = Rd;
873 let Inst{19-16} = Rn;
874 let Inst{11-0} = imm;
876 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
877 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
878 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
883 let Inst{11-4} = 0b00000000;
885 let isCommutable = Commutable;
887 let Inst{15-12} = Rd;
888 let Inst{19-16} = Rn;
890 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
891 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
892 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
898 let Inst{11-0} = shift;
899 let Inst{15-12} = Rd;
900 let Inst{19-16} = Rn;
903 // Carry setting variants
904 let isCodeGenOnly = 1, Defs = [CPSR] in {
905 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
906 bit Commutable = 0> {
907 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
908 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
909 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
914 let Inst{15-12} = Rd;
915 let Inst{19-16} = Rn;
916 let Inst{11-0} = imm;
920 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
921 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
922 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
927 let Inst{11-4} = 0b00000000;
928 let isCommutable = Commutable;
930 let Inst{15-12} = Rd;
931 let Inst{19-16} = Rn;
935 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
936 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
937 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
942 let Inst{11-0} = shift;
943 let Inst{15-12} = Rd;
944 let Inst{19-16} = Rn;
952 let canFoldAsLoad = 1, isReMaterializable = 1 in {
953 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
954 InstrItinClass iir, PatFrag opnode> {
955 // Note: We use the complex addrmode_imm12 rather than just an input
956 // GPR and a constrained immediate so that we can use this to match
957 // frame index references and avoid matching constant pool references.
958 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
959 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
960 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
963 let Inst{23} = addr{12}; // U (add = ('U' == 1))
964 let Inst{19-16} = addr{16-13}; // Rn
965 let Inst{15-12} = Rt;
966 let Inst{11-0} = addr{11-0}; // imm12
968 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
969 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
970 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
973 let Inst{23} = shift{12}; // U (add = ('U' == 1))
974 let Inst{19-16} = shift{16-13}; // Rn
975 let Inst{15-12} = Rt;
976 let Inst{11-0} = shift{11-0};
981 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
982 InstrItinClass iir, PatFrag opnode> {
983 // Note: We use the complex addrmode_imm12 rather than just an input
984 // GPR and a constrained immediate so that we can use this to match
985 // frame index references and avoid matching constant pool references.
986 def i12 : AI2ldst<0b010, 0, isByte, (outs),
987 (ins GPR:$Rt, addrmode_imm12:$addr),
988 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
989 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
992 let Inst{23} = addr{12}; // U (add = ('U' == 1))
993 let Inst{19-16} = addr{16-13}; // Rn
994 let Inst{15-12} = Rt;
995 let Inst{11-0} = addr{11-0}; // imm12
997 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
998 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
999 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1002 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1003 let Inst{19-16} = shift{16-13}; // Rn
1004 let Inst{15-12} = Rt;
1005 let Inst{11-0} = shift{11-0};
1008 //===----------------------------------------------------------------------===//
1010 //===----------------------------------------------------------------------===//
1012 //===----------------------------------------------------------------------===//
1013 // Miscellaneous Instructions.
1016 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1017 /// the function. The first operand is the ID# for this instruction, the second
1018 /// is the index into the MachineConstantPool that this is, the third is the
1019 /// size in bytes of this constant pool entry.
1020 let neverHasSideEffects = 1, isNotDuplicable = 1 in
1021 def CONSTPOOL_ENTRY :
1022 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1023 i32imm:$size), NoItinerary, []>;
1025 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1026 // from removing one half of the matched pairs. That breaks PEI, which assumes
1027 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1028 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1029 def ADJCALLSTACKUP :
1030 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1031 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1033 def ADJCALLSTACKDOWN :
1034 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1035 [(ARMcallseq_start timm:$amt)]>;
1038 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
1039 [/* For disassembly only; pattern left blank */]>,
1040 Requires<[IsARM, HasV6T2]> {
1041 let Inst{27-16} = 0b001100100000;
1042 let Inst{15-8} = 0b11110000;
1043 let Inst{7-0} = 0b00000000;
1046 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1047 [/* For disassembly only; pattern left blank */]>,
1048 Requires<[IsARM, HasV6T2]> {
1049 let Inst{27-16} = 0b001100100000;
1050 let Inst{15-8} = 0b11110000;
1051 let Inst{7-0} = 0b00000001;
1054 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1055 [/* For disassembly only; pattern left blank */]>,
1056 Requires<[IsARM, HasV6T2]> {
1057 let Inst{27-16} = 0b001100100000;
1058 let Inst{15-8} = 0b11110000;
1059 let Inst{7-0} = 0b00000010;
1062 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1063 [/* For disassembly only; pattern left blank */]>,
1064 Requires<[IsARM, HasV6T2]> {
1065 let Inst{27-16} = 0b001100100000;
1066 let Inst{15-8} = 0b11110000;
1067 let Inst{7-0} = 0b00000011;
1070 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1072 [/* For disassembly only; pattern left blank */]>,
1073 Requires<[IsARM, HasV6]> {
1078 let Inst{15-12} = Rd;
1079 let Inst{19-16} = Rn;
1080 let Inst{27-20} = 0b01101000;
1081 let Inst{7-4} = 0b1011;
1082 let Inst{11-8} = 0b1111;
1085 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1086 [/* For disassembly only; pattern left blank */]>,
1087 Requires<[IsARM, HasV6T2]> {
1088 let Inst{27-16} = 0b001100100000;
1089 let Inst{15-8} = 0b11110000;
1090 let Inst{7-0} = 0b00000100;
1093 // The i32imm operand $val can be used by a debugger to store more information
1094 // about the breakpoint.
1095 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1096 [/* For disassembly only; pattern left blank */]>,
1099 let Inst{3-0} = val{3-0};
1100 let Inst{19-8} = val{15-4};
1101 let Inst{27-20} = 0b00010010;
1102 let Inst{7-4} = 0b0111;
1105 // Change Processor State is a system instruction -- for disassembly and
1107 // FIXME: Since the asm parser has currently no clean way to handle optional
1108 // operands, create 3 versions of the same instruction. Once there's a clean
1109 // framework to represent optional operands, change this behavior.
1110 class CPS<dag iops, string asm_ops>
1111 : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
1112 [/* For disassembly only; pattern left blank */]>, Requires<[IsARM]> {
1118 let Inst{31-28} = 0b1111;
1119 let Inst{27-20} = 0b00010000;
1120 let Inst{19-18} = imod;
1121 let Inst{17} = M; // Enabled if mode is set;
1123 let Inst{8-6} = iflags;
1125 let Inst{4-0} = mode;
1129 def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
1130 "$imod\t$iflags, $mode">;
1131 let mode = 0, M = 0 in
1132 def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
1134 let imod = 0, iflags = 0, M = 1 in
1135 def CPS1p : CPS<(ins i32imm:$mode), "\t$mode">;
1137 // Preload signals the memory system of possible future data/instruction access.
1138 // These are for disassembly only.
1139 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1141 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1142 !strconcat(opc, "\t$addr"),
1143 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1146 let Inst{31-26} = 0b111101;
1147 let Inst{25} = 0; // 0 for immediate form
1148 let Inst{24} = data;
1149 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1150 let Inst{22} = read;
1151 let Inst{21-20} = 0b01;
1152 let Inst{19-16} = addr{16-13}; // Rn
1153 let Inst{15-12} = 0b1111;
1154 let Inst{11-0} = addr{11-0}; // imm12
1157 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1158 !strconcat(opc, "\t$shift"),
1159 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1161 let Inst{31-26} = 0b111101;
1162 let Inst{25} = 1; // 1 for register form
1163 let Inst{24} = data;
1164 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1165 let Inst{22} = read;
1166 let Inst{21-20} = 0b01;
1167 let Inst{19-16} = shift{16-13}; // Rn
1168 let Inst{15-12} = 0b1111;
1169 let Inst{11-0} = shift{11-0};
1173 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1174 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1175 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1177 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1179 [/* For disassembly only; pattern left blank */]>,
1182 let Inst{31-10} = 0b1111000100000001000000;
1187 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1188 [/* For disassembly only; pattern left blank */]>,
1189 Requires<[IsARM, HasV7]> {
1191 let Inst{27-4} = 0b001100100000111100001111;
1192 let Inst{3-0} = opt;
1195 // A5.4 Permanently UNDEFINED instructions.
1196 let isBarrier = 1, isTerminator = 1 in
1197 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1200 let Inst = 0xe7ffdefe;
1203 // Address computation and loads and stores in PIC mode.
1204 let isNotDuplicable = 1 in {
1205 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1206 Size4Bytes, IIC_iALUr,
1207 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1209 let AddedComplexity = 10 in {
1210 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1211 Size4Bytes, IIC_iLoad_r,
1212 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1214 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1215 Size4Bytes, IIC_iLoad_bh_r,
1216 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1218 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1219 Size4Bytes, IIC_iLoad_bh_r,
1220 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1222 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1223 Size4Bytes, IIC_iLoad_bh_r,
1224 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1226 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1227 Size4Bytes, IIC_iLoad_bh_r,
1228 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1230 let AddedComplexity = 10 in {
1231 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1232 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1234 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1235 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1236 addrmodepc:$addr)]>;
1238 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1239 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1241 } // isNotDuplicable = 1
1244 // LEApcrel - Load a pc-relative address into a register without offending the
1246 let neverHasSideEffects = 1, isReMaterializable = 1 in
1247 // The 'adr' mnemonic encodes differently if the label is before or after
1248 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1249 // know until then which form of the instruction will be used.
1250 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1251 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1254 let Inst{27-25} = 0b001;
1256 let Inst{19-16} = 0b1111;
1257 let Inst{15-12} = Rd;
1258 let Inst{11-0} = label;
1260 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1261 Size4Bytes, IIC_iALUi, []>;
1263 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1264 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1265 Size4Bytes, IIC_iALUi, []>;
1267 //===----------------------------------------------------------------------===//
1268 // Control Flow Instructions.
1271 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1273 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1274 "bx", "\tlr", [(ARMretflag)]>,
1275 Requires<[IsARM, HasV4T]> {
1276 let Inst{27-0} = 0b0001001011111111111100011110;
1280 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1281 "mov", "\tpc, lr", [(ARMretflag)]>,
1282 Requires<[IsARM, NoV4T]> {
1283 let Inst{27-0} = 0b0001101000001111000000001110;
1287 // Indirect branches
1288 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1290 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1291 [(brind GPR:$dst)]>,
1292 Requires<[IsARM, HasV4T]> {
1294 let Inst{31-4} = 0b1110000100101111111111110001;
1295 let Inst{3-0} = dst;
1299 // FIXME: We would really like to define this as a vanilla ARMPat like:
1300 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1301 // With that, however, we can't set isBranch, isTerminator, etc..
1302 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1303 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1304 Requires<[IsARM, NoV4T]>;
1307 // All calls clobber the non-callee saved registers. SP is marked as
1308 // a use to prevent stack-pointer assignments that appear immediately
1309 // before calls from potentially appearing dead.
1311 // On non-Darwin platforms R9 is callee-saved.
1312 // FIXME: Do we really need a non-predicated version? If so, it should
1313 // at least be a pseudo instruction expanding to the predicated version
1314 // at MC lowering time.
1315 Defs = [R0, R1, R2, R3, R12, LR,
1316 D0, D1, D2, D3, D4, D5, D6, D7,
1317 D16, D17, D18, D19, D20, D21, D22, D23,
1318 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1320 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1321 IIC_Br, "bl\t$func",
1322 [(ARMcall tglobaladdr:$func)]>,
1323 Requires<[IsARM, IsNotDarwin]> {
1324 let Inst{31-28} = 0b1110;
1326 let Inst{23-0} = func;
1329 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1330 IIC_Br, "bl", "\t$func",
1331 [(ARMcall_pred tglobaladdr:$func)]>,
1332 Requires<[IsARM, IsNotDarwin]> {
1334 let Inst{23-0} = func;
1338 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1339 IIC_Br, "blx\t$func",
1340 [(ARMcall GPR:$func)]>,
1341 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1343 let Inst{31-4} = 0b1110000100101111111111110011;
1344 let Inst{3-0} = func;
1347 def BLX_pred : AI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1348 IIC_Br, "blx", "\t$func",
1349 [(ARMcall_pred GPR:$func)]>,
1350 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1352 let Inst{27-4} = 0b000100101111111111110011;
1353 let Inst{3-0} = func;
1357 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1358 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1359 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1360 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1363 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1364 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1365 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1369 // On Darwin R9 is call-clobbered.
1370 // R7 is marked as a use to prevent frame-pointer assignments from being
1371 // moved above / below calls.
1372 Defs = [R0, R1, R2, R3, R9, R12, LR,
1373 D0, D1, D2, D3, D4, D5, D6, D7,
1374 D16, D17, D18, D19, D20, D21, D22, D23,
1375 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1376 Uses = [R7, SP] in {
1377 def BLr9 : ARMPseudoInst<(outs), (ins bltarget:$func, variable_ops),
1379 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>;
1381 def BLr9_pred : ARMPseudoInst<(outs),
1382 (ins bltarget:$func, pred:$p, variable_ops),
1384 [(ARMcall_pred tglobaladdr:$func)]>,
1385 Requires<[IsARM, IsDarwin]>;
1388 def BLXr9 : ARMPseudoInst<(outs), (ins GPR:$func, variable_ops),
1390 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]>;
1392 def BLXr9_pred: ARMPseudoInst<(outs), (ins GPR:$func, pred:$p, variable_ops),
1394 [(ARMcall_pred GPR:$func)]>,
1395 Requires<[IsARM, HasV5T, IsDarwin]>;
1398 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1399 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1400 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1401 Requires<[IsARM, HasV4T, IsDarwin]>;
1404 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1405 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1406 Requires<[IsARM, NoV4T, IsDarwin]>;
1411 // FIXME: The Thumb versions of these should live in ARMInstrThumb.td
1412 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1414 let Defs = [R0, R1, R2, R3, R9, R12,
1415 D0, D1, D2, D3, D4, D5, D6, D7,
1416 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1417 D27, D28, D29, D30, D31, PC],
1419 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1420 IIC_Br, []>, Requires<[IsDarwin]>;
1422 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1423 IIC_Br, []>, Requires<[IsDarwin]>;
1425 def TAILJMPd : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
1427 []>, Requires<[IsARM, IsDarwin]>;
1429 def tTAILJMPd: tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
1431 []>, Requires<[IsThumb, IsDarwin]>;
1433 def TAILJMPr : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1435 []>, Requires<[IsARM, IsDarwin]>;
1437 def tTAILJMPr : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1439 []>, Requires<[IsThumb, IsDarwin]>;
1442 // Non-Darwin versions (the difference is R9).
1443 let Defs = [R0, R1, R2, R3, R12,
1444 D0, D1, D2, D3, D4, D5, D6, D7,
1445 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1446 D27, D28, D29, D30, D31, PC],
1448 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1449 IIC_Br, []>, Requires<[IsNotDarwin]>;
1451 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1452 IIC_Br, []>, Requires<[IsNotDarwin]>;
1454 def TAILJMPdND : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
1456 []>, Requires<[IsARM, IsNotDarwin]>;
1458 def tTAILJMPdND : tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
1460 []>, Requires<[IsThumb, IsNotDarwin]>;
1462 def TAILJMPrND : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1464 []>, Requires<[IsARM, IsNotDarwin]>;
1465 def tTAILJMPrND : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1467 []>, Requires<[IsThumb, IsNotDarwin]>;
1471 let isBranch = 1, isTerminator = 1 in {
1472 // B is "predicable" since it's just a Bcc with an 'always' condition.
1473 let isBarrier = 1 in {
1474 let isPredicable = 1 in
1475 // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
1476 // should be sufficient.
1477 def B : ARMPseudoInst<(outs), (ins brtarget:$target), Size4Bytes, IIC_Br,
1480 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1481 def BR_JTr : ARMPseudoInst<(outs),
1482 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1483 SizeSpecial, IIC_Br,
1484 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1485 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1486 // into i12 and rs suffixed versions.
1487 def BR_JTm : ARMPseudoInst<(outs),
1488 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1489 SizeSpecial, IIC_Br,
1490 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1492 def BR_JTadd : ARMPseudoInst<(outs),
1493 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1494 SizeSpecial, IIC_Br,
1495 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1497 } // isNotDuplicable = 1, isIndirectBranch = 1
1500 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1501 // a two-value operand where a dag node expects two operands. :(
1502 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1503 IIC_Br, "b", "\t$target",
1504 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1506 let Inst{23-0} = target;
1510 // Branch and Exchange Jazelle -- for disassembly only
1511 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1512 [/* For disassembly only; pattern left blank */]> {
1513 let Inst{23-20} = 0b0010;
1514 //let Inst{19-8} = 0xfff;
1515 let Inst{7-4} = 0b0010;
1518 // Secure Monitor Call is a system instruction -- for disassembly only
1519 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1520 [/* For disassembly only; pattern left blank */]> {
1522 let Inst{23-4} = 0b01100000000000000111;
1523 let Inst{3-0} = opt;
1526 // Supervisor Call (Software Interrupt) -- for disassembly only
1527 let isCall = 1, Uses = [SP] in {
1528 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1529 [/* For disassembly only; pattern left blank */]> {
1531 let Inst{23-0} = svc;
1535 // Store Return State is a system instruction -- for disassembly only
1536 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1537 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1538 NoItinerary, "srs${amode}\tsp!, $mode",
1539 [/* For disassembly only; pattern left blank */]> {
1540 let Inst{31-28} = 0b1111;
1541 let Inst{22-20} = 0b110; // W = 1
1544 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1545 NoItinerary, "srs${amode}\tsp, $mode",
1546 [/* For disassembly only; pattern left blank */]> {
1547 let Inst{31-28} = 0b1111;
1548 let Inst{22-20} = 0b100; // W = 0
1551 // Return From Exception is a system instruction -- for disassembly only
1552 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1553 NoItinerary, "rfe${amode}\t$base!",
1554 [/* For disassembly only; pattern left blank */]> {
1555 let Inst{31-28} = 0b1111;
1556 let Inst{22-20} = 0b011; // W = 1
1559 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1560 NoItinerary, "rfe${amode}\t$base",
1561 [/* For disassembly only; pattern left blank */]> {
1562 let Inst{31-28} = 0b1111;
1563 let Inst{22-20} = 0b001; // W = 0
1565 } // isCodeGenOnly = 1
1567 //===----------------------------------------------------------------------===//
1568 // Load / store Instructions.
1574 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1575 UnOpFrag<(load node:$Src)>>;
1576 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1577 UnOpFrag<(zextloadi8 node:$Src)>>;
1578 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1579 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1580 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1581 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1583 // Special LDR for loads from non-pc-relative constpools.
1584 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1585 isReMaterializable = 1 in
1586 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1587 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1591 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1592 let Inst{19-16} = 0b1111;
1593 let Inst{15-12} = Rt;
1594 let Inst{11-0} = addr{11-0}; // imm12
1597 // Loads with zero extension
1598 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1599 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1600 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1602 // Loads with sign extension
1603 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1604 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1605 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1607 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1608 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1609 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1611 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1612 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1613 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1614 // how to represent that such that tblgen is happy and we don't
1615 // mark this codegen only?
1617 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1618 (ins addrmode3:$addr), LdMiscFrm,
1619 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1620 []>, Requires<[IsARM, HasV5TE]>;
1624 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1625 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1626 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1627 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1629 // {13} 1 == Rm, 0 == imm12
1633 let Inst{25} = addr{13};
1634 let Inst{23} = addr{12};
1635 let Inst{19-16} = addr{17-14};
1636 let Inst{11-0} = addr{11-0};
1638 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1639 (ins GPR:$Rn, am2offset:$offset),
1640 IndexModePost, LdFrm, itin,
1641 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1642 // {13} 1 == Rm, 0 == imm12
1647 let Inst{25} = offset{13};
1648 let Inst{23} = offset{12};
1649 let Inst{19-16} = Rn;
1650 let Inst{11-0} = offset{11-0};
1654 let mayLoad = 1, neverHasSideEffects = 1 in {
1655 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1656 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1659 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1660 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1661 (ins addrmode3:$addr), IndexModePre,
1663 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1665 let Inst{23} = addr{8}; // U bit
1666 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1667 let Inst{19-16} = addr{12-9}; // Rn
1668 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1669 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1671 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1672 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1674 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1677 let Inst{23} = offset{8}; // U bit
1678 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1679 let Inst{19-16} = Rn;
1680 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1681 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1685 let mayLoad = 1, neverHasSideEffects = 1 in {
1686 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1687 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1688 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1689 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1690 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1691 } // mayLoad = 1, neverHasSideEffects = 1
1693 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1694 let mayLoad = 1, neverHasSideEffects = 1 in {
1695 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1696 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1697 LdFrm, IIC_iLoad_ru,
1698 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1699 let Inst{21} = 1; // overwrite
1701 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1702 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1703 LdFrm, IIC_iLoad_bh_ru,
1704 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1705 let Inst{21} = 1; // overwrite
1707 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1708 (ins GPR:$base, am3offset:$offset), IndexModePost,
1709 LdMiscFrm, IIC_iLoad_bh_ru,
1710 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1711 let Inst{21} = 1; // overwrite
1713 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1714 (ins GPR:$base, am3offset:$offset), IndexModePost,
1715 LdMiscFrm, IIC_iLoad_bh_ru,
1716 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1717 let Inst{21} = 1; // overwrite
1719 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1720 (ins GPR:$base, am3offset:$offset), IndexModePost,
1721 LdMiscFrm, IIC_iLoad_bh_ru,
1722 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1723 let Inst{21} = 1; // overwrite
1729 // Stores with truncate
1730 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1731 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1732 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1735 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1736 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1737 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1738 StMiscFrm, IIC_iStore_d_r,
1739 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1742 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1743 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1744 IndexModePre, StFrm, IIC_iStore_ru,
1745 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1747 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1749 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1750 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1751 IndexModePost, StFrm, IIC_iStore_ru,
1752 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1754 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1756 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1757 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1758 IndexModePre, StFrm, IIC_iStore_bh_ru,
1759 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1760 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1761 GPR:$Rn, am2offset:$offset))]>;
1762 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1763 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1764 IndexModePost, StFrm, IIC_iStore_bh_ru,
1765 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1766 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1767 GPR:$Rn, am2offset:$offset))]>;
1769 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1770 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1771 IndexModePre, StMiscFrm, IIC_iStore_ru,
1772 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1774 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1776 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1777 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1778 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1779 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1780 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1781 GPR:$Rn, am3offset:$offset))]>;
1783 // For disassembly only
1784 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1785 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1786 StMiscFrm, IIC_iStore_d_ru,
1787 "strd", "\t$src1, $src2, [$base, $offset]!",
1788 "$base = $base_wb", []>;
1790 // For disassembly only
1791 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1792 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1793 StMiscFrm, IIC_iStore_d_ru,
1794 "strd", "\t$src1, $src2, [$base], $offset",
1795 "$base = $base_wb", []>;
1797 // STRT, STRBT, and STRHT are for disassembly only.
1799 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1800 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1801 IndexModeNone, StFrm, IIC_iStore_ru,
1802 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1803 [/* For disassembly only; pattern left blank */]> {
1804 let Inst{21} = 1; // overwrite
1807 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1808 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1809 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1810 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1811 [/* For disassembly only; pattern left blank */]> {
1812 let Inst{21} = 1; // overwrite
1815 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1816 (ins GPR:$src, GPR:$base,am3offset:$offset),
1817 StMiscFrm, IIC_iStore_bh_ru,
1818 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1819 [/* For disassembly only; pattern left blank */]> {
1820 let Inst{21} = 1; // overwrite
1823 //===----------------------------------------------------------------------===//
1824 // Load / store multiple Instructions.
1827 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1828 InstrItinClass itin, InstrItinClass itin_upd> {
1830 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1831 IndexModeNone, f, itin,
1832 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1833 let Inst{24-23} = 0b01; // Increment After
1834 let Inst{21} = 0; // No writeback
1835 let Inst{20} = L_bit;
1838 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1839 IndexModeUpd, f, itin_upd,
1840 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1841 let Inst{24-23} = 0b01; // Increment After
1842 let Inst{21} = 1; // Writeback
1843 let Inst{20} = L_bit;
1846 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1847 IndexModeNone, f, itin,
1848 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1849 let Inst{24-23} = 0b00; // Decrement After
1850 let Inst{21} = 0; // No writeback
1851 let Inst{20} = L_bit;
1854 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1855 IndexModeUpd, f, itin_upd,
1856 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1857 let Inst{24-23} = 0b00; // Decrement After
1858 let Inst{21} = 1; // Writeback
1859 let Inst{20} = L_bit;
1862 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1863 IndexModeNone, f, itin,
1864 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1865 let Inst{24-23} = 0b10; // Decrement Before
1866 let Inst{21} = 0; // No writeback
1867 let Inst{20} = L_bit;
1870 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1871 IndexModeUpd, f, itin_upd,
1872 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1873 let Inst{24-23} = 0b10; // Decrement Before
1874 let Inst{21} = 1; // Writeback
1875 let Inst{20} = L_bit;
1878 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1879 IndexModeNone, f, itin,
1880 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1881 let Inst{24-23} = 0b11; // Increment Before
1882 let Inst{21} = 0; // No writeback
1883 let Inst{20} = L_bit;
1886 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1887 IndexModeUpd, f, itin_upd,
1888 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1889 let Inst{24-23} = 0b11; // Increment Before
1890 let Inst{21} = 1; // Writeback
1891 let Inst{20} = L_bit;
1895 let neverHasSideEffects = 1 in {
1897 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1898 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1900 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1901 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1903 } // neverHasSideEffects
1905 // Load / Store Multiple Mnemonic Aliases
1906 def : MnemonicAlias<"ldm", "ldmia">;
1907 def : MnemonicAlias<"stm", "stmia">;
1909 // FIXME: remove when we have a way to marking a MI with these properties.
1910 // FIXME: Should pc be an implicit operand like PICADD, etc?
1911 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1912 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1913 def LDMIA_RET : ARMPseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1914 reglist:$regs, variable_ops),
1915 Size4Bytes, IIC_iLoad_mBr, []>,
1916 RegConstraint<"$Rn = $wb">;
1918 //===----------------------------------------------------------------------===//
1919 // Move Instructions.
1922 let neverHasSideEffects = 1 in
1923 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1924 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1928 let Inst{11-4} = 0b00000000;
1931 let Inst{15-12} = Rd;
1934 // A version for the smaller set of tail call registers.
1935 let neverHasSideEffects = 1 in
1936 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1937 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1941 let Inst{11-4} = 0b00000000;
1944 let Inst{15-12} = Rd;
1947 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1948 DPSoRegFrm, IIC_iMOVsr,
1949 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1953 let Inst{15-12} = Rd;
1954 let Inst{11-0} = src;
1958 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1959 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1960 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1964 let Inst{15-12} = Rd;
1965 let Inst{19-16} = 0b0000;
1966 let Inst{11-0} = imm;
1969 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1970 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1972 "movw", "\t$Rd, $imm",
1973 [(set GPR:$Rd, imm0_65535:$imm)]>,
1974 Requires<[IsARM, HasV6T2]>, UnaryDP {
1977 let Inst{15-12} = Rd;
1978 let Inst{11-0} = imm{11-0};
1979 let Inst{19-16} = imm{15-12};
1984 def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1985 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1987 let Constraints = "$src = $Rd" in {
1988 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1990 "movt", "\t$Rd, $imm",
1992 (or (and GPR:$src, 0xffff),
1993 lo16AllZero:$imm))]>, UnaryDP,
1994 Requires<[IsARM, HasV6T2]> {
1997 let Inst{15-12} = Rd;
1998 let Inst{11-0} = imm{11-0};
1999 let Inst{19-16} = imm{15-12};
2004 def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2005 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2009 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2010 Requires<[IsARM, HasV6T2]>;
2012 let Uses = [CPSR] in
2013 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2014 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2017 // These aren't really mov instructions, but we have to define them this way
2018 // due to flag operands.
2020 let Defs = [CPSR] in {
2021 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2022 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2024 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2025 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2029 //===----------------------------------------------------------------------===//
2030 // Extend Instructions.
2035 defm SXTB : AI_ext_rrot<0b01101010,
2036 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2037 defm SXTH : AI_ext_rrot<0b01101011,
2038 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2040 defm SXTAB : AI_exta_rrot<0b01101010,
2041 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2042 defm SXTAH : AI_exta_rrot<0b01101011,
2043 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2045 // For disassembly only
2046 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2048 // For disassembly only
2049 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2053 let AddedComplexity = 16 in {
2054 defm UXTB : AI_ext_rrot<0b01101110,
2055 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2056 defm UXTH : AI_ext_rrot<0b01101111,
2057 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2058 defm UXTB16 : AI_ext_rrot<0b01101100,
2059 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2061 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2062 // The transformation should probably be done as a combiner action
2063 // instead so we can include a check for masking back in the upper
2064 // eight bits of the source into the lower eight bits of the result.
2065 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2066 // (UXTB16r_rot GPR:$Src, 24)>;
2067 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2068 (UXTB16r_rot GPR:$Src, 8)>;
2070 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2071 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2072 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2073 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2076 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2077 // For disassembly only
2078 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2081 def SBFX : I<(outs GPR:$Rd),
2082 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2083 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2084 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2085 Requires<[IsARM, HasV6T2]> {
2090 let Inst{27-21} = 0b0111101;
2091 let Inst{6-4} = 0b101;
2092 let Inst{20-16} = width;
2093 let Inst{15-12} = Rd;
2094 let Inst{11-7} = lsb;
2098 def UBFX : I<(outs GPR:$Rd),
2099 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2100 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2101 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2102 Requires<[IsARM, HasV6T2]> {
2107 let Inst{27-21} = 0b0111111;
2108 let Inst{6-4} = 0b101;
2109 let Inst{20-16} = width;
2110 let Inst{15-12} = Rd;
2111 let Inst{11-7} = lsb;
2115 //===----------------------------------------------------------------------===//
2116 // Arithmetic Instructions.
2119 defm ADD : AsI1_bin_irs<0b0100, "add",
2120 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2121 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2122 defm SUB : AsI1_bin_irs<0b0010, "sub",
2123 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2124 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2126 // ADD and SUB with 's' bit set.
2127 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2128 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2129 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2130 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2131 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2132 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2134 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2135 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2136 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2137 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2139 // ADC and SUBC with 's' bit set.
2140 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2141 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2142 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2143 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2145 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2146 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2147 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2152 let Inst{15-12} = Rd;
2153 let Inst{19-16} = Rn;
2154 let Inst{11-0} = imm;
2157 // The reg/reg form is only defined for the disassembler; for codegen it is
2158 // equivalent to SUBrr.
2159 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2160 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2161 [/* For disassembly only; pattern left blank */]> {
2165 let Inst{11-4} = 0b00000000;
2168 let Inst{15-12} = Rd;
2169 let Inst{19-16} = Rn;
2172 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2173 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2174 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2179 let Inst{11-0} = shift;
2180 let Inst{15-12} = Rd;
2181 let Inst{19-16} = Rn;
2184 // RSB with 's' bit set.
2185 let isCodeGenOnly = 1, Defs = [CPSR] in {
2186 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2187 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2188 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2194 let Inst{15-12} = Rd;
2195 let Inst{19-16} = Rn;
2196 let Inst{11-0} = imm;
2198 def RSBSrr : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2199 IIC_iALUr, "rsbs", "\t$Rd, $Rn, $Rm",
2200 [/* For disassembly only; pattern left blank */]> {
2204 let Inst{11-4} = 0b00000000;
2208 let Inst{15-12} = Rd;
2209 let Inst{19-16} = Rn;
2211 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2212 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2213 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2219 let Inst{11-0} = shift;
2220 let Inst{15-12} = Rd;
2221 let Inst{19-16} = Rn;
2225 let Uses = [CPSR] in {
2226 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2227 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2228 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2234 let Inst{15-12} = Rd;
2235 let Inst{19-16} = Rn;
2236 let Inst{11-0} = imm;
2238 // The reg/reg form is only defined for the disassembler; for codegen it is
2239 // equivalent to SUBrr.
2240 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2241 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2242 [/* For disassembly only; pattern left blank */]> {
2246 let Inst{11-4} = 0b00000000;
2249 let Inst{15-12} = Rd;
2250 let Inst{19-16} = Rn;
2252 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2253 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2254 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2260 let Inst{11-0} = shift;
2261 let Inst{15-12} = Rd;
2262 let Inst{19-16} = Rn;
2266 // FIXME: Allow these to be predicated.
2267 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2268 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2269 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2270 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2277 let Inst{15-12} = Rd;
2278 let Inst{19-16} = Rn;
2279 let Inst{11-0} = imm;
2281 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2282 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2283 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2290 let Inst{11-0} = shift;
2291 let Inst{15-12} = Rd;
2292 let Inst{19-16} = Rn;
2296 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2297 // The assume-no-carry-in form uses the negation of the input since add/sub
2298 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2299 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2301 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2302 (SUBri GPR:$src, so_imm_neg:$imm)>;
2303 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2304 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2305 // The with-carry-in form matches bitwise not instead of the negation.
2306 // Effectively, the inverse interpretation of the carry flag already accounts
2307 // for part of the negation.
2308 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2309 (SBCri GPR:$src, so_imm_not:$imm)>;
2311 // Note: These are implemented in C++ code, because they have to generate
2312 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2314 // (mul X, 2^n+1) -> (add (X << n), X)
2315 // (mul X, 2^n-1) -> (rsb X, (X << n))
2317 // ARM Arithmetic Instruction -- for disassembly only
2318 // GPR:$dst = GPR:$a op GPR:$b
2319 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2320 list<dag> pattern = [/* For disassembly only; pattern left blank */],
2321 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm">
2322 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
2326 let Inst{27-20} = op27_20;
2327 let Inst{11-4} = op11_4;
2328 let Inst{19-16} = Rn;
2329 let Inst{15-12} = Rd;
2333 // Saturating add/subtract -- for disassembly only
2335 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2336 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))],
2337 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2338 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2339 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))],
2340 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2341 def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn),
2343 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn),
2346 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2347 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2348 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2349 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2350 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2351 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2352 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2353 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2354 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2355 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2356 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2357 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2359 // Signed/Unsigned add/subtract -- for disassembly only
2361 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2362 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2363 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2364 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2365 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2366 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2367 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2368 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2369 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2370 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2371 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2372 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2374 // Signed/Unsigned halving add/subtract -- for disassembly only
2376 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2377 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2378 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2379 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2380 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2381 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2382 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2383 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2384 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2385 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2386 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2387 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2389 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2391 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2392 MulFrm /* for convenience */, NoItinerary, "usad8",
2393 "\t$Rd, $Rn, $Rm", []>,
2394 Requires<[IsARM, HasV6]> {
2398 let Inst{27-20} = 0b01111000;
2399 let Inst{15-12} = 0b1111;
2400 let Inst{7-4} = 0b0001;
2401 let Inst{19-16} = Rd;
2402 let Inst{11-8} = Rm;
2405 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2406 MulFrm /* for convenience */, NoItinerary, "usada8",
2407 "\t$Rd, $Rn, $Rm, $Ra", []>,
2408 Requires<[IsARM, HasV6]> {
2413 let Inst{27-20} = 0b01111000;
2414 let Inst{7-4} = 0b0001;
2415 let Inst{19-16} = Rd;
2416 let Inst{15-12} = Ra;
2417 let Inst{11-8} = Rm;
2421 // Signed/Unsigned saturate -- for disassembly only
2423 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2424 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2425 [/* For disassembly only; pattern left blank */]> {
2430 let Inst{27-21} = 0b0110101;
2431 let Inst{5-4} = 0b01;
2432 let Inst{20-16} = sat_imm;
2433 let Inst{15-12} = Rd;
2434 let Inst{11-7} = sh{7-3};
2435 let Inst{6} = sh{0};
2439 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2440 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2441 [/* For disassembly only; pattern left blank */]> {
2445 let Inst{27-20} = 0b01101010;
2446 let Inst{11-4} = 0b11110011;
2447 let Inst{15-12} = Rd;
2448 let Inst{19-16} = sat_imm;
2452 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2453 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2454 [/* For disassembly only; pattern left blank */]> {
2459 let Inst{27-21} = 0b0110111;
2460 let Inst{5-4} = 0b01;
2461 let Inst{15-12} = Rd;
2462 let Inst{11-7} = sh{7-3};
2463 let Inst{6} = sh{0};
2464 let Inst{20-16} = sat_imm;
2468 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2469 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2470 [/* For disassembly only; pattern left blank */]> {
2474 let Inst{27-20} = 0b01101110;
2475 let Inst{11-4} = 0b11110011;
2476 let Inst{15-12} = Rd;
2477 let Inst{19-16} = sat_imm;
2481 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2482 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2484 //===----------------------------------------------------------------------===//
2485 // Bitwise Instructions.
2488 defm AND : AsI1_bin_irs<0b0000, "and",
2489 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2490 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2491 defm ORR : AsI1_bin_irs<0b1100, "orr",
2492 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2493 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2494 defm EOR : AsI1_bin_irs<0b0001, "eor",
2495 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2496 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2497 defm BIC : AsI1_bin_irs<0b1110, "bic",
2498 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2499 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2501 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2502 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2503 "bfc", "\t$Rd, $imm", "$src = $Rd",
2504 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2505 Requires<[IsARM, HasV6T2]> {
2508 let Inst{27-21} = 0b0111110;
2509 let Inst{6-0} = 0b0011111;
2510 let Inst{15-12} = Rd;
2511 let Inst{11-7} = imm{4-0}; // lsb
2512 let Inst{20-16} = imm{9-5}; // width
2515 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2516 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2517 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2518 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2519 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2520 bf_inv_mask_imm:$imm))]>,
2521 Requires<[IsARM, HasV6T2]> {
2525 let Inst{27-21} = 0b0111110;
2526 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2527 let Inst{15-12} = Rd;
2528 let Inst{11-7} = imm{4-0}; // lsb
2529 let Inst{20-16} = imm{9-5}; // width
2533 // GNU as only supports this form of bfi (w/ 4 arguments)
2534 let isAsmParserOnly = 1 in
2535 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2536 lsb_pos_imm:$lsb, width_imm:$width),
2537 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2538 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2539 []>, Requires<[IsARM, HasV6T2]> {
2544 let Inst{27-21} = 0b0111110;
2545 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2546 let Inst{15-12} = Rd;
2547 let Inst{11-7} = lsb;
2548 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2552 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2553 "mvn", "\t$Rd, $Rm",
2554 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2558 let Inst{19-16} = 0b0000;
2559 let Inst{11-4} = 0b00000000;
2560 let Inst{15-12} = Rd;
2563 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2564 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2565 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2569 let Inst{19-16} = 0b0000;
2570 let Inst{15-12} = Rd;
2571 let Inst{11-0} = shift;
2573 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2574 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2575 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2576 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2580 let Inst{19-16} = 0b0000;
2581 let Inst{15-12} = Rd;
2582 let Inst{11-0} = imm;
2585 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2586 (BICri GPR:$src, so_imm_not:$imm)>;
2588 //===----------------------------------------------------------------------===//
2589 // Multiply Instructions.
2591 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2592 string opc, string asm, list<dag> pattern>
2593 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2597 let Inst{19-16} = Rd;
2598 let Inst{11-8} = Rm;
2601 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2602 string opc, string asm, list<dag> pattern>
2603 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2608 let Inst{19-16} = RdHi;
2609 let Inst{15-12} = RdLo;
2610 let Inst{11-8} = Rm;
2614 let isCommutable = 1 in {
2615 let Constraints = "@earlyclobber $Rd" in
2616 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2617 pred:$p, cc_out:$s),
2618 Size4Bytes, IIC_iMUL32,
2619 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2620 Requires<[IsARM, NoV6]>;
2622 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2623 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2624 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2625 Requires<[IsARM, HasV6]>;
2628 let Constraints = "@earlyclobber $Rd" in
2629 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2630 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2631 Size4Bytes, IIC_iMAC32,
2632 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2633 Requires<[IsARM, NoV6]> {
2635 let Inst{15-12} = Ra;
2637 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2638 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2639 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2640 Requires<[IsARM, HasV6]> {
2642 let Inst{15-12} = Ra;
2645 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2646 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2647 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2648 Requires<[IsARM, HasV6T2]> {
2653 let Inst{19-16} = Rd;
2654 let Inst{15-12} = Ra;
2655 let Inst{11-8} = Rm;
2659 // Extra precision multiplies with low / high results
2661 let neverHasSideEffects = 1 in {
2662 let isCommutable = 1 in {
2663 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2664 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2665 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2666 Size4Bytes, IIC_iMUL64, []>,
2667 Requires<[IsARM, NoV6]>;
2669 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2670 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2671 Size4Bytes, IIC_iMUL64, []>,
2672 Requires<[IsARM, NoV6]>;
2675 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2676 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2677 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2678 Requires<[IsARM, HasV6]>;
2680 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2681 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2682 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2683 Requires<[IsARM, HasV6]>;
2686 // Multiply + accumulate
2687 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2688 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2689 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2690 Size4Bytes, IIC_iMAC64, []>,
2691 Requires<[IsARM, NoV6]>;
2692 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2693 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2694 Size4Bytes, IIC_iMAC64, []>,
2695 Requires<[IsARM, NoV6]>;
2696 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2697 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2698 Size4Bytes, IIC_iMAC64, []>,
2699 Requires<[IsARM, NoV6]>;
2703 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2704 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2705 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2706 Requires<[IsARM, HasV6]>;
2707 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2708 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2709 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2710 Requires<[IsARM, HasV6]>;
2712 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2713 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2714 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2715 Requires<[IsARM, HasV6]> {
2720 let Inst{19-16} = RdLo;
2721 let Inst{15-12} = RdHi;
2722 let Inst{11-8} = Rm;
2725 } // neverHasSideEffects
2727 // Most significant word multiply
2728 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2729 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2730 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2731 Requires<[IsARM, HasV6]> {
2732 let Inst{15-12} = 0b1111;
2735 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2736 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2737 [/* For disassembly only; pattern left blank */]>,
2738 Requires<[IsARM, HasV6]> {
2739 let Inst{15-12} = 0b1111;
2742 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2743 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2744 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2745 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2746 Requires<[IsARM, HasV6]>;
2748 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2749 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2750 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2751 [/* For disassembly only; pattern left blank */]>,
2752 Requires<[IsARM, HasV6]>;
2754 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2755 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2756 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2757 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2758 Requires<[IsARM, HasV6]>;
2760 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2761 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2762 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2763 [/* For disassembly only; pattern left blank */]>,
2764 Requires<[IsARM, HasV6]>;
2766 multiclass AI_smul<string opc, PatFrag opnode> {
2767 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2768 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2769 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2770 (sext_inreg GPR:$Rm, i16)))]>,
2771 Requires<[IsARM, HasV5TE]>;
2773 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2774 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2775 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2776 (sra GPR:$Rm, (i32 16))))]>,
2777 Requires<[IsARM, HasV5TE]>;
2779 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2780 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2781 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2782 (sext_inreg GPR:$Rm, i16)))]>,
2783 Requires<[IsARM, HasV5TE]>;
2785 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2786 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2787 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2788 (sra GPR:$Rm, (i32 16))))]>,
2789 Requires<[IsARM, HasV5TE]>;
2791 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2792 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2793 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2794 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2795 Requires<[IsARM, HasV5TE]>;
2797 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2798 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2799 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2800 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2801 Requires<[IsARM, HasV5TE]>;
2805 multiclass AI_smla<string opc, PatFrag opnode> {
2806 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2807 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2808 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2809 [(set GPR:$Rd, (add GPR:$Ra,
2810 (opnode (sext_inreg GPR:$Rn, i16),
2811 (sext_inreg GPR:$Rm, i16))))]>,
2812 Requires<[IsARM, HasV5TE]>;
2814 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2815 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2816 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2817 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2818 (sra GPR:$Rm, (i32 16)))))]>,
2819 Requires<[IsARM, HasV5TE]>;
2821 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2822 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2823 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2824 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2825 (sext_inreg GPR:$Rm, i16))))]>,
2826 Requires<[IsARM, HasV5TE]>;
2828 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2829 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2830 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2831 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2832 (sra GPR:$Rm, (i32 16)))))]>,
2833 Requires<[IsARM, HasV5TE]>;
2835 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2836 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2837 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2838 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2839 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2840 Requires<[IsARM, HasV5TE]>;
2842 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2843 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2844 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2845 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2846 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2847 Requires<[IsARM, HasV5TE]>;
2850 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2851 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2853 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2854 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2855 (ins GPR:$Rn, GPR:$Rm),
2856 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2857 [/* For disassembly only; pattern left blank */]>,
2858 Requires<[IsARM, HasV5TE]>;
2860 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2861 (ins GPR:$Rn, GPR:$Rm),
2862 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2863 [/* For disassembly only; pattern left blank */]>,
2864 Requires<[IsARM, HasV5TE]>;
2866 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2867 (ins GPR:$Rn, GPR:$Rm),
2868 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2869 [/* For disassembly only; pattern left blank */]>,
2870 Requires<[IsARM, HasV5TE]>;
2872 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2873 (ins GPR:$Rn, GPR:$Rm),
2874 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2875 [/* For disassembly only; pattern left blank */]>,
2876 Requires<[IsARM, HasV5TE]>;
2878 // Helper class for AI_smld -- for disassembly only
2879 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2880 InstrItinClass itin, string opc, string asm>
2881 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2888 let Inst{21-20} = 0b00;
2889 let Inst{22} = long;
2890 let Inst{27-23} = 0b01110;
2891 let Inst{11-8} = Rm;
2894 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2895 InstrItinClass itin, string opc, string asm>
2896 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2898 let Inst{15-12} = 0b1111;
2899 let Inst{19-16} = Rd;
2901 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2902 InstrItinClass itin, string opc, string asm>
2903 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2905 let Inst{15-12} = Ra;
2907 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2908 InstrItinClass itin, string opc, string asm>
2909 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2912 let Inst{19-16} = RdHi;
2913 let Inst{15-12} = RdLo;
2916 multiclass AI_smld<bit sub, string opc> {
2918 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2919 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2921 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2922 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2924 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2925 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2926 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2928 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2929 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2930 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2934 defm SMLA : AI_smld<0, "smla">;
2935 defm SMLS : AI_smld<1, "smls">;
2937 multiclass AI_sdml<bit sub, string opc> {
2939 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2940 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2941 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2942 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2945 defm SMUA : AI_sdml<0, "smua">;
2946 defm SMUS : AI_sdml<1, "smus">;
2948 //===----------------------------------------------------------------------===//
2949 // Misc. Arithmetic Instructions.
2952 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2953 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2954 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2956 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2957 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2958 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2959 Requires<[IsARM, HasV6T2]>;
2961 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2962 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2963 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2965 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2966 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2968 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2969 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2970 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2971 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2972 Requires<[IsARM, HasV6]>;
2974 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2975 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2978 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2979 (shl GPR:$Rm, (i32 8))), i16))]>,
2980 Requires<[IsARM, HasV6]>;
2982 def lsl_shift_imm : SDNodeXForm<imm, [{
2983 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2984 return CurDAG->getTargetConstant(Sh, MVT::i32);
2987 def lsl_amt : PatLeaf<(i32 imm), [{
2988 return (N->getZExtValue() < 32);
2991 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2992 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2993 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2994 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2995 (and (shl GPR:$Rm, lsl_amt:$sh),
2997 Requires<[IsARM, HasV6]>;
2999 // Alternate cases for PKHBT where identities eliminate some nodes.
3000 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
3001 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
3002 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
3003 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
3005 def asr_shift_imm : SDNodeXForm<imm, [{
3006 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
3007 return CurDAG->getTargetConstant(Sh, MVT::i32);
3010 def asr_amt : PatLeaf<(i32 imm), [{
3011 return (N->getZExtValue() <= 32);
3014 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3015 // will match the pattern below.
3016 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
3017 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
3018 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3019 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
3020 (and (sra GPR:$Rm, asr_amt:$sh),
3022 Requires<[IsARM, HasV6]>;
3024 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
3025 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
3026 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
3027 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
3028 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
3029 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
3030 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
3032 //===----------------------------------------------------------------------===//
3033 // Comparison Instructions...
3036 defm CMP : AI1_cmp_irs<0b1010, "cmp",
3037 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3038 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3040 // ARMcmpZ can re-use the above instruction definitions.
3041 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3042 (CMPri GPR:$src, so_imm:$imm)>;
3043 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3044 (CMPrr GPR:$src, GPR:$rhs)>;
3045 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
3046 (CMPrs GPR:$src, so_reg:$rhs)>;
3048 // FIXME: We have to be careful when using the CMN instruction and comparison
3049 // with 0. One would expect these two pieces of code should give identical
3065 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3066 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3067 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3068 // value of r0 and the carry bit (because the "carry bit" parameter to
3069 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3070 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3071 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3072 // parameter to AddWithCarry is defined as 0).
3074 // When x is 0 and unsigned:
3078 // ~x + 1 = 0x1 0000 0000
3079 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3081 // Therefore, we should disable CMN when comparing against zero, until we can
3082 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3083 // when it's a comparison which doesn't look at the 'carry' flag).
3085 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3087 // This is related to <rdar://problem/7569620>.
3089 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3090 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3092 // Note that TST/TEQ don't set all the same flags that CMP does!
3093 defm TST : AI1_cmp_irs<0b1000, "tst",
3094 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3095 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3096 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3097 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3098 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3100 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3101 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3102 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3104 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3105 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3107 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3108 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3110 // Pseudo i64 compares for some floating point compares.
3111 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3113 def BCCi64 : PseudoInst<(outs),
3114 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3116 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3118 def BCCZi64 : PseudoInst<(outs),
3119 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3120 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3121 } // usesCustomInserter
3124 // Conditional moves
3125 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3126 // a two-value operand where a dag node expects two operands. :(
3127 let neverHasSideEffects = 1 in {
3128 def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p),
3129 Size4Bytes, IIC_iCMOVr,
3130 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3131 RegConstraint<"$false = $Rd">;
3132 def MOVCCs : ARMPseudoInst<(outs GPR:$Rd),
3133 (ins GPR:$false, so_reg:$shift, pred:$p),
3134 Size4Bytes, IIC_iCMOVsr,
3135 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3136 RegConstraint<"$false = $Rd">;
3138 let isMoveImm = 1 in
3139 def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd),
3140 (ins GPR:$false, i32imm_hilo16:$imm, pred:$p),
3141 Size4Bytes, IIC_iMOVi,
3143 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>;
3145 let isMoveImm = 1 in
3146 def MOVCCi : ARMPseudoInst<(outs GPR:$Rd),
3147 (ins GPR:$false, so_imm:$imm, pred:$p),
3148 Size4Bytes, IIC_iCMOVi,
3149 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3150 RegConstraint<"$false = $Rd">;
3152 // Two instruction predicate mov immediate.
3153 let isMoveImm = 1 in
3154 def MOVCCi32imm : ARMPseudoInst<(outs GPR:$Rd),
3155 (ins GPR:$false, i32imm:$src, pred:$p),
3156 Size8Bytes, IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3158 let isMoveImm = 1 in
3159 def MVNCCi : ARMPseudoInst<(outs GPR:$Rd),
3160 (ins GPR:$false, so_imm:$imm, pred:$p),
3161 Size4Bytes, IIC_iCMOVi,
3162 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3163 RegConstraint<"$false = $Rd">;
3164 } // neverHasSideEffects
3166 //===----------------------------------------------------------------------===//
3167 // Atomic operations intrinsics
3170 def memb_opt : Operand<i32> {
3171 let PrintMethod = "printMemBOption";
3172 let ParserMatchClass = MemBarrierOptOperand;
3175 // memory barriers protect the atomic sequences
3176 let hasSideEffects = 1 in {
3177 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3178 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3179 Requires<[IsARM, HasDB]> {
3181 let Inst{31-4} = 0xf57ff05;
3182 let Inst{3-0} = opt;
3186 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3188 [/* For disassembly only; pattern left blank */]>,
3189 Requires<[IsARM, HasDB]> {
3191 let Inst{31-4} = 0xf57ff04;
3192 let Inst{3-0} = opt;
3195 // ISB has only full system option -- for disassembly only
3196 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3197 Requires<[IsARM, HasDB]> {
3198 let Inst{31-4} = 0xf57ff06;
3199 let Inst{3-0} = 0b1111;
3202 let usesCustomInserter = 1 in {
3203 let Uses = [CPSR] in {
3204 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3205 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3206 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3207 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3208 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3209 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3210 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3211 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3212 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3213 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3214 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3215 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3216 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3217 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3218 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3219 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3220 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3221 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3222 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3223 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3224 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3225 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3226 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3227 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3228 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3229 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3230 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3231 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3232 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3233 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3234 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3235 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3236 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3237 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3238 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3239 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3240 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3241 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3242 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3243 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3244 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3245 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3246 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3247 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3248 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3249 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3250 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3251 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3252 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3253 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3254 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3255 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3256 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3257 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3259 def ATOMIC_SWAP_I8 : PseudoInst<
3260 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3261 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3262 def ATOMIC_SWAP_I16 : PseudoInst<
3263 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3264 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3265 def ATOMIC_SWAP_I32 : PseudoInst<
3266 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3267 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3269 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3270 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3271 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3272 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3273 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3274 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3275 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3276 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3277 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3281 let mayLoad = 1 in {
3282 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3283 "ldrexb", "\t$Rt, [$Rn]",
3285 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3286 "ldrexh", "\t$Rt, [$Rn]",
3288 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3289 "ldrex", "\t$Rt, [$Rn]",
3291 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3293 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3297 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3298 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3300 "strexb", "\t$Rd, $src, [$Rn]",
3302 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3304 "strexh", "\t$Rd, $Rt, [$Rn]",
3306 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3308 "strex", "\t$Rd, $Rt, [$Rn]",
3310 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3311 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3313 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3317 // Clear-Exclusive is for disassembly only.
3318 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3319 [/* For disassembly only; pattern left blank */]>,
3320 Requires<[IsARM, HasV7]> {
3321 let Inst{31-0} = 0b11110101011111111111000000011111;
3324 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3325 let mayLoad = 1 in {
3326 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3327 [/* For disassembly only; pattern left blank */]>;
3328 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3329 [/* For disassembly only; pattern left blank */]>;
3332 //===----------------------------------------------------------------------===//
3333 // Coprocessor Instructions.
3336 def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3337 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3338 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3339 [/* For disassembly only; pattern left blank */]> {
3347 let Inst{3-0} = CRm;
3349 let Inst{7-5} = opc2;
3350 let Inst{11-8} = cop;
3351 let Inst{15-12} = CRd;
3352 let Inst{19-16} = CRn;
3353 let Inst{23-20} = opc1;
3356 def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3357 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3358 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3359 [/* For disassembly only; pattern left blank */]> {
3360 let Inst{31-28} = 0b1111;
3368 let Inst{3-0} = CRm;
3370 let Inst{7-5} = opc2;
3371 let Inst{11-8} = cop;
3372 let Inst{15-12} = CRd;
3373 let Inst{19-16} = CRn;
3374 let Inst{23-20} = opc1;
3377 class ACI<dag oops, dag iops, string opc, string asm>
3378 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3379 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3380 let Inst{27-25} = 0b110;
3383 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3385 def _OFFSET : ACI<(outs),
3386 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3387 opc, "\tp$cop, cr$CRd, $addr"> {
3388 let Inst{31-28} = op31_28;
3389 let Inst{24} = 1; // P = 1
3390 let Inst{21} = 0; // W = 0
3391 let Inst{22} = 0; // D = 0
3392 let Inst{20} = load;
3395 def _PRE : ACI<(outs),
3396 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3397 opc, "\tp$cop, cr$CRd, $addr!"> {
3398 let Inst{31-28} = op31_28;
3399 let Inst{24} = 1; // P = 1
3400 let Inst{21} = 1; // W = 1
3401 let Inst{22} = 0; // D = 0
3402 let Inst{20} = load;
3405 def _POST : ACI<(outs),
3406 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3407 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3408 let Inst{31-28} = op31_28;
3409 let Inst{24} = 0; // P = 0
3410 let Inst{21} = 1; // W = 1
3411 let Inst{22} = 0; // D = 0
3412 let Inst{20} = load;
3415 def _OPTION : ACI<(outs),
3416 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3417 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3418 let Inst{31-28} = op31_28;
3419 let Inst{24} = 0; // P = 0
3420 let Inst{23} = 1; // U = 1
3421 let Inst{21} = 0; // W = 0
3422 let Inst{22} = 0; // D = 0
3423 let Inst{20} = load;
3426 def L_OFFSET : ACI<(outs),
3427 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3428 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3429 let Inst{31-28} = op31_28;
3430 let Inst{24} = 1; // P = 1
3431 let Inst{21} = 0; // W = 0
3432 let Inst{22} = 1; // D = 1
3433 let Inst{20} = load;
3436 def L_PRE : ACI<(outs),
3437 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3438 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3439 let Inst{31-28} = op31_28;
3440 let Inst{24} = 1; // P = 1
3441 let Inst{21} = 1; // W = 1
3442 let Inst{22} = 1; // D = 1
3443 let Inst{20} = load;
3446 def L_POST : ACI<(outs),
3447 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3448 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3449 let Inst{31-28} = op31_28;
3450 let Inst{24} = 0; // P = 0
3451 let Inst{21} = 1; // W = 1
3452 let Inst{22} = 1; // D = 1
3453 let Inst{20} = load;
3456 def L_OPTION : ACI<(outs),
3457 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3458 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3459 let Inst{31-28} = op31_28;
3460 let Inst{24} = 0; // P = 0
3461 let Inst{23} = 1; // U = 1
3462 let Inst{21} = 0; // W = 0
3463 let Inst{22} = 1; // D = 1
3464 let Inst{20} = load;
3468 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3469 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3470 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3471 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3473 //===----------------------------------------------------------------------===//
3474 // Move between coprocessor and ARM core register -- for disassembly only
3477 class MovRCopro<string opc, bit direction>
3478 : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3479 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3480 NoItinerary, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3481 [/* For disassembly only; pattern left blank */]> {
3482 let Inst{20} = direction;
3492 let Inst{15-12} = Rt;
3493 let Inst{11-8} = cop;
3494 let Inst{23-21} = opc1;
3495 let Inst{7-5} = opc2;
3496 let Inst{3-0} = CRm;
3497 let Inst{19-16} = CRn;
3500 def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */>;
3501 def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */>;
3503 class MovRCopro2<string opc, bit direction>
3504 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3505 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3506 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3507 [/* For disassembly only; pattern left blank */]> {
3508 let Inst{31-28} = 0b1111;
3509 let Inst{20} = direction;
3519 let Inst{15-12} = Rt;
3520 let Inst{11-8} = cop;
3521 let Inst{23-21} = opc1;
3522 let Inst{7-5} = opc2;
3523 let Inst{3-0} = CRm;
3524 let Inst{19-16} = CRn;
3527 def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */>;
3528 def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */>;
3530 class MovRRCopro<string opc, bit direction>
3531 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3532 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3533 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
3534 [/* For disassembly only; pattern left blank */]> {
3535 let Inst{23-21} = 0b010;
3536 let Inst{20} = direction;
3544 let Inst{15-12} = Rt;
3545 let Inst{19-16} = Rt2;
3546 let Inst{11-8} = cop;
3547 let Inst{7-4} = opc1;
3548 let Inst{3-0} = CRm;
3551 def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
3552 def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
3554 class MovRRCopro2<string opc, bit direction>
3555 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3556 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3557 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3558 [/* For disassembly only; pattern left blank */]> {
3559 let Inst{31-28} = 0b1111;
3560 let Inst{23-21} = 0b010;
3561 let Inst{20} = direction;
3569 let Inst{15-12} = Rt;
3570 let Inst{19-16} = Rt2;
3571 let Inst{11-8} = cop;
3572 let Inst{7-4} = opc1;
3573 let Inst{3-0} = CRm;
3576 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
3577 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
3579 //===----------------------------------------------------------------------===//
3580 // Move between special register and ARM core register -- for disassembly only
3583 // Move to ARM core register from Special Register
3584 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3585 [/* For disassembly only; pattern left blank */]> {
3587 let Inst{23-16} = 0b00001111;
3588 let Inst{15-12} = Rd;
3589 let Inst{7-4} = 0b0000;
3592 def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr",
3593 [/* For disassembly only; pattern left blank */]> {
3595 let Inst{23-16} = 0b01001111;
3596 let Inst{15-12} = Rd;
3597 let Inst{7-4} = 0b0000;
3600 // Move from ARM core register to Special Register
3602 // No need to have both system and application versions, the encodings are the
3603 // same and the assembly parser has no way to distinguish between them. The mask
3604 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3605 // the mask with the fields to be accessed in the special register.
3606 def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
3607 "msr", "\t$mask, $Rn",
3608 [/* For disassembly only; pattern left blank */]> {
3613 let Inst{22} = mask{4}; // R bit
3614 let Inst{21-20} = 0b10;
3615 let Inst{19-16} = mask{3-0};
3616 let Inst{15-12} = 0b1111;
3617 let Inst{11-4} = 0b00000000;
3621 def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary,
3622 "msr", "\t$mask, $a",
3623 [/* For disassembly only; pattern left blank */]> {
3628 let Inst{22} = mask{4}; // R bit
3629 let Inst{21-20} = 0b10;
3630 let Inst{19-16} = mask{3-0};
3631 let Inst{15-12} = 0b1111;
3635 //===----------------------------------------------------------------------===//
3639 // __aeabi_read_tp preserves the registers r1-r3.
3640 // This is a pseudo inst so that we can get the encoding right,
3641 // complete with fixup for the aeabi_read_tp function.
3643 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3644 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3645 [(set R0, ARMthread_pointer)]>;
3648 //===----------------------------------------------------------------------===//
3649 // SJLJ Exception handling intrinsics
3650 // eh_sjlj_setjmp() is an instruction sequence to store the return
3651 // address and save #0 in R0 for the non-longjmp case.
3652 // Since by its nature we may be coming from some other function to get
3653 // here, and we're using the stack frame for the containing function to
3654 // save/restore registers, we can't keep anything live in regs across
3655 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3656 // when we get here from a longjmp(). We force everthing out of registers
3657 // except for our own input by listing the relevant registers in Defs. By
3658 // doing so, we also cause the prologue/epilogue code to actively preserve
3659 // all of the callee-saved resgisters, which is exactly what we want.
3660 // A constant value is passed in $val, and we use the location as a scratch.
3662 // These are pseudo-instructions and are lowered to individual MC-insts, so
3663 // no encoding information is necessary.
3665 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3666 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3667 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3668 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3669 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3671 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3672 Requires<[IsARM, HasVFP2]>;
3676 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3677 hasSideEffects = 1, isBarrier = 1 in {
3678 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3680 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3681 Requires<[IsARM, NoVFP]>;
3684 // FIXME: Non-Darwin version(s)
3685 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3686 Defs = [ R7, LR, SP ] in {
3687 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3689 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3690 Requires<[IsARM, IsDarwin]>;
3693 // eh.sjlj.dispatchsetup pseudo-instruction.
3694 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3695 // handled when the pseudo is expanded (which happens before any passes
3696 // that need the instruction size).
3697 let isBarrier = 1, hasSideEffects = 1 in
3698 def Int_eh_sjlj_dispatchsetup :
3699 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3700 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3701 Requires<[IsDarwin]>;
3703 //===----------------------------------------------------------------------===//
3704 // Non-Instruction Patterns
3707 // Large immediate handling.
3709 // 32-bit immediate using two piece so_imms or movw + movt.
3710 // This is a single pseudo instruction, the benefit is that it can be remat'd
3711 // as a single unit instead of having to handle reg inputs.
3712 // FIXME: Remove this when we can do generalized remat.
3713 let isReMaterializable = 1, isMoveImm = 1 in
3714 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3715 [(set GPR:$dst, (arm_i32imm:$src))]>,
3718 // Pseudo instruction that combines movw + movt + add pc (if PIC).
3719 // It also makes it possible to rematerialize the instructions.
3720 // FIXME: Remove this when we can do generalized remat and when machine licm
3721 // can properly the instructions.
3722 let isReMaterializable = 1 in {
3723 def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3725 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3726 Requires<[IsARM, UseMovt]>;
3728 def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3730 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3731 Requires<[IsARM, UseMovt]>;
3733 let AddedComplexity = 10 in
3734 def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3736 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
3737 Requires<[IsARM, UseMovt]>;
3738 } // isReMaterializable
3740 // ConstantPool, GlobalAddress, and JumpTable
3741 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3742 Requires<[IsARM, DontUseMovt]>;
3743 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3744 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3745 Requires<[IsARM, UseMovt]>;
3746 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3747 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3749 // TODO: add,sub,and, 3-instr forms?
3752 def : ARMPat<(ARMtcret tcGPR:$dst),
3753 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3755 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3756 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3758 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3759 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3761 def : ARMPat<(ARMtcret tcGPR:$dst),
3762 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3764 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3765 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3767 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3768 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3771 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3772 Requires<[IsARM, IsNotDarwin]>;
3773 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3774 Requires<[IsARM, IsDarwin]>;
3776 // zextload i1 -> zextload i8
3777 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3778 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3780 // extload -> zextload
3781 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3782 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3783 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3784 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3786 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3788 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3789 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3792 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3793 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3794 (SMULBB GPR:$a, GPR:$b)>;
3795 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3796 (SMULBB GPR:$a, GPR:$b)>;
3797 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3798 (sra GPR:$b, (i32 16))),
3799 (SMULBT GPR:$a, GPR:$b)>;
3800 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3801 (SMULBT GPR:$a, GPR:$b)>;
3802 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3803 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3804 (SMULTB GPR:$a, GPR:$b)>;
3805 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3806 (SMULTB GPR:$a, GPR:$b)>;
3807 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3809 (SMULWB GPR:$a, GPR:$b)>;
3810 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3811 (SMULWB GPR:$a, GPR:$b)>;
3813 def : ARMV5TEPat<(add GPR:$acc,
3814 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3815 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3816 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3817 def : ARMV5TEPat<(add GPR:$acc,
3818 (mul sext_16_node:$a, sext_16_node:$b)),
3819 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3820 def : ARMV5TEPat<(add GPR:$acc,
3821 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3822 (sra GPR:$b, (i32 16)))),
3823 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3824 def : ARMV5TEPat<(add GPR:$acc,
3825 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3826 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3827 def : ARMV5TEPat<(add GPR:$acc,
3828 (mul (sra GPR:$a, (i32 16)),
3829 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3830 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3831 def : ARMV5TEPat<(add GPR:$acc,
3832 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3833 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3834 def : ARMV5TEPat<(add GPR:$acc,
3835 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3837 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3838 def : ARMV5TEPat<(add GPR:$acc,
3839 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3840 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3843 // Pre-v7 uses MCR for synchronization barriers.
3844 def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>,
3845 Requires<[IsARM, HasV6]>;
3848 //===----------------------------------------------------------------------===//
3852 include "ARMInstrThumb.td"
3854 //===----------------------------------------------------------------------===//
3858 include "ARMInstrThumb2.td"
3860 //===----------------------------------------------------------------------===//
3861 // Floating Point Support
3864 include "ARMInstrVFP.td"
3866 //===----------------------------------------------------------------------===//
3867 // Advanced SIMD (NEON) Support
3870 include "ARMInstrNEON.td"