1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>;
73 def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
74 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
76 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
77 [SDNPHasChain, SDNPOutGlue]>;
78 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
79 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
81 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
82 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
84 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
85 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
87 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
88 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
91 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
92 [SDNPHasChain, SDNPOptInGlue]>;
94 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
96 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
99 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
100 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
102 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
104 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
107 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
110 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
113 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
114 [SDNPOutGlue, SDNPCommutative]>;
116 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
118 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
119 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
120 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
122 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
123 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
124 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
126 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
128 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
131 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
133 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
135 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
136 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
138 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
140 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
141 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
144 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
146 //===----------------------------------------------------------------------===//
147 // ARM Instruction Predicate Definitions.
149 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
150 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
151 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
152 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
153 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
154 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
162 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
163 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
164 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
166 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
168 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
170 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
171 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
172 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
173 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
174 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
175 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
176 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
177 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
179 // FIXME: Eventually this will be just "hasV6T2Ops".
180 def UseMovt : Predicate<"Subtarget->useMovt()">;
181 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
182 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
184 //===----------------------------------------------------------------------===//
185 // ARM Flag Definitions.
187 class RegConstraint<string C> {
188 string Constraints = C;
191 //===----------------------------------------------------------------------===//
192 // ARM specific transformation functions and pattern fragments.
195 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
196 // so_imm_neg def below.
197 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
198 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
201 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
202 // so_imm_not def below.
203 def so_imm_not_XFORM : SDNodeXForm<imm, [{
204 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
207 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
208 def imm1_15 : PatLeaf<(i32 imm), [{
209 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
212 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
213 def imm16_31 : PatLeaf<(i32 imm), [{
214 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
219 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
220 }], so_imm_neg_XFORM>;
224 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
225 }], so_imm_not_XFORM>;
227 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
228 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
229 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
232 /// Split a 32-bit immediate into two 16 bit parts.
233 def hi16 : SDNodeXForm<imm, [{
234 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
237 def lo16AllZero : PatLeaf<(i32 imm), [{
238 // Returns true if all low 16-bits are 0.
239 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
242 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
244 def imm0_65535 : PatLeaf<(i32 imm), [{
245 return (uint32_t)N->getZExtValue() < 65536;
248 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
249 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
251 /// adde and sube predicates - True based on whether the carry flag output
252 /// will be needed or not.
253 def adde_dead_carry :
254 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
255 [{return !N->hasAnyUseOfValue(1);}]>;
256 def sube_dead_carry :
257 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
258 [{return !N->hasAnyUseOfValue(1);}]>;
259 def adde_live_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return N->hasAnyUseOfValue(1);}]>;
262 def sube_live_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return N->hasAnyUseOfValue(1);}]>;
266 // An 'and' node with a single use.
267 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
268 return N->hasOneUse();
271 // An 'xor' node with a single use.
272 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
273 return N->hasOneUse();
276 // An 'fmul' node with a single use.
277 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
278 return N->hasOneUse();
281 // An 'fadd' node which checks for single non-hazardous use.
282 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
283 return hasNoVMLxHazardUse(N);
286 // An 'fsub' node which checks for single non-hazardous use.
287 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
288 return hasNoVMLxHazardUse(N);
291 //===----------------------------------------------------------------------===//
292 // Operand Definitions.
296 // FIXME: rename brtarget to t2_brtarget
297 def brtarget : Operand<OtherVT> {
298 let EncoderMethod = "getBranchTargetOpValue";
301 // FIXME: get rid of this one?
302 def uncondbrtarget : Operand<OtherVT> {
303 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
306 // Branch target for ARM. Handles conditional/unconditional
307 def br_target : Operand<OtherVT> {
308 let EncoderMethod = "getARMBranchTargetOpValue";
312 // FIXME: rename bltarget to t2_bl_target?
313 def bltarget : Operand<i32> {
314 // Encoded the same as branch targets.
315 let EncoderMethod = "getBranchTargetOpValue";
318 // Call target for ARM. Handles conditional/unconditional
319 // FIXME: rename bl_target to t2_bltarget?
320 def bl_target : Operand<i32> {
321 // Encoded the same as branch targets.
322 let EncoderMethod = "getARMBranchTargetOpValue";
326 // A list of registers separated by comma. Used by load/store multiple.
327 def RegListAsmOperand : AsmOperandClass {
328 let Name = "RegList";
329 let SuperClasses = [];
332 def DPRRegListAsmOperand : AsmOperandClass {
333 let Name = "DPRRegList";
334 let SuperClasses = [];
337 def SPRRegListAsmOperand : AsmOperandClass {
338 let Name = "SPRRegList";
339 let SuperClasses = [];
342 def reglist : Operand<i32> {
343 let EncoderMethod = "getRegisterListOpValue";
344 let ParserMatchClass = RegListAsmOperand;
345 let PrintMethod = "printRegisterList";
348 def dpr_reglist : Operand<i32> {
349 let EncoderMethod = "getRegisterListOpValue";
350 let ParserMatchClass = DPRRegListAsmOperand;
351 let PrintMethod = "printRegisterList";
354 def spr_reglist : Operand<i32> {
355 let EncoderMethod = "getRegisterListOpValue";
356 let ParserMatchClass = SPRRegListAsmOperand;
357 let PrintMethod = "printRegisterList";
360 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
361 def cpinst_operand : Operand<i32> {
362 let PrintMethod = "printCPInstOperand";
366 def pclabel : Operand<i32> {
367 let PrintMethod = "printPCLabel";
370 // ADR instruction labels.
371 def adrlabel : Operand<i32> {
372 let EncoderMethod = "getAdrLabelOpValue";
375 def neon_vcvt_imm32 : Operand<i32> {
376 let EncoderMethod = "getNEONVcvtImm32OpValue";
379 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
380 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
381 int32_t v = (int32_t)N->getZExtValue();
382 return v == 8 || v == 16 || v == 24; }]> {
383 let EncoderMethod = "getRotImmOpValue";
386 // shift_imm: An integer that encodes a shift amount and the type of shift
387 // (currently either asr or lsl) using the same encoding used for the
388 // immediates in so_reg operands.
389 def shift_imm : Operand<i32> {
390 let PrintMethod = "printShiftImmOperand";
393 // shifter_operand operands: so_reg and so_imm.
394 def so_reg : Operand<i32>, // reg reg imm
395 ComplexPattern<i32, 3, "SelectShifterOperandReg",
396 [shl,srl,sra,rotr]> {
397 let EncoderMethod = "getSORegOpValue";
398 let PrintMethod = "printSORegOperand";
399 let MIOperandInfo = (ops GPR, GPR, i32imm);
401 def shift_so_reg : Operand<i32>, // reg reg imm
402 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
403 [shl,srl,sra,rotr]> {
404 let EncoderMethod = "getSORegOpValue";
405 let PrintMethod = "printSORegOperand";
406 let MIOperandInfo = (ops GPR, GPR, i32imm);
409 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
410 // 8-bit immediate rotated by an arbitrary number of bits.
411 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
412 let EncoderMethod = "getSOImmOpValue";
413 let PrintMethod = "printSOImmOperand";
416 // Break so_imm's up into two pieces. This handles immediates with up to 16
417 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
418 // get the first/second pieces.
419 def so_imm2part : PatLeaf<(imm), [{
420 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
423 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
425 def arm_i32imm : PatLeaf<(imm), [{
426 if (Subtarget->hasV6T2Ops())
428 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
431 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
432 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
433 return (int32_t)N->getZExtValue() < 32;
436 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
437 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
438 return (int32_t)N->getZExtValue() < 32;
440 let EncoderMethod = "getImmMinusOneOpValue";
443 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
444 // The imm is split into imm{15-12}, imm{11-0}
446 def i32imm_hilo16 : Operand<i32> {
447 let EncoderMethod = "getHiLo16ImmOpValue";
450 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
452 def bf_inv_mask_imm : Operand<i32>,
454 return ARM::isBitFieldInvertedMask(N->getZExtValue());
456 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
457 let PrintMethod = "printBitfieldInvMaskImmOperand";
460 /// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
461 def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
462 return isInt<5>(N->getSExtValue());
465 /// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
466 def width_imm : Operand<i32>, PatLeaf<(imm), [{
467 return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
469 let EncoderMethod = "getMsbOpValue";
472 // Define ARM specific addressing modes.
475 // addrmode_imm12 := reg +/- imm12
477 def addrmode_imm12 : Operand<i32>,
478 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
479 // 12-bit immediate operand. Note that instructions using this encode
480 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
481 // immediate values are as normal.
483 let EncoderMethod = "getAddrModeImm12OpValue";
484 let PrintMethod = "printAddrModeImm12Operand";
485 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
487 // ldst_so_reg := reg +/- reg shop imm
489 def ldst_so_reg : Operand<i32>,
490 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
491 let EncoderMethod = "getLdStSORegOpValue";
492 // FIXME: Simplify the printer
493 let PrintMethod = "printAddrMode2Operand";
494 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
497 // addrmode2 := reg +/- imm12
498 // := reg +/- reg shop imm
500 def addrmode2 : Operand<i32>,
501 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
502 let EncoderMethod = "getAddrMode2OpValue";
503 let PrintMethod = "printAddrMode2Operand";
504 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
507 def am2offset : Operand<i32>,
508 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
509 [], [SDNPWantRoot]> {
510 let EncoderMethod = "getAddrMode2OffsetOpValue";
511 let PrintMethod = "printAddrMode2OffsetOperand";
512 let MIOperandInfo = (ops GPR, i32imm);
515 // addrmode3 := reg +/- reg
516 // addrmode3 := reg +/- imm8
518 def addrmode3 : Operand<i32>,
519 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
520 let EncoderMethod = "getAddrMode3OpValue";
521 let PrintMethod = "printAddrMode3Operand";
522 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
525 def am3offset : Operand<i32>,
526 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
527 [], [SDNPWantRoot]> {
528 let EncoderMethod = "getAddrMode3OffsetOpValue";
529 let PrintMethod = "printAddrMode3OffsetOperand";
530 let MIOperandInfo = (ops GPR, i32imm);
533 // ldstm_mode := {ia, ib, da, db}
535 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
536 let EncoderMethod = "getLdStmModeOpValue";
537 let PrintMethod = "printLdStmModeOperand";
540 def MemMode5AsmOperand : AsmOperandClass {
541 let Name = "MemMode5";
542 let SuperClasses = [];
545 // addrmode5 := reg +/- imm8*4
547 def addrmode5 : Operand<i32>,
548 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
549 let PrintMethod = "printAddrMode5Operand";
550 let MIOperandInfo = (ops GPR:$base, i32imm);
551 let ParserMatchClass = MemMode5AsmOperand;
552 let EncoderMethod = "getAddrMode5OpValue";
555 // addrmode6 := reg with optional alignment
557 def addrmode6 : Operand<i32>,
558 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
559 let PrintMethod = "printAddrMode6Operand";
560 let MIOperandInfo = (ops GPR:$addr, i32imm);
561 let EncoderMethod = "getAddrMode6AddressOpValue";
564 def am6offset : Operand<i32> {
565 let PrintMethod = "printAddrMode6OffsetOperand";
566 let MIOperandInfo = (ops GPR);
567 let EncoderMethod = "getAddrMode6OffsetOpValue";
570 // Special version of addrmode6 to handle alignment encoding for VLD-dup
571 // instructions, specifically VLD4-dup.
572 def addrmode6dup : Operand<i32>,
573 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
574 let PrintMethod = "printAddrMode6Operand";
575 let MIOperandInfo = (ops GPR:$addr, i32imm);
576 let EncoderMethod = "getAddrMode6DupAddressOpValue";
579 // addrmodepc := pc + reg
581 def addrmodepc : Operand<i32>,
582 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
583 let PrintMethod = "printAddrModePCOperand";
584 let MIOperandInfo = (ops GPR, i32imm);
587 def nohash_imm : Operand<i32> {
588 let PrintMethod = "printNoHashImmediate";
591 def CoprocNumAsmOperand : AsmOperandClass {
592 let Name = "CoprocNum";
593 let SuperClasses = [];
594 let ParserMethod = "tryParseCoprocNumOperand";
597 def CoprocRegAsmOperand : AsmOperandClass {
598 let Name = "CoprocReg";
599 let SuperClasses = [];
600 let ParserMethod = "tryParseCoprocRegOperand";
603 def p_imm : Operand<i32> {
604 let PrintMethod = "printPImmediate";
605 let ParserMatchClass = CoprocNumAsmOperand;
608 def c_imm : Operand<i32> {
609 let PrintMethod = "printCImmediate";
610 let ParserMatchClass = CoprocRegAsmOperand;
613 //===----------------------------------------------------------------------===//
615 include "ARMInstrFormats.td"
617 //===----------------------------------------------------------------------===//
618 // Multiclass helpers...
621 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
622 /// binop that produces a value.
623 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
624 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
625 PatFrag opnode, bit Commutable = 0> {
626 // The register-immediate version is re-materializable. This is useful
627 // in particular for taking the address of a local.
628 let isReMaterializable = 1 in {
629 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
630 iii, opc, "\t$Rd, $Rn, $imm",
631 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
636 let Inst{19-16} = Rn;
637 let Inst{15-12} = Rd;
638 let Inst{11-0} = imm;
641 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
642 iir, opc, "\t$Rd, $Rn, $Rm",
643 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
648 let isCommutable = Commutable;
649 let Inst{19-16} = Rn;
650 let Inst{15-12} = Rd;
651 let Inst{11-4} = 0b00000000;
654 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
655 iis, opc, "\t$Rd, $Rn, $shift",
656 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
661 let Inst{19-16} = Rn;
662 let Inst{15-12} = Rd;
663 let Inst{11-0} = shift;
667 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
668 /// instruction modifies the CPSR register.
669 let isCodeGenOnly = 1, Defs = [CPSR] in {
670 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
671 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
672 PatFrag opnode, bit Commutable = 0> {
673 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
674 iii, opc, "\t$Rd, $Rn, $imm",
675 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
681 let Inst{19-16} = Rn;
682 let Inst{15-12} = Rd;
683 let Inst{11-0} = imm;
685 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
686 iir, opc, "\t$Rd, $Rn, $Rm",
687 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
691 let isCommutable = Commutable;
694 let Inst{19-16} = Rn;
695 let Inst{15-12} = Rd;
696 let Inst{11-4} = 0b00000000;
699 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
700 iis, opc, "\t$Rd, $Rn, $shift",
701 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
707 let Inst{19-16} = Rn;
708 let Inst{15-12} = Rd;
709 let Inst{11-0} = shift;
714 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
715 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
716 /// a explicit result, only implicitly set CPSR.
717 let isCompare = 1, Defs = [CPSR] in {
718 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
719 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
720 PatFrag opnode, bit Commutable = 0> {
721 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
723 [(opnode GPR:$Rn, so_imm:$imm)]> {
728 let Inst{19-16} = Rn;
729 let Inst{15-12} = 0b0000;
730 let Inst{11-0} = imm;
732 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
734 [(opnode GPR:$Rn, GPR:$Rm)]> {
737 let isCommutable = Commutable;
740 let Inst{19-16} = Rn;
741 let Inst{15-12} = 0b0000;
742 let Inst{11-4} = 0b00000000;
745 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
746 opc, "\t$Rn, $shift",
747 [(opnode GPR:$Rn, so_reg:$shift)]> {
752 let Inst{19-16} = Rn;
753 let Inst{15-12} = 0b0000;
754 let Inst{11-0} = shift;
759 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
760 /// register and one whose operand is a register rotated by 8/16/24.
761 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
762 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
763 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
764 IIC_iEXTr, opc, "\t$Rd, $Rm",
765 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
766 Requires<[IsARM, HasV6]> {
769 let Inst{19-16} = 0b1111;
770 let Inst{15-12} = Rd;
771 let Inst{11-10} = 0b00;
774 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
775 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
776 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
777 Requires<[IsARM, HasV6]> {
781 let Inst{19-16} = 0b1111;
782 let Inst{15-12} = Rd;
783 let Inst{11-10} = rot;
788 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
789 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
790 IIC_iEXTr, opc, "\t$Rd, $Rm",
791 [/* For disassembly only; pattern left blank */]>,
792 Requires<[IsARM, HasV6]> {
793 let Inst{19-16} = 0b1111;
794 let Inst{11-10} = 0b00;
796 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
797 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
798 [/* For disassembly only; pattern left blank */]>,
799 Requires<[IsARM, HasV6]> {
801 let Inst{19-16} = 0b1111;
802 let Inst{11-10} = rot;
806 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
807 /// register and one whose operand is a register rotated by 8/16/24.
808 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
809 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
810 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
811 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
812 Requires<[IsARM, HasV6]> {
816 let Inst{19-16} = Rn;
817 let Inst{15-12} = Rd;
818 let Inst{11-10} = 0b00;
819 let Inst{9-4} = 0b000111;
822 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
824 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
825 [(set GPR:$Rd, (opnode GPR:$Rn,
826 (rotr GPR:$Rm, rot_imm:$rot)))]>,
827 Requires<[IsARM, HasV6]> {
832 let Inst{19-16} = Rn;
833 let Inst{15-12} = Rd;
834 let Inst{11-10} = rot;
835 let Inst{9-4} = 0b000111;
840 // For disassembly only.
841 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
842 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
843 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
844 [/* For disassembly only; pattern left blank */]>,
845 Requires<[IsARM, HasV6]> {
846 let Inst{11-10} = 0b00;
848 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
850 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
851 [/* For disassembly only; pattern left blank */]>,
852 Requires<[IsARM, HasV6]> {
855 let Inst{19-16} = Rn;
856 let Inst{11-10} = rot;
860 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
861 let Uses = [CPSR] in {
862 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
863 bit Commutable = 0> {
864 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
865 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
866 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
872 let Inst{15-12} = Rd;
873 let Inst{19-16} = Rn;
874 let Inst{11-0} = imm;
876 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
877 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
878 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
883 let Inst{11-4} = 0b00000000;
885 let isCommutable = Commutable;
887 let Inst{15-12} = Rd;
888 let Inst{19-16} = Rn;
890 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
891 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
892 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
898 let Inst{11-0} = shift;
899 let Inst{15-12} = Rd;
900 let Inst{19-16} = Rn;
903 // Carry setting variants
904 let isCodeGenOnly = 1, Defs = [CPSR] in {
905 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
906 bit Commutable = 0> {
907 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
908 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
909 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
914 let Inst{15-12} = Rd;
915 let Inst{19-16} = Rn;
916 let Inst{11-0} = imm;
920 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
921 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
922 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
927 let Inst{11-4} = 0b00000000;
928 let isCommutable = Commutable;
930 let Inst{15-12} = Rd;
931 let Inst{19-16} = Rn;
935 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
936 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
937 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
942 let Inst{11-0} = shift;
943 let Inst{15-12} = Rd;
944 let Inst{19-16} = Rn;
952 let canFoldAsLoad = 1, isReMaterializable = 1 in {
953 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
954 InstrItinClass iir, PatFrag opnode> {
955 // Note: We use the complex addrmode_imm12 rather than just an input
956 // GPR and a constrained immediate so that we can use this to match
957 // frame index references and avoid matching constant pool references.
958 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
959 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
960 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
963 let Inst{23} = addr{12}; // U (add = ('U' == 1))
964 let Inst{19-16} = addr{16-13}; // Rn
965 let Inst{15-12} = Rt;
966 let Inst{11-0} = addr{11-0}; // imm12
968 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
969 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
970 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
973 let Inst{23} = shift{12}; // U (add = ('U' == 1))
974 let Inst{19-16} = shift{16-13}; // Rn
975 let Inst{15-12} = Rt;
976 let Inst{11-0} = shift{11-0};
981 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
982 InstrItinClass iir, PatFrag opnode> {
983 // Note: We use the complex addrmode_imm12 rather than just an input
984 // GPR and a constrained immediate so that we can use this to match
985 // frame index references and avoid matching constant pool references.
986 def i12 : AI2ldst<0b010, 0, isByte, (outs),
987 (ins GPR:$Rt, addrmode_imm12:$addr),
988 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
989 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
992 let Inst{23} = addr{12}; // U (add = ('U' == 1))
993 let Inst{19-16} = addr{16-13}; // Rn
994 let Inst{15-12} = Rt;
995 let Inst{11-0} = addr{11-0}; // imm12
997 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
998 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
999 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1002 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1003 let Inst{19-16} = shift{16-13}; // Rn
1004 let Inst{15-12} = Rt;
1005 let Inst{11-0} = shift{11-0};
1008 //===----------------------------------------------------------------------===//
1010 //===----------------------------------------------------------------------===//
1012 //===----------------------------------------------------------------------===//
1013 // Miscellaneous Instructions.
1016 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1017 /// the function. The first operand is the ID# for this instruction, the second
1018 /// is the index into the MachineConstantPool that this is, the third is the
1019 /// size in bytes of this constant pool entry.
1020 let neverHasSideEffects = 1, isNotDuplicable = 1 in
1021 def CONSTPOOL_ENTRY :
1022 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1023 i32imm:$size), NoItinerary, []>;
1025 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1026 // from removing one half of the matched pairs. That breaks PEI, which assumes
1027 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1028 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1029 def ADJCALLSTACKUP :
1030 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1031 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1033 def ADJCALLSTACKDOWN :
1034 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1035 [(ARMcallseq_start timm:$amt)]>;
1038 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
1039 [/* For disassembly only; pattern left blank */]>,
1040 Requires<[IsARM, HasV6T2]> {
1041 let Inst{27-16} = 0b001100100000;
1042 let Inst{15-8} = 0b11110000;
1043 let Inst{7-0} = 0b00000000;
1046 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1047 [/* For disassembly only; pattern left blank */]>,
1048 Requires<[IsARM, HasV6T2]> {
1049 let Inst{27-16} = 0b001100100000;
1050 let Inst{15-8} = 0b11110000;
1051 let Inst{7-0} = 0b00000001;
1054 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1055 [/* For disassembly only; pattern left blank */]>,
1056 Requires<[IsARM, HasV6T2]> {
1057 let Inst{27-16} = 0b001100100000;
1058 let Inst{15-8} = 0b11110000;
1059 let Inst{7-0} = 0b00000010;
1062 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1063 [/* For disassembly only; pattern left blank */]>,
1064 Requires<[IsARM, HasV6T2]> {
1065 let Inst{27-16} = 0b001100100000;
1066 let Inst{15-8} = 0b11110000;
1067 let Inst{7-0} = 0b00000011;
1070 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1072 [/* For disassembly only; pattern left blank */]>,
1073 Requires<[IsARM, HasV6]> {
1078 let Inst{15-12} = Rd;
1079 let Inst{19-16} = Rn;
1080 let Inst{27-20} = 0b01101000;
1081 let Inst{7-4} = 0b1011;
1082 let Inst{11-8} = 0b1111;
1085 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1086 [/* For disassembly only; pattern left blank */]>,
1087 Requires<[IsARM, HasV6T2]> {
1088 let Inst{27-16} = 0b001100100000;
1089 let Inst{15-8} = 0b11110000;
1090 let Inst{7-0} = 0b00000100;
1093 // The i32imm operand $val can be used by a debugger to store more information
1094 // about the breakpoint.
1095 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1096 [/* For disassembly only; pattern left blank */]>,
1099 let Inst{3-0} = val{3-0};
1100 let Inst{19-8} = val{15-4};
1101 let Inst{27-20} = 0b00010010;
1102 let Inst{7-4} = 0b0111;
1105 // Change Processor State is a system instruction -- for disassembly only.
1106 // The singleton $opt operand contains the following information:
1107 // opt{4-0} = mode from Inst{4-0}
1108 // opt{5} = changemode from Inst{17}
1109 // opt{8-6} = AIF from Inst{8-6}
1110 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1111 // FIXME: Integrated assembler will need these split out.
1112 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1113 [/* For disassembly only; pattern left blank */]>,
1115 let Inst{31-28} = 0b1111;
1116 let Inst{27-20} = 0b00010000;
1121 // Preload signals the memory system of possible future data/instruction access.
1122 // These are for disassembly only.
1123 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1125 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1126 !strconcat(opc, "\t$addr"),
1127 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1130 let Inst{31-26} = 0b111101;
1131 let Inst{25} = 0; // 0 for immediate form
1132 let Inst{24} = data;
1133 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1134 let Inst{22} = read;
1135 let Inst{21-20} = 0b01;
1136 let Inst{19-16} = addr{16-13}; // Rn
1137 let Inst{15-12} = 0b1111;
1138 let Inst{11-0} = addr{11-0}; // imm12
1141 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1142 !strconcat(opc, "\t$shift"),
1143 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1145 let Inst{31-26} = 0b111101;
1146 let Inst{25} = 1; // 1 for register form
1147 let Inst{24} = data;
1148 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1149 let Inst{22} = read;
1150 let Inst{21-20} = 0b01;
1151 let Inst{19-16} = shift{16-13}; // Rn
1152 let Inst{15-12} = 0b1111;
1153 let Inst{11-0} = shift{11-0};
1157 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1158 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1159 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1161 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1163 [/* For disassembly only; pattern left blank */]>,
1166 let Inst{31-10} = 0b1111000100000001000000;
1171 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1172 [/* For disassembly only; pattern left blank */]>,
1173 Requires<[IsARM, HasV7]> {
1175 let Inst{27-4} = 0b001100100000111100001111;
1176 let Inst{3-0} = opt;
1179 // A5.4 Permanently UNDEFINED instructions.
1180 let isBarrier = 1, isTerminator = 1 in
1181 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1184 let Inst = 0xe7ffdefe;
1187 // Address computation and loads and stores in PIC mode.
1188 let isNotDuplicable = 1 in {
1189 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1190 Size4Bytes, IIC_iALUr,
1191 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1193 let AddedComplexity = 10 in {
1194 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1195 Size4Bytes, IIC_iLoad_r,
1196 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1198 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1199 Size4Bytes, IIC_iLoad_bh_r,
1200 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1202 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1203 Size4Bytes, IIC_iLoad_bh_r,
1204 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1206 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1207 Size4Bytes, IIC_iLoad_bh_r,
1208 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1210 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1211 Size4Bytes, IIC_iLoad_bh_r,
1212 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1214 let AddedComplexity = 10 in {
1215 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1216 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1218 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1219 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1220 addrmodepc:$addr)]>;
1222 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1223 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1225 } // isNotDuplicable = 1
1228 // LEApcrel - Load a pc-relative address into a register without offending the
1230 let neverHasSideEffects = 1, isReMaterializable = 1 in
1231 // The 'adr' mnemonic encodes differently if the label is before or after
1232 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1233 // know until then which form of the instruction will be used.
1234 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1235 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1238 let Inst{27-25} = 0b001;
1240 let Inst{19-16} = 0b1111;
1241 let Inst{15-12} = Rd;
1242 let Inst{11-0} = label;
1244 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1245 Size4Bytes, IIC_iALUi, []>;
1247 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1248 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1249 Size4Bytes, IIC_iALUi, []>;
1251 //===----------------------------------------------------------------------===//
1252 // Control Flow Instructions.
1255 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1257 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1258 "bx", "\tlr", [(ARMretflag)]>,
1259 Requires<[IsARM, HasV4T]> {
1260 let Inst{27-0} = 0b0001001011111111111100011110;
1264 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1265 "mov", "\tpc, lr", [(ARMretflag)]>,
1266 Requires<[IsARM, NoV4T]> {
1267 let Inst{27-0} = 0b0001101000001111000000001110;
1271 // Indirect branches
1272 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1274 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1275 [(brind GPR:$dst)]>,
1276 Requires<[IsARM, HasV4T]> {
1278 let Inst{31-4} = 0b1110000100101111111111110001;
1279 let Inst{3-0} = dst;
1283 // FIXME: We would really like to define this as a vanilla ARMPat like:
1284 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1285 // With that, however, we can't set isBranch, isTerminator, etc..
1286 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1287 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1288 Requires<[IsARM, NoV4T]>;
1291 // All calls clobber the non-callee saved registers. SP is marked as
1292 // a use to prevent stack-pointer assignments that appear immediately
1293 // before calls from potentially appearing dead.
1295 // On non-Darwin platforms R9 is callee-saved.
1296 Defs = [R0, R1, R2, R3, R12, LR,
1297 D0, D1, D2, D3, D4, D5, D6, D7,
1298 D16, D17, D18, D19, D20, D21, D22, D23,
1299 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1301 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1302 IIC_Br, "bl\t$func",
1303 [(ARMcall tglobaladdr:$func)]>,
1304 Requires<[IsARM, IsNotDarwin]> {
1305 let Inst{31-28} = 0b1110;
1307 let Inst{23-0} = func;
1310 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1311 IIC_Br, "bl", "\t$func",
1312 [(ARMcall_pred tglobaladdr:$func)]>,
1313 Requires<[IsARM, IsNotDarwin]> {
1315 let Inst{23-0} = func;
1319 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1320 IIC_Br, "blx\t$func",
1321 [(ARMcall GPR:$func)]>,
1322 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1324 let Inst{31-4} = 0b1110000100101111111111110011;
1325 let Inst{3-0} = func;
1329 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1330 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1331 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1332 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1335 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1336 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1337 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1341 // On Darwin R9 is call-clobbered.
1342 // R7 is marked as a use to prevent frame-pointer assignments from being
1343 // moved above / below calls.
1344 Defs = [R0, R1, R2, R3, R9, R12, LR,
1345 D0, D1, D2, D3, D4, D5, D6, D7,
1346 D16, D17, D18, D19, D20, D21, D22, D23,
1347 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1348 Uses = [R7, SP] in {
1349 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1350 IIC_Br, "bl\t$func",
1351 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1352 let Inst{31-28} = 0b1110;
1354 let Inst{23-0} = func;
1357 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1358 IIC_Br, "bl", "\t$func",
1359 [(ARMcall_pred tglobaladdr:$func)]>,
1360 Requires<[IsARM, IsDarwin]> {
1362 let Inst{23-0} = func;
1366 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1367 IIC_Br, "blx\t$func",
1368 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1370 let Inst{31-4} = 0b1110000100101111111111110011;
1371 let Inst{3-0} = func;
1375 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1376 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1377 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1378 Requires<[IsARM, HasV4T, IsDarwin]>;
1381 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1382 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1383 Requires<[IsARM, NoV4T, IsDarwin]>;
1388 // FIXME: These should probably be xformed into the non-TC versions of the
1389 // instructions as part of MC lowering.
1390 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1391 // Thumb should have its own version since the instruction is actually
1392 // different, even though the mnemonic is the same.
1393 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1395 let Defs = [R0, R1, R2, R3, R9, R12,
1396 D0, D1, D2, D3, D4, D5, D6, D7,
1397 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1398 D27, D28, D29, D30, D31, PC],
1400 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1401 IIC_Br, []>, Requires<[IsDarwin]>;
1403 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1404 IIC_Br, []>, Requires<[IsDarwin]>;
1406 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1407 IIC_Br, "b\t$dst @ TAILCALL",
1408 []>, Requires<[IsARM, IsDarwin]>;
1410 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1411 IIC_Br, "b.w\t$dst @ TAILCALL",
1412 []>, Requires<[IsThumb, IsDarwin]>;
1414 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1415 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1416 []>, Requires<[IsDarwin]> {
1418 let Inst{31-4} = 0b1110000100101111111111110001;
1419 let Inst{3-0} = dst;
1423 // Non-Darwin versions (the difference is R9).
1424 let Defs = [R0, R1, R2, R3, R12,
1425 D0, D1, D2, D3, D4, D5, D6, D7,
1426 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1427 D27, D28, D29, D30, D31, PC],
1429 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1430 IIC_Br, []>, Requires<[IsNotDarwin]>;
1432 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1433 IIC_Br, []>, Requires<[IsNotDarwin]>;
1435 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1436 IIC_Br, "b\t$dst @ TAILCALL",
1437 []>, Requires<[IsARM, IsNotDarwin]>;
1439 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1440 IIC_Br, "b.w\t$dst @ TAILCALL",
1441 []>, Requires<[IsThumb, IsNotDarwin]>;
1443 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1444 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1445 []>, Requires<[IsNotDarwin]> {
1447 let Inst{31-4} = 0b1110000100101111111111110001;
1448 let Inst{3-0} = dst;
1453 let isBranch = 1, isTerminator = 1 in {
1454 // B is "predicable" since it can be xformed into a Bcc.
1455 let isBarrier = 1 in {
1456 let isPredicable = 1 in
1457 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1458 "b\t$target", [(br bb:$target)]> {
1460 let Inst{31-28} = 0b1110;
1461 let Inst{23-0} = target;
1464 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1465 def BR_JTr : ARMPseudoInst<(outs),
1466 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1467 SizeSpecial, IIC_Br,
1468 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1469 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1470 // into i12 and rs suffixed versions.
1471 def BR_JTm : ARMPseudoInst<(outs),
1472 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1473 SizeSpecial, IIC_Br,
1474 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1476 def BR_JTadd : ARMPseudoInst<(outs),
1477 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1478 SizeSpecial, IIC_Br,
1479 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1481 } // isNotDuplicable = 1, isIndirectBranch = 1
1484 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1485 // a two-value operand where a dag node expects two operands. :(
1486 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1487 IIC_Br, "b", "\t$target",
1488 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1490 let Inst{23-0} = target;
1494 // Branch and Exchange Jazelle -- for disassembly only
1495 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1496 [/* For disassembly only; pattern left blank */]> {
1497 let Inst{23-20} = 0b0010;
1498 //let Inst{19-8} = 0xfff;
1499 let Inst{7-4} = 0b0010;
1502 // Secure Monitor Call is a system instruction -- for disassembly only
1503 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1504 [/* For disassembly only; pattern left blank */]> {
1506 let Inst{23-4} = 0b01100000000000000111;
1507 let Inst{3-0} = opt;
1510 // Supervisor Call (Software Interrupt) -- for disassembly only
1511 let isCall = 1, Uses = [SP] in {
1512 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1513 [/* For disassembly only; pattern left blank */]> {
1515 let Inst{23-0} = svc;
1519 // Store Return State is a system instruction -- for disassembly only
1520 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1521 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1522 NoItinerary, "srs${amode}\tsp!, $mode",
1523 [/* For disassembly only; pattern left blank */]> {
1524 let Inst{31-28} = 0b1111;
1525 let Inst{22-20} = 0b110; // W = 1
1528 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1529 NoItinerary, "srs${amode}\tsp, $mode",
1530 [/* For disassembly only; pattern left blank */]> {
1531 let Inst{31-28} = 0b1111;
1532 let Inst{22-20} = 0b100; // W = 0
1535 // Return From Exception is a system instruction -- for disassembly only
1536 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1537 NoItinerary, "rfe${amode}\t$base!",
1538 [/* For disassembly only; pattern left blank */]> {
1539 let Inst{31-28} = 0b1111;
1540 let Inst{22-20} = 0b011; // W = 1
1543 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1544 NoItinerary, "rfe${amode}\t$base",
1545 [/* For disassembly only; pattern left blank */]> {
1546 let Inst{31-28} = 0b1111;
1547 let Inst{22-20} = 0b001; // W = 0
1549 } // isCodeGenOnly = 1
1551 //===----------------------------------------------------------------------===//
1552 // Load / store Instructions.
1558 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1559 UnOpFrag<(load node:$Src)>>;
1560 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1561 UnOpFrag<(zextloadi8 node:$Src)>>;
1562 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1563 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1564 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1565 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1567 // Special LDR for loads from non-pc-relative constpools.
1568 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1569 isReMaterializable = 1 in
1570 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1571 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1575 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1576 let Inst{19-16} = 0b1111;
1577 let Inst{15-12} = Rt;
1578 let Inst{11-0} = addr{11-0}; // imm12
1581 // Loads with zero extension
1582 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1583 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1584 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1586 // Loads with sign extension
1587 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1588 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1589 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1591 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1592 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1593 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1595 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1596 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1597 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1598 // how to represent that such that tblgen is happy and we don't
1599 // mark this codegen only?
1601 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1602 (ins addrmode3:$addr), LdMiscFrm,
1603 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1604 []>, Requires<[IsARM, HasV5TE]>;
1608 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1609 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1610 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1611 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1613 // {13} 1 == Rm, 0 == imm12
1617 let Inst{25} = addr{13};
1618 let Inst{23} = addr{12};
1619 let Inst{19-16} = addr{17-14};
1620 let Inst{11-0} = addr{11-0};
1622 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1623 (ins GPR:$Rn, am2offset:$offset),
1624 IndexModePost, LdFrm, itin,
1625 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1626 // {13} 1 == Rm, 0 == imm12
1631 let Inst{25} = offset{13};
1632 let Inst{23} = offset{12};
1633 let Inst{19-16} = Rn;
1634 let Inst{11-0} = offset{11-0};
1638 let mayLoad = 1, neverHasSideEffects = 1 in {
1639 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1640 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1643 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1644 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1645 (ins addrmode3:$addr), IndexModePre,
1647 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1649 let Inst{23} = addr{8}; // U bit
1650 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1651 let Inst{19-16} = addr{12-9}; // Rn
1652 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1653 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1655 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1656 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1658 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1661 let Inst{23} = offset{8}; // U bit
1662 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1663 let Inst{19-16} = Rn;
1664 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1665 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1669 let mayLoad = 1, neverHasSideEffects = 1 in {
1670 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1671 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1672 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1673 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1674 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1675 } // mayLoad = 1, neverHasSideEffects = 1
1677 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1678 let mayLoad = 1, neverHasSideEffects = 1 in {
1679 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1680 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1681 LdFrm, IIC_iLoad_ru,
1682 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1683 let Inst{21} = 1; // overwrite
1685 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1686 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1687 LdFrm, IIC_iLoad_bh_ru,
1688 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1689 let Inst{21} = 1; // overwrite
1691 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1692 (ins GPR:$base, am3offset:$offset), IndexModePost,
1693 LdMiscFrm, IIC_iLoad_bh_ru,
1694 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1695 let Inst{21} = 1; // overwrite
1697 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1698 (ins GPR:$base, am3offset:$offset), IndexModePost,
1699 LdMiscFrm, IIC_iLoad_bh_ru,
1700 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1701 let Inst{21} = 1; // overwrite
1703 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1704 (ins GPR:$base, am3offset:$offset), IndexModePost,
1705 LdMiscFrm, IIC_iLoad_bh_ru,
1706 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1707 let Inst{21} = 1; // overwrite
1713 // Stores with truncate
1714 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1715 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1716 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1719 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1720 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1721 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1722 StMiscFrm, IIC_iStore_d_r,
1723 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1726 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1727 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1728 IndexModePre, StFrm, IIC_iStore_ru,
1729 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1731 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1733 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1734 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1735 IndexModePost, StFrm, IIC_iStore_ru,
1736 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1738 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1740 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1741 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1742 IndexModePre, StFrm, IIC_iStore_bh_ru,
1743 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1744 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1745 GPR:$Rn, am2offset:$offset))]>;
1746 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1747 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1748 IndexModePost, StFrm, IIC_iStore_bh_ru,
1749 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1750 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1751 GPR:$Rn, am2offset:$offset))]>;
1753 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1754 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1755 IndexModePre, StMiscFrm, IIC_iStore_ru,
1756 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1758 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1760 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1761 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1762 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1763 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1764 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1765 GPR:$Rn, am3offset:$offset))]>;
1767 // For disassembly only
1768 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1769 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1770 StMiscFrm, IIC_iStore_d_ru,
1771 "strd", "\t$src1, $src2, [$base, $offset]!",
1772 "$base = $base_wb", []>;
1774 // For disassembly only
1775 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1776 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1777 StMiscFrm, IIC_iStore_d_ru,
1778 "strd", "\t$src1, $src2, [$base], $offset",
1779 "$base = $base_wb", []>;
1781 // STRT, STRBT, and STRHT are for disassembly only.
1783 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1784 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1785 IndexModeNone, StFrm, IIC_iStore_ru,
1786 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1787 [/* For disassembly only; pattern left blank */]> {
1788 let Inst{21} = 1; // overwrite
1791 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1792 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1793 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1794 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1795 [/* For disassembly only; pattern left blank */]> {
1796 let Inst{21} = 1; // overwrite
1799 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1800 (ins GPR:$src, GPR:$base,am3offset:$offset),
1801 StMiscFrm, IIC_iStore_bh_ru,
1802 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1803 [/* For disassembly only; pattern left blank */]> {
1804 let Inst{21} = 1; // overwrite
1807 //===----------------------------------------------------------------------===//
1808 // Load / store multiple Instructions.
1811 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1812 InstrItinClass itin, InstrItinClass itin_upd> {
1814 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1815 IndexModeNone, f, itin,
1816 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1817 let Inst{24-23} = 0b01; // Increment After
1818 let Inst{21} = 0; // No writeback
1819 let Inst{20} = L_bit;
1822 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1823 IndexModeUpd, f, itin_upd,
1824 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1825 let Inst{24-23} = 0b01; // Increment After
1826 let Inst{21} = 1; // Writeback
1827 let Inst{20} = L_bit;
1830 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1831 IndexModeNone, f, itin,
1832 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1833 let Inst{24-23} = 0b00; // Decrement After
1834 let Inst{21} = 0; // No writeback
1835 let Inst{20} = L_bit;
1838 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1839 IndexModeUpd, f, itin_upd,
1840 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1841 let Inst{24-23} = 0b00; // Decrement After
1842 let Inst{21} = 1; // Writeback
1843 let Inst{20} = L_bit;
1846 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1847 IndexModeNone, f, itin,
1848 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1849 let Inst{24-23} = 0b10; // Decrement Before
1850 let Inst{21} = 0; // No writeback
1851 let Inst{20} = L_bit;
1854 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1855 IndexModeUpd, f, itin_upd,
1856 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1857 let Inst{24-23} = 0b10; // Decrement Before
1858 let Inst{21} = 1; // Writeback
1859 let Inst{20} = L_bit;
1862 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1863 IndexModeNone, f, itin,
1864 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1865 let Inst{24-23} = 0b11; // Increment Before
1866 let Inst{21} = 0; // No writeback
1867 let Inst{20} = L_bit;
1870 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1871 IndexModeUpd, f, itin_upd,
1872 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1873 let Inst{24-23} = 0b11; // Increment Before
1874 let Inst{21} = 1; // Writeback
1875 let Inst{20} = L_bit;
1879 let neverHasSideEffects = 1 in {
1881 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1882 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1884 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1885 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1887 } // neverHasSideEffects
1889 // Load / Store Multiple Mnemonic Aliases
1890 def : MnemonicAlias<"ldm", "ldmia">;
1891 def : MnemonicAlias<"stm", "stmia">;
1893 // FIXME: remove when we have a way to marking a MI with these properties.
1894 // FIXME: Should pc be an implicit operand like PICADD, etc?
1895 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1896 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1897 // FIXME: Should be a pseudo-instruction.
1898 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1899 reglist:$regs, variable_ops),
1900 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1901 "ldmia${p}\t$Rn!, $regs",
1903 let Inst{24-23} = 0b01; // Increment After
1904 let Inst{21} = 1; // Writeback
1905 let Inst{20} = 1; // Load
1908 //===----------------------------------------------------------------------===//
1909 // Move Instructions.
1912 let neverHasSideEffects = 1 in
1913 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1914 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1918 let Inst{11-4} = 0b00000000;
1921 let Inst{15-12} = Rd;
1924 // A version for the smaller set of tail call registers.
1925 let neverHasSideEffects = 1 in
1926 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1927 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1931 let Inst{11-4} = 0b00000000;
1934 let Inst{15-12} = Rd;
1937 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1938 DPSoRegFrm, IIC_iMOVsr,
1939 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1943 let Inst{15-12} = Rd;
1944 let Inst{11-0} = src;
1948 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1949 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1950 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1954 let Inst{15-12} = Rd;
1955 let Inst{19-16} = 0b0000;
1956 let Inst{11-0} = imm;
1959 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1960 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1962 "movw", "\t$Rd, $imm",
1963 [(set GPR:$Rd, imm0_65535:$imm)]>,
1964 Requires<[IsARM, HasV6T2]>, UnaryDP {
1967 let Inst{15-12} = Rd;
1968 let Inst{11-0} = imm{11-0};
1969 let Inst{19-16} = imm{15-12};
1974 def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1975 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1977 let Constraints = "$src = $Rd" in {
1978 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1980 "movt", "\t$Rd, $imm",
1982 (or (and GPR:$src, 0xffff),
1983 lo16AllZero:$imm))]>, UnaryDP,
1984 Requires<[IsARM, HasV6T2]> {
1987 let Inst{15-12} = Rd;
1988 let Inst{11-0} = imm{11-0};
1989 let Inst{19-16} = imm{15-12};
1994 def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1995 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1999 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2000 Requires<[IsARM, HasV6T2]>;
2002 let Uses = [CPSR] in
2003 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2004 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2007 // These aren't really mov instructions, but we have to define them this way
2008 // due to flag operands.
2010 let Defs = [CPSR] in {
2011 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2012 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2014 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2015 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2019 //===----------------------------------------------------------------------===//
2020 // Extend Instructions.
2025 defm SXTB : AI_ext_rrot<0b01101010,
2026 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2027 defm SXTH : AI_ext_rrot<0b01101011,
2028 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2030 defm SXTAB : AI_exta_rrot<0b01101010,
2031 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2032 defm SXTAH : AI_exta_rrot<0b01101011,
2033 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2035 // For disassembly only
2036 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2038 // For disassembly only
2039 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2043 let AddedComplexity = 16 in {
2044 defm UXTB : AI_ext_rrot<0b01101110,
2045 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2046 defm UXTH : AI_ext_rrot<0b01101111,
2047 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2048 defm UXTB16 : AI_ext_rrot<0b01101100,
2049 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2051 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2052 // The transformation should probably be done as a combiner action
2053 // instead so we can include a check for masking back in the upper
2054 // eight bits of the source into the lower eight bits of the result.
2055 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2056 // (UXTB16r_rot GPR:$Src, 24)>;
2057 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2058 (UXTB16r_rot GPR:$Src, 8)>;
2060 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2061 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2062 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2063 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2066 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2067 // For disassembly only
2068 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2071 def SBFX : I<(outs GPR:$Rd),
2072 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2073 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2074 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2075 Requires<[IsARM, HasV6T2]> {
2080 let Inst{27-21} = 0b0111101;
2081 let Inst{6-4} = 0b101;
2082 let Inst{20-16} = width;
2083 let Inst{15-12} = Rd;
2084 let Inst{11-7} = lsb;
2088 def UBFX : I<(outs GPR:$Rd),
2089 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2090 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2091 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2092 Requires<[IsARM, HasV6T2]> {
2097 let Inst{27-21} = 0b0111111;
2098 let Inst{6-4} = 0b101;
2099 let Inst{20-16} = width;
2100 let Inst{15-12} = Rd;
2101 let Inst{11-7} = lsb;
2105 //===----------------------------------------------------------------------===//
2106 // Arithmetic Instructions.
2109 defm ADD : AsI1_bin_irs<0b0100, "add",
2110 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2111 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2112 defm SUB : AsI1_bin_irs<0b0010, "sub",
2113 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2114 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2116 // ADD and SUB with 's' bit set.
2117 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2118 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2119 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2120 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2121 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2122 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2124 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2125 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2126 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2127 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2129 // ADC and SUBC with 's' bit set.
2130 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2131 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2132 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2133 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2135 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2136 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2137 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2142 let Inst{15-12} = Rd;
2143 let Inst{19-16} = Rn;
2144 let Inst{11-0} = imm;
2147 // The reg/reg form is only defined for the disassembler; for codegen it is
2148 // equivalent to SUBrr.
2149 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2150 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2151 [/* For disassembly only; pattern left blank */]> {
2155 let Inst{11-4} = 0b00000000;
2158 let Inst{15-12} = Rd;
2159 let Inst{19-16} = Rn;
2162 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2163 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2164 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2169 let Inst{11-0} = shift;
2170 let Inst{15-12} = Rd;
2171 let Inst{19-16} = Rn;
2174 // RSB with 's' bit set.
2175 let isCodeGenOnly = 1, Defs = [CPSR] in {
2176 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2177 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2178 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2184 let Inst{15-12} = Rd;
2185 let Inst{19-16} = Rn;
2186 let Inst{11-0} = imm;
2188 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2189 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2190 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2196 let Inst{11-0} = shift;
2197 let Inst{15-12} = Rd;
2198 let Inst{19-16} = Rn;
2202 let Uses = [CPSR] in {
2203 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2204 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2205 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2211 let Inst{15-12} = Rd;
2212 let Inst{19-16} = Rn;
2213 let Inst{11-0} = imm;
2215 // The reg/reg form is only defined for the disassembler; for codegen it is
2216 // equivalent to SUBrr.
2217 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2218 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2219 [/* For disassembly only; pattern left blank */]> {
2223 let Inst{11-4} = 0b00000000;
2226 let Inst{15-12} = Rd;
2227 let Inst{19-16} = Rn;
2229 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2230 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2231 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2237 let Inst{11-0} = shift;
2238 let Inst{15-12} = Rd;
2239 let Inst{19-16} = Rn;
2243 // FIXME: Allow these to be predicated.
2244 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2245 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2246 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2247 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2254 let Inst{15-12} = Rd;
2255 let Inst{19-16} = Rn;
2256 let Inst{11-0} = imm;
2258 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2259 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2260 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2267 let Inst{11-0} = shift;
2268 let Inst{15-12} = Rd;
2269 let Inst{19-16} = Rn;
2273 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2274 // The assume-no-carry-in form uses the negation of the input since add/sub
2275 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2276 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2278 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2279 (SUBri GPR:$src, so_imm_neg:$imm)>;
2280 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2281 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2282 // The with-carry-in form matches bitwise not instead of the negation.
2283 // Effectively, the inverse interpretation of the carry flag already accounts
2284 // for part of the negation.
2285 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2286 (SBCri GPR:$src, so_imm_not:$imm)>;
2288 // Note: These are implemented in C++ code, because they have to generate
2289 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2291 // (mul X, 2^n+1) -> (add (X << n), X)
2292 // (mul X, 2^n-1) -> (rsb X, (X << n))
2294 // ARM Arithmetic Instruction -- for disassembly only
2295 // GPR:$dst = GPR:$a op GPR:$b
2296 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2297 list<dag> pattern = [/* For disassembly only; pattern left blank */],
2298 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm">
2299 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
2303 let Inst{27-20} = op27_20;
2304 let Inst{11-4} = op11_4;
2305 let Inst{19-16} = Rn;
2306 let Inst{15-12} = Rd;
2310 // Saturating add/subtract -- for disassembly only
2312 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2313 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))],
2314 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2315 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2316 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))],
2317 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2318 def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn),
2320 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn),
2323 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2324 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2325 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2326 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2327 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2328 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2329 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2330 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2331 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2332 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2333 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2334 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2336 // Signed/Unsigned add/subtract -- for disassembly only
2338 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2339 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2340 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2341 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2342 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2343 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2344 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2345 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2346 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2347 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2348 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2349 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2351 // Signed/Unsigned halving add/subtract -- for disassembly only
2353 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2354 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2355 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2356 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2357 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2358 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2359 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2360 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2361 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2362 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2363 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2364 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2366 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2368 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2369 MulFrm /* for convenience */, NoItinerary, "usad8",
2370 "\t$Rd, $Rn, $Rm", []>,
2371 Requires<[IsARM, HasV6]> {
2375 let Inst{27-20} = 0b01111000;
2376 let Inst{15-12} = 0b1111;
2377 let Inst{7-4} = 0b0001;
2378 let Inst{19-16} = Rd;
2379 let Inst{11-8} = Rm;
2382 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2383 MulFrm /* for convenience */, NoItinerary, "usada8",
2384 "\t$Rd, $Rn, $Rm, $Ra", []>,
2385 Requires<[IsARM, HasV6]> {
2390 let Inst{27-20} = 0b01111000;
2391 let Inst{7-4} = 0b0001;
2392 let Inst{19-16} = Rd;
2393 let Inst{15-12} = Ra;
2394 let Inst{11-8} = Rm;
2398 // Signed/Unsigned saturate -- for disassembly only
2400 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2401 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2402 [/* For disassembly only; pattern left blank */]> {
2407 let Inst{27-21} = 0b0110101;
2408 let Inst{5-4} = 0b01;
2409 let Inst{20-16} = sat_imm;
2410 let Inst{15-12} = Rd;
2411 let Inst{11-7} = sh{7-3};
2412 let Inst{6} = sh{0};
2416 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2417 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2418 [/* For disassembly only; pattern left blank */]> {
2422 let Inst{27-20} = 0b01101010;
2423 let Inst{11-4} = 0b11110011;
2424 let Inst{15-12} = Rd;
2425 let Inst{19-16} = sat_imm;
2429 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2430 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2431 [/* For disassembly only; pattern left blank */]> {
2436 let Inst{27-21} = 0b0110111;
2437 let Inst{5-4} = 0b01;
2438 let Inst{15-12} = Rd;
2439 let Inst{11-7} = sh{7-3};
2440 let Inst{6} = sh{0};
2441 let Inst{20-16} = sat_imm;
2445 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2446 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2447 [/* For disassembly only; pattern left blank */]> {
2451 let Inst{27-20} = 0b01101110;
2452 let Inst{11-4} = 0b11110011;
2453 let Inst{15-12} = Rd;
2454 let Inst{19-16} = sat_imm;
2458 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2459 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2461 //===----------------------------------------------------------------------===//
2462 // Bitwise Instructions.
2465 defm AND : AsI1_bin_irs<0b0000, "and",
2466 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2467 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2468 defm ORR : AsI1_bin_irs<0b1100, "orr",
2469 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2470 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2471 defm EOR : AsI1_bin_irs<0b0001, "eor",
2472 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2473 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2474 defm BIC : AsI1_bin_irs<0b1110, "bic",
2475 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2476 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2478 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2479 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2480 "bfc", "\t$Rd, $imm", "$src = $Rd",
2481 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2482 Requires<[IsARM, HasV6T2]> {
2485 let Inst{27-21} = 0b0111110;
2486 let Inst{6-0} = 0b0011111;
2487 let Inst{15-12} = Rd;
2488 let Inst{11-7} = imm{4-0}; // lsb
2489 let Inst{20-16} = imm{9-5}; // width
2492 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2493 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2494 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2495 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2496 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2497 bf_inv_mask_imm:$imm))]>,
2498 Requires<[IsARM, HasV6T2]> {
2502 let Inst{27-21} = 0b0111110;
2503 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2504 let Inst{15-12} = Rd;
2505 let Inst{11-7} = imm{4-0}; // lsb
2506 let Inst{20-16} = imm{9-5}; // width
2510 // GNU as only supports this form of bfi (w/ 4 arguments)
2511 let isAsmParserOnly = 1 in
2512 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2513 lsb_pos_imm:$lsb, width_imm:$width),
2514 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2515 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2516 []>, Requires<[IsARM, HasV6T2]> {
2521 let Inst{27-21} = 0b0111110;
2522 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2523 let Inst{15-12} = Rd;
2524 let Inst{11-7} = lsb;
2525 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2529 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2530 "mvn", "\t$Rd, $Rm",
2531 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2535 let Inst{19-16} = 0b0000;
2536 let Inst{11-4} = 0b00000000;
2537 let Inst{15-12} = Rd;
2540 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2541 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2542 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2546 let Inst{19-16} = 0b0000;
2547 let Inst{15-12} = Rd;
2548 let Inst{11-0} = shift;
2550 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2551 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2552 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2553 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2557 let Inst{19-16} = 0b0000;
2558 let Inst{15-12} = Rd;
2559 let Inst{11-0} = imm;
2562 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2563 (BICri GPR:$src, so_imm_not:$imm)>;
2565 //===----------------------------------------------------------------------===//
2566 // Multiply Instructions.
2568 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2569 string opc, string asm, list<dag> pattern>
2570 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2574 let Inst{19-16} = Rd;
2575 let Inst{11-8} = Rm;
2578 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2579 string opc, string asm, list<dag> pattern>
2580 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2585 let Inst{19-16} = RdHi;
2586 let Inst{15-12} = RdLo;
2587 let Inst{11-8} = Rm;
2591 let isCommutable = 1 in {
2592 let Constraints = "@earlyclobber $Rd" in
2593 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2594 pred:$p, cc_out:$s),
2595 Size4Bytes, IIC_iMUL32,
2596 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2597 Requires<[IsARM, NoV6]>;
2599 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2600 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2601 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2602 Requires<[IsARM, HasV6]>;
2605 let Constraints = "@earlyclobber $Rd" in
2606 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2607 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2608 Size4Bytes, IIC_iMAC32,
2609 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2610 Requires<[IsARM, NoV6]> {
2612 let Inst{15-12} = Ra;
2614 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2615 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2616 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2617 Requires<[IsARM, HasV6]> {
2619 let Inst{15-12} = Ra;
2622 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2623 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2624 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2625 Requires<[IsARM, HasV6T2]> {
2630 let Inst{19-16} = Rd;
2631 let Inst{15-12} = Ra;
2632 let Inst{11-8} = Rm;
2636 // Extra precision multiplies with low / high results
2638 let neverHasSideEffects = 1 in {
2639 let isCommutable = 1 in {
2640 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2641 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2642 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2643 Size4Bytes, IIC_iMUL64, []>,
2644 Requires<[IsARM, NoV6]>;
2646 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2647 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2648 Size4Bytes, IIC_iMUL64, []>,
2649 Requires<[IsARM, NoV6]>;
2652 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2653 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2654 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2655 Requires<[IsARM, HasV6]>;
2657 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2658 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2659 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2660 Requires<[IsARM, HasV6]>;
2663 // Multiply + accumulate
2664 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2665 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2666 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2667 Size4Bytes, IIC_iMAC64, []>,
2668 Requires<[IsARM, NoV6]>;
2669 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2670 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2671 Size4Bytes, IIC_iMAC64, []>,
2672 Requires<[IsARM, NoV6]>;
2673 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2674 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2675 Size4Bytes, IIC_iMAC64, []>,
2676 Requires<[IsARM, NoV6]>;
2680 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2681 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2682 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2683 Requires<[IsARM, HasV6]>;
2684 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2685 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2686 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2687 Requires<[IsARM, HasV6]>;
2689 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2690 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2691 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2692 Requires<[IsARM, HasV6]> {
2697 let Inst{19-16} = RdLo;
2698 let Inst{15-12} = RdHi;
2699 let Inst{11-8} = Rm;
2702 } // neverHasSideEffects
2704 // Most significant word multiply
2705 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2706 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2707 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2708 Requires<[IsARM, HasV6]> {
2709 let Inst{15-12} = 0b1111;
2712 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2713 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2714 [/* For disassembly only; pattern left blank */]>,
2715 Requires<[IsARM, HasV6]> {
2716 let Inst{15-12} = 0b1111;
2719 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2720 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2721 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2722 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2723 Requires<[IsARM, HasV6]>;
2725 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2726 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2727 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2728 [/* For disassembly only; pattern left blank */]>,
2729 Requires<[IsARM, HasV6]>;
2731 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2732 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2733 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2734 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2735 Requires<[IsARM, HasV6]>;
2737 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2738 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2739 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2740 [/* For disassembly only; pattern left blank */]>,
2741 Requires<[IsARM, HasV6]>;
2743 multiclass AI_smul<string opc, PatFrag opnode> {
2744 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2745 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2746 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2747 (sext_inreg GPR:$Rm, i16)))]>,
2748 Requires<[IsARM, HasV5TE]>;
2750 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2751 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2752 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2753 (sra GPR:$Rm, (i32 16))))]>,
2754 Requires<[IsARM, HasV5TE]>;
2756 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2757 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2758 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2759 (sext_inreg GPR:$Rm, i16)))]>,
2760 Requires<[IsARM, HasV5TE]>;
2762 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2763 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2764 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2765 (sra GPR:$Rm, (i32 16))))]>,
2766 Requires<[IsARM, HasV5TE]>;
2768 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2769 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2770 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2771 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2772 Requires<[IsARM, HasV5TE]>;
2774 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2775 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2776 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2777 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2778 Requires<[IsARM, HasV5TE]>;
2782 multiclass AI_smla<string opc, PatFrag opnode> {
2783 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2784 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2785 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2786 [(set GPR:$Rd, (add GPR:$Ra,
2787 (opnode (sext_inreg GPR:$Rn, i16),
2788 (sext_inreg GPR:$Rm, i16))))]>,
2789 Requires<[IsARM, HasV5TE]>;
2791 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2792 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2793 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2794 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2795 (sra GPR:$Rm, (i32 16)))))]>,
2796 Requires<[IsARM, HasV5TE]>;
2798 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2799 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2800 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2801 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2802 (sext_inreg GPR:$Rm, i16))))]>,
2803 Requires<[IsARM, HasV5TE]>;
2805 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2806 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2807 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2808 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2809 (sra GPR:$Rm, (i32 16)))))]>,
2810 Requires<[IsARM, HasV5TE]>;
2812 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2813 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2814 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2815 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2816 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2817 Requires<[IsARM, HasV5TE]>;
2819 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2820 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2821 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2822 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2823 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2824 Requires<[IsARM, HasV5TE]>;
2827 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2828 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2830 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2831 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2832 (ins GPR:$Rn, GPR:$Rm),
2833 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2834 [/* For disassembly only; pattern left blank */]>,
2835 Requires<[IsARM, HasV5TE]>;
2837 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2838 (ins GPR:$Rn, GPR:$Rm),
2839 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2840 [/* For disassembly only; pattern left blank */]>,
2841 Requires<[IsARM, HasV5TE]>;
2843 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2844 (ins GPR:$Rn, GPR:$Rm),
2845 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2846 [/* For disassembly only; pattern left blank */]>,
2847 Requires<[IsARM, HasV5TE]>;
2849 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2850 (ins GPR:$Rn, GPR:$Rm),
2851 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2852 [/* For disassembly only; pattern left blank */]>,
2853 Requires<[IsARM, HasV5TE]>;
2855 // Helper class for AI_smld -- for disassembly only
2856 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2857 InstrItinClass itin, string opc, string asm>
2858 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2865 let Inst{21-20} = 0b00;
2866 let Inst{22} = long;
2867 let Inst{27-23} = 0b01110;
2868 let Inst{11-8} = Rm;
2871 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2872 InstrItinClass itin, string opc, string asm>
2873 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2875 let Inst{15-12} = 0b1111;
2876 let Inst{19-16} = Rd;
2878 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2879 InstrItinClass itin, string opc, string asm>
2880 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2882 let Inst{15-12} = Ra;
2884 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2885 InstrItinClass itin, string opc, string asm>
2886 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2889 let Inst{19-16} = RdHi;
2890 let Inst{15-12} = RdLo;
2893 multiclass AI_smld<bit sub, string opc> {
2895 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2896 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2898 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2899 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2901 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2902 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2903 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2905 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2906 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2907 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2911 defm SMLA : AI_smld<0, "smla">;
2912 defm SMLS : AI_smld<1, "smls">;
2914 multiclass AI_sdml<bit sub, string opc> {
2916 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2917 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2918 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2919 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2922 defm SMUA : AI_sdml<0, "smua">;
2923 defm SMUS : AI_sdml<1, "smus">;
2925 //===----------------------------------------------------------------------===//
2926 // Misc. Arithmetic Instructions.
2929 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2930 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2931 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2933 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2934 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2935 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2936 Requires<[IsARM, HasV6T2]>;
2938 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2939 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2940 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2942 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2943 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2945 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2946 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2947 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2948 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2949 Requires<[IsARM, HasV6]>;
2951 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2952 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2955 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2956 (shl GPR:$Rm, (i32 8))), i16))]>,
2957 Requires<[IsARM, HasV6]>;
2959 def lsl_shift_imm : SDNodeXForm<imm, [{
2960 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2961 return CurDAG->getTargetConstant(Sh, MVT::i32);
2964 def lsl_amt : PatLeaf<(i32 imm), [{
2965 return (N->getZExtValue() < 32);
2968 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2969 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2970 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2971 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2972 (and (shl GPR:$Rm, lsl_amt:$sh),
2974 Requires<[IsARM, HasV6]>;
2976 // Alternate cases for PKHBT where identities eliminate some nodes.
2977 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2978 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2979 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2980 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2982 def asr_shift_imm : SDNodeXForm<imm, [{
2983 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2984 return CurDAG->getTargetConstant(Sh, MVT::i32);
2987 def asr_amt : PatLeaf<(i32 imm), [{
2988 return (N->getZExtValue() <= 32);
2991 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2992 // will match the pattern below.
2993 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2994 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2995 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2996 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2997 (and (sra GPR:$Rm, asr_amt:$sh),
2999 Requires<[IsARM, HasV6]>;
3001 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
3002 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
3003 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
3004 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
3005 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
3006 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
3007 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
3009 //===----------------------------------------------------------------------===//
3010 // Comparison Instructions...
3013 defm CMP : AI1_cmp_irs<0b1010, "cmp",
3014 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3015 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3017 // ARMcmpZ can re-use the above instruction definitions.
3018 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3019 (CMPri GPR:$src, so_imm:$imm)>;
3020 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3021 (CMPrr GPR:$src, GPR:$rhs)>;
3022 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
3023 (CMPrs GPR:$src, so_reg:$rhs)>;
3025 // FIXME: We have to be careful when using the CMN instruction and comparison
3026 // with 0. One would expect these two pieces of code should give identical
3042 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3043 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3044 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3045 // value of r0 and the carry bit (because the "carry bit" parameter to
3046 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3047 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3048 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3049 // parameter to AddWithCarry is defined as 0).
3051 // When x is 0 and unsigned:
3055 // ~x + 1 = 0x1 0000 0000
3056 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3058 // Therefore, we should disable CMN when comparing against zero, until we can
3059 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3060 // when it's a comparison which doesn't look at the 'carry' flag).
3062 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3064 // This is related to <rdar://problem/7569620>.
3066 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3067 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3069 // Note that TST/TEQ don't set all the same flags that CMP does!
3070 defm TST : AI1_cmp_irs<0b1000, "tst",
3071 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3072 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3073 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3074 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3075 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3077 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3078 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3079 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3081 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3082 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3084 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3085 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3087 // Pseudo i64 compares for some floating point compares.
3088 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3090 def BCCi64 : PseudoInst<(outs),
3091 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3093 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3095 def BCCZi64 : PseudoInst<(outs),
3096 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3097 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3098 } // usesCustomInserter
3101 // Conditional moves
3102 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3103 // a two-value operand where a dag node expects two operands. :(
3104 // FIXME: These should all be pseudo-instructions that get expanded to
3105 // the normal MOV instructions. That would fix the dependency on
3106 // special casing them in tblgen.
3107 let neverHasSideEffects = 1 in {
3108 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3109 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3110 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3111 RegConstraint<"$false = $Rd">, UnaryDP {
3116 let Inst{15-12} = Rd;
3117 let Inst{11-4} = 0b00000000;
3121 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3122 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3123 "mov", "\t$Rd, $shift",
3124 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3125 RegConstraint<"$false = $Rd">, UnaryDP {
3130 let Inst{19-16} = 0;
3131 let Inst{15-12} = Rd;
3132 let Inst{11-0} = shift;
3135 let isMoveImm = 1 in
3136 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3138 "movw", "\t$Rd, $imm",
3140 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3146 let Inst{19-16} = imm{15-12};
3147 let Inst{15-12} = Rd;
3148 let Inst{11-0} = imm{11-0};
3151 let isMoveImm = 1 in
3152 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3153 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3154 "mov", "\t$Rd, $imm",
3155 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3156 RegConstraint<"$false = $Rd">, UnaryDP {
3161 let Inst{19-16} = 0b0000;
3162 let Inst{15-12} = Rd;
3163 let Inst{11-0} = imm;
3166 // Two instruction predicate mov immediate.
3167 let isMoveImm = 1 in
3168 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3169 (ins GPR:$false, i32imm:$src, pred:$p),
3170 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3172 let isMoveImm = 1 in
3173 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3174 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3175 "mvn", "\t$Rd, $imm",
3176 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3177 RegConstraint<"$false = $Rd">, UnaryDP {
3182 let Inst{19-16} = 0b0000;
3183 let Inst{15-12} = Rd;
3184 let Inst{11-0} = imm;
3186 } // neverHasSideEffects
3188 //===----------------------------------------------------------------------===//
3189 // Atomic operations intrinsics
3192 def memb_opt : Operand<i32> {
3193 let PrintMethod = "printMemBOption";
3194 let ParserMatchClass = MemBarrierOptOperand;
3197 // memory barriers protect the atomic sequences
3198 let hasSideEffects = 1 in {
3199 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3200 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3201 Requires<[IsARM, HasDB]> {
3203 let Inst{31-4} = 0xf57ff05;
3204 let Inst{3-0} = opt;
3207 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3208 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3209 [(ARMMemBarrierMCR GPR:$zero)]>,
3210 Requires<[IsARM, HasV6]> {
3211 // FIXME: add encoding
3215 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3217 [/* For disassembly only; pattern left blank */]>,
3218 Requires<[IsARM, HasDB]> {
3220 let Inst{31-4} = 0xf57ff04;
3221 let Inst{3-0} = opt;
3224 // ISB has only full system option -- for disassembly only
3225 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3226 Requires<[IsARM, HasDB]> {
3227 let Inst{31-4} = 0xf57ff06;
3228 let Inst{3-0} = 0b1111;
3231 let usesCustomInserter = 1 in {
3232 let Uses = [CPSR] in {
3233 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3234 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3235 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3236 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3237 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3238 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3239 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3240 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3241 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3242 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3243 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3244 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3245 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3246 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3247 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3248 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3249 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3250 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3251 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3252 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3253 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3254 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3255 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3256 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3257 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3258 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3259 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3260 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3261 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3262 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3263 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3264 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3265 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3266 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3267 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3268 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3269 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3270 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3271 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3272 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3273 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3274 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3275 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3276 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3277 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3278 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3279 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3280 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3281 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3282 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3283 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3284 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3285 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3286 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3288 def ATOMIC_SWAP_I8 : PseudoInst<
3289 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3290 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3291 def ATOMIC_SWAP_I16 : PseudoInst<
3292 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3293 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3294 def ATOMIC_SWAP_I32 : PseudoInst<
3295 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3296 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3298 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3299 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3300 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3301 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3302 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3303 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3304 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3305 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3306 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3310 let mayLoad = 1 in {
3311 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3312 "ldrexb", "\t$Rt, [$Rn]",
3314 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3315 "ldrexh", "\t$Rt, [$Rn]",
3317 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3318 "ldrex", "\t$Rt, [$Rn]",
3320 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3322 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3326 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3327 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3329 "strexb", "\t$Rd, $src, [$Rn]",
3331 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3333 "strexh", "\t$Rd, $Rt, [$Rn]",
3335 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3337 "strex", "\t$Rd, $Rt, [$Rn]",
3339 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3340 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3342 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3346 // Clear-Exclusive is for disassembly only.
3347 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3348 [/* For disassembly only; pattern left blank */]>,
3349 Requires<[IsARM, HasV7]> {
3350 let Inst{31-0} = 0b11110101011111111111000000011111;
3353 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3354 let mayLoad = 1 in {
3355 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3356 [/* For disassembly only; pattern left blank */]>;
3357 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3358 [/* For disassembly only; pattern left blank */]>;
3361 //===----------------------------------------------------------------------===//
3365 // __aeabi_read_tp preserves the registers r1-r3.
3366 // This is a pseudo inst so that we can get the encoding right,
3367 // complete with fixup for the aeabi_read_tp function.
3369 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3370 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3371 [(set R0, ARMthread_pointer)]>;
3374 //===----------------------------------------------------------------------===//
3375 // SJLJ Exception handling intrinsics
3376 // eh_sjlj_setjmp() is an instruction sequence to store the return
3377 // address and save #0 in R0 for the non-longjmp case.
3378 // Since by its nature we may be coming from some other function to get
3379 // here, and we're using the stack frame for the containing function to
3380 // save/restore registers, we can't keep anything live in regs across
3381 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3382 // when we get here from a longjmp(). We force everthing out of registers
3383 // except for our own input by listing the relevant registers in Defs. By
3384 // doing so, we also cause the prologue/epilogue code to actively preserve
3385 // all of the callee-saved resgisters, which is exactly what we want.
3386 // A constant value is passed in $val, and we use the location as a scratch.
3388 // These are pseudo-instructions and are lowered to individual MC-insts, so
3389 // no encoding information is necessary.
3391 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3392 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3393 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3394 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3395 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3397 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3398 Requires<[IsARM, HasVFP2]>;
3402 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3403 hasSideEffects = 1, isBarrier = 1 in {
3404 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3406 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3407 Requires<[IsARM, NoVFP]>;
3410 // FIXME: Non-Darwin version(s)
3411 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3412 Defs = [ R7, LR, SP ] in {
3413 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3415 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3416 Requires<[IsARM, IsDarwin]>;
3419 // eh.sjlj.dispatchsetup pseudo-instruction.
3420 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3421 // handled when the pseudo is expanded (which happens before any passes
3422 // that need the instruction size).
3423 let isBarrier = 1, hasSideEffects = 1 in
3424 def Int_eh_sjlj_dispatchsetup :
3425 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3426 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3427 Requires<[IsDarwin]>;
3429 //===----------------------------------------------------------------------===//
3430 // Non-Instruction Patterns
3433 // Large immediate handling.
3435 // 32-bit immediate using two piece so_imms or movw + movt.
3436 // This is a single pseudo instruction, the benefit is that it can be remat'd
3437 // as a single unit instead of having to handle reg inputs.
3438 // FIXME: Remove this when we can do generalized remat.
3439 let isReMaterializable = 1, isMoveImm = 1 in
3440 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3441 [(set GPR:$dst, (arm_i32imm:$src))]>,
3444 // Pseudo instruction that combines movw + movt + add pc (if PIC).
3445 // It also makes it possible to rematerialize the instructions.
3446 // FIXME: Remove this when we can do generalized remat and when machine licm
3447 // can properly the instructions.
3448 let isReMaterializable = 1 in {
3449 def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3451 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3452 Requires<[IsARM, UseMovt]>;
3454 def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3456 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3457 Requires<[IsARM, UseMovt]>;
3459 let AddedComplexity = 10 in
3460 def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3462 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
3463 Requires<[IsARM, UseMovt]>;
3464 } // isReMaterializable
3466 // ConstantPool, GlobalAddress, and JumpTable
3467 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3468 Requires<[IsARM, DontUseMovt]>;
3469 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3470 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3471 Requires<[IsARM, UseMovt]>;
3472 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3473 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3475 // TODO: add,sub,and, 3-instr forms?
3478 def : ARMPat<(ARMtcret tcGPR:$dst),
3479 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3481 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3482 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3484 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3485 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3487 def : ARMPat<(ARMtcret tcGPR:$dst),
3488 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3490 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3491 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3493 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3494 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3497 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3498 Requires<[IsARM, IsNotDarwin]>;
3499 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3500 Requires<[IsARM, IsDarwin]>;
3502 // zextload i1 -> zextload i8
3503 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3504 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3506 // extload -> zextload
3507 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3508 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3509 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3510 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3512 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3514 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3515 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3518 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3519 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3520 (SMULBB GPR:$a, GPR:$b)>;
3521 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3522 (SMULBB GPR:$a, GPR:$b)>;
3523 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3524 (sra GPR:$b, (i32 16))),
3525 (SMULBT GPR:$a, GPR:$b)>;
3526 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3527 (SMULBT GPR:$a, GPR:$b)>;
3528 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3529 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3530 (SMULTB GPR:$a, GPR:$b)>;
3531 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3532 (SMULTB GPR:$a, GPR:$b)>;
3533 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3535 (SMULWB GPR:$a, GPR:$b)>;
3536 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3537 (SMULWB GPR:$a, GPR:$b)>;
3539 def : ARMV5TEPat<(add GPR:$acc,
3540 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3541 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3542 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3543 def : ARMV5TEPat<(add GPR:$acc,
3544 (mul sext_16_node:$a, sext_16_node:$b)),
3545 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3546 def : ARMV5TEPat<(add GPR:$acc,
3547 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3548 (sra GPR:$b, (i32 16)))),
3549 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3550 def : ARMV5TEPat<(add GPR:$acc,
3551 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3552 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3553 def : ARMV5TEPat<(add GPR:$acc,
3554 (mul (sra GPR:$a, (i32 16)),
3555 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3556 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3557 def : ARMV5TEPat<(add GPR:$acc,
3558 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3559 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3560 def : ARMV5TEPat<(add GPR:$acc,
3561 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3563 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3564 def : ARMV5TEPat<(add GPR:$acc,
3565 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3566 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3568 //===----------------------------------------------------------------------===//
3572 include "ARMInstrThumb.td"
3574 //===----------------------------------------------------------------------===//
3578 include "ARMInstrThumb2.td"
3580 //===----------------------------------------------------------------------===//
3581 // Floating Point Support
3584 include "ARMInstrVFP.td"
3586 //===----------------------------------------------------------------------===//
3587 // Advanced SIMD (NEON) Support
3590 include "ARMInstrNEON.td"
3592 //===----------------------------------------------------------------------===//
3593 // Coprocessor Instructions. For disassembly only.
3596 def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3597 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3598 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3599 [/* For disassembly only; pattern left blank */]> {
3607 let Inst{3-0} = CRm;
3609 let Inst{7-5} = opc2;
3610 let Inst{11-8} = cop;
3611 let Inst{15-12} = CRd;
3612 let Inst{19-16} = CRn;
3613 let Inst{23-20} = opc1;
3616 def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3617 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3618 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3619 [/* For disassembly only; pattern left blank */]> {
3620 let Inst{31-28} = 0b1111;
3628 let Inst{3-0} = CRm;
3630 let Inst{7-5} = opc2;
3631 let Inst{11-8} = cop;
3632 let Inst{15-12} = CRd;
3633 let Inst{19-16} = CRn;
3634 let Inst{23-20} = opc1;
3637 class ACI<dag oops, dag iops, string opc, string asm>
3638 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3639 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3640 let Inst{27-25} = 0b110;
3643 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3645 def _OFFSET : ACI<(outs),
3646 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3647 opc, "\tp$cop, cr$CRd, $addr"> {
3648 let Inst{31-28} = op31_28;
3649 let Inst{24} = 1; // P = 1
3650 let Inst{21} = 0; // W = 0
3651 let Inst{22} = 0; // D = 0
3652 let Inst{20} = load;
3655 def _PRE : ACI<(outs),
3656 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3657 opc, "\tp$cop, cr$CRd, $addr!"> {
3658 let Inst{31-28} = op31_28;
3659 let Inst{24} = 1; // P = 1
3660 let Inst{21} = 1; // W = 1
3661 let Inst{22} = 0; // D = 0
3662 let Inst{20} = load;
3665 def _POST : ACI<(outs),
3666 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3667 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3668 let Inst{31-28} = op31_28;
3669 let Inst{24} = 0; // P = 0
3670 let Inst{21} = 1; // W = 1
3671 let Inst{22} = 0; // D = 0
3672 let Inst{20} = load;
3675 def _OPTION : ACI<(outs),
3676 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3677 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3678 let Inst{31-28} = op31_28;
3679 let Inst{24} = 0; // P = 0
3680 let Inst{23} = 1; // U = 1
3681 let Inst{21} = 0; // W = 0
3682 let Inst{22} = 0; // D = 0
3683 let Inst{20} = load;
3686 def L_OFFSET : ACI<(outs),
3687 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3688 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3689 let Inst{31-28} = op31_28;
3690 let Inst{24} = 1; // P = 1
3691 let Inst{21} = 0; // W = 0
3692 let Inst{22} = 1; // D = 1
3693 let Inst{20} = load;
3696 def L_PRE : ACI<(outs),
3697 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3698 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3699 let Inst{31-28} = op31_28;
3700 let Inst{24} = 1; // P = 1
3701 let Inst{21} = 1; // W = 1
3702 let Inst{22} = 1; // D = 1
3703 let Inst{20} = load;
3706 def L_POST : ACI<(outs),
3707 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3708 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3709 let Inst{31-28} = op31_28;
3710 let Inst{24} = 0; // P = 0
3711 let Inst{21} = 1; // W = 1
3712 let Inst{22} = 1; // D = 1
3713 let Inst{20} = load;
3716 def L_OPTION : ACI<(outs),
3717 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3718 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3719 let Inst{31-28} = op31_28;
3720 let Inst{24} = 0; // P = 0
3721 let Inst{23} = 1; // U = 1
3722 let Inst{21} = 0; // W = 0
3723 let Inst{22} = 1; // D = 1
3724 let Inst{20} = load;
3728 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3729 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3730 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3731 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3733 //===----------------------------------------------------------------------===//
3734 // Move between coprocessor and ARM core register -- for disassembly only
3737 class MovRCopro<string opc, bit direction>
3738 : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3739 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3740 NoItinerary, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3741 [/* For disassembly only; pattern left blank */]> {
3742 let Inst{20} = direction;
3752 let Inst{15-12} = Rt;
3753 let Inst{11-8} = cop;
3754 let Inst{23-21} = opc1;
3755 let Inst{7-5} = opc2;
3756 let Inst{3-0} = CRm;
3757 let Inst{19-16} = CRn;
3760 def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */>;
3761 def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */>;
3763 class MovRCopro2<string opc, bit direction>
3764 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3765 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3766 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3767 [/* For disassembly only; pattern left blank */]> {
3768 let Inst{31-28} = 0b1111;
3769 let Inst{20} = direction;
3779 let Inst{15-12} = Rt;
3780 let Inst{11-8} = cop;
3781 let Inst{23-21} = opc1;
3782 let Inst{7-5} = opc2;
3783 let Inst{3-0} = CRm;
3784 let Inst{19-16} = CRn;
3787 def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */>;
3788 def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */>;
3790 class MovRRCopro<string opc, bit direction>
3791 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3792 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3793 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
3794 [/* For disassembly only; pattern left blank */]> {
3795 let Inst{23-21} = 0b010;
3796 let Inst{20} = direction;
3804 let Inst{15-12} = Rt;
3805 let Inst{19-16} = Rt2;
3806 let Inst{11-8} = cop;
3807 let Inst{7-4} = opc1;
3808 let Inst{3-0} = CRm;
3811 def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
3812 def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
3814 class MovRRCopro2<string opc, bit direction>
3815 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3816 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3817 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3818 [/* For disassembly only; pattern left blank */]> {
3819 let Inst{31-28} = 0b1111;
3820 let Inst{23-21} = 0b010;
3821 let Inst{20} = direction;
3829 let Inst{15-12} = Rt;
3830 let Inst{19-16} = Rt2;
3831 let Inst{11-8} = cop;
3832 let Inst{7-4} = opc1;
3833 let Inst{3-0} = CRm;
3836 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
3837 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
3839 //===----------------------------------------------------------------------===//
3840 // Move between special register and ARM core register -- for disassembly only
3843 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3844 [/* For disassembly only; pattern left blank */]> {
3846 let Inst{23-16} = 0b00001111;
3847 let Inst{15-12} = Rd;
3848 let Inst{7-4} = 0b0000;
3851 def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr",
3852 [/* For disassembly only; pattern left blank */]> {
3854 let Inst{23-16} = 0b01001111;
3855 let Inst{15-12} = Rd;
3856 let Inst{7-4} = 0b0000;
3859 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3860 "msr", "\tcpsr$mask, $src",
3861 [/* For disassembly only; pattern left blank */]> {
3862 let Inst{23-20} = 0b0010;
3863 let Inst{7-4} = 0b0000;
3866 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3867 "msr", "\tcpsr$mask, $a",
3868 [/* For disassembly only; pattern left blank */]> {
3869 let Inst{23-20} = 0b0010;
3870 let Inst{7-4} = 0b0000;
3873 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3874 "msr", "\tspsr$mask, $src",
3875 [/* For disassembly only; pattern left blank */]> {
3876 let Inst{23-20} = 0b0110;
3877 let Inst{7-4} = 0b0000;
3880 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3881 "msr", "\tspsr$mask, $a",
3882 [/* For disassembly only; pattern left blank */]> {
3883 let Inst{23-20} = 0b0110;
3884 let Inst{7-4} = 0b0000;