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 ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
73 def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntBinOp>;
75 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
76 [SDNPHasChain, SDNPOutGlue]>;
77 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
78 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
80 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
81 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
83 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
84 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
86 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
87 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
90 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
91 [SDNPHasChain, SDNPOptInGlue]>;
93 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
95 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
98 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
99 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
101 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
103 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
106 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
109 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
112 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
113 [SDNPOutGlue, SDNPCommutative]>;
115 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
117 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
118 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
119 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
121 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
122 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
123 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
124 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
125 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
126 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
127 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
130 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
132 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
134 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
135 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
137 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
139 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
140 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
143 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
145 //===----------------------------------------------------------------------===//
146 // ARM Instruction Predicate Definitions.
148 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
149 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
150 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
151 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
152 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
153 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
154 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
155 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
156 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
157 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
158 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
159 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
160 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
161 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
162 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
163 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
165 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
167 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
169 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
170 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
171 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
172 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
173 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
174 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
175 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
176 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
178 // FIXME: Eventually this will be just "hasV6T2Ops".
179 def UseMovt : Predicate<"Subtarget->useMovt()">;
180 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
181 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
183 //===----------------------------------------------------------------------===//
184 // ARM Flag Definitions.
186 class RegConstraint<string C> {
187 string Constraints = C;
190 //===----------------------------------------------------------------------===//
191 // ARM specific transformation functions and pattern fragments.
194 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
195 // so_imm_neg def below.
196 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
197 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
200 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
201 // so_imm_not def below.
202 def so_imm_not_XFORM : SDNodeXForm<imm, [{
203 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
206 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
207 def imm1_15 : PatLeaf<(i32 imm), [{
208 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
211 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
212 def imm16_31 : PatLeaf<(i32 imm), [{
213 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
218 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
219 }], so_imm_neg_XFORM>;
223 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
224 }], so_imm_not_XFORM>;
226 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
227 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
228 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
231 /// Split a 32-bit immediate into two 16 bit parts.
232 def hi16 : SDNodeXForm<imm, [{
233 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
236 def lo16AllZero : PatLeaf<(i32 imm), [{
237 // Returns true if all low 16-bits are 0.
238 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
241 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
243 def imm0_65535 : PatLeaf<(i32 imm), [{
244 return (uint32_t)N->getZExtValue() < 65536;
247 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
248 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
250 /// adde and sube predicates - True based on whether the carry flag output
251 /// will be needed or not.
252 def adde_dead_carry :
253 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
254 [{return !N->hasAnyUseOfValue(1);}]>;
255 def sube_dead_carry :
256 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
257 [{return !N->hasAnyUseOfValue(1);}]>;
258 def adde_live_carry :
259 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
260 [{return N->hasAnyUseOfValue(1);}]>;
261 def sube_live_carry :
262 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
263 [{return N->hasAnyUseOfValue(1);}]>;
265 // An 'and' node with a single use.
266 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
267 return N->hasOneUse();
270 // An 'xor' node with a single use.
271 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
272 return N->hasOneUse();
275 // An 'fmul' node with a single use.
276 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
277 return N->hasOneUse();
280 // An 'fadd' node which checks for single non-hazardous use.
281 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
282 return hasNoVMLxHazardUse(N);
285 // An 'fsub' node which checks for single non-hazardous use.
286 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
287 return hasNoVMLxHazardUse(N);
290 //===----------------------------------------------------------------------===//
291 // Operand Definitions.
295 def brtarget : Operand<OtherVT> {
296 let EncoderMethod = "getBranchTargetOpValue";
299 def uncondbrtarget : Operand<OtherVT> {
300 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
304 def bltarget : Operand<i32> {
305 // Encoded the same as branch targets.
306 let EncoderMethod = "getBranchTargetOpValue";
309 // A list of registers separated by comma. Used by load/store multiple.
310 def RegListAsmOperand : AsmOperandClass {
311 let Name = "RegList";
312 let SuperClasses = [];
315 def DPRRegListAsmOperand : AsmOperandClass {
316 let Name = "DPRRegList";
317 let SuperClasses = [];
320 def SPRRegListAsmOperand : AsmOperandClass {
321 let Name = "SPRRegList";
322 let SuperClasses = [];
325 def reglist : Operand<i32> {
326 let EncoderMethod = "getRegisterListOpValue";
327 let ParserMatchClass = RegListAsmOperand;
328 let PrintMethod = "printRegisterList";
331 def dpr_reglist : Operand<i32> {
332 let EncoderMethod = "getRegisterListOpValue";
333 let ParserMatchClass = DPRRegListAsmOperand;
334 let PrintMethod = "printRegisterList";
337 def spr_reglist : Operand<i32> {
338 let EncoderMethod = "getRegisterListOpValue";
339 let ParserMatchClass = SPRRegListAsmOperand;
340 let PrintMethod = "printRegisterList";
343 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
344 def cpinst_operand : Operand<i32> {
345 let PrintMethod = "printCPInstOperand";
349 def pclabel : Operand<i32> {
350 let PrintMethod = "printPCLabel";
353 // ADR instruction labels.
354 def adrlabel : Operand<i32> {
355 let EncoderMethod = "getAdrLabelOpValue";
358 def neon_vcvt_imm32 : Operand<i32> {
359 let EncoderMethod = "getNEONVcvtImm32OpValue";
362 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
363 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
364 int32_t v = (int32_t)N->getZExtValue();
365 return v == 8 || v == 16 || v == 24; }]> {
366 let EncoderMethod = "getRotImmOpValue";
369 // shift_imm: An integer that encodes a shift amount and the type of shift
370 // (currently either asr or lsl) using the same encoding used for the
371 // immediates in so_reg operands.
372 def shift_imm : Operand<i32> {
373 let PrintMethod = "printShiftImmOperand";
376 // shifter_operand operands: so_reg and so_imm.
377 def so_reg : Operand<i32>, // reg reg imm
378 ComplexPattern<i32, 3, "SelectShifterOperandReg",
379 [shl,srl,sra,rotr]> {
380 let EncoderMethod = "getSORegOpValue";
381 let PrintMethod = "printSORegOperand";
382 let MIOperandInfo = (ops GPR, GPR, i32imm);
384 def shift_so_reg : Operand<i32>, // reg reg imm
385 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
386 [shl,srl,sra,rotr]> {
387 let EncoderMethod = "getSORegOpValue";
388 let PrintMethod = "printSORegOperand";
389 let MIOperandInfo = (ops GPR, GPR, i32imm);
392 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
393 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
394 // represented in the imm field in the same 12-bit form that they are encoded
395 // into so_imm instructions: the 8-bit immediate is the least significant bits
396 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
397 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
398 let EncoderMethod = "getSOImmOpValue";
399 let PrintMethod = "printSOImmOperand";
402 // Break so_imm's up into two pieces. This handles immediates with up to 16
403 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
404 // get the first/second pieces.
405 def so_imm2part : PatLeaf<(imm), [{
406 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
409 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
411 def arm_i32imm : PatLeaf<(imm), [{
412 if (Subtarget->hasV6T2Ops())
414 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
417 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
418 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
419 return (int32_t)N->getZExtValue() < 32;
422 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
423 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
424 return (int32_t)N->getZExtValue() < 32;
426 let EncoderMethod = "getImmMinusOneOpValue";
429 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
430 // The imm is split into imm{15-12}, imm{11-0}
432 def i32imm_hilo16 : Operand<i32> {
433 let EncoderMethod = "getHiLo16ImmOpValue";
436 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
438 def bf_inv_mask_imm : Operand<i32>,
440 return ARM::isBitFieldInvertedMask(N->getZExtValue());
442 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
443 let PrintMethod = "printBitfieldInvMaskImmOperand";
446 /// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
447 def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
448 return isInt<5>(N->getSExtValue());
451 /// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
452 def width_imm : Operand<i32>, PatLeaf<(imm), [{
453 return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
455 let EncoderMethod = "getMsbOpValue";
458 // Define ARM specific addressing modes.
461 // addrmode_imm12 := reg +/- imm12
463 def addrmode_imm12 : Operand<i32>,
464 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
465 // 12-bit immediate operand. Note that instructions using this encode
466 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
467 // immediate values are as normal.
469 let EncoderMethod = "getAddrModeImm12OpValue";
470 let PrintMethod = "printAddrModeImm12Operand";
471 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
473 // ldst_so_reg := reg +/- reg shop imm
475 def ldst_so_reg : Operand<i32>,
476 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
477 let EncoderMethod = "getLdStSORegOpValue";
478 // FIXME: Simplify the printer
479 let PrintMethod = "printAddrMode2Operand";
480 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
483 // addrmode2 := reg +/- imm12
484 // := reg +/- reg shop imm
486 def addrmode2 : Operand<i32>,
487 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
488 let EncoderMethod = "getAddrMode2OpValue";
489 let PrintMethod = "printAddrMode2Operand";
490 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
493 def am2offset : Operand<i32>,
494 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
495 [], [SDNPWantRoot]> {
496 let EncoderMethod = "getAddrMode2OffsetOpValue";
497 let PrintMethod = "printAddrMode2OffsetOperand";
498 let MIOperandInfo = (ops GPR, i32imm);
501 // addrmode3 := reg +/- reg
502 // addrmode3 := reg +/- imm8
504 def addrmode3 : Operand<i32>,
505 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
506 let EncoderMethod = "getAddrMode3OpValue";
507 let PrintMethod = "printAddrMode3Operand";
508 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
511 def am3offset : Operand<i32>,
512 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
513 [], [SDNPWantRoot]> {
514 let EncoderMethod = "getAddrMode3OffsetOpValue";
515 let PrintMethod = "printAddrMode3OffsetOperand";
516 let MIOperandInfo = (ops GPR, i32imm);
519 // ldstm_mode := {ia, ib, da, db}
521 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
522 let EncoderMethod = "getLdStmModeOpValue";
523 let PrintMethod = "printLdStmModeOperand";
526 def MemMode5AsmOperand : AsmOperandClass {
527 let Name = "MemMode5";
528 let SuperClasses = [];
531 // addrmode5 := reg +/- imm8*4
533 def addrmode5 : Operand<i32>,
534 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
535 let PrintMethod = "printAddrMode5Operand";
536 let MIOperandInfo = (ops GPR:$base, i32imm);
537 let ParserMatchClass = MemMode5AsmOperand;
538 let EncoderMethod = "getAddrMode5OpValue";
541 // addrmode6 := reg with optional writeback
543 def addrmode6 : Operand<i32>,
544 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
545 let PrintMethod = "printAddrMode6Operand";
546 let MIOperandInfo = (ops GPR:$addr, i32imm);
547 let EncoderMethod = "getAddrMode6AddressOpValue";
550 def am6offset : Operand<i32> {
551 let PrintMethod = "printAddrMode6OffsetOperand";
552 let MIOperandInfo = (ops GPR);
553 let EncoderMethod = "getAddrMode6OffsetOpValue";
556 // Special version of addrmode6 to handle alignment encoding for VLD-dup
557 // instructions, specifically VLD4-dup.
558 def addrmode6dup : Operand<i32>,
559 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
560 let PrintMethod = "printAddrMode6Operand";
561 let MIOperandInfo = (ops GPR:$addr, i32imm);
562 let EncoderMethod = "getAddrMode6DupAddressOpValue";
565 // addrmodepc := pc + reg
567 def addrmodepc : Operand<i32>,
568 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
569 let PrintMethod = "printAddrModePCOperand";
570 let MIOperandInfo = (ops GPR, i32imm);
573 def nohash_imm : Operand<i32> {
574 let PrintMethod = "printNoHashImmediate";
577 def p_imm : Operand<i32> {
578 let PrintMethod = "printPImmediate";
581 def c_imm : Operand<i32> {
582 let PrintMethod = "printCImmediate";
585 //===----------------------------------------------------------------------===//
587 include "ARMInstrFormats.td"
589 //===----------------------------------------------------------------------===//
590 // Multiclass helpers...
593 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
594 /// binop that produces a value.
595 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
596 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
597 PatFrag opnode, bit Commutable = 0> {
598 // The register-immediate version is re-materializable. This is useful
599 // in particular for taking the address of a local.
600 let isReMaterializable = 1 in {
601 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
602 iii, opc, "\t$Rd, $Rn, $imm",
603 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
608 let Inst{19-16} = Rn;
609 let Inst{15-12} = Rd;
610 let Inst{11-0} = imm;
613 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
614 iir, opc, "\t$Rd, $Rn, $Rm",
615 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
620 let isCommutable = Commutable;
621 let Inst{19-16} = Rn;
622 let Inst{15-12} = Rd;
623 let Inst{11-4} = 0b00000000;
626 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
627 iis, opc, "\t$Rd, $Rn, $shift",
628 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
633 let Inst{19-16} = Rn;
634 let Inst{15-12} = Rd;
635 let Inst{11-0} = shift;
639 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
640 /// instruction modifies the CPSR register.
641 let isCodeGenOnly = 1, Defs = [CPSR] in {
642 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
643 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
644 PatFrag opnode, bit Commutable = 0> {
645 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
646 iii, opc, "\t$Rd, $Rn, $imm",
647 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
653 let Inst{19-16} = Rn;
654 let Inst{15-12} = Rd;
655 let Inst{11-0} = imm;
657 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
658 iir, opc, "\t$Rd, $Rn, $Rm",
659 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
663 let isCommutable = Commutable;
666 let Inst{19-16} = Rn;
667 let Inst{15-12} = Rd;
668 let Inst{11-4} = 0b00000000;
671 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
672 iis, opc, "\t$Rd, $Rn, $shift",
673 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
679 let Inst{19-16} = Rn;
680 let Inst{15-12} = Rd;
681 let Inst{11-0} = shift;
686 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
687 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
688 /// a explicit result, only implicitly set CPSR.
689 let isCompare = 1, Defs = [CPSR] in {
690 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
691 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
692 PatFrag opnode, bit Commutable = 0> {
693 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
695 [(opnode GPR:$Rn, so_imm:$imm)]> {
700 let Inst{19-16} = Rn;
701 let Inst{15-12} = 0b0000;
702 let Inst{11-0} = imm;
704 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
706 [(opnode GPR:$Rn, GPR:$Rm)]> {
709 let isCommutable = Commutable;
712 let Inst{19-16} = Rn;
713 let Inst{15-12} = 0b0000;
714 let Inst{11-4} = 0b00000000;
717 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
718 opc, "\t$Rn, $shift",
719 [(opnode GPR:$Rn, so_reg:$shift)]> {
724 let Inst{19-16} = Rn;
725 let Inst{15-12} = 0b0000;
726 let Inst{11-0} = shift;
731 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
732 /// register and one whose operand is a register rotated by 8/16/24.
733 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
734 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
735 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
736 IIC_iEXTr, opc, "\t$Rd, $Rm",
737 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
738 Requires<[IsARM, HasV6]> {
741 let Inst{19-16} = 0b1111;
742 let Inst{15-12} = Rd;
743 let Inst{11-10} = 0b00;
746 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
747 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
748 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
749 Requires<[IsARM, HasV6]> {
753 let Inst{19-16} = 0b1111;
754 let Inst{15-12} = Rd;
755 let Inst{11-10} = rot;
760 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
761 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
762 IIC_iEXTr, opc, "\t$Rd, $Rm",
763 [/* For disassembly only; pattern left blank */]>,
764 Requires<[IsARM, HasV6]> {
765 let Inst{19-16} = 0b1111;
766 let Inst{11-10} = 0b00;
768 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
769 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
770 [/* For disassembly only; pattern left blank */]>,
771 Requires<[IsARM, HasV6]> {
773 let Inst{19-16} = 0b1111;
774 let Inst{11-10} = rot;
778 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
779 /// register and one whose operand is a register rotated by 8/16/24.
780 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
781 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
782 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
783 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
784 Requires<[IsARM, HasV6]> {
788 let Inst{19-16} = Rn;
789 let Inst{15-12} = Rd;
790 let Inst{11-10} = 0b00;
791 let Inst{9-4} = 0b000111;
794 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
796 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
797 [(set GPR:$Rd, (opnode GPR:$Rn,
798 (rotr GPR:$Rm, rot_imm:$rot)))]>,
799 Requires<[IsARM, HasV6]> {
804 let Inst{19-16} = Rn;
805 let Inst{15-12} = Rd;
806 let Inst{11-10} = rot;
807 let Inst{9-4} = 0b000111;
812 // For disassembly only.
813 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
814 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
815 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
816 [/* For disassembly only; pattern left blank */]>,
817 Requires<[IsARM, HasV6]> {
818 let Inst{11-10} = 0b00;
820 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
822 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
823 [/* For disassembly only; pattern left blank */]>,
824 Requires<[IsARM, HasV6]> {
827 let Inst{19-16} = Rn;
828 let Inst{11-10} = rot;
832 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
833 let Uses = [CPSR] in {
834 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
835 bit Commutable = 0> {
836 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
837 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
838 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
844 let Inst{15-12} = Rd;
845 let Inst{19-16} = Rn;
846 let Inst{11-0} = imm;
848 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
849 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
850 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
855 let Inst{11-4} = 0b00000000;
857 let isCommutable = Commutable;
859 let Inst{15-12} = Rd;
860 let Inst{19-16} = Rn;
862 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
863 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
864 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
870 let Inst{11-0} = shift;
871 let Inst{15-12} = Rd;
872 let Inst{19-16} = Rn;
875 // Carry setting variants
876 let isCodeGenOnly = 1, Defs = [CPSR] in {
877 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
878 bit Commutable = 0> {
879 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
880 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
881 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
886 let Inst{15-12} = Rd;
887 let Inst{19-16} = Rn;
888 let Inst{11-0} = imm;
892 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
893 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
894 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
899 let Inst{11-4} = 0b00000000;
900 let isCommutable = Commutable;
902 let Inst{15-12} = Rd;
903 let Inst{19-16} = Rn;
907 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
908 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
909 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
914 let Inst{11-0} = shift;
915 let Inst{15-12} = Rd;
916 let Inst{19-16} = Rn;
924 let canFoldAsLoad = 1, isReMaterializable = 1 in {
925 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
926 InstrItinClass iir, PatFrag opnode> {
927 // Note: We use the complex addrmode_imm12 rather than just an input
928 // GPR and a constrained immediate so that we can use this to match
929 // frame index references and avoid matching constant pool references.
930 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
931 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
932 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
935 let Inst{23} = addr{12}; // U (add = ('U' == 1))
936 let Inst{19-16} = addr{16-13}; // Rn
937 let Inst{15-12} = Rt;
938 let Inst{11-0} = addr{11-0}; // imm12
940 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
941 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
942 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
945 let Inst{23} = shift{12}; // U (add = ('U' == 1))
946 let Inst{19-16} = shift{16-13}; // Rn
947 let Inst{15-12} = Rt;
948 let Inst{11-0} = shift{11-0};
953 multiclass AI_str1<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, 0, isByte, (outs),
959 (ins GPR:$Rt, addrmode_imm12:$addr),
960 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
961 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
964 let Inst{23} = addr{12}; // U (add = ('U' == 1))
965 let Inst{19-16} = addr{16-13}; // Rn
966 let Inst{15-12} = Rt;
967 let Inst{11-0} = addr{11-0}; // imm12
969 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
970 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
971 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
974 let Inst{23} = shift{12}; // U (add = ('U' == 1))
975 let Inst{19-16} = shift{16-13}; // Rn
976 let Inst{15-12} = Rt;
977 let Inst{11-0} = shift{11-0};
980 //===----------------------------------------------------------------------===//
982 //===----------------------------------------------------------------------===//
984 //===----------------------------------------------------------------------===//
985 // Miscellaneous Instructions.
988 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
989 /// the function. The first operand is the ID# for this instruction, the second
990 /// is the index into the MachineConstantPool that this is, the third is the
991 /// size in bytes of this constant pool entry.
992 let neverHasSideEffects = 1, isNotDuplicable = 1 in
993 def CONSTPOOL_ENTRY :
994 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
995 i32imm:$size), NoItinerary, []>;
997 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
998 // from removing one half of the matched pairs. That breaks PEI, which assumes
999 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1000 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1001 def ADJCALLSTACKUP :
1002 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1003 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1005 def ADJCALLSTACKDOWN :
1006 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1007 [(ARMcallseq_start timm:$amt)]>;
1010 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
1011 [/* For disassembly only; pattern left blank */]>,
1012 Requires<[IsARM, HasV6T2]> {
1013 let Inst{27-16} = 0b001100100000;
1014 let Inst{15-8} = 0b11110000;
1015 let Inst{7-0} = 0b00000000;
1018 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1019 [/* For disassembly only; pattern left blank */]>,
1020 Requires<[IsARM, HasV6T2]> {
1021 let Inst{27-16} = 0b001100100000;
1022 let Inst{15-8} = 0b11110000;
1023 let Inst{7-0} = 0b00000001;
1026 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1027 [/* For disassembly only; pattern left blank */]>,
1028 Requires<[IsARM, HasV6T2]> {
1029 let Inst{27-16} = 0b001100100000;
1030 let Inst{15-8} = 0b11110000;
1031 let Inst{7-0} = 0b00000010;
1034 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1035 [/* For disassembly only; pattern left blank */]>,
1036 Requires<[IsARM, HasV6T2]> {
1037 let Inst{27-16} = 0b001100100000;
1038 let Inst{15-8} = 0b11110000;
1039 let Inst{7-0} = 0b00000011;
1042 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1044 [/* For disassembly only; pattern left blank */]>,
1045 Requires<[IsARM, HasV6]> {
1050 let Inst{15-12} = Rd;
1051 let Inst{19-16} = Rn;
1052 let Inst{27-20} = 0b01101000;
1053 let Inst{7-4} = 0b1011;
1054 let Inst{11-8} = 0b1111;
1057 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1058 [/* For disassembly only; pattern left blank */]>,
1059 Requires<[IsARM, HasV6T2]> {
1060 let Inst{27-16} = 0b001100100000;
1061 let Inst{15-8} = 0b11110000;
1062 let Inst{7-0} = 0b00000100;
1065 // The i32imm operand $val can be used by a debugger to store more information
1066 // about the breakpoint.
1067 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1068 [/* For disassembly only; pattern left blank */]>,
1071 let Inst{3-0} = val{3-0};
1072 let Inst{19-8} = val{15-4};
1073 let Inst{27-20} = 0b00010010;
1074 let Inst{7-4} = 0b0111;
1077 // Change Processor State is a system instruction -- for disassembly only.
1078 // The singleton $opt operand contains the following information:
1079 // opt{4-0} = mode from Inst{4-0}
1080 // opt{5} = changemode from Inst{17}
1081 // opt{8-6} = AIF from Inst{8-6}
1082 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1083 // FIXME: Integrated assembler will need these split out.
1084 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1085 [/* For disassembly only; pattern left blank */]>,
1087 let Inst{31-28} = 0b1111;
1088 let Inst{27-20} = 0b00010000;
1093 // Preload signals the memory system of possible future data/instruction access.
1094 // These are for disassembly only.
1095 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1097 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1098 !strconcat(opc, "\t$addr"),
1099 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1102 let Inst{31-26} = 0b111101;
1103 let Inst{25} = 0; // 0 for immediate form
1104 let Inst{24} = data;
1105 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1106 let Inst{22} = read;
1107 let Inst{21-20} = 0b01;
1108 let Inst{19-16} = addr{16-13}; // Rn
1109 let Inst{15-12} = Rt;
1110 let Inst{11-0} = addr{11-0}; // imm12
1113 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1114 !strconcat(opc, "\t$shift"),
1115 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1118 let Inst{31-26} = 0b111101;
1119 let Inst{25} = 1; // 1 for register form
1120 let Inst{24} = data;
1121 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1122 let Inst{22} = read;
1123 let Inst{21-20} = 0b01;
1124 let Inst{19-16} = shift{16-13}; // Rn
1125 let Inst{11-0} = shift{11-0};
1129 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1130 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1131 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1133 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1135 [/* For disassembly only; pattern left blank */]>,
1138 let Inst{31-10} = 0b1111000100000001000000;
1143 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1144 [/* For disassembly only; pattern left blank */]>,
1145 Requires<[IsARM, HasV7]> {
1147 let Inst{27-4} = 0b001100100000111100001111;
1148 let Inst{3-0} = opt;
1151 // A5.4 Permanently UNDEFINED instructions.
1152 let isBarrier = 1, isTerminator = 1 in
1153 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1156 let Inst = 0xe7ffdefe;
1159 // Address computation and loads and stores in PIC mode.
1160 let isNotDuplicable = 1 in {
1161 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1162 Size4Bytes, IIC_iALUr,
1163 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1165 let AddedComplexity = 10 in {
1166 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1167 Size4Bytes, IIC_iLoad_r,
1168 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1170 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1171 Size4Bytes, IIC_iLoad_bh_r,
1172 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1174 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1175 Size4Bytes, IIC_iLoad_bh_r,
1176 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1178 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1179 Size4Bytes, IIC_iLoad_bh_r,
1180 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1182 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1183 Size4Bytes, IIC_iLoad_bh_r,
1184 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1186 let AddedComplexity = 10 in {
1187 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1188 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1190 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1191 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1192 addrmodepc:$addr)]>;
1194 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1195 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1197 } // isNotDuplicable = 1
1200 // LEApcrel - Load a pc-relative address into a register without offending the
1202 let neverHasSideEffects = 1, isReMaterializable = 1 in
1203 // The 'adr' mnemonic encodes differently if the label is before or after
1204 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1205 // know until then which form of the instruction will be used.
1206 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1207 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1210 let Inst{27-25} = 0b001;
1212 let Inst{19-16} = 0b1111;
1213 let Inst{15-12} = Rd;
1214 let Inst{11-0} = label;
1216 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1217 Size4Bytes, IIC_iALUi, []>;
1219 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1220 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1221 Size4Bytes, IIC_iALUi, []>;
1223 //===----------------------------------------------------------------------===//
1224 // Control Flow Instructions.
1227 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1229 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1230 "bx", "\tlr", [(ARMretflag)]>,
1231 Requires<[IsARM, HasV4T]> {
1232 let Inst{27-0} = 0b0001001011111111111100011110;
1236 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1237 "mov", "\tpc, lr", [(ARMretflag)]>,
1238 Requires<[IsARM, NoV4T]> {
1239 let Inst{27-0} = 0b0001101000001111000000001110;
1243 // Indirect branches
1244 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1246 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1247 [(brind GPR:$dst)]>,
1248 Requires<[IsARM, HasV4T]> {
1250 let Inst{31-4} = 0b1110000100101111111111110001;
1251 let Inst{3-0} = dst;
1255 // FIXME: We would really like to define this as a vanilla ARMPat like:
1256 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1257 // With that, however, we can't set isBranch, isTerminator, etc..
1258 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1259 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1260 Requires<[IsARM, NoV4T]>;
1263 // All calls clobber the non-callee saved registers. SP is marked as
1264 // a use to prevent stack-pointer assignments that appear immediately
1265 // before calls from potentially appearing dead.
1267 // On non-Darwin platforms R9 is callee-saved.
1268 Defs = [R0, R1, R2, R3, R12, LR,
1269 D0, D1, D2, D3, D4, D5, D6, D7,
1270 D16, D17, D18, D19, D20, D21, D22, D23,
1271 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1273 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1274 IIC_Br, "bl\t$func",
1275 [(ARMcall tglobaladdr:$func)]>,
1276 Requires<[IsARM, IsNotDarwin]> {
1277 let Inst{31-28} = 0b1110;
1279 let Inst{23-0} = func;
1282 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1283 IIC_Br, "bl", "\t$func",
1284 [(ARMcall_pred tglobaladdr:$func)]>,
1285 Requires<[IsARM, IsNotDarwin]> {
1287 let Inst{23-0} = func;
1291 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1292 IIC_Br, "blx\t$func",
1293 [(ARMcall GPR:$func)]>,
1294 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1296 let Inst{31-4} = 0b1110000100101111111111110011;
1297 let Inst{3-0} = func;
1301 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1302 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1303 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1304 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1307 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1308 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1309 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1313 // On Darwin R9 is call-clobbered.
1314 // R7 is marked as a use to prevent frame-pointer assignments from being
1315 // moved above / below calls.
1316 Defs = [R0, R1, R2, R3, R9, R12, LR,
1317 D0, D1, D2, D3, D4, D5, D6, D7,
1318 D16, D17, D18, D19, D20, D21, D22, D23,
1319 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1320 Uses = [R7, SP] in {
1321 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1322 IIC_Br, "bl\t$func",
1323 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1324 let Inst{31-28} = 0b1110;
1326 let Inst{23-0} = func;
1329 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1330 IIC_Br, "bl", "\t$func",
1331 [(ARMcall_pred tglobaladdr:$func)]>,
1332 Requires<[IsARM, IsDarwin]> {
1334 let Inst{23-0} = func;
1338 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1339 IIC_Br, "blx\t$func",
1340 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1342 let Inst{31-4} = 0b1110000100101111111111110011;
1343 let Inst{3-0} = func;
1347 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1348 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1349 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1350 Requires<[IsARM, HasV4T, IsDarwin]>;
1353 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1354 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1355 Requires<[IsARM, NoV4T, IsDarwin]>;
1360 // FIXME: These should probably be xformed into the non-TC versions of the
1361 // instructions as part of MC lowering.
1362 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1363 // Thumb should have its own version since the instruction is actually
1364 // different, even though the mnemonic is the same.
1365 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1367 let Defs = [R0, R1, R2, R3, R9, R12,
1368 D0, D1, D2, D3, D4, D5, D6, D7,
1369 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1370 D27, D28, D29, D30, D31, PC],
1372 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1373 IIC_Br, []>, Requires<[IsDarwin]>;
1375 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1376 IIC_Br, []>, Requires<[IsDarwin]>;
1378 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1379 IIC_Br, "b\t$dst @ TAILCALL",
1380 []>, Requires<[IsARM, IsDarwin]>;
1382 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1383 IIC_Br, "b.w\t$dst @ TAILCALL",
1384 []>, Requires<[IsThumb, IsDarwin]>;
1386 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1387 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1388 []>, Requires<[IsDarwin]> {
1390 let Inst{31-4} = 0b1110000100101111111111110001;
1391 let Inst{3-0} = dst;
1395 // Non-Darwin versions (the difference is R9).
1396 let Defs = [R0, R1, R2, R3, R12,
1397 D0, D1, D2, D3, D4, D5, D6, D7,
1398 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1399 D27, D28, D29, D30, D31, PC],
1401 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1402 IIC_Br, []>, Requires<[IsNotDarwin]>;
1404 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1405 IIC_Br, []>, Requires<[IsNotDarwin]>;
1407 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1408 IIC_Br, "b\t$dst @ TAILCALL",
1409 []>, Requires<[IsARM, IsNotDarwin]>;
1411 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1412 IIC_Br, "b.w\t$dst @ TAILCALL",
1413 []>, Requires<[IsThumb, IsNotDarwin]>;
1415 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1416 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1417 []>, Requires<[IsNotDarwin]> {
1419 let Inst{31-4} = 0b1110000100101111111111110001;
1420 let Inst{3-0} = dst;
1425 let isBranch = 1, isTerminator = 1 in {
1426 // B is "predicable" since it can be xformed into a Bcc.
1427 let isBarrier = 1 in {
1428 let isPredicable = 1 in
1429 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1430 "b\t$target", [(br bb:$target)]> {
1432 let Inst{31-28} = 0b1110;
1433 let Inst{23-0} = target;
1436 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1437 def BR_JTr : ARMPseudoInst<(outs),
1438 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1439 SizeSpecial, IIC_Br,
1440 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1441 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1442 // into i12 and rs suffixed versions.
1443 def BR_JTm : ARMPseudoInst<(outs),
1444 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1445 SizeSpecial, IIC_Br,
1446 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1448 def BR_JTadd : ARMPseudoInst<(outs),
1449 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1450 SizeSpecial, IIC_Br,
1451 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1453 } // isNotDuplicable = 1, isIndirectBranch = 1
1456 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1457 // a two-value operand where a dag node expects two operands. :(
1458 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1459 IIC_Br, "b", "\t$target",
1460 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1462 let Inst{23-0} = target;
1466 // Branch and Exchange Jazelle -- for disassembly only
1467 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1468 [/* For disassembly only; pattern left blank */]> {
1469 let Inst{23-20} = 0b0010;
1470 //let Inst{19-8} = 0xfff;
1471 let Inst{7-4} = 0b0010;
1474 // Secure Monitor Call is a system instruction -- for disassembly only
1475 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1476 [/* For disassembly only; pattern left blank */]> {
1478 let Inst{23-4} = 0b01100000000000000111;
1479 let Inst{3-0} = opt;
1482 // Supervisor Call (Software Interrupt) -- for disassembly only
1483 let isCall = 1, Uses = [SP] in {
1484 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1485 [/* For disassembly only; pattern left blank */]> {
1487 let Inst{23-0} = svc;
1491 // Store Return State is a system instruction -- for disassembly only
1492 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1493 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1494 NoItinerary, "srs${amode}\tsp!, $mode",
1495 [/* For disassembly only; pattern left blank */]> {
1496 let Inst{31-28} = 0b1111;
1497 let Inst{22-20} = 0b110; // W = 1
1500 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1501 NoItinerary, "srs${amode}\tsp, $mode",
1502 [/* For disassembly only; pattern left blank */]> {
1503 let Inst{31-28} = 0b1111;
1504 let Inst{22-20} = 0b100; // W = 0
1507 // Return From Exception is a system instruction -- for disassembly only
1508 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1509 NoItinerary, "rfe${amode}\t$base!",
1510 [/* For disassembly only; pattern left blank */]> {
1511 let Inst{31-28} = 0b1111;
1512 let Inst{22-20} = 0b011; // W = 1
1515 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1516 NoItinerary, "rfe${amode}\t$base",
1517 [/* For disassembly only; pattern left blank */]> {
1518 let Inst{31-28} = 0b1111;
1519 let Inst{22-20} = 0b001; // W = 0
1521 } // isCodeGenOnly = 1
1523 //===----------------------------------------------------------------------===//
1524 // Load / store Instructions.
1530 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1531 UnOpFrag<(load node:$Src)>>;
1532 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1533 UnOpFrag<(zextloadi8 node:$Src)>>;
1534 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1535 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1536 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1537 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1539 // Special LDR for loads from non-pc-relative constpools.
1540 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1541 isReMaterializable = 1 in
1542 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1543 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1547 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1548 let Inst{19-16} = 0b1111;
1549 let Inst{15-12} = Rt;
1550 let Inst{11-0} = addr{11-0}; // imm12
1553 // Loads with zero extension
1554 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1555 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1556 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1558 // Loads with sign extension
1559 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1560 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1561 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1563 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1564 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1565 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1567 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1568 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1569 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1570 // how to represent that such that tblgen is happy and we don't
1571 // mark this codegen only?
1573 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1574 (ins addrmode3:$addr), LdMiscFrm,
1575 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1576 []>, Requires<[IsARM, HasV5TE]>;
1580 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1581 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1582 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1583 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1585 // {13} 1 == Rm, 0 == imm12
1589 let Inst{25} = addr{13};
1590 let Inst{23} = addr{12};
1591 let Inst{19-16} = addr{17-14};
1592 let Inst{11-0} = addr{11-0};
1594 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1595 (ins GPR:$Rn, am2offset:$offset),
1596 IndexModePost, LdFrm, itin,
1597 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1598 // {13} 1 == Rm, 0 == imm12
1603 let Inst{25} = offset{13};
1604 let Inst{23} = offset{12};
1605 let Inst{19-16} = Rn;
1606 let Inst{11-0} = offset{11-0};
1610 let mayLoad = 1, neverHasSideEffects = 1 in {
1611 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1612 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1615 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1616 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1617 (ins addrmode3:$addr), IndexModePre,
1619 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1621 let Inst{23} = addr{8}; // U bit
1622 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1623 let Inst{19-16} = addr{12-9}; // Rn
1624 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1625 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1627 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1628 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1630 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1633 let Inst{23} = offset{8}; // U bit
1634 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1635 let Inst{19-16} = Rn;
1636 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1637 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1641 let mayLoad = 1, neverHasSideEffects = 1 in {
1642 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1643 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1644 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1645 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1646 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1647 } // mayLoad = 1, neverHasSideEffects = 1
1649 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1650 let mayLoad = 1, neverHasSideEffects = 1 in {
1651 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1652 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1653 LdFrm, IIC_iLoad_ru,
1654 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1655 let Inst{21} = 1; // overwrite
1657 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1658 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1659 LdFrm, IIC_iLoad_bh_ru,
1660 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1661 let Inst{21} = 1; // overwrite
1663 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1664 (ins GPR:$base, am3offset:$offset), IndexModePost,
1665 LdMiscFrm, IIC_iLoad_bh_ru,
1666 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1667 let Inst{21} = 1; // overwrite
1669 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1670 (ins GPR:$base, am3offset:$offset), IndexModePost,
1671 LdMiscFrm, IIC_iLoad_bh_ru,
1672 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1673 let Inst{21} = 1; // overwrite
1675 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1676 (ins GPR:$base, am3offset:$offset), IndexModePost,
1677 LdMiscFrm, IIC_iLoad_bh_ru,
1678 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1679 let Inst{21} = 1; // overwrite
1685 // Stores with truncate
1686 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1687 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1688 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1691 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1692 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1693 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1694 StMiscFrm, IIC_iStore_d_r,
1695 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1698 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1699 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1700 IndexModePre, StFrm, IIC_iStore_ru,
1701 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1703 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1705 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1706 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1707 IndexModePost, StFrm, IIC_iStore_ru,
1708 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1710 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1712 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1713 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1714 IndexModePre, StFrm, IIC_iStore_bh_ru,
1715 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1716 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1717 GPR:$Rn, am2offset:$offset))]>;
1718 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1719 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1720 IndexModePost, StFrm, IIC_iStore_bh_ru,
1721 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1722 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1723 GPR:$Rn, am2offset:$offset))]>;
1725 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1726 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1727 IndexModePre, StMiscFrm, IIC_iStore_ru,
1728 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1730 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1732 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1733 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1734 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1735 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1736 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1737 GPR:$Rn, am3offset:$offset))]>;
1739 // For disassembly only
1740 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1741 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1742 StMiscFrm, IIC_iStore_d_ru,
1743 "strd", "\t$src1, $src2, [$base, $offset]!",
1744 "$base = $base_wb", []>;
1746 // For disassembly only
1747 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1748 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1749 StMiscFrm, IIC_iStore_d_ru,
1750 "strd", "\t$src1, $src2, [$base], $offset",
1751 "$base = $base_wb", []>;
1753 // STRT, STRBT, and STRHT are for disassembly only.
1755 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1756 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1757 IndexModeNone, StFrm, IIC_iStore_ru,
1758 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1759 [/* For disassembly only; pattern left blank */]> {
1760 let Inst{21} = 1; // overwrite
1763 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1764 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1765 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1766 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1767 [/* For disassembly only; pattern left blank */]> {
1768 let Inst{21} = 1; // overwrite
1771 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1772 (ins GPR:$src, GPR:$base,am3offset:$offset),
1773 StMiscFrm, IIC_iStore_bh_ru,
1774 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1775 [/* For disassembly only; pattern left blank */]> {
1776 let Inst{21} = 1; // overwrite
1779 //===----------------------------------------------------------------------===//
1780 // Load / store multiple Instructions.
1783 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1784 InstrItinClass itin, InstrItinClass itin_upd> {
1786 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1787 IndexModeNone, f, itin,
1788 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1789 let Inst{24-23} = 0b01; // Increment After
1790 let Inst{21} = 0; // No writeback
1791 let Inst{20} = L_bit;
1794 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1795 IndexModeUpd, f, itin_upd,
1796 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1797 let Inst{24-23} = 0b01; // Increment After
1798 let Inst{21} = 1; // Writeback
1799 let Inst{20} = L_bit;
1802 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1803 IndexModeNone, f, itin,
1804 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1805 let Inst{24-23} = 0b00; // Decrement After
1806 let Inst{21} = 0; // No writeback
1807 let Inst{20} = L_bit;
1810 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1811 IndexModeUpd, f, itin_upd,
1812 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1813 let Inst{24-23} = 0b00; // Decrement After
1814 let Inst{21} = 1; // Writeback
1815 let Inst{20} = L_bit;
1818 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1819 IndexModeNone, f, itin,
1820 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1821 let Inst{24-23} = 0b10; // Decrement Before
1822 let Inst{21} = 0; // No writeback
1823 let Inst{20} = L_bit;
1826 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1827 IndexModeUpd, f, itin_upd,
1828 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1829 let Inst{24-23} = 0b10; // Decrement Before
1830 let Inst{21} = 1; // Writeback
1831 let Inst{20} = L_bit;
1834 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1835 IndexModeNone, f, itin,
1836 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1837 let Inst{24-23} = 0b11; // Increment Before
1838 let Inst{21} = 0; // No writeback
1839 let Inst{20} = L_bit;
1842 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1843 IndexModeUpd, f, itin_upd,
1844 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1845 let Inst{24-23} = 0b11; // Increment Before
1846 let Inst{21} = 1; // Writeback
1847 let Inst{20} = L_bit;
1851 let neverHasSideEffects = 1 in {
1853 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1854 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1856 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1857 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1859 } // neverHasSideEffects
1861 // Load / Store Multiple Mnemonic Aliases
1862 def : MnemonicAlias<"ldm", "ldmia">;
1863 def : MnemonicAlias<"stm", "stmia">;
1865 // FIXME: remove when we have a way to marking a MI with these properties.
1866 // FIXME: Should pc be an implicit operand like PICADD, etc?
1867 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1868 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1869 // FIXME: Should be a pseudo-instruction.
1870 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1871 reglist:$regs, variable_ops),
1872 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1873 "ldmia${p}\t$Rn!, $regs",
1875 let Inst{24-23} = 0b01; // Increment After
1876 let Inst{21} = 1; // Writeback
1877 let Inst{20} = 1; // Load
1880 //===----------------------------------------------------------------------===//
1881 // Move Instructions.
1884 let neverHasSideEffects = 1 in
1885 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1886 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1890 let Inst{11-4} = 0b00000000;
1893 let Inst{15-12} = Rd;
1896 // A version for the smaller set of tail call registers.
1897 let neverHasSideEffects = 1 in
1898 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1899 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1903 let Inst{11-4} = 0b00000000;
1906 let Inst{15-12} = Rd;
1909 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1910 DPSoRegFrm, IIC_iMOVsr,
1911 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1915 let Inst{15-12} = Rd;
1916 let Inst{11-0} = src;
1920 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1921 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1922 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1926 let Inst{15-12} = Rd;
1927 let Inst{19-16} = 0b0000;
1928 let Inst{11-0} = imm;
1931 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1932 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1934 "movw", "\t$Rd, $imm",
1935 [(set GPR:$Rd, imm0_65535:$imm)]>,
1936 Requires<[IsARM, HasV6T2]>, UnaryDP {
1939 let Inst{15-12} = Rd;
1940 let Inst{11-0} = imm{11-0};
1941 let Inst{19-16} = imm{15-12};
1946 def MOVi16_pic_ga : PseudoInst<(outs GPR:$Rd),
1947 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1949 let Constraints = "$src = $Rd" in {
1950 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1952 "movt", "\t$Rd, $imm",
1954 (or (and GPR:$src, 0xffff),
1955 lo16AllZero:$imm))]>, UnaryDP,
1956 Requires<[IsARM, HasV6T2]> {
1959 let Inst{15-12} = Rd;
1960 let Inst{11-0} = imm{11-0};
1961 let Inst{19-16} = imm{15-12};
1966 def MOVTi16_pic_ga : PseudoInst<(outs GPR:$Rd),
1967 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1971 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1972 Requires<[IsARM, HasV6T2]>;
1974 let Uses = [CPSR] in
1975 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
1976 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1979 // These aren't really mov instructions, but we have to define them this way
1980 // due to flag operands.
1982 let Defs = [CPSR] in {
1983 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1984 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1986 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1987 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1991 //===----------------------------------------------------------------------===//
1992 // Extend Instructions.
1997 defm SXTB : AI_ext_rrot<0b01101010,
1998 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1999 defm SXTH : AI_ext_rrot<0b01101011,
2000 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2002 defm SXTAB : AI_exta_rrot<0b01101010,
2003 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2004 defm SXTAH : AI_exta_rrot<0b01101011,
2005 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2007 // For disassembly only
2008 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2010 // For disassembly only
2011 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2015 let AddedComplexity = 16 in {
2016 defm UXTB : AI_ext_rrot<0b01101110,
2017 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2018 defm UXTH : AI_ext_rrot<0b01101111,
2019 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2020 defm UXTB16 : AI_ext_rrot<0b01101100,
2021 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2023 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2024 // The transformation should probably be done as a combiner action
2025 // instead so we can include a check for masking back in the upper
2026 // eight bits of the source into the lower eight bits of the result.
2027 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2028 // (UXTB16r_rot GPR:$Src, 24)>;
2029 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2030 (UXTB16r_rot GPR:$Src, 8)>;
2032 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2033 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2034 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2035 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2038 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2039 // For disassembly only
2040 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2043 def SBFX : I<(outs GPR:$Rd),
2044 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2045 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2046 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2047 Requires<[IsARM, HasV6T2]> {
2052 let Inst{27-21} = 0b0111101;
2053 let Inst{6-4} = 0b101;
2054 let Inst{20-16} = width;
2055 let Inst{15-12} = Rd;
2056 let Inst{11-7} = lsb;
2060 def UBFX : I<(outs GPR:$Rd),
2061 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2062 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2063 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2064 Requires<[IsARM, HasV6T2]> {
2069 let Inst{27-21} = 0b0111111;
2070 let Inst{6-4} = 0b101;
2071 let Inst{20-16} = width;
2072 let Inst{15-12} = Rd;
2073 let Inst{11-7} = lsb;
2077 //===----------------------------------------------------------------------===//
2078 // Arithmetic Instructions.
2081 defm ADD : AsI1_bin_irs<0b0100, "add",
2082 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2083 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2084 defm SUB : AsI1_bin_irs<0b0010, "sub",
2085 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2086 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2088 // ADD and SUB with 's' bit set.
2089 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2090 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2091 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2092 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2093 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2094 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2096 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2097 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2098 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2099 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2101 // ADC and SUBC with 's' bit set.
2102 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2103 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2104 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2105 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2107 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2108 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2109 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2114 let Inst{15-12} = Rd;
2115 let Inst{19-16} = Rn;
2116 let Inst{11-0} = imm;
2119 // The reg/reg form is only defined for the disassembler; for codegen it is
2120 // equivalent to SUBrr.
2121 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2122 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2123 [/* For disassembly only; pattern left blank */]> {
2127 let Inst{11-4} = 0b00000000;
2130 let Inst{15-12} = Rd;
2131 let Inst{19-16} = Rn;
2134 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2135 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2136 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2141 let Inst{11-0} = shift;
2142 let Inst{15-12} = Rd;
2143 let Inst{19-16} = Rn;
2146 // RSB with 's' bit set.
2147 let isCodeGenOnly = 1, Defs = [CPSR] in {
2148 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2149 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2150 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2156 let Inst{15-12} = Rd;
2157 let Inst{19-16} = Rn;
2158 let Inst{11-0} = imm;
2160 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2161 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2162 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2168 let Inst{11-0} = shift;
2169 let Inst{15-12} = Rd;
2170 let Inst{19-16} = Rn;
2174 let Uses = [CPSR] in {
2175 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2176 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2177 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2183 let Inst{15-12} = Rd;
2184 let Inst{19-16} = Rn;
2185 let Inst{11-0} = imm;
2187 // The reg/reg form is only defined for the disassembler; for codegen it is
2188 // equivalent to SUBrr.
2189 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2190 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2191 [/* For disassembly only; pattern left blank */]> {
2195 let Inst{11-4} = 0b00000000;
2198 let Inst{15-12} = Rd;
2199 let Inst{19-16} = Rn;
2201 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2202 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2203 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2209 let Inst{11-0} = shift;
2210 let Inst{15-12} = Rd;
2211 let Inst{19-16} = Rn;
2215 // FIXME: Allow these to be predicated.
2216 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2217 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2218 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2219 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2226 let Inst{15-12} = Rd;
2227 let Inst{19-16} = Rn;
2228 let Inst{11-0} = imm;
2230 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2231 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2232 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2239 let Inst{11-0} = shift;
2240 let Inst{15-12} = Rd;
2241 let Inst{19-16} = Rn;
2245 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2246 // The assume-no-carry-in form uses the negation of the input since add/sub
2247 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2248 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2250 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2251 (SUBri GPR:$src, so_imm_neg:$imm)>;
2252 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2253 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2254 // The with-carry-in form matches bitwise not instead of the negation.
2255 // Effectively, the inverse interpretation of the carry flag already accounts
2256 // for part of the negation.
2257 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2258 (SBCri GPR:$src, so_imm_not:$imm)>;
2260 // Note: These are implemented in C++ code, because they have to generate
2261 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2263 // (mul X, 2^n+1) -> (add (X << n), X)
2264 // (mul X, 2^n-1) -> (rsb X, (X << n))
2266 // ARM Arithmetic Instruction -- for disassembly only
2267 // GPR:$dst = GPR:$a op GPR:$b
2268 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2269 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2270 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2271 opc, "\t$Rd, $Rn, $Rm", pattern> {
2275 let Inst{27-20} = op27_20;
2276 let Inst{11-4} = op11_4;
2277 let Inst{19-16} = Rn;
2278 let Inst{15-12} = Rd;
2282 // Saturating add/subtract -- for disassembly only
2284 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2285 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2286 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2287 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2288 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2289 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2291 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2292 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2293 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2294 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2295 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2296 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2297 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2298 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2299 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2300 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2301 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2302 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2304 // Signed/Unsigned add/subtract -- for disassembly only
2306 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2307 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2308 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2309 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2310 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2311 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2312 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2313 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2314 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2315 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2316 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2317 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2319 // Signed/Unsigned halving add/subtract -- for disassembly only
2321 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2322 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2323 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2324 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2325 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2326 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2327 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2328 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2329 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2330 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2331 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2332 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2334 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2336 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2337 MulFrm /* for convenience */, NoItinerary, "usad8",
2338 "\t$Rd, $Rn, $Rm", []>,
2339 Requires<[IsARM, HasV6]> {
2343 let Inst{27-20} = 0b01111000;
2344 let Inst{15-12} = 0b1111;
2345 let Inst{7-4} = 0b0001;
2346 let Inst{19-16} = Rd;
2347 let Inst{11-8} = Rm;
2350 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2351 MulFrm /* for convenience */, NoItinerary, "usada8",
2352 "\t$Rd, $Rn, $Rm, $Ra", []>,
2353 Requires<[IsARM, HasV6]> {
2358 let Inst{27-20} = 0b01111000;
2359 let Inst{7-4} = 0b0001;
2360 let Inst{19-16} = Rd;
2361 let Inst{15-12} = Ra;
2362 let Inst{11-8} = Rm;
2366 // Signed/Unsigned saturate -- for disassembly only
2368 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2369 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2370 [/* For disassembly only; pattern left blank */]> {
2375 let Inst{27-21} = 0b0110101;
2376 let Inst{5-4} = 0b01;
2377 let Inst{20-16} = sat_imm;
2378 let Inst{15-12} = Rd;
2379 let Inst{11-7} = sh{7-3};
2380 let Inst{6} = sh{0};
2384 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2385 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2386 [/* For disassembly only; pattern left blank */]> {
2390 let Inst{27-20} = 0b01101010;
2391 let Inst{11-4} = 0b11110011;
2392 let Inst{15-12} = Rd;
2393 let Inst{19-16} = sat_imm;
2397 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2398 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2399 [/* For disassembly only; pattern left blank */]> {
2404 let Inst{27-21} = 0b0110111;
2405 let Inst{5-4} = 0b01;
2406 let Inst{15-12} = Rd;
2407 let Inst{11-7} = sh{7-3};
2408 let Inst{6} = sh{0};
2409 let Inst{20-16} = sat_imm;
2413 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2414 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2415 [/* For disassembly only; pattern left blank */]> {
2419 let Inst{27-20} = 0b01101110;
2420 let Inst{11-4} = 0b11110011;
2421 let Inst{15-12} = Rd;
2422 let Inst{19-16} = sat_imm;
2426 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2427 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2429 //===----------------------------------------------------------------------===//
2430 // Bitwise Instructions.
2433 defm AND : AsI1_bin_irs<0b0000, "and",
2434 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2435 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2436 defm ORR : AsI1_bin_irs<0b1100, "orr",
2437 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2438 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2439 defm EOR : AsI1_bin_irs<0b0001, "eor",
2440 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2441 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2442 defm BIC : AsI1_bin_irs<0b1110, "bic",
2443 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2444 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2446 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2447 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2448 "bfc", "\t$Rd, $imm", "$src = $Rd",
2449 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2450 Requires<[IsARM, HasV6T2]> {
2453 let Inst{27-21} = 0b0111110;
2454 let Inst{6-0} = 0b0011111;
2455 let Inst{15-12} = Rd;
2456 let Inst{11-7} = imm{4-0}; // lsb
2457 let Inst{20-16} = imm{9-5}; // width
2460 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2461 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2462 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2463 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2464 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2465 bf_inv_mask_imm:$imm))]>,
2466 Requires<[IsARM, HasV6T2]> {
2470 let Inst{27-21} = 0b0111110;
2471 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2472 let Inst{15-12} = Rd;
2473 let Inst{11-7} = imm{4-0}; // lsb
2474 let Inst{20-16} = imm{9-5}; // width
2478 // GNU as only supports this form of bfi (w/ 4 arguments)
2479 let isAsmParserOnly = 1 in
2480 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2481 lsb_pos_imm:$lsb, width_imm:$width),
2482 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2483 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2484 []>, Requires<[IsARM, HasV6T2]> {
2489 let Inst{27-21} = 0b0111110;
2490 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2491 let Inst{15-12} = Rd;
2492 let Inst{11-7} = lsb;
2493 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2497 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2498 "mvn", "\t$Rd, $Rm",
2499 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2503 let Inst{19-16} = 0b0000;
2504 let Inst{11-4} = 0b00000000;
2505 let Inst{15-12} = Rd;
2508 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2509 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2510 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2514 let Inst{19-16} = 0b0000;
2515 let Inst{15-12} = Rd;
2516 let Inst{11-0} = shift;
2518 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2519 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2520 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2521 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2525 let Inst{19-16} = 0b0000;
2526 let Inst{15-12} = Rd;
2527 let Inst{11-0} = imm;
2530 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2531 (BICri GPR:$src, so_imm_not:$imm)>;
2533 //===----------------------------------------------------------------------===//
2534 // Multiply Instructions.
2536 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2537 string opc, string asm, list<dag> pattern>
2538 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2542 let Inst{19-16} = Rd;
2543 let Inst{11-8} = Rm;
2546 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2547 string opc, string asm, list<dag> pattern>
2548 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2553 let Inst{19-16} = RdHi;
2554 let Inst{15-12} = RdLo;
2555 let Inst{11-8} = Rm;
2559 let isCommutable = 1 in {
2560 let Constraints = "@earlyclobber $Rd" in
2561 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2562 pred:$p, cc_out:$s),
2563 Size4Bytes, IIC_iMUL32,
2564 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2565 Requires<[IsARM, NoV6]>;
2567 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2568 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2569 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2570 Requires<[IsARM, HasV6]>;
2573 let Constraints = "@earlyclobber $Rd" in
2574 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2575 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2576 Size4Bytes, IIC_iMAC32,
2577 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2578 Requires<[IsARM, NoV6]> {
2580 let Inst{15-12} = Ra;
2582 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2583 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2584 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2585 Requires<[IsARM, HasV6]> {
2587 let Inst{15-12} = Ra;
2590 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2591 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2592 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2593 Requires<[IsARM, HasV6T2]> {
2598 let Inst{19-16} = Rd;
2599 let Inst{15-12} = Ra;
2600 let Inst{11-8} = Rm;
2604 // Extra precision multiplies with low / high results
2606 let neverHasSideEffects = 1 in {
2607 let isCommutable = 1 in {
2608 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2609 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2610 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2611 Size4Bytes, IIC_iMUL64, []>,
2612 Requires<[IsARM, NoV6]>;
2614 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2615 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2616 Size4Bytes, IIC_iMUL64, []>,
2617 Requires<[IsARM, NoV6]>;
2620 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2621 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2622 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2623 Requires<[IsARM, HasV6]>;
2625 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2626 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2627 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2628 Requires<[IsARM, HasV6]>;
2631 // Multiply + accumulate
2632 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2633 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2634 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2635 Size4Bytes, IIC_iMAC64, []>,
2636 Requires<[IsARM, NoV6]>;
2637 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2638 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2639 Size4Bytes, IIC_iMAC64, []>,
2640 Requires<[IsARM, NoV6]>;
2641 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2642 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2643 Size4Bytes, IIC_iMAC64, []>,
2644 Requires<[IsARM, NoV6]>;
2648 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2649 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2650 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2651 Requires<[IsARM, HasV6]>;
2652 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2653 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2654 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2655 Requires<[IsARM, HasV6]>;
2657 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2658 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2659 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2660 Requires<[IsARM, HasV6]> {
2665 let Inst{19-16} = RdLo;
2666 let Inst{15-12} = RdHi;
2667 let Inst{11-8} = Rm;
2670 } // neverHasSideEffects
2672 // Most significant word multiply
2673 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2674 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2675 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2676 Requires<[IsARM, HasV6]> {
2677 let Inst{15-12} = 0b1111;
2680 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2681 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2682 [/* For disassembly only; pattern left blank */]>,
2683 Requires<[IsARM, HasV6]> {
2684 let Inst{15-12} = 0b1111;
2687 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2688 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2689 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2690 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2691 Requires<[IsARM, HasV6]>;
2693 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2694 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2695 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2696 [/* For disassembly only; pattern left blank */]>,
2697 Requires<[IsARM, HasV6]>;
2699 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2700 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2701 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2702 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2703 Requires<[IsARM, HasV6]>;
2705 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2706 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2707 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2708 [/* For disassembly only; pattern left blank */]>,
2709 Requires<[IsARM, HasV6]>;
2711 multiclass AI_smul<string opc, PatFrag opnode> {
2712 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2713 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2714 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2715 (sext_inreg GPR:$Rm, i16)))]>,
2716 Requires<[IsARM, HasV5TE]>;
2718 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2719 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2720 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2721 (sra GPR:$Rm, (i32 16))))]>,
2722 Requires<[IsARM, HasV5TE]>;
2724 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2725 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2726 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2727 (sext_inreg GPR:$Rm, i16)))]>,
2728 Requires<[IsARM, HasV5TE]>;
2730 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2731 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2732 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2733 (sra GPR:$Rm, (i32 16))))]>,
2734 Requires<[IsARM, HasV5TE]>;
2736 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2737 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2738 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2739 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2740 Requires<[IsARM, HasV5TE]>;
2742 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2743 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2744 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2745 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2746 Requires<[IsARM, HasV5TE]>;
2750 multiclass AI_smla<string opc, PatFrag opnode> {
2751 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2752 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2753 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2754 [(set GPR:$Rd, (add GPR:$Ra,
2755 (opnode (sext_inreg GPR:$Rn, i16),
2756 (sext_inreg GPR:$Rm, i16))))]>,
2757 Requires<[IsARM, HasV5TE]>;
2759 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2760 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2761 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2762 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2763 (sra GPR:$Rm, (i32 16)))))]>,
2764 Requires<[IsARM, HasV5TE]>;
2766 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2767 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2768 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2769 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2770 (sext_inreg GPR:$Rm, i16))))]>,
2771 Requires<[IsARM, HasV5TE]>;
2773 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2774 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2775 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2776 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2777 (sra GPR:$Rm, (i32 16)))))]>,
2778 Requires<[IsARM, HasV5TE]>;
2780 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2781 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2782 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2783 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2784 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2785 Requires<[IsARM, HasV5TE]>;
2787 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2788 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2789 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2790 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2791 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2792 Requires<[IsARM, HasV5TE]>;
2795 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2796 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2798 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2799 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2800 (ins GPR:$Rn, GPR:$Rm),
2801 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2802 [/* For disassembly only; pattern left blank */]>,
2803 Requires<[IsARM, HasV5TE]>;
2805 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2806 (ins GPR:$Rn, GPR:$Rm),
2807 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2808 [/* For disassembly only; pattern left blank */]>,
2809 Requires<[IsARM, HasV5TE]>;
2811 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2812 (ins GPR:$Rn, GPR:$Rm),
2813 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2814 [/* For disassembly only; pattern left blank */]>,
2815 Requires<[IsARM, HasV5TE]>;
2817 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2818 (ins GPR:$Rn, GPR:$Rm),
2819 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2820 [/* For disassembly only; pattern left blank */]>,
2821 Requires<[IsARM, HasV5TE]>;
2823 // Helper class for AI_smld -- for disassembly only
2824 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2825 InstrItinClass itin, string opc, string asm>
2826 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2833 let Inst{21-20} = 0b00;
2834 let Inst{22} = long;
2835 let Inst{27-23} = 0b01110;
2836 let Inst{11-8} = Rm;
2839 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2840 InstrItinClass itin, string opc, string asm>
2841 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2843 let Inst{15-12} = 0b1111;
2844 let Inst{19-16} = Rd;
2846 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2847 InstrItinClass itin, string opc, string asm>
2848 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2850 let Inst{15-12} = Ra;
2852 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2853 InstrItinClass itin, string opc, string asm>
2854 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2857 let Inst{19-16} = RdHi;
2858 let Inst{15-12} = RdLo;
2861 multiclass AI_smld<bit sub, string opc> {
2863 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2864 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2866 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2867 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2869 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2870 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2871 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2873 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2874 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2875 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2879 defm SMLA : AI_smld<0, "smla">;
2880 defm SMLS : AI_smld<1, "smls">;
2882 multiclass AI_sdml<bit sub, string opc> {
2884 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2885 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2886 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2887 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2890 defm SMUA : AI_sdml<0, "smua">;
2891 defm SMUS : AI_sdml<1, "smus">;
2893 //===----------------------------------------------------------------------===//
2894 // Misc. Arithmetic Instructions.
2897 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2898 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2899 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2901 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2902 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2903 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2904 Requires<[IsARM, HasV6T2]>;
2906 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2907 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2908 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2910 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2911 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2913 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2914 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2915 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2916 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2917 Requires<[IsARM, HasV6]>;
2919 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2920 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2923 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2924 (shl GPR:$Rm, (i32 8))), i16))]>,
2925 Requires<[IsARM, HasV6]>;
2927 def lsl_shift_imm : SDNodeXForm<imm, [{
2928 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2929 return CurDAG->getTargetConstant(Sh, MVT::i32);
2932 def lsl_amt : PatLeaf<(i32 imm), [{
2933 return (N->getZExtValue() < 32);
2936 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2937 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2938 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2939 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2940 (and (shl GPR:$Rm, lsl_amt:$sh),
2942 Requires<[IsARM, HasV6]>;
2944 // Alternate cases for PKHBT where identities eliminate some nodes.
2945 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2946 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2947 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2948 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2950 def asr_shift_imm : SDNodeXForm<imm, [{
2951 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2952 return CurDAG->getTargetConstant(Sh, MVT::i32);
2955 def asr_amt : PatLeaf<(i32 imm), [{
2956 return (N->getZExtValue() <= 32);
2959 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2960 // will match the pattern below.
2961 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2962 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2963 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2964 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2965 (and (sra GPR:$Rm, asr_amt:$sh),
2967 Requires<[IsARM, HasV6]>;
2969 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2970 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2971 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2972 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2973 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2974 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2975 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2977 //===----------------------------------------------------------------------===//
2978 // Comparison Instructions...
2981 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2982 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2983 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2985 // ARMcmpZ can re-use the above instruction definitions.
2986 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
2987 (CMPri GPR:$src, so_imm:$imm)>;
2988 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
2989 (CMPrr GPR:$src, GPR:$rhs)>;
2990 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
2991 (CMPrs GPR:$src, so_reg:$rhs)>;
2993 // FIXME: We have to be careful when using the CMN instruction and comparison
2994 // with 0. One would expect these two pieces of code should give identical
3010 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3011 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3012 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3013 // value of r0 and the carry bit (because the "carry bit" parameter to
3014 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3015 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3016 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3017 // parameter to AddWithCarry is defined as 0).
3019 // When x is 0 and unsigned:
3023 // ~x + 1 = 0x1 0000 0000
3024 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3026 // Therefore, we should disable CMN when comparing against zero, until we can
3027 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3028 // when it's a comparison which doesn't look at the 'carry' flag).
3030 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3032 // This is related to <rdar://problem/7569620>.
3034 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3035 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3037 // Note that TST/TEQ don't set all the same flags that CMP does!
3038 defm TST : AI1_cmp_irs<0b1000, "tst",
3039 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3040 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3041 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3042 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3043 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3045 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3046 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3047 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3049 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3050 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3052 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3053 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3055 // Pseudo i64 compares for some floating point compares.
3056 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3058 def BCCi64 : PseudoInst<(outs),
3059 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3061 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3063 def BCCZi64 : PseudoInst<(outs),
3064 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3065 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3066 } // usesCustomInserter
3069 // Conditional moves
3070 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3071 // a two-value operand where a dag node expects two operands. :(
3072 // FIXME: These should all be pseudo-instructions that get expanded to
3073 // the normal MOV instructions. That would fix the dependency on
3074 // special casing them in tblgen.
3075 let neverHasSideEffects = 1 in {
3076 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3077 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3078 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3079 RegConstraint<"$false = $Rd">, UnaryDP {
3084 let Inst{15-12} = Rd;
3085 let Inst{11-4} = 0b00000000;
3089 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3090 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3091 "mov", "\t$Rd, $shift",
3092 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3093 RegConstraint<"$false = $Rd">, UnaryDP {
3098 let Inst{19-16} = 0;
3099 let Inst{15-12} = Rd;
3100 let Inst{11-0} = shift;
3103 let isMoveImm = 1 in
3104 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3106 "movw", "\t$Rd, $imm",
3108 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3114 let Inst{19-16} = imm{15-12};
3115 let Inst{15-12} = Rd;
3116 let Inst{11-0} = imm{11-0};
3119 let isMoveImm = 1 in
3120 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3121 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3122 "mov", "\t$Rd, $imm",
3123 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3124 RegConstraint<"$false = $Rd">, UnaryDP {
3129 let Inst{19-16} = 0b0000;
3130 let Inst{15-12} = Rd;
3131 let Inst{11-0} = imm;
3134 // Two instruction predicate mov immediate.
3135 let isMoveImm = 1 in
3136 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3137 (ins GPR:$false, i32imm:$src, pred:$p),
3138 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3140 let isMoveImm = 1 in
3141 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3142 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3143 "mvn", "\t$Rd, $imm",
3144 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3145 RegConstraint<"$false = $Rd">, UnaryDP {
3150 let Inst{19-16} = 0b0000;
3151 let Inst{15-12} = Rd;
3152 let Inst{11-0} = imm;
3154 } // neverHasSideEffects
3156 //===----------------------------------------------------------------------===//
3157 // Atomic operations intrinsics
3160 def memb_opt : Operand<i32> {
3161 let PrintMethod = "printMemBOption";
3164 // memory barriers protect the atomic sequences
3165 let hasSideEffects = 1 in {
3166 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3167 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3168 Requires<[IsARM, HasDB]> {
3170 let Inst{31-4} = 0xf57ff05;
3171 let Inst{3-0} = opt;
3174 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3175 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3176 [(ARMMemBarrierMCR GPR:$zero)]>,
3177 Requires<[IsARM, HasV6]> {
3178 // FIXME: add encoding
3182 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3184 [/* For disassembly only; pattern left blank */]>,
3185 Requires<[IsARM, HasDB]> {
3187 let Inst{31-4} = 0xf57ff04;
3188 let Inst{3-0} = opt;
3191 // ISB has only full system option -- for disassembly only
3192 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3193 Requires<[IsARM, HasDB]> {
3194 let Inst{31-4} = 0xf57ff06;
3195 let Inst{3-0} = 0b1111;
3198 let usesCustomInserter = 1 in {
3199 let Uses = [CPSR] in {
3200 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3201 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3202 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3203 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3204 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3205 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3206 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3207 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3208 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3209 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3210 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3211 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3212 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3213 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3214 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3215 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3216 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3217 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3218 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3219 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3220 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3221 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3222 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3223 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3224 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3225 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3226 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3227 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3228 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3229 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3230 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3231 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3232 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3233 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3234 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3235 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3236 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3237 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3238 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3239 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3240 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3241 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3242 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3243 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3244 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3245 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3246 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3247 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3248 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3249 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3250 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3251 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3252 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3253 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3255 def ATOMIC_SWAP_I8 : PseudoInst<
3256 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3257 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3258 def ATOMIC_SWAP_I16 : PseudoInst<
3259 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3260 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3261 def ATOMIC_SWAP_I32 : PseudoInst<
3262 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3263 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3265 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3266 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3267 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3268 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3269 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3270 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3271 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3272 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3273 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3277 let mayLoad = 1 in {
3278 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3279 "ldrexb", "\t$Rt, [$Rn]",
3281 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3282 "ldrexh", "\t$Rt, [$Rn]",
3284 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3285 "ldrex", "\t$Rt, [$Rn]",
3287 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3289 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3293 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3294 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3296 "strexb", "\t$Rd, $src, [$Rn]",
3298 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3300 "strexh", "\t$Rd, $Rt, [$Rn]",
3302 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3304 "strex", "\t$Rd, $Rt, [$Rn]",
3306 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3307 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3309 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3313 // Clear-Exclusive is for disassembly only.
3314 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3315 [/* For disassembly only; pattern left blank */]>,
3316 Requires<[IsARM, HasV7]> {
3317 let Inst{31-0} = 0b11110101011111111111000000011111;
3320 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3321 let mayLoad = 1 in {
3322 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3323 [/* For disassembly only; pattern left blank */]>;
3324 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3325 [/* For disassembly only; pattern left blank */]>;
3328 //===----------------------------------------------------------------------===//
3332 // __aeabi_read_tp preserves the registers r1-r3.
3333 // This is a pseudo inst so that we can get the encoding right,
3334 // complete with fixup for the aeabi_read_tp function.
3336 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3337 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3338 [(set R0, ARMthread_pointer)]>;
3341 //===----------------------------------------------------------------------===//
3342 // SJLJ Exception handling intrinsics
3343 // eh_sjlj_setjmp() is an instruction sequence to store the return
3344 // address and save #0 in R0 for the non-longjmp case.
3345 // Since by its nature we may be coming from some other function to get
3346 // here, and we're using the stack frame for the containing function to
3347 // save/restore registers, we can't keep anything live in regs across
3348 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3349 // when we get here from a longjmp(). We force everthing out of registers
3350 // except for our own input by listing the relevant registers in Defs. By
3351 // doing so, we also cause the prologue/epilogue code to actively preserve
3352 // all of the callee-saved resgisters, which is exactly what we want.
3353 // A constant value is passed in $val, and we use the location as a scratch.
3355 // These are pseudo-instructions and are lowered to individual MC-insts, so
3356 // no encoding information is necessary.
3358 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3359 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3360 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3361 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3362 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3364 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3365 Requires<[IsARM, HasVFP2]>;
3369 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3370 hasSideEffects = 1, isBarrier = 1 in {
3371 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3373 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3374 Requires<[IsARM, NoVFP]>;
3377 // FIXME: Non-Darwin version(s)
3378 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3379 Defs = [ R7, LR, SP ] in {
3380 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3382 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3383 Requires<[IsARM, IsDarwin]>;
3386 // eh.sjlj.dispatchsetup pseudo-instruction.
3387 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3388 // handled when the pseudo is expanded (which happens before any passes
3389 // that need the instruction size).
3390 let isBarrier = 1, hasSideEffects = 1 in
3391 def Int_eh_sjlj_dispatchsetup :
3392 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3393 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3394 Requires<[IsDarwin]>;
3396 //===----------------------------------------------------------------------===//
3397 // Non-Instruction Patterns
3400 // Large immediate handling.
3402 // 32-bit immediate using two piece so_imms or movw + movt.
3403 // This is a single pseudo instruction, the benefit is that it can be remat'd
3404 // as a single unit instead of having to handle reg inputs.
3405 // FIXME: Remove this when we can do generalized remat.
3406 let isReMaterializable = 1, isMoveImm = 1 in {
3407 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3408 [(set GPR:$dst, (arm_i32imm:$src))]>,
3411 def MOV_pic_ga : PseudoInst<(outs GPR:$dst),
3412 (ins i32imm:$addr, pclabel:$id), IIC_iMOVix2,
3413 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>,
3414 Requires<[IsARM, UseMovt]>;
3415 } // isReMaterializable = 1, isMoveImm = 1 in
3417 // ConstantPool, GlobalAddress, and JumpTable
3418 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3419 Requires<[IsARM, DontUseMovt]>;
3420 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3421 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3422 Requires<[IsARM, UseMovt]>;
3423 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3424 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3426 // TODO: add,sub,and, 3-instr forms?
3429 def : ARMPat<(ARMtcret tcGPR:$dst),
3430 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3432 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3433 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3435 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3436 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3438 def : ARMPat<(ARMtcret tcGPR:$dst),
3439 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3441 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3442 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3444 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3445 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3448 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3449 Requires<[IsARM, IsNotDarwin]>;
3450 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3451 Requires<[IsARM, IsDarwin]>;
3453 // zextload i1 -> zextload i8
3454 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3455 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3457 // extload -> zextload
3458 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3459 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3460 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3461 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3463 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3465 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3466 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3469 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3470 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3471 (SMULBB GPR:$a, GPR:$b)>;
3472 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3473 (SMULBB GPR:$a, GPR:$b)>;
3474 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3475 (sra GPR:$b, (i32 16))),
3476 (SMULBT GPR:$a, GPR:$b)>;
3477 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3478 (SMULBT GPR:$a, GPR:$b)>;
3479 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3480 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3481 (SMULTB GPR:$a, GPR:$b)>;
3482 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3483 (SMULTB GPR:$a, GPR:$b)>;
3484 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3486 (SMULWB GPR:$a, GPR:$b)>;
3487 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3488 (SMULWB GPR:$a, GPR:$b)>;
3490 def : ARMV5TEPat<(add GPR:$acc,
3491 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3492 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3493 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3494 def : ARMV5TEPat<(add GPR:$acc,
3495 (mul sext_16_node:$a, sext_16_node:$b)),
3496 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3497 def : ARMV5TEPat<(add GPR:$acc,
3498 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3499 (sra GPR:$b, (i32 16)))),
3500 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3501 def : ARMV5TEPat<(add GPR:$acc,
3502 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3503 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3504 def : ARMV5TEPat<(add GPR:$acc,
3505 (mul (sra GPR:$a, (i32 16)),
3506 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3507 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3508 def : ARMV5TEPat<(add GPR:$acc,
3509 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3510 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3511 def : ARMV5TEPat<(add GPR:$acc,
3512 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3514 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3515 def : ARMV5TEPat<(add GPR:$acc,
3516 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3517 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3519 //===----------------------------------------------------------------------===//
3523 include "ARMInstrThumb.td"
3525 //===----------------------------------------------------------------------===//
3529 include "ARMInstrThumb2.td"
3531 //===----------------------------------------------------------------------===//
3532 // Floating Point Support
3535 include "ARMInstrVFP.td"
3537 //===----------------------------------------------------------------------===//
3538 // Advanced SIMD (NEON) Support
3541 include "ARMInstrNEON.td"
3543 //===----------------------------------------------------------------------===//
3544 // Coprocessor Instructions. For disassembly only.
3547 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3548 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3549 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3550 [/* For disassembly only; pattern left blank */]> {
3554 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3555 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3556 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3557 [/* For disassembly only; pattern left blank */]> {
3558 let Inst{31-28} = 0b1111;
3562 class ACI<dag oops, dag iops, string opc, string asm>
3563 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3564 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3565 let Inst{27-25} = 0b110;
3568 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3570 def _OFFSET : ACI<(outs),
3571 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3572 opc, "\tp$cop, cr$CRd, $addr"> {
3573 let Inst{31-28} = op31_28;
3574 let Inst{24} = 1; // P = 1
3575 let Inst{21} = 0; // W = 0
3576 let Inst{22} = 0; // D = 0
3577 let Inst{20} = load;
3580 def _PRE : ACI<(outs),
3581 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3582 opc, "\tp$cop, cr$CRd, $addr!"> {
3583 let Inst{31-28} = op31_28;
3584 let Inst{24} = 1; // P = 1
3585 let Inst{21} = 1; // W = 1
3586 let Inst{22} = 0; // D = 0
3587 let Inst{20} = load;
3590 def _POST : ACI<(outs),
3591 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3592 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3593 let Inst{31-28} = op31_28;
3594 let Inst{24} = 0; // P = 0
3595 let Inst{21} = 1; // W = 1
3596 let Inst{22} = 0; // D = 0
3597 let Inst{20} = load;
3600 def _OPTION : ACI<(outs),
3601 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3602 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3603 let Inst{31-28} = op31_28;
3604 let Inst{24} = 0; // P = 0
3605 let Inst{23} = 1; // U = 1
3606 let Inst{21} = 0; // W = 0
3607 let Inst{22} = 0; // D = 0
3608 let Inst{20} = load;
3611 def L_OFFSET : ACI<(outs),
3612 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3613 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3614 let Inst{31-28} = op31_28;
3615 let Inst{24} = 1; // P = 1
3616 let Inst{21} = 0; // W = 0
3617 let Inst{22} = 1; // D = 1
3618 let Inst{20} = load;
3621 def L_PRE : ACI<(outs),
3622 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3623 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3624 let Inst{31-28} = op31_28;
3625 let Inst{24} = 1; // P = 1
3626 let Inst{21} = 1; // W = 1
3627 let Inst{22} = 1; // D = 1
3628 let Inst{20} = load;
3631 def L_POST : ACI<(outs),
3632 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3633 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3634 let Inst{31-28} = op31_28;
3635 let Inst{24} = 0; // P = 0
3636 let Inst{21} = 1; // W = 1
3637 let Inst{22} = 1; // D = 1
3638 let Inst{20} = load;
3641 def L_OPTION : ACI<(outs),
3642 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3643 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3644 let Inst{31-28} = op31_28;
3645 let Inst{24} = 0; // P = 0
3646 let Inst{23} = 1; // U = 1
3647 let Inst{21} = 0; // W = 0
3648 let Inst{22} = 1; // D = 1
3649 let Inst{20} = load;
3653 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3654 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3655 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3656 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3658 def MCR : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3659 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3660 NoItinerary, "mcr", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3661 [/* For disassembly only; pattern left blank */]> {
3672 let Inst{15-12} = Rt;
3673 let Inst{11-8} = cop;
3674 let Inst{23-21} = opc1;
3675 let Inst{7-5} = opc2;
3676 let Inst{3-0} = CRm;
3677 let Inst{19-16} = CRn;
3680 def MCR2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3681 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3682 NoItinerary, "mcr2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3683 [/* For disassembly only; pattern left blank */]> {
3684 let Inst{31-28} = 0b1111;
3695 let Inst{15-12} = Rt;
3696 let Inst{11-8} = cop;
3697 let Inst{23-21} = opc1;
3698 let Inst{7-5} = opc2;
3699 let Inst{3-0} = CRm;
3700 let Inst{19-16} = CRn;
3703 def MRC : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3704 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3705 NoItinerary, "mrc", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3706 [/* For disassembly only; pattern left blank */]> {
3717 let Inst{15-12} = Rt;
3718 let Inst{11-8} = cop;
3719 let Inst{23-21} = opc1;
3720 let Inst{7-5} = opc2;
3721 let Inst{3-0} = CRm;
3722 let Inst{19-16} = CRn;
3725 def MRC2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3726 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3727 NoItinerary, "mrc2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3728 [/* For disassembly only; pattern left blank */]> {
3729 let Inst{31-28} = 0b1111;
3740 let Inst{15-12} = Rt;
3741 let Inst{11-8} = cop;
3742 let Inst{23-21} = opc1;
3743 let Inst{7-5} = opc2;
3744 let Inst{3-0} = CRm;
3745 let Inst{19-16} = CRn;
3748 def MCRR : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3749 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3750 NoItinerary, "mcrr", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3751 [/* For disassembly only; pattern left blank */]> {
3752 let Inst{23-20} = 0b0100;
3760 let Inst{15-12} = Rt;
3761 let Inst{19-16} = Rt2;
3762 let Inst{11-8} = cop;
3763 let Inst{7-5} = opc1;
3764 let Inst{3-0} = CRm;
3767 def MCRR2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3768 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3769 NoItinerary, "mcrr2\t$cop, $opc, $Rt, $Rt2, $CRm",
3770 [/* For disassembly only; pattern left blank */]> {
3771 let Inst{31-28} = 0b1111;
3772 let Inst{23-20} = 0b0100;
3780 let Inst{15-12} = Rt;
3781 let Inst{19-16} = Rt2;
3782 let Inst{11-8} = cop;
3783 let Inst{7-5} = opc1;
3784 let Inst{3-0} = CRm;
3787 def MRRC : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3788 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3789 NoItinerary, "mrrc", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3790 [/* For disassembly only; pattern left blank */]> {
3791 let Inst{23-20} = 0b0101;
3799 let Inst{15-12} = Rt;
3800 let Inst{19-16} = Rt2;
3801 let Inst{11-8} = cop;
3802 let Inst{7-5} = opc1;
3803 let Inst{3-0} = CRm;
3806 def MRRC2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3807 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3808 NoItinerary, "mrrc2\t$cop, $opc, $Rt, $Rt2, $CRm",
3809 [/* For disassembly only; pattern left blank */]> {
3810 let Inst{31-28} = 0b1111;
3811 let Inst{23-20} = 0b0101;
3819 let Inst{15-12} = Rt;
3820 let Inst{19-16} = Rt2;
3821 let Inst{11-8} = cop;
3822 let Inst{7-5} = opc1;
3823 let Inst{3-0} = CRm;
3826 //===----------------------------------------------------------------------===//
3827 // Move between special register and ARM core register -- for disassembly only
3830 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3831 [/* For disassembly only; pattern left blank */]> {
3832 let Inst{23-20} = 0b0000;
3833 let Inst{7-4} = 0b0000;
3836 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3837 [/* For disassembly only; pattern left blank */]> {
3838 let Inst{23-20} = 0b0100;
3839 let Inst{7-4} = 0b0000;
3842 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3843 "msr", "\tcpsr$mask, $src",
3844 [/* For disassembly only; pattern left blank */]> {
3845 let Inst{23-20} = 0b0010;
3846 let Inst{7-4} = 0b0000;
3849 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3850 "msr", "\tcpsr$mask, $a",
3851 [/* For disassembly only; pattern left blank */]> {
3852 let Inst{23-20} = 0b0010;
3853 let Inst{7-4} = 0b0000;
3856 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3857 "msr", "\tspsr$mask, $src",
3858 [/* For disassembly only; pattern left blank */]> {
3859 let Inst{23-20} = 0b0110;
3860 let Inst{7-4} = 0b0000;
3863 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3864 "msr", "\tspsr$mask, $a",
3865 [/* For disassembly only; pattern left blank */]> {
3866 let Inst{23-20} = 0b0110;
3867 let Inst{7-4} = 0b0000;