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 writeback
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 p_imm : Operand<i32> {
592 let PrintMethod = "printPImmediate";
595 def c_imm : Operand<i32> {
596 let PrintMethod = "printCImmediate";
599 //===----------------------------------------------------------------------===//
601 include "ARMInstrFormats.td"
603 //===----------------------------------------------------------------------===//
604 // Multiclass helpers...
607 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
608 /// binop that produces a value.
609 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
610 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
611 PatFrag opnode, bit Commutable = 0> {
612 // The register-immediate version is re-materializable. This is useful
613 // in particular for taking the address of a local.
614 let isReMaterializable = 1 in {
615 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
616 iii, opc, "\t$Rd, $Rn, $imm",
617 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
622 let Inst{19-16} = Rn;
623 let Inst{15-12} = Rd;
624 let Inst{11-0} = imm;
627 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
628 iir, opc, "\t$Rd, $Rn, $Rm",
629 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
634 let isCommutable = Commutable;
635 let Inst{19-16} = Rn;
636 let Inst{15-12} = Rd;
637 let Inst{11-4} = 0b00000000;
640 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
641 iis, opc, "\t$Rd, $Rn, $shift",
642 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
647 let Inst{19-16} = Rn;
648 let Inst{15-12} = Rd;
649 let Inst{11-0} = shift;
653 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
654 /// instruction modifies the CPSR register.
655 let isCodeGenOnly = 1, Defs = [CPSR] in {
656 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
657 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
658 PatFrag opnode, bit Commutable = 0> {
659 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
660 iii, opc, "\t$Rd, $Rn, $imm",
661 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
667 let Inst{19-16} = Rn;
668 let Inst{15-12} = Rd;
669 let Inst{11-0} = imm;
671 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
672 iir, opc, "\t$Rd, $Rn, $Rm",
673 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
677 let isCommutable = Commutable;
680 let Inst{19-16} = Rn;
681 let Inst{15-12} = Rd;
682 let Inst{11-4} = 0b00000000;
685 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
686 iis, opc, "\t$Rd, $Rn, $shift",
687 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
693 let Inst{19-16} = Rn;
694 let Inst{15-12} = Rd;
695 let Inst{11-0} = shift;
700 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
701 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
702 /// a explicit result, only implicitly set CPSR.
703 let isCompare = 1, Defs = [CPSR] in {
704 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
705 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
706 PatFrag opnode, bit Commutable = 0> {
707 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
709 [(opnode GPR:$Rn, so_imm:$imm)]> {
714 let Inst{19-16} = Rn;
715 let Inst{15-12} = 0b0000;
716 let Inst{11-0} = imm;
718 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
720 [(opnode GPR:$Rn, GPR:$Rm)]> {
723 let isCommutable = Commutable;
726 let Inst{19-16} = Rn;
727 let Inst{15-12} = 0b0000;
728 let Inst{11-4} = 0b00000000;
731 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
732 opc, "\t$Rn, $shift",
733 [(opnode GPR:$Rn, so_reg:$shift)]> {
738 let Inst{19-16} = Rn;
739 let Inst{15-12} = 0b0000;
740 let Inst{11-0} = shift;
745 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
746 /// register and one whose operand is a register rotated by 8/16/24.
747 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
748 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
749 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
750 IIC_iEXTr, opc, "\t$Rd, $Rm",
751 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
752 Requires<[IsARM, HasV6]> {
755 let Inst{19-16} = 0b1111;
756 let Inst{15-12} = Rd;
757 let Inst{11-10} = 0b00;
760 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
761 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
762 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
763 Requires<[IsARM, HasV6]> {
767 let Inst{19-16} = 0b1111;
768 let Inst{15-12} = Rd;
769 let Inst{11-10} = rot;
774 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
775 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
776 IIC_iEXTr, opc, "\t$Rd, $Rm",
777 [/* For disassembly only; pattern left blank */]>,
778 Requires<[IsARM, HasV6]> {
779 let Inst{19-16} = 0b1111;
780 let Inst{11-10} = 0b00;
782 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
783 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
784 [/* For disassembly only; pattern left blank */]>,
785 Requires<[IsARM, HasV6]> {
787 let Inst{19-16} = 0b1111;
788 let Inst{11-10} = rot;
792 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
793 /// register and one whose operand is a register rotated by 8/16/24.
794 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
795 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
796 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
797 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
798 Requires<[IsARM, HasV6]> {
802 let Inst{19-16} = Rn;
803 let Inst{15-12} = Rd;
804 let Inst{11-10} = 0b00;
805 let Inst{9-4} = 0b000111;
808 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
810 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
811 [(set GPR:$Rd, (opnode GPR:$Rn,
812 (rotr GPR:$Rm, rot_imm:$rot)))]>,
813 Requires<[IsARM, HasV6]> {
818 let Inst{19-16} = Rn;
819 let Inst{15-12} = Rd;
820 let Inst{11-10} = rot;
821 let Inst{9-4} = 0b000111;
826 // For disassembly only.
827 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
828 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
829 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
830 [/* For disassembly only; pattern left blank */]>,
831 Requires<[IsARM, HasV6]> {
832 let Inst{11-10} = 0b00;
834 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
836 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
837 [/* For disassembly only; pattern left blank */]>,
838 Requires<[IsARM, HasV6]> {
841 let Inst{19-16} = Rn;
842 let Inst{11-10} = rot;
846 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
847 let Uses = [CPSR] in {
848 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
849 bit Commutable = 0> {
850 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
851 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
852 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
858 let Inst{15-12} = Rd;
859 let Inst{19-16} = Rn;
860 let Inst{11-0} = imm;
862 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
863 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
864 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
869 let Inst{11-4} = 0b00000000;
871 let isCommutable = Commutable;
873 let Inst{15-12} = Rd;
874 let Inst{19-16} = Rn;
876 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
877 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
878 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
884 let Inst{11-0} = shift;
885 let Inst{15-12} = Rd;
886 let Inst{19-16} = Rn;
889 // Carry setting variants
890 let isCodeGenOnly = 1, Defs = [CPSR] in {
891 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
892 bit Commutable = 0> {
893 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
894 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
895 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
900 let Inst{15-12} = Rd;
901 let Inst{19-16} = Rn;
902 let Inst{11-0} = imm;
906 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
907 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
908 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
913 let Inst{11-4} = 0b00000000;
914 let isCommutable = Commutable;
916 let Inst{15-12} = Rd;
917 let Inst{19-16} = Rn;
921 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
922 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
923 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
928 let Inst{11-0} = shift;
929 let Inst{15-12} = Rd;
930 let Inst{19-16} = Rn;
938 let canFoldAsLoad = 1, isReMaterializable = 1 in {
939 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
940 InstrItinClass iir, PatFrag opnode> {
941 // Note: We use the complex addrmode_imm12 rather than just an input
942 // GPR and a constrained immediate so that we can use this to match
943 // frame index references and avoid matching constant pool references.
944 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
945 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
946 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
949 let Inst{23} = addr{12}; // U (add = ('U' == 1))
950 let Inst{19-16} = addr{16-13}; // Rn
951 let Inst{15-12} = Rt;
952 let Inst{11-0} = addr{11-0}; // imm12
954 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
955 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
956 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
959 let Inst{23} = shift{12}; // U (add = ('U' == 1))
960 let Inst{19-16} = shift{16-13}; // Rn
961 let Inst{15-12} = Rt;
962 let Inst{11-0} = shift{11-0};
967 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
968 InstrItinClass iir, PatFrag opnode> {
969 // Note: We use the complex addrmode_imm12 rather than just an input
970 // GPR and a constrained immediate so that we can use this to match
971 // frame index references and avoid matching constant pool references.
972 def i12 : AI2ldst<0b010, 0, isByte, (outs),
973 (ins GPR:$Rt, addrmode_imm12:$addr),
974 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
975 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
978 let Inst{23} = addr{12}; // U (add = ('U' == 1))
979 let Inst{19-16} = addr{16-13}; // Rn
980 let Inst{15-12} = Rt;
981 let Inst{11-0} = addr{11-0}; // imm12
983 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
984 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
985 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
988 let Inst{23} = shift{12}; // U (add = ('U' == 1))
989 let Inst{19-16} = shift{16-13}; // Rn
990 let Inst{15-12} = Rt;
991 let Inst{11-0} = shift{11-0};
994 //===----------------------------------------------------------------------===//
996 //===----------------------------------------------------------------------===//
998 //===----------------------------------------------------------------------===//
999 // Miscellaneous Instructions.
1002 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1003 /// the function. The first operand is the ID# for this instruction, the second
1004 /// is the index into the MachineConstantPool that this is, the third is the
1005 /// size in bytes of this constant pool entry.
1006 let neverHasSideEffects = 1, isNotDuplicable = 1 in
1007 def CONSTPOOL_ENTRY :
1008 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1009 i32imm:$size), NoItinerary, []>;
1011 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1012 // from removing one half of the matched pairs. That breaks PEI, which assumes
1013 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1014 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1015 def ADJCALLSTACKUP :
1016 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1017 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1019 def ADJCALLSTACKDOWN :
1020 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1021 [(ARMcallseq_start timm:$amt)]>;
1024 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
1025 [/* For disassembly only; pattern left blank */]>,
1026 Requires<[IsARM, HasV6T2]> {
1027 let Inst{27-16} = 0b001100100000;
1028 let Inst{15-8} = 0b11110000;
1029 let Inst{7-0} = 0b00000000;
1032 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1033 [/* For disassembly only; pattern left blank */]>,
1034 Requires<[IsARM, HasV6T2]> {
1035 let Inst{27-16} = 0b001100100000;
1036 let Inst{15-8} = 0b11110000;
1037 let Inst{7-0} = 0b00000001;
1040 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1041 [/* For disassembly only; pattern left blank */]>,
1042 Requires<[IsARM, HasV6T2]> {
1043 let Inst{27-16} = 0b001100100000;
1044 let Inst{15-8} = 0b11110000;
1045 let Inst{7-0} = 0b00000010;
1048 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1049 [/* For disassembly only; pattern left blank */]>,
1050 Requires<[IsARM, HasV6T2]> {
1051 let Inst{27-16} = 0b001100100000;
1052 let Inst{15-8} = 0b11110000;
1053 let Inst{7-0} = 0b00000011;
1056 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1058 [/* For disassembly only; pattern left blank */]>,
1059 Requires<[IsARM, HasV6]> {
1064 let Inst{15-12} = Rd;
1065 let Inst{19-16} = Rn;
1066 let Inst{27-20} = 0b01101000;
1067 let Inst{7-4} = 0b1011;
1068 let Inst{11-8} = 0b1111;
1071 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1072 [/* For disassembly only; pattern left blank */]>,
1073 Requires<[IsARM, HasV6T2]> {
1074 let Inst{27-16} = 0b001100100000;
1075 let Inst{15-8} = 0b11110000;
1076 let Inst{7-0} = 0b00000100;
1079 // The i32imm operand $val can be used by a debugger to store more information
1080 // about the breakpoint.
1081 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1082 [/* For disassembly only; pattern left blank */]>,
1085 let Inst{3-0} = val{3-0};
1086 let Inst{19-8} = val{15-4};
1087 let Inst{27-20} = 0b00010010;
1088 let Inst{7-4} = 0b0111;
1091 // Change Processor State is a system instruction -- for disassembly only.
1092 // The singleton $opt operand contains the following information:
1093 // opt{4-0} = mode from Inst{4-0}
1094 // opt{5} = changemode from Inst{17}
1095 // opt{8-6} = AIF from Inst{8-6}
1096 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1097 // FIXME: Integrated assembler will need these split out.
1098 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1099 [/* For disassembly only; pattern left blank */]>,
1101 let Inst{31-28} = 0b1111;
1102 let Inst{27-20} = 0b00010000;
1107 // Preload signals the memory system of possible future data/instruction access.
1108 // These are for disassembly only.
1109 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1111 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1112 !strconcat(opc, "\t$addr"),
1113 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1116 let Inst{31-26} = 0b111101;
1117 let Inst{25} = 0; // 0 for immediate form
1118 let Inst{24} = data;
1119 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1120 let Inst{22} = read;
1121 let Inst{21-20} = 0b01;
1122 let Inst{19-16} = addr{16-13}; // Rn
1123 let Inst{15-12} = 0b1111;
1124 let Inst{11-0} = addr{11-0}; // imm12
1127 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1128 !strconcat(opc, "\t$shift"),
1129 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1131 let Inst{31-26} = 0b111101;
1132 let Inst{25} = 1; // 1 for register form
1133 let Inst{24} = data;
1134 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1135 let Inst{22} = read;
1136 let Inst{21-20} = 0b01;
1137 let Inst{19-16} = shift{16-13}; // Rn
1138 let Inst{15-12} = 0b1111;
1139 let Inst{11-0} = shift{11-0};
1143 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1144 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1145 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1147 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1149 [/* For disassembly only; pattern left blank */]>,
1152 let Inst{31-10} = 0b1111000100000001000000;
1157 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1158 [/* For disassembly only; pattern left blank */]>,
1159 Requires<[IsARM, HasV7]> {
1161 let Inst{27-4} = 0b001100100000111100001111;
1162 let Inst{3-0} = opt;
1165 // A5.4 Permanently UNDEFINED instructions.
1166 let isBarrier = 1, isTerminator = 1 in
1167 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1170 let Inst = 0xe7ffdefe;
1173 // Address computation and loads and stores in PIC mode.
1174 let isNotDuplicable = 1 in {
1175 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1176 Size4Bytes, IIC_iALUr,
1177 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1179 let AddedComplexity = 10 in {
1180 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1181 Size4Bytes, IIC_iLoad_r,
1182 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1184 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1185 Size4Bytes, IIC_iLoad_bh_r,
1186 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1188 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1189 Size4Bytes, IIC_iLoad_bh_r,
1190 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1192 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1193 Size4Bytes, IIC_iLoad_bh_r,
1194 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1196 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1197 Size4Bytes, IIC_iLoad_bh_r,
1198 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1200 let AddedComplexity = 10 in {
1201 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1202 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1204 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1205 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1206 addrmodepc:$addr)]>;
1208 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1209 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1211 } // isNotDuplicable = 1
1214 // LEApcrel - Load a pc-relative address into a register without offending the
1216 let neverHasSideEffects = 1, isReMaterializable = 1 in
1217 // The 'adr' mnemonic encodes differently if the label is before or after
1218 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1219 // know until then which form of the instruction will be used.
1220 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1221 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1224 let Inst{27-25} = 0b001;
1226 let Inst{19-16} = 0b1111;
1227 let Inst{15-12} = Rd;
1228 let Inst{11-0} = label;
1230 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1231 Size4Bytes, IIC_iALUi, []>;
1233 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1234 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1235 Size4Bytes, IIC_iALUi, []>;
1237 //===----------------------------------------------------------------------===//
1238 // Control Flow Instructions.
1241 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1243 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1244 "bx", "\tlr", [(ARMretflag)]>,
1245 Requires<[IsARM, HasV4T]> {
1246 let Inst{27-0} = 0b0001001011111111111100011110;
1250 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1251 "mov", "\tpc, lr", [(ARMretflag)]>,
1252 Requires<[IsARM, NoV4T]> {
1253 let Inst{27-0} = 0b0001101000001111000000001110;
1257 // Indirect branches
1258 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1260 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1261 [(brind GPR:$dst)]>,
1262 Requires<[IsARM, HasV4T]> {
1264 let Inst{31-4} = 0b1110000100101111111111110001;
1265 let Inst{3-0} = dst;
1269 // FIXME: We would really like to define this as a vanilla ARMPat like:
1270 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1271 // With that, however, we can't set isBranch, isTerminator, etc..
1272 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1273 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1274 Requires<[IsARM, NoV4T]>;
1277 // All calls clobber the non-callee saved registers. SP is marked as
1278 // a use to prevent stack-pointer assignments that appear immediately
1279 // before calls from potentially appearing dead.
1281 // On non-Darwin platforms R9 is callee-saved.
1282 Defs = [R0, R1, R2, R3, R12, LR,
1283 D0, D1, D2, D3, D4, D5, D6, D7,
1284 D16, D17, D18, D19, D20, D21, D22, D23,
1285 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1287 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1288 IIC_Br, "bl\t$func",
1289 [(ARMcall tglobaladdr:$func)]>,
1290 Requires<[IsARM, IsNotDarwin]> {
1291 let Inst{31-28} = 0b1110;
1293 let Inst{23-0} = func;
1296 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1297 IIC_Br, "bl", "\t$func",
1298 [(ARMcall_pred tglobaladdr:$func)]>,
1299 Requires<[IsARM, IsNotDarwin]> {
1301 let Inst{23-0} = func;
1305 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1306 IIC_Br, "blx\t$func",
1307 [(ARMcall GPR:$func)]>,
1308 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1310 let Inst{31-4} = 0b1110000100101111111111110011;
1311 let Inst{3-0} = func;
1315 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1316 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1317 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1318 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1321 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1322 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1323 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1327 // On Darwin R9 is call-clobbered.
1328 // R7 is marked as a use to prevent frame-pointer assignments from being
1329 // moved above / below calls.
1330 Defs = [R0, R1, R2, R3, R9, R12, LR,
1331 D0, D1, D2, D3, D4, D5, D6, D7,
1332 D16, D17, D18, D19, D20, D21, D22, D23,
1333 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1334 Uses = [R7, SP] in {
1335 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1336 IIC_Br, "bl\t$func",
1337 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1338 let Inst{31-28} = 0b1110;
1340 let Inst{23-0} = func;
1343 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1344 IIC_Br, "bl", "\t$func",
1345 [(ARMcall_pred tglobaladdr:$func)]>,
1346 Requires<[IsARM, IsDarwin]> {
1348 let Inst{23-0} = func;
1352 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1353 IIC_Br, "blx\t$func",
1354 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1356 let Inst{31-4} = 0b1110000100101111111111110011;
1357 let Inst{3-0} = func;
1361 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1362 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1363 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1364 Requires<[IsARM, HasV4T, IsDarwin]>;
1367 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1368 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1369 Requires<[IsARM, NoV4T, IsDarwin]>;
1374 // FIXME: These should probably be xformed into the non-TC versions of the
1375 // instructions as part of MC lowering.
1376 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1377 // Thumb should have its own version since the instruction is actually
1378 // different, even though the mnemonic is the same.
1379 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1381 let Defs = [R0, R1, R2, R3, R9, R12,
1382 D0, D1, D2, D3, D4, D5, D6, D7,
1383 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1384 D27, D28, D29, D30, D31, PC],
1386 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1387 IIC_Br, []>, Requires<[IsDarwin]>;
1389 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1390 IIC_Br, []>, Requires<[IsDarwin]>;
1392 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1393 IIC_Br, "b\t$dst @ TAILCALL",
1394 []>, Requires<[IsARM, IsDarwin]>;
1396 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1397 IIC_Br, "b.w\t$dst @ TAILCALL",
1398 []>, Requires<[IsThumb, IsDarwin]>;
1400 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1401 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1402 []>, Requires<[IsDarwin]> {
1404 let Inst{31-4} = 0b1110000100101111111111110001;
1405 let Inst{3-0} = dst;
1409 // Non-Darwin versions (the difference is R9).
1410 let Defs = [R0, R1, R2, R3, R12,
1411 D0, D1, D2, D3, D4, D5, D6, D7,
1412 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1413 D27, D28, D29, D30, D31, PC],
1415 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1416 IIC_Br, []>, Requires<[IsNotDarwin]>;
1418 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1419 IIC_Br, []>, Requires<[IsNotDarwin]>;
1421 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1422 IIC_Br, "b\t$dst @ TAILCALL",
1423 []>, Requires<[IsARM, IsNotDarwin]>;
1425 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1426 IIC_Br, "b.w\t$dst @ TAILCALL",
1427 []>, Requires<[IsThumb, IsNotDarwin]>;
1429 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1430 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1431 []>, Requires<[IsNotDarwin]> {
1433 let Inst{31-4} = 0b1110000100101111111111110001;
1434 let Inst{3-0} = dst;
1439 let isBranch = 1, isTerminator = 1 in {
1440 // B is "predicable" since it can be xformed into a Bcc.
1441 let isBarrier = 1 in {
1442 let isPredicable = 1 in
1443 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1444 "b\t$target", [(br bb:$target)]> {
1446 let Inst{31-28} = 0b1110;
1447 let Inst{23-0} = target;
1450 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1451 def BR_JTr : ARMPseudoInst<(outs),
1452 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1453 SizeSpecial, IIC_Br,
1454 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1455 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1456 // into i12 and rs suffixed versions.
1457 def BR_JTm : ARMPseudoInst<(outs),
1458 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1459 SizeSpecial, IIC_Br,
1460 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1462 def BR_JTadd : ARMPseudoInst<(outs),
1463 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1464 SizeSpecial, IIC_Br,
1465 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1467 } // isNotDuplicable = 1, isIndirectBranch = 1
1470 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1471 // a two-value operand where a dag node expects two operands. :(
1472 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1473 IIC_Br, "b", "\t$target",
1474 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1476 let Inst{23-0} = target;
1480 // Branch and Exchange Jazelle -- for disassembly only
1481 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1482 [/* For disassembly only; pattern left blank */]> {
1483 let Inst{23-20} = 0b0010;
1484 //let Inst{19-8} = 0xfff;
1485 let Inst{7-4} = 0b0010;
1488 // Secure Monitor Call is a system instruction -- for disassembly only
1489 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1490 [/* For disassembly only; pattern left blank */]> {
1492 let Inst{23-4} = 0b01100000000000000111;
1493 let Inst{3-0} = opt;
1496 // Supervisor Call (Software Interrupt) -- for disassembly only
1497 let isCall = 1, Uses = [SP] in {
1498 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1499 [/* For disassembly only; pattern left blank */]> {
1501 let Inst{23-0} = svc;
1505 // Store Return State is a system instruction -- for disassembly only
1506 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1507 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1508 NoItinerary, "srs${amode}\tsp!, $mode",
1509 [/* For disassembly only; pattern left blank */]> {
1510 let Inst{31-28} = 0b1111;
1511 let Inst{22-20} = 0b110; // W = 1
1514 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1515 NoItinerary, "srs${amode}\tsp, $mode",
1516 [/* For disassembly only; pattern left blank */]> {
1517 let Inst{31-28} = 0b1111;
1518 let Inst{22-20} = 0b100; // W = 0
1521 // Return From Exception is a system instruction -- for disassembly only
1522 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1523 NoItinerary, "rfe${amode}\t$base!",
1524 [/* For disassembly only; pattern left blank */]> {
1525 let Inst{31-28} = 0b1111;
1526 let Inst{22-20} = 0b011; // W = 1
1529 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1530 NoItinerary, "rfe${amode}\t$base",
1531 [/* For disassembly only; pattern left blank */]> {
1532 let Inst{31-28} = 0b1111;
1533 let Inst{22-20} = 0b001; // W = 0
1535 } // isCodeGenOnly = 1
1537 //===----------------------------------------------------------------------===//
1538 // Load / store Instructions.
1544 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1545 UnOpFrag<(load node:$Src)>>;
1546 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1547 UnOpFrag<(zextloadi8 node:$Src)>>;
1548 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1549 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1550 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1551 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1553 // Special LDR for loads from non-pc-relative constpools.
1554 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1555 isReMaterializable = 1 in
1556 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1557 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1561 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1562 let Inst{19-16} = 0b1111;
1563 let Inst{15-12} = Rt;
1564 let Inst{11-0} = addr{11-0}; // imm12
1567 // Loads with zero extension
1568 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1569 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1570 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1572 // Loads with sign extension
1573 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1574 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1575 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1577 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1578 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1579 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1581 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1582 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1583 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1584 // how to represent that such that tblgen is happy and we don't
1585 // mark this codegen only?
1587 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1588 (ins addrmode3:$addr), LdMiscFrm,
1589 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1590 []>, Requires<[IsARM, HasV5TE]>;
1594 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1595 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1596 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1597 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1599 // {13} 1 == Rm, 0 == imm12
1603 let Inst{25} = addr{13};
1604 let Inst{23} = addr{12};
1605 let Inst{19-16} = addr{17-14};
1606 let Inst{11-0} = addr{11-0};
1608 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1609 (ins GPR:$Rn, am2offset:$offset),
1610 IndexModePost, LdFrm, itin,
1611 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1612 // {13} 1 == Rm, 0 == imm12
1617 let Inst{25} = offset{13};
1618 let Inst{23} = offset{12};
1619 let Inst{19-16} = Rn;
1620 let Inst{11-0} = offset{11-0};
1624 let mayLoad = 1, neverHasSideEffects = 1 in {
1625 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1626 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1629 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1630 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1631 (ins addrmode3:$addr), IndexModePre,
1633 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1635 let Inst{23} = addr{8}; // U bit
1636 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1637 let Inst{19-16} = addr{12-9}; // Rn
1638 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1639 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1641 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1642 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1644 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1647 let Inst{23} = offset{8}; // U bit
1648 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1649 let Inst{19-16} = Rn;
1650 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1651 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1655 let mayLoad = 1, neverHasSideEffects = 1 in {
1656 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1657 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1658 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1659 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1660 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1661 } // mayLoad = 1, neverHasSideEffects = 1
1663 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1664 let mayLoad = 1, neverHasSideEffects = 1 in {
1665 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1666 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1667 LdFrm, IIC_iLoad_ru,
1668 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1669 let Inst{21} = 1; // overwrite
1671 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1672 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1673 LdFrm, IIC_iLoad_bh_ru,
1674 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1675 let Inst{21} = 1; // overwrite
1677 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1678 (ins GPR:$base, am3offset:$offset), IndexModePost,
1679 LdMiscFrm, IIC_iLoad_bh_ru,
1680 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1681 let Inst{21} = 1; // overwrite
1683 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1684 (ins GPR:$base, am3offset:$offset), IndexModePost,
1685 LdMiscFrm, IIC_iLoad_bh_ru,
1686 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1687 let Inst{21} = 1; // overwrite
1689 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1690 (ins GPR:$base, am3offset:$offset), IndexModePost,
1691 LdMiscFrm, IIC_iLoad_bh_ru,
1692 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1693 let Inst{21} = 1; // overwrite
1699 // Stores with truncate
1700 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1701 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1702 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1705 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1706 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1707 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1708 StMiscFrm, IIC_iStore_d_r,
1709 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1712 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1713 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1714 IndexModePre, StFrm, IIC_iStore_ru,
1715 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1717 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1719 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1720 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1721 IndexModePost, StFrm, IIC_iStore_ru,
1722 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1724 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1726 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1727 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1728 IndexModePre, StFrm, IIC_iStore_bh_ru,
1729 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1730 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1731 GPR:$Rn, am2offset:$offset))]>;
1732 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1733 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1734 IndexModePost, StFrm, IIC_iStore_bh_ru,
1735 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1736 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1737 GPR:$Rn, am2offset:$offset))]>;
1739 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1740 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1741 IndexModePre, StMiscFrm, IIC_iStore_ru,
1742 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1744 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1746 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1747 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1748 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1749 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1750 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1751 GPR:$Rn, am3offset:$offset))]>;
1753 // For disassembly only
1754 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1755 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1756 StMiscFrm, IIC_iStore_d_ru,
1757 "strd", "\t$src1, $src2, [$base, $offset]!",
1758 "$base = $base_wb", []>;
1760 // For disassembly only
1761 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1762 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1763 StMiscFrm, IIC_iStore_d_ru,
1764 "strd", "\t$src1, $src2, [$base], $offset",
1765 "$base = $base_wb", []>;
1767 // STRT, STRBT, and STRHT are for disassembly only.
1769 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1770 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1771 IndexModeNone, StFrm, IIC_iStore_ru,
1772 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1773 [/* For disassembly only; pattern left blank */]> {
1774 let Inst{21} = 1; // overwrite
1777 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1778 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1779 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1780 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1781 [/* For disassembly only; pattern left blank */]> {
1782 let Inst{21} = 1; // overwrite
1785 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1786 (ins GPR:$src, GPR:$base,am3offset:$offset),
1787 StMiscFrm, IIC_iStore_bh_ru,
1788 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1789 [/* For disassembly only; pattern left blank */]> {
1790 let Inst{21} = 1; // overwrite
1793 //===----------------------------------------------------------------------===//
1794 // Load / store multiple Instructions.
1797 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1798 InstrItinClass itin, InstrItinClass itin_upd> {
1800 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1801 IndexModeNone, f, itin,
1802 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1803 let Inst{24-23} = 0b01; // Increment After
1804 let Inst{21} = 0; // No writeback
1805 let Inst{20} = L_bit;
1808 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1809 IndexModeUpd, f, itin_upd,
1810 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1811 let Inst{24-23} = 0b01; // Increment After
1812 let Inst{21} = 1; // Writeback
1813 let Inst{20} = L_bit;
1816 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1817 IndexModeNone, f, itin,
1818 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1819 let Inst{24-23} = 0b00; // Decrement After
1820 let Inst{21} = 0; // No writeback
1821 let Inst{20} = L_bit;
1824 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1825 IndexModeUpd, f, itin_upd,
1826 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1827 let Inst{24-23} = 0b00; // Decrement After
1828 let Inst{21} = 1; // Writeback
1829 let Inst{20} = L_bit;
1832 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1833 IndexModeNone, f, itin,
1834 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1835 let Inst{24-23} = 0b10; // Decrement Before
1836 let Inst{21} = 0; // No writeback
1837 let Inst{20} = L_bit;
1840 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1841 IndexModeUpd, f, itin_upd,
1842 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1843 let Inst{24-23} = 0b10; // Decrement Before
1844 let Inst{21} = 1; // Writeback
1845 let Inst{20} = L_bit;
1848 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1849 IndexModeNone, f, itin,
1850 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1851 let Inst{24-23} = 0b11; // Increment Before
1852 let Inst{21} = 0; // No writeback
1853 let Inst{20} = L_bit;
1856 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1857 IndexModeUpd, f, itin_upd,
1858 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1859 let Inst{24-23} = 0b11; // Increment Before
1860 let Inst{21} = 1; // Writeback
1861 let Inst{20} = L_bit;
1865 let neverHasSideEffects = 1 in {
1867 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1868 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1870 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1871 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1873 } // neverHasSideEffects
1875 // Load / Store Multiple Mnemonic Aliases
1876 def : MnemonicAlias<"ldm", "ldmia">;
1877 def : MnemonicAlias<"stm", "stmia">;
1879 // FIXME: remove when we have a way to marking a MI with these properties.
1880 // FIXME: Should pc be an implicit operand like PICADD, etc?
1881 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1882 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1883 // FIXME: Should be a pseudo-instruction.
1884 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1885 reglist:$regs, variable_ops),
1886 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1887 "ldmia${p}\t$Rn!, $regs",
1889 let Inst{24-23} = 0b01; // Increment After
1890 let Inst{21} = 1; // Writeback
1891 let Inst{20} = 1; // Load
1894 //===----------------------------------------------------------------------===//
1895 // Move Instructions.
1898 let neverHasSideEffects = 1 in
1899 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1900 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1904 let Inst{11-4} = 0b00000000;
1907 let Inst{15-12} = Rd;
1910 // A version for the smaller set of tail call registers.
1911 let neverHasSideEffects = 1 in
1912 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1913 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1917 let Inst{11-4} = 0b00000000;
1920 let Inst{15-12} = Rd;
1923 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1924 DPSoRegFrm, IIC_iMOVsr,
1925 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1929 let Inst{15-12} = Rd;
1930 let Inst{11-0} = src;
1934 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1935 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1936 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1940 let Inst{15-12} = Rd;
1941 let Inst{19-16} = 0b0000;
1942 let Inst{11-0} = imm;
1945 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1946 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1948 "movw", "\t$Rd, $imm",
1949 [(set GPR:$Rd, imm0_65535:$imm)]>,
1950 Requires<[IsARM, HasV6T2]>, UnaryDP {
1953 let Inst{15-12} = Rd;
1954 let Inst{11-0} = imm{11-0};
1955 let Inst{19-16} = imm{15-12};
1960 def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1961 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1963 let Constraints = "$src = $Rd" in {
1964 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1966 "movt", "\t$Rd, $imm",
1968 (or (and GPR:$src, 0xffff),
1969 lo16AllZero:$imm))]>, UnaryDP,
1970 Requires<[IsARM, HasV6T2]> {
1973 let Inst{15-12} = Rd;
1974 let Inst{11-0} = imm{11-0};
1975 let Inst{19-16} = imm{15-12};
1980 def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1981 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1985 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1986 Requires<[IsARM, HasV6T2]>;
1988 let Uses = [CPSR] in
1989 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
1990 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1993 // These aren't really mov instructions, but we have to define them this way
1994 // due to flag operands.
1996 let Defs = [CPSR] in {
1997 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1998 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2000 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2001 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2005 //===----------------------------------------------------------------------===//
2006 // Extend Instructions.
2011 defm SXTB : AI_ext_rrot<0b01101010,
2012 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2013 defm SXTH : AI_ext_rrot<0b01101011,
2014 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2016 defm SXTAB : AI_exta_rrot<0b01101010,
2017 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2018 defm SXTAH : AI_exta_rrot<0b01101011,
2019 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2021 // For disassembly only
2022 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2024 // For disassembly only
2025 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2029 let AddedComplexity = 16 in {
2030 defm UXTB : AI_ext_rrot<0b01101110,
2031 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2032 defm UXTH : AI_ext_rrot<0b01101111,
2033 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2034 defm UXTB16 : AI_ext_rrot<0b01101100,
2035 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2037 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2038 // The transformation should probably be done as a combiner action
2039 // instead so we can include a check for masking back in the upper
2040 // eight bits of the source into the lower eight bits of the result.
2041 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2042 // (UXTB16r_rot GPR:$Src, 24)>;
2043 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2044 (UXTB16r_rot GPR:$Src, 8)>;
2046 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2047 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2048 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2049 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2052 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2053 // For disassembly only
2054 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2057 def SBFX : I<(outs GPR:$Rd),
2058 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2059 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2060 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2061 Requires<[IsARM, HasV6T2]> {
2066 let Inst{27-21} = 0b0111101;
2067 let Inst{6-4} = 0b101;
2068 let Inst{20-16} = width;
2069 let Inst{15-12} = Rd;
2070 let Inst{11-7} = lsb;
2074 def UBFX : I<(outs GPR:$Rd),
2075 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2076 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2077 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2078 Requires<[IsARM, HasV6T2]> {
2083 let Inst{27-21} = 0b0111111;
2084 let Inst{6-4} = 0b101;
2085 let Inst{20-16} = width;
2086 let Inst{15-12} = Rd;
2087 let Inst{11-7} = lsb;
2091 //===----------------------------------------------------------------------===//
2092 // Arithmetic Instructions.
2095 defm ADD : AsI1_bin_irs<0b0100, "add",
2096 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2097 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2098 defm SUB : AsI1_bin_irs<0b0010, "sub",
2099 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2100 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2102 // ADD and SUB with 's' bit set.
2103 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2104 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2105 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2106 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2107 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2108 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2110 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2111 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2112 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2113 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2115 // ADC and SUBC with 's' bit set.
2116 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2117 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2118 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2119 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2121 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2122 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2123 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2128 let Inst{15-12} = Rd;
2129 let Inst{19-16} = Rn;
2130 let Inst{11-0} = imm;
2133 // The reg/reg form is only defined for the disassembler; for codegen it is
2134 // equivalent to SUBrr.
2135 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2136 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2137 [/* For disassembly only; pattern left blank */]> {
2141 let Inst{11-4} = 0b00000000;
2144 let Inst{15-12} = Rd;
2145 let Inst{19-16} = Rn;
2148 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2149 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2150 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2155 let Inst{11-0} = shift;
2156 let Inst{15-12} = Rd;
2157 let Inst{19-16} = Rn;
2160 // RSB with 's' bit set.
2161 let isCodeGenOnly = 1, Defs = [CPSR] in {
2162 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2163 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2164 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2170 let Inst{15-12} = Rd;
2171 let Inst{19-16} = Rn;
2172 let Inst{11-0} = imm;
2174 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2175 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2176 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2182 let Inst{11-0} = shift;
2183 let Inst{15-12} = Rd;
2184 let Inst{19-16} = Rn;
2188 let Uses = [CPSR] in {
2189 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2190 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2191 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2197 let Inst{15-12} = Rd;
2198 let Inst{19-16} = Rn;
2199 let Inst{11-0} = imm;
2201 // The reg/reg form is only defined for the disassembler; for codegen it is
2202 // equivalent to SUBrr.
2203 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2204 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2205 [/* For disassembly only; pattern left blank */]> {
2209 let Inst{11-4} = 0b00000000;
2212 let Inst{15-12} = Rd;
2213 let Inst{19-16} = Rn;
2215 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2216 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2217 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2223 let Inst{11-0} = shift;
2224 let Inst{15-12} = Rd;
2225 let Inst{19-16} = Rn;
2229 // FIXME: Allow these to be predicated.
2230 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2231 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2232 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2233 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2240 let Inst{15-12} = Rd;
2241 let Inst{19-16} = Rn;
2242 let Inst{11-0} = imm;
2244 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2245 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2246 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2253 let Inst{11-0} = shift;
2254 let Inst{15-12} = Rd;
2255 let Inst{19-16} = Rn;
2259 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2260 // The assume-no-carry-in form uses the negation of the input since add/sub
2261 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2262 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2264 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2265 (SUBri GPR:$src, so_imm_neg:$imm)>;
2266 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2267 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2268 // The with-carry-in form matches bitwise not instead of the negation.
2269 // Effectively, the inverse interpretation of the carry flag already accounts
2270 // for part of the negation.
2271 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2272 (SBCri GPR:$src, so_imm_not:$imm)>;
2274 // Note: These are implemented in C++ code, because they have to generate
2275 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2277 // (mul X, 2^n+1) -> (add (X << n), X)
2278 // (mul X, 2^n-1) -> (rsb X, (X << n))
2280 // ARM Arithmetic Instruction -- for disassembly only
2281 // GPR:$dst = GPR:$a op GPR:$b
2282 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2283 list<dag> pattern = [/* For disassembly only; pattern left blank */],
2284 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm">
2285 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
2289 let Inst{27-20} = op27_20;
2290 let Inst{11-4} = op11_4;
2291 let Inst{19-16} = Rn;
2292 let Inst{15-12} = Rd;
2296 // Saturating add/subtract -- for disassembly only
2298 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2299 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))],
2300 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2301 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2302 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))],
2303 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2304 def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn),
2306 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn),
2309 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2310 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2311 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2312 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2313 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2314 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2315 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2316 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2317 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2318 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2319 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2320 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2322 // Signed/Unsigned add/subtract -- for disassembly only
2324 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2325 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2326 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2327 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2328 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2329 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2330 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2331 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2332 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2333 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2334 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2335 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2337 // Signed/Unsigned halving add/subtract -- for disassembly only
2339 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2340 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2341 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2342 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2343 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2344 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2345 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2346 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2347 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2348 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2349 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2350 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2352 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2354 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2355 MulFrm /* for convenience */, NoItinerary, "usad8",
2356 "\t$Rd, $Rn, $Rm", []>,
2357 Requires<[IsARM, HasV6]> {
2361 let Inst{27-20} = 0b01111000;
2362 let Inst{15-12} = 0b1111;
2363 let Inst{7-4} = 0b0001;
2364 let Inst{19-16} = Rd;
2365 let Inst{11-8} = Rm;
2368 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2369 MulFrm /* for convenience */, NoItinerary, "usada8",
2370 "\t$Rd, $Rn, $Rm, $Ra", []>,
2371 Requires<[IsARM, HasV6]> {
2376 let Inst{27-20} = 0b01111000;
2377 let Inst{7-4} = 0b0001;
2378 let Inst{19-16} = Rd;
2379 let Inst{15-12} = Ra;
2380 let Inst{11-8} = Rm;
2384 // Signed/Unsigned saturate -- for disassembly only
2386 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2387 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2388 [/* For disassembly only; pattern left blank */]> {
2393 let Inst{27-21} = 0b0110101;
2394 let Inst{5-4} = 0b01;
2395 let Inst{20-16} = sat_imm;
2396 let Inst{15-12} = Rd;
2397 let Inst{11-7} = sh{7-3};
2398 let Inst{6} = sh{0};
2402 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2403 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2404 [/* For disassembly only; pattern left blank */]> {
2408 let Inst{27-20} = 0b01101010;
2409 let Inst{11-4} = 0b11110011;
2410 let Inst{15-12} = Rd;
2411 let Inst{19-16} = sat_imm;
2415 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2416 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2417 [/* For disassembly only; pattern left blank */]> {
2422 let Inst{27-21} = 0b0110111;
2423 let Inst{5-4} = 0b01;
2424 let Inst{15-12} = Rd;
2425 let Inst{11-7} = sh{7-3};
2426 let Inst{6} = sh{0};
2427 let Inst{20-16} = sat_imm;
2431 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2432 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2433 [/* For disassembly only; pattern left blank */]> {
2437 let Inst{27-20} = 0b01101110;
2438 let Inst{11-4} = 0b11110011;
2439 let Inst{15-12} = Rd;
2440 let Inst{19-16} = sat_imm;
2444 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2445 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2447 //===----------------------------------------------------------------------===//
2448 // Bitwise Instructions.
2451 defm AND : AsI1_bin_irs<0b0000, "and",
2452 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2453 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2454 defm ORR : AsI1_bin_irs<0b1100, "orr",
2455 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2456 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2457 defm EOR : AsI1_bin_irs<0b0001, "eor",
2458 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2459 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2460 defm BIC : AsI1_bin_irs<0b1110, "bic",
2461 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2462 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2464 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2465 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2466 "bfc", "\t$Rd, $imm", "$src = $Rd",
2467 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2468 Requires<[IsARM, HasV6T2]> {
2471 let Inst{27-21} = 0b0111110;
2472 let Inst{6-0} = 0b0011111;
2473 let Inst{15-12} = Rd;
2474 let Inst{11-7} = imm{4-0}; // lsb
2475 let Inst{20-16} = imm{9-5}; // width
2478 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2479 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2480 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2481 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2482 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2483 bf_inv_mask_imm:$imm))]>,
2484 Requires<[IsARM, HasV6T2]> {
2488 let Inst{27-21} = 0b0111110;
2489 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2490 let Inst{15-12} = Rd;
2491 let Inst{11-7} = imm{4-0}; // lsb
2492 let Inst{20-16} = imm{9-5}; // width
2496 // GNU as only supports this form of bfi (w/ 4 arguments)
2497 let isAsmParserOnly = 1 in
2498 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2499 lsb_pos_imm:$lsb, width_imm:$width),
2500 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2501 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2502 []>, Requires<[IsARM, HasV6T2]> {
2507 let Inst{27-21} = 0b0111110;
2508 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2509 let Inst{15-12} = Rd;
2510 let Inst{11-7} = lsb;
2511 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2515 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2516 "mvn", "\t$Rd, $Rm",
2517 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2521 let Inst{19-16} = 0b0000;
2522 let Inst{11-4} = 0b00000000;
2523 let Inst{15-12} = Rd;
2526 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2527 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2528 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2532 let Inst{19-16} = 0b0000;
2533 let Inst{15-12} = Rd;
2534 let Inst{11-0} = shift;
2536 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2537 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2538 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2539 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2543 let Inst{19-16} = 0b0000;
2544 let Inst{15-12} = Rd;
2545 let Inst{11-0} = imm;
2548 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2549 (BICri GPR:$src, so_imm_not:$imm)>;
2551 //===----------------------------------------------------------------------===//
2552 // Multiply Instructions.
2554 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2555 string opc, string asm, list<dag> pattern>
2556 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2560 let Inst{19-16} = Rd;
2561 let Inst{11-8} = Rm;
2564 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2565 string opc, string asm, list<dag> pattern>
2566 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2571 let Inst{19-16} = RdHi;
2572 let Inst{15-12} = RdLo;
2573 let Inst{11-8} = Rm;
2577 let isCommutable = 1 in {
2578 let Constraints = "@earlyclobber $Rd" in
2579 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2580 pred:$p, cc_out:$s),
2581 Size4Bytes, IIC_iMUL32,
2582 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2583 Requires<[IsARM, NoV6]>;
2585 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2586 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2587 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2588 Requires<[IsARM, HasV6]>;
2591 let Constraints = "@earlyclobber $Rd" in
2592 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2593 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2594 Size4Bytes, IIC_iMAC32,
2595 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2596 Requires<[IsARM, NoV6]> {
2598 let Inst{15-12} = Ra;
2600 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2601 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2602 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2603 Requires<[IsARM, HasV6]> {
2605 let Inst{15-12} = Ra;
2608 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2609 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2610 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2611 Requires<[IsARM, HasV6T2]> {
2616 let Inst{19-16} = Rd;
2617 let Inst{15-12} = Ra;
2618 let Inst{11-8} = Rm;
2622 // Extra precision multiplies with low / high results
2624 let neverHasSideEffects = 1 in {
2625 let isCommutable = 1 in {
2626 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2627 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2628 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2629 Size4Bytes, IIC_iMUL64, []>,
2630 Requires<[IsARM, NoV6]>;
2632 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2633 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2634 Size4Bytes, IIC_iMUL64, []>,
2635 Requires<[IsARM, NoV6]>;
2638 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2639 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2640 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2641 Requires<[IsARM, HasV6]>;
2643 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2644 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2645 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2646 Requires<[IsARM, HasV6]>;
2649 // Multiply + accumulate
2650 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2651 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2652 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2653 Size4Bytes, IIC_iMAC64, []>,
2654 Requires<[IsARM, NoV6]>;
2655 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2656 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2657 Size4Bytes, IIC_iMAC64, []>,
2658 Requires<[IsARM, NoV6]>;
2659 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2660 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2661 Size4Bytes, IIC_iMAC64, []>,
2662 Requires<[IsARM, NoV6]>;
2666 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2667 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2668 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2669 Requires<[IsARM, HasV6]>;
2670 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2671 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2672 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2673 Requires<[IsARM, HasV6]>;
2675 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2676 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2677 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2678 Requires<[IsARM, HasV6]> {
2683 let Inst{19-16} = RdLo;
2684 let Inst{15-12} = RdHi;
2685 let Inst{11-8} = Rm;
2688 } // neverHasSideEffects
2690 // Most significant word multiply
2691 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2692 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2693 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2694 Requires<[IsARM, HasV6]> {
2695 let Inst{15-12} = 0b1111;
2698 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2699 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2700 [/* For disassembly only; pattern left blank */]>,
2701 Requires<[IsARM, HasV6]> {
2702 let Inst{15-12} = 0b1111;
2705 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2706 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2707 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2708 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2709 Requires<[IsARM, HasV6]>;
2711 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2712 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2713 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2714 [/* For disassembly only; pattern left blank */]>,
2715 Requires<[IsARM, HasV6]>;
2717 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2718 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2719 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2720 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2721 Requires<[IsARM, HasV6]>;
2723 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2724 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2725 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2726 [/* For disassembly only; pattern left blank */]>,
2727 Requires<[IsARM, HasV6]>;
2729 multiclass AI_smul<string opc, PatFrag opnode> {
2730 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2731 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2732 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2733 (sext_inreg GPR:$Rm, i16)))]>,
2734 Requires<[IsARM, HasV5TE]>;
2736 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2737 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2738 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2739 (sra GPR:$Rm, (i32 16))))]>,
2740 Requires<[IsARM, HasV5TE]>;
2742 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2743 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2744 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2745 (sext_inreg GPR:$Rm, i16)))]>,
2746 Requires<[IsARM, HasV5TE]>;
2748 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2749 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2750 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2751 (sra GPR:$Rm, (i32 16))))]>,
2752 Requires<[IsARM, HasV5TE]>;
2754 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2755 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2756 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2757 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2758 Requires<[IsARM, HasV5TE]>;
2760 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2761 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2762 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2763 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2764 Requires<[IsARM, HasV5TE]>;
2768 multiclass AI_smla<string opc, PatFrag opnode> {
2769 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2770 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2771 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2772 [(set GPR:$Rd, (add GPR:$Ra,
2773 (opnode (sext_inreg GPR:$Rn, i16),
2774 (sext_inreg GPR:$Rm, i16))))]>,
2775 Requires<[IsARM, HasV5TE]>;
2777 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2778 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2779 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2780 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2781 (sra GPR:$Rm, (i32 16)))))]>,
2782 Requires<[IsARM, HasV5TE]>;
2784 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2785 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2786 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2787 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2788 (sext_inreg GPR:$Rm, i16))))]>,
2789 Requires<[IsARM, HasV5TE]>;
2791 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2792 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2793 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2794 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2795 (sra GPR:$Rm, (i32 16)))))]>,
2796 Requires<[IsARM, HasV5TE]>;
2798 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2799 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2800 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2801 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2802 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2803 Requires<[IsARM, HasV5TE]>;
2805 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2806 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2807 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2808 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2809 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2810 Requires<[IsARM, HasV5TE]>;
2813 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2814 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2816 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2817 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2818 (ins GPR:$Rn, GPR:$Rm),
2819 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2820 [/* For disassembly only; pattern left blank */]>,
2821 Requires<[IsARM, HasV5TE]>;
2823 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2824 (ins GPR:$Rn, GPR:$Rm),
2825 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2826 [/* For disassembly only; pattern left blank */]>,
2827 Requires<[IsARM, HasV5TE]>;
2829 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2830 (ins GPR:$Rn, GPR:$Rm),
2831 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2832 [/* For disassembly only; pattern left blank */]>,
2833 Requires<[IsARM, HasV5TE]>;
2835 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2836 (ins GPR:$Rn, GPR:$Rm),
2837 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2838 [/* For disassembly only; pattern left blank */]>,
2839 Requires<[IsARM, HasV5TE]>;
2841 // Helper class for AI_smld -- for disassembly only
2842 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2843 InstrItinClass itin, string opc, string asm>
2844 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2851 let Inst{21-20} = 0b00;
2852 let Inst{22} = long;
2853 let Inst{27-23} = 0b01110;
2854 let Inst{11-8} = Rm;
2857 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2858 InstrItinClass itin, string opc, string asm>
2859 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2861 let Inst{15-12} = 0b1111;
2862 let Inst{19-16} = Rd;
2864 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2865 InstrItinClass itin, string opc, string asm>
2866 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2868 let Inst{15-12} = Ra;
2870 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2871 InstrItinClass itin, string opc, string asm>
2872 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2875 let Inst{19-16} = RdHi;
2876 let Inst{15-12} = RdLo;
2879 multiclass AI_smld<bit sub, string opc> {
2881 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2882 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2884 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2885 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2887 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2888 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2889 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2891 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2892 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2893 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2897 defm SMLA : AI_smld<0, "smla">;
2898 defm SMLS : AI_smld<1, "smls">;
2900 multiclass AI_sdml<bit sub, string opc> {
2902 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2903 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2904 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2905 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2908 defm SMUA : AI_sdml<0, "smua">;
2909 defm SMUS : AI_sdml<1, "smus">;
2911 //===----------------------------------------------------------------------===//
2912 // Misc. Arithmetic Instructions.
2915 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2916 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2917 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2919 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2920 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2921 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2922 Requires<[IsARM, HasV6T2]>;
2924 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2925 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2926 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2928 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2929 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2931 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2932 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2933 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2934 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2935 Requires<[IsARM, HasV6]>;
2937 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2938 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2941 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2942 (shl GPR:$Rm, (i32 8))), i16))]>,
2943 Requires<[IsARM, HasV6]>;
2945 def lsl_shift_imm : SDNodeXForm<imm, [{
2946 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2947 return CurDAG->getTargetConstant(Sh, MVT::i32);
2950 def lsl_amt : PatLeaf<(i32 imm), [{
2951 return (N->getZExtValue() < 32);
2954 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2955 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2956 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2957 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2958 (and (shl GPR:$Rm, lsl_amt:$sh),
2960 Requires<[IsARM, HasV6]>;
2962 // Alternate cases for PKHBT where identities eliminate some nodes.
2963 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2964 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2965 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2966 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2968 def asr_shift_imm : SDNodeXForm<imm, [{
2969 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2970 return CurDAG->getTargetConstant(Sh, MVT::i32);
2973 def asr_amt : PatLeaf<(i32 imm), [{
2974 return (N->getZExtValue() <= 32);
2977 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2978 // will match the pattern below.
2979 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2980 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2981 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2982 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2983 (and (sra GPR:$Rm, asr_amt:$sh),
2985 Requires<[IsARM, HasV6]>;
2987 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2988 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2989 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2990 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2991 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2992 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2993 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2995 //===----------------------------------------------------------------------===//
2996 // Comparison Instructions...
2999 defm CMP : AI1_cmp_irs<0b1010, "cmp",
3000 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3001 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3003 // ARMcmpZ can re-use the above instruction definitions.
3004 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3005 (CMPri GPR:$src, so_imm:$imm)>;
3006 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3007 (CMPrr GPR:$src, GPR:$rhs)>;
3008 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
3009 (CMPrs GPR:$src, so_reg:$rhs)>;
3011 // FIXME: We have to be careful when using the CMN instruction and comparison
3012 // with 0. One would expect these two pieces of code should give identical
3028 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3029 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3030 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3031 // value of r0 and the carry bit (because the "carry bit" parameter to
3032 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3033 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3034 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3035 // parameter to AddWithCarry is defined as 0).
3037 // When x is 0 and unsigned:
3041 // ~x + 1 = 0x1 0000 0000
3042 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3044 // Therefore, we should disable CMN when comparing against zero, until we can
3045 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3046 // when it's a comparison which doesn't look at the 'carry' flag).
3048 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3050 // This is related to <rdar://problem/7569620>.
3052 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3053 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3055 // Note that TST/TEQ don't set all the same flags that CMP does!
3056 defm TST : AI1_cmp_irs<0b1000, "tst",
3057 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3058 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3059 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3060 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3061 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3063 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3064 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3065 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3067 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3068 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3070 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3071 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3073 // Pseudo i64 compares for some floating point compares.
3074 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3076 def BCCi64 : PseudoInst<(outs),
3077 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3079 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3081 def BCCZi64 : PseudoInst<(outs),
3082 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3083 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3084 } // usesCustomInserter
3087 // Conditional moves
3088 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3089 // a two-value operand where a dag node expects two operands. :(
3090 // FIXME: These should all be pseudo-instructions that get expanded to
3091 // the normal MOV instructions. That would fix the dependency on
3092 // special casing them in tblgen.
3093 let neverHasSideEffects = 1 in {
3094 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3095 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3096 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3097 RegConstraint<"$false = $Rd">, UnaryDP {
3102 let Inst{15-12} = Rd;
3103 let Inst{11-4} = 0b00000000;
3107 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3108 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3109 "mov", "\t$Rd, $shift",
3110 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3111 RegConstraint<"$false = $Rd">, UnaryDP {
3116 let Inst{19-16} = 0;
3117 let Inst{15-12} = Rd;
3118 let Inst{11-0} = shift;
3121 let isMoveImm = 1 in
3122 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3124 "movw", "\t$Rd, $imm",
3126 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3132 let Inst{19-16} = imm{15-12};
3133 let Inst{15-12} = Rd;
3134 let Inst{11-0} = imm{11-0};
3137 let isMoveImm = 1 in
3138 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3139 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3140 "mov", "\t$Rd, $imm",
3141 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3142 RegConstraint<"$false = $Rd">, UnaryDP {
3147 let Inst{19-16} = 0b0000;
3148 let Inst{15-12} = Rd;
3149 let Inst{11-0} = imm;
3152 // Two instruction predicate mov immediate.
3153 let isMoveImm = 1 in
3154 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3155 (ins GPR:$false, i32imm:$src, pred:$p),
3156 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3158 let isMoveImm = 1 in
3159 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3160 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3161 "mvn", "\t$Rd, $imm",
3162 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3163 RegConstraint<"$false = $Rd">, UnaryDP {
3168 let Inst{19-16} = 0b0000;
3169 let Inst{15-12} = Rd;
3170 let Inst{11-0} = imm;
3172 } // neverHasSideEffects
3174 //===----------------------------------------------------------------------===//
3175 // Atomic operations intrinsics
3178 def memb_opt : Operand<i32> {
3179 let PrintMethod = "printMemBOption";
3182 // memory barriers protect the atomic sequences
3183 let hasSideEffects = 1 in {
3184 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3185 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3186 Requires<[IsARM, HasDB]> {
3188 let Inst{31-4} = 0xf57ff05;
3189 let Inst{3-0} = opt;
3192 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3193 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3194 [(ARMMemBarrierMCR GPR:$zero)]>,
3195 Requires<[IsARM, HasV6]> {
3196 // FIXME: add encoding
3200 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3202 [/* For disassembly only; pattern left blank */]>,
3203 Requires<[IsARM, HasDB]> {
3205 let Inst{31-4} = 0xf57ff04;
3206 let Inst{3-0} = opt;
3209 // ISB has only full system option -- for disassembly only
3210 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3211 Requires<[IsARM, HasDB]> {
3212 let Inst{31-4} = 0xf57ff06;
3213 let Inst{3-0} = 0b1111;
3216 let usesCustomInserter = 1 in {
3217 let Uses = [CPSR] in {
3218 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3219 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3220 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3221 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3222 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3223 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3224 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3225 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3226 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3227 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3228 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3229 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3230 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3231 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3232 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3233 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3234 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3235 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3236 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3237 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3238 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3239 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3240 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3241 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3242 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3243 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3244 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3245 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3246 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3247 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3248 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3249 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3250 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3251 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3252 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3253 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3254 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3255 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3256 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3257 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3258 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3259 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3260 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3261 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3262 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3263 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3264 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3265 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3266 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3267 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3268 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3269 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3270 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3271 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3273 def ATOMIC_SWAP_I8 : PseudoInst<
3274 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3275 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3276 def ATOMIC_SWAP_I16 : PseudoInst<
3277 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3278 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3279 def ATOMIC_SWAP_I32 : PseudoInst<
3280 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3281 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3283 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3284 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3285 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3286 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3287 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3288 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3289 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3290 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3291 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3295 let mayLoad = 1 in {
3296 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3297 "ldrexb", "\t$Rt, [$Rn]",
3299 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3300 "ldrexh", "\t$Rt, [$Rn]",
3302 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3303 "ldrex", "\t$Rt, [$Rn]",
3305 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3307 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3311 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3312 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3314 "strexb", "\t$Rd, $src, [$Rn]",
3316 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3318 "strexh", "\t$Rd, $Rt, [$Rn]",
3320 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3322 "strex", "\t$Rd, $Rt, [$Rn]",
3324 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3325 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3327 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3331 // Clear-Exclusive is for disassembly only.
3332 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3333 [/* For disassembly only; pattern left blank */]>,
3334 Requires<[IsARM, HasV7]> {
3335 let Inst{31-0} = 0b11110101011111111111000000011111;
3338 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3339 let mayLoad = 1 in {
3340 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3341 [/* For disassembly only; pattern left blank */]>;
3342 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3343 [/* For disassembly only; pattern left blank */]>;
3346 //===----------------------------------------------------------------------===//
3350 // __aeabi_read_tp preserves the registers r1-r3.
3351 // This is a pseudo inst so that we can get the encoding right,
3352 // complete with fixup for the aeabi_read_tp function.
3354 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3355 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3356 [(set R0, ARMthread_pointer)]>;
3359 //===----------------------------------------------------------------------===//
3360 // SJLJ Exception handling intrinsics
3361 // eh_sjlj_setjmp() is an instruction sequence to store the return
3362 // address and save #0 in R0 for the non-longjmp case.
3363 // Since by its nature we may be coming from some other function to get
3364 // here, and we're using the stack frame for the containing function to
3365 // save/restore registers, we can't keep anything live in regs across
3366 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3367 // when we get here from a longjmp(). We force everthing out of registers
3368 // except for our own input by listing the relevant registers in Defs. By
3369 // doing so, we also cause the prologue/epilogue code to actively preserve
3370 // all of the callee-saved resgisters, which is exactly what we want.
3371 // A constant value is passed in $val, and we use the location as a scratch.
3373 // These are pseudo-instructions and are lowered to individual MC-insts, so
3374 // no encoding information is necessary.
3376 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3377 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3378 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3379 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3380 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3382 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3383 Requires<[IsARM, HasVFP2]>;
3387 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3388 hasSideEffects = 1, isBarrier = 1 in {
3389 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3391 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3392 Requires<[IsARM, NoVFP]>;
3395 // FIXME: Non-Darwin version(s)
3396 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3397 Defs = [ R7, LR, SP ] in {
3398 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3400 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3401 Requires<[IsARM, IsDarwin]>;
3404 // eh.sjlj.dispatchsetup pseudo-instruction.
3405 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3406 // handled when the pseudo is expanded (which happens before any passes
3407 // that need the instruction size).
3408 let isBarrier = 1, hasSideEffects = 1 in
3409 def Int_eh_sjlj_dispatchsetup :
3410 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3411 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3412 Requires<[IsDarwin]>;
3414 //===----------------------------------------------------------------------===//
3415 // Non-Instruction Patterns
3418 // Large immediate handling.
3420 // 32-bit immediate using two piece so_imms or movw + movt.
3421 // This is a single pseudo instruction, the benefit is that it can be remat'd
3422 // as a single unit instead of having to handle reg inputs.
3423 // FIXME: Remove this when we can do generalized remat.
3424 let isReMaterializable = 1, isMoveImm = 1 in
3425 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3426 [(set GPR:$dst, (arm_i32imm:$src))]>,
3429 // Pseudo instruction that combines movw + movt + add pc (if PIC).
3430 // It also makes it possible to rematerialize the instructions.
3431 // FIXME: Remove this when we can do generalized remat and when machine licm
3432 // can properly the instructions.
3433 let isReMaterializable = 1 in {
3434 def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3436 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3437 Requires<[IsARM, UseMovt]>;
3439 def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3441 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3442 Requires<[IsARM, UseMovt]>;
3444 let AddedComplexity = 10 in
3445 def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3447 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
3448 Requires<[IsARM, UseMovt]>;
3449 } // isReMaterializable
3451 // ConstantPool, GlobalAddress, and JumpTable
3452 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3453 Requires<[IsARM, DontUseMovt]>;
3454 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3455 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3456 Requires<[IsARM, UseMovt]>;
3457 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3458 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3460 // TODO: add,sub,and, 3-instr forms?
3463 def : ARMPat<(ARMtcret tcGPR:$dst),
3464 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3466 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3467 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3469 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3470 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3472 def : ARMPat<(ARMtcret tcGPR:$dst),
3473 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3475 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3476 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3478 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3479 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3482 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3483 Requires<[IsARM, IsNotDarwin]>;
3484 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3485 Requires<[IsARM, IsDarwin]>;
3487 // zextload i1 -> zextload i8
3488 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3489 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3491 // extload -> zextload
3492 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3493 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3494 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3495 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3497 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3499 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3500 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3503 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3504 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3505 (SMULBB GPR:$a, GPR:$b)>;
3506 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3507 (SMULBB GPR:$a, GPR:$b)>;
3508 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3509 (sra GPR:$b, (i32 16))),
3510 (SMULBT GPR:$a, GPR:$b)>;
3511 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3512 (SMULBT GPR:$a, GPR:$b)>;
3513 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3514 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3515 (SMULTB GPR:$a, GPR:$b)>;
3516 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3517 (SMULTB GPR:$a, GPR:$b)>;
3518 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3520 (SMULWB GPR:$a, GPR:$b)>;
3521 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3522 (SMULWB GPR:$a, GPR:$b)>;
3524 def : ARMV5TEPat<(add GPR:$acc,
3525 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3526 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3527 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3528 def : ARMV5TEPat<(add GPR:$acc,
3529 (mul sext_16_node:$a, sext_16_node:$b)),
3530 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3531 def : ARMV5TEPat<(add GPR:$acc,
3532 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3533 (sra GPR:$b, (i32 16)))),
3534 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3535 def : ARMV5TEPat<(add GPR:$acc,
3536 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3537 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3538 def : ARMV5TEPat<(add GPR:$acc,
3539 (mul (sra GPR:$a, (i32 16)),
3540 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3541 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3542 def : ARMV5TEPat<(add GPR:$acc,
3543 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3544 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3545 def : ARMV5TEPat<(add GPR:$acc,
3546 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3548 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3549 def : ARMV5TEPat<(add GPR:$acc,
3550 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3551 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3553 //===----------------------------------------------------------------------===//
3557 include "ARMInstrThumb.td"
3559 //===----------------------------------------------------------------------===//
3563 include "ARMInstrThumb2.td"
3565 //===----------------------------------------------------------------------===//
3566 // Floating Point Support
3569 include "ARMInstrVFP.td"
3571 //===----------------------------------------------------------------------===//
3572 // Advanced SIMD (NEON) Support
3575 include "ARMInstrNEON.td"
3577 //===----------------------------------------------------------------------===//
3578 // Coprocessor Instructions. For disassembly only.
3581 def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3582 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3583 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3584 [/* For disassembly only; pattern left blank */]> {
3592 let Inst{3-0} = CRm;
3594 let Inst{7-5} = opc2;
3595 let Inst{11-8} = cop;
3596 let Inst{15-12} = CRd;
3597 let Inst{19-16} = CRn;
3598 let Inst{23-20} = opc1;
3601 def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3602 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3603 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3604 [/* For disassembly only; pattern left blank */]> {
3605 let Inst{31-28} = 0b1111;
3613 let Inst{3-0} = CRm;
3615 let Inst{7-5} = opc2;
3616 let Inst{11-8} = cop;
3617 let Inst{15-12} = CRd;
3618 let Inst{19-16} = CRn;
3619 let Inst{23-20} = opc1;
3622 class ACI<dag oops, dag iops, string opc, string asm>
3623 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3624 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3625 let Inst{27-25} = 0b110;
3628 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3630 def _OFFSET : ACI<(outs),
3631 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3632 opc, "\tp$cop, cr$CRd, $addr"> {
3633 let Inst{31-28} = op31_28;
3634 let Inst{24} = 1; // P = 1
3635 let Inst{21} = 0; // W = 0
3636 let Inst{22} = 0; // D = 0
3637 let Inst{20} = load;
3640 def _PRE : ACI<(outs),
3641 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3642 opc, "\tp$cop, cr$CRd, $addr!"> {
3643 let Inst{31-28} = op31_28;
3644 let Inst{24} = 1; // P = 1
3645 let Inst{21} = 1; // W = 1
3646 let Inst{22} = 0; // D = 0
3647 let Inst{20} = load;
3650 def _POST : ACI<(outs),
3651 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3652 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3653 let Inst{31-28} = op31_28;
3654 let Inst{24} = 0; // P = 0
3655 let Inst{21} = 1; // W = 1
3656 let Inst{22} = 0; // D = 0
3657 let Inst{20} = load;
3660 def _OPTION : ACI<(outs),
3661 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3662 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3663 let Inst{31-28} = op31_28;
3664 let Inst{24} = 0; // P = 0
3665 let Inst{23} = 1; // U = 1
3666 let Inst{21} = 0; // W = 0
3667 let Inst{22} = 0; // D = 0
3668 let Inst{20} = load;
3671 def L_OFFSET : ACI<(outs),
3672 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3673 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3674 let Inst{31-28} = op31_28;
3675 let Inst{24} = 1; // P = 1
3676 let Inst{21} = 0; // W = 0
3677 let Inst{22} = 1; // D = 1
3678 let Inst{20} = load;
3681 def L_PRE : ACI<(outs),
3682 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3683 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3684 let Inst{31-28} = op31_28;
3685 let Inst{24} = 1; // P = 1
3686 let Inst{21} = 1; // W = 1
3687 let Inst{22} = 1; // D = 1
3688 let Inst{20} = load;
3691 def L_POST : ACI<(outs),
3692 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3693 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3694 let Inst{31-28} = op31_28;
3695 let Inst{24} = 0; // P = 0
3696 let Inst{21} = 1; // W = 1
3697 let Inst{22} = 1; // D = 1
3698 let Inst{20} = load;
3701 def L_OPTION : ACI<(outs),
3702 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3703 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3704 let Inst{31-28} = op31_28;
3705 let Inst{24} = 0; // P = 0
3706 let Inst{23} = 1; // U = 1
3707 let Inst{21} = 0; // W = 0
3708 let Inst{22} = 1; // D = 1
3709 let Inst{20} = load;
3713 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3714 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3715 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3716 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3718 //===----------------------------------------------------------------------===//
3719 // Move between coprocessor and ARM core register -- for disassembly only
3722 class MovRCopro<string opc, bit direction>
3723 : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3724 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3725 NoItinerary, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3726 [/* For disassembly only; pattern left blank */]> {
3727 let Inst{20} = direction;
3737 let Inst{15-12} = Rt;
3738 let Inst{11-8} = cop;
3739 let Inst{23-21} = opc1;
3740 let Inst{7-5} = opc2;
3741 let Inst{3-0} = CRm;
3742 let Inst{19-16} = CRn;
3745 def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */>;
3746 def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */>;
3748 class MovRCopro2<string opc, bit direction>
3749 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3750 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3751 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3752 [/* For disassembly only; pattern left blank */]> {
3753 let Inst{31-28} = 0b1111;
3754 let Inst{20} = direction;
3764 let Inst{15-12} = Rt;
3765 let Inst{11-8} = cop;
3766 let Inst{23-21} = opc1;
3767 let Inst{7-5} = opc2;
3768 let Inst{3-0} = CRm;
3769 let Inst{19-16} = CRn;
3772 def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */>;
3773 def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */>;
3775 class MovRRCopro<string opc, bit direction>
3776 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3777 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3778 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
3779 [/* For disassembly only; pattern left blank */]> {
3780 let Inst{23-21} = 0b010;
3781 let Inst{20} = direction;
3789 let Inst{15-12} = Rt;
3790 let Inst{19-16} = Rt2;
3791 let Inst{11-8} = cop;
3792 let Inst{7-4} = opc1;
3793 let Inst{3-0} = CRm;
3796 def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
3797 def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
3799 class MovRRCopro2<string opc, bit direction>
3800 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3801 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3802 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3803 [/* For disassembly only; pattern left blank */]> {
3804 let Inst{31-28} = 0b1111;
3805 let Inst{23-21} = 0b010;
3806 let Inst{20} = direction;
3814 let Inst{15-12} = Rt;
3815 let Inst{19-16} = Rt2;
3816 let Inst{11-8} = cop;
3817 let Inst{7-4} = opc1;
3818 let Inst{3-0} = CRm;
3821 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
3822 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
3824 //===----------------------------------------------------------------------===//
3825 // Move between special register and ARM core register -- for disassembly only
3828 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3829 [/* For disassembly only; pattern left blank */]> {
3831 let Inst{23-16} = 0b00001111;
3832 let Inst{15-12} = Rd;
3833 let Inst{7-4} = 0b0000;
3836 def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr",
3837 [/* For disassembly only; pattern left blank */]> {
3839 let Inst{23-16} = 0b01001111;
3840 let Inst{15-12} = Rd;
3841 let Inst{7-4} = 0b0000;
3844 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3845 "msr", "\tcpsr$mask, $src",
3846 [/* For disassembly only; pattern left blank */]> {
3847 let Inst{23-20} = 0b0010;
3848 let Inst{7-4} = 0b0000;
3851 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3852 "msr", "\tcpsr$mask, $a",
3853 [/* For disassembly only; pattern left blank */]> {
3854 let Inst{23-20} = 0b0010;
3855 let Inst{7-4} = 0b0000;
3858 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3859 "msr", "\tspsr$mask, $src",
3860 [/* For disassembly only; pattern left blank */]> {
3861 let Inst{23-20} = 0b0110;
3862 let Inst{7-4} = 0b0000;
3865 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3866 "msr", "\tspsr$mask, $a",
3867 [/* For disassembly only; pattern left blank */]> {
3868 let Inst{23-20} = 0b0110;
3869 let Inst{7-4} = 0b0000;