1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>;
73 def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
74 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
76 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
77 [SDNPHasChain, SDNPOutGlue]>;
78 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
79 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
81 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
82 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
84 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
85 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
87 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
88 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
91 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
92 [SDNPHasChain, SDNPOptInGlue]>;
94 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
96 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
99 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
100 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
102 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
104 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
107 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
110 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
113 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
114 [SDNPOutGlue, SDNPCommutative]>;
116 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
118 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
119 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
120 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
122 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
123 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
124 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
126 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
128 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
131 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
133 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
135 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
136 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
138 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
140 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
141 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
144 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
146 //===----------------------------------------------------------------------===//
147 // ARM Instruction Predicate Definitions.
149 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
150 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
151 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
152 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
153 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
154 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
162 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
163 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
164 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
166 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
168 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
170 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
171 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
172 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
173 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
174 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
175 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
176 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
177 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
179 // FIXME: Eventually this will be just "hasV6T2Ops".
180 def UseMovt : Predicate<"Subtarget->useMovt()">;
181 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
182 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
184 //===----------------------------------------------------------------------===//
185 // ARM Flag Definitions.
187 class RegConstraint<string C> {
188 string Constraints = C;
191 //===----------------------------------------------------------------------===//
192 // ARM specific transformation functions and pattern fragments.
195 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
196 // so_imm_neg def below.
197 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
198 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
201 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
202 // so_imm_not def below.
203 def so_imm_not_XFORM : SDNodeXForm<imm, [{
204 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
207 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
208 def imm1_15 : PatLeaf<(i32 imm), [{
209 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
212 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
213 def imm16_31 : PatLeaf<(i32 imm), [{
214 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
219 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
220 }], so_imm_neg_XFORM>;
224 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
225 }], so_imm_not_XFORM>;
227 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
228 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
229 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
232 /// Split a 32-bit immediate into two 16 bit parts.
233 def hi16 : SDNodeXForm<imm, [{
234 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
237 def lo16AllZero : PatLeaf<(i32 imm), [{
238 // Returns true if all low 16-bits are 0.
239 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
242 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
244 def imm0_65535 : PatLeaf<(i32 imm), [{
245 return (uint32_t)N->getZExtValue() < 65536;
248 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
249 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
251 /// adde and sube predicates - True based on whether the carry flag output
252 /// will be needed or not.
253 def adde_dead_carry :
254 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
255 [{return !N->hasAnyUseOfValue(1);}]>;
256 def sube_dead_carry :
257 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
258 [{return !N->hasAnyUseOfValue(1);}]>;
259 def adde_live_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return N->hasAnyUseOfValue(1);}]>;
262 def sube_live_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return N->hasAnyUseOfValue(1);}]>;
266 // An 'and' node with a single use.
267 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
268 return N->hasOneUse();
271 // An 'xor' node with a single use.
272 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
273 return N->hasOneUse();
276 // An 'fmul' node with a single use.
277 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
278 return N->hasOneUse();
281 // An 'fadd' node which checks for single non-hazardous use.
282 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
283 return hasNoVMLxHazardUse(N);
286 // An 'fsub' node which checks for single non-hazardous use.
287 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
288 return hasNoVMLxHazardUse(N);
291 //===----------------------------------------------------------------------===//
292 // Operand Definitions.
296 // FIXME: rename brtarget to t2_brtarget
297 def brtarget : Operand<OtherVT> {
298 let EncoderMethod = "getBranchTargetOpValue";
301 // FIXME: get rid of this one?
302 def uncondbrtarget : Operand<OtherVT> {
303 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
306 // Branch target for ARM. Handles conditional/unconditional
307 def br_target : Operand<OtherVT> {
308 let EncoderMethod = "getARMBranchTargetOpValue";
312 // FIXME: rename bltarget to t2_bl_target?
313 def bltarget : Operand<i32> {
314 // Encoded the same as branch targets.
315 let EncoderMethod = "getBranchTargetOpValue";
318 // Call target for ARM. Handles conditional/unconditional
319 // FIXME: rename bl_target to t2_bltarget?
320 def bl_target : Operand<i32> {
321 // Encoded the same as branch targets.
322 let EncoderMethod = "getARMBranchTargetOpValue";
326 // A list of registers separated by comma. Used by load/store multiple.
327 def RegListAsmOperand : AsmOperandClass {
328 let Name = "RegList";
329 let SuperClasses = [];
332 def DPRRegListAsmOperand : AsmOperandClass {
333 let Name = "DPRRegList";
334 let SuperClasses = [];
337 def SPRRegListAsmOperand : AsmOperandClass {
338 let Name = "SPRRegList";
339 let SuperClasses = [];
342 def reglist : Operand<i32> {
343 let EncoderMethod = "getRegisterListOpValue";
344 let ParserMatchClass = RegListAsmOperand;
345 let PrintMethod = "printRegisterList";
348 def dpr_reglist : Operand<i32> {
349 let EncoderMethod = "getRegisterListOpValue";
350 let ParserMatchClass = DPRRegListAsmOperand;
351 let PrintMethod = "printRegisterList";
354 def spr_reglist : Operand<i32> {
355 let EncoderMethod = "getRegisterListOpValue";
356 let ParserMatchClass = SPRRegListAsmOperand;
357 let PrintMethod = "printRegisterList";
360 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
361 def cpinst_operand : Operand<i32> {
362 let PrintMethod = "printCPInstOperand";
366 def pclabel : Operand<i32> {
367 let PrintMethod = "printPCLabel";
370 // ADR instruction labels.
371 def adrlabel : Operand<i32> {
372 let EncoderMethod = "getAdrLabelOpValue";
375 def neon_vcvt_imm32 : Operand<i32> {
376 let EncoderMethod = "getNEONVcvtImm32OpValue";
379 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
380 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
381 int32_t v = (int32_t)N->getZExtValue();
382 return v == 8 || v == 16 || v == 24; }]> {
383 let EncoderMethod = "getRotImmOpValue";
386 // shift_imm: An integer that encodes a shift amount and the type of shift
387 // (currently either asr or lsl) using the same encoding used for the
388 // immediates in so_reg operands.
389 def shift_imm : Operand<i32> {
390 let PrintMethod = "printShiftImmOperand";
393 // shifter_operand operands: so_reg and so_imm.
394 def so_reg : Operand<i32>, // reg reg imm
395 ComplexPattern<i32, 3, "SelectShifterOperandReg",
396 [shl,srl,sra,rotr]> {
397 let EncoderMethod = "getSORegOpValue";
398 let PrintMethod = "printSORegOperand";
399 let MIOperandInfo = (ops GPR, GPR, i32imm);
401 def shift_so_reg : Operand<i32>, // reg reg imm
402 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
403 [shl,srl,sra,rotr]> {
404 let EncoderMethod = "getSORegOpValue";
405 let PrintMethod = "printSORegOperand";
406 let MIOperandInfo = (ops GPR, GPR, i32imm);
409 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
410 // 8-bit immediate rotated by an arbitrary number of bits.
411 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
412 let EncoderMethod = "getSOImmOpValue";
413 let PrintMethod = "printSOImmOperand";
416 // Break so_imm's up into two pieces. This handles immediates with up to 16
417 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
418 // get the first/second pieces.
419 def so_imm2part : PatLeaf<(imm), [{
420 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
423 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
425 def arm_i32imm : PatLeaf<(imm), [{
426 if (Subtarget->hasV6T2Ops())
428 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
431 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
432 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
433 return (int32_t)N->getZExtValue() < 32;
436 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
437 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
438 return (int32_t)N->getZExtValue() < 32;
440 let EncoderMethod = "getImmMinusOneOpValue";
443 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
444 // The imm is split into imm{15-12}, imm{11-0}
446 def i32imm_hilo16 : Operand<i32> {
447 let EncoderMethod = "getHiLo16ImmOpValue";
450 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
452 def bf_inv_mask_imm : Operand<i32>,
454 return ARM::isBitFieldInvertedMask(N->getZExtValue());
456 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
457 let PrintMethod = "printBitfieldInvMaskImmOperand";
460 /// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
461 def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
462 return isInt<5>(N->getSExtValue());
465 /// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
466 def width_imm : Operand<i32>, PatLeaf<(imm), [{
467 return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
469 let EncoderMethod = "getMsbOpValue";
472 // Define ARM specific addressing modes.
475 // addrmode_imm12 := reg +/- imm12
477 def addrmode_imm12 : Operand<i32>,
478 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
479 // 12-bit immediate operand. Note that instructions using this encode
480 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
481 // immediate values are as normal.
483 let EncoderMethod = "getAddrModeImm12OpValue";
484 let PrintMethod = "printAddrModeImm12Operand";
485 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
487 // ldst_so_reg := reg +/- reg shop imm
489 def ldst_so_reg : Operand<i32>,
490 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
491 let EncoderMethod = "getLdStSORegOpValue";
492 // FIXME: Simplify the printer
493 let PrintMethod = "printAddrMode2Operand";
494 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
497 // addrmode2 := reg +/- imm12
498 // := reg +/- reg shop imm
500 def addrmode2 : Operand<i32>,
501 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
502 let EncoderMethod = "getAddrMode2OpValue";
503 let PrintMethod = "printAddrMode2Operand";
504 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
507 def am2offset : Operand<i32>,
508 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
509 [], [SDNPWantRoot]> {
510 let EncoderMethod = "getAddrMode2OffsetOpValue";
511 let PrintMethod = "printAddrMode2OffsetOperand";
512 let MIOperandInfo = (ops GPR, i32imm);
515 // addrmode3 := reg +/- reg
516 // addrmode3 := reg +/- imm8
518 def addrmode3 : Operand<i32>,
519 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
520 let EncoderMethod = "getAddrMode3OpValue";
521 let PrintMethod = "printAddrMode3Operand";
522 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
525 def am3offset : Operand<i32>,
526 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
527 [], [SDNPWantRoot]> {
528 let EncoderMethod = "getAddrMode3OffsetOpValue";
529 let PrintMethod = "printAddrMode3OffsetOperand";
530 let MIOperandInfo = (ops GPR, i32imm);
533 // ldstm_mode := {ia, ib, da, db}
535 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
536 let EncoderMethod = "getLdStmModeOpValue";
537 let PrintMethod = "printLdStmModeOperand";
540 def MemMode5AsmOperand : AsmOperandClass {
541 let Name = "MemMode5";
542 let SuperClasses = [];
545 // addrmode5 := reg +/- imm8*4
547 def addrmode5 : Operand<i32>,
548 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
549 let PrintMethod = "printAddrMode5Operand";
550 let MIOperandInfo = (ops GPR:$base, i32imm);
551 let ParserMatchClass = MemMode5AsmOperand;
552 let EncoderMethod = "getAddrMode5OpValue";
555 // addrmode6 := reg with optional alignment
557 def addrmode6 : Operand<i32>,
558 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
559 let PrintMethod = "printAddrMode6Operand";
560 let MIOperandInfo = (ops GPR:$addr, i32imm);
561 let EncoderMethod = "getAddrMode6AddressOpValue";
564 def am6offset : Operand<i32>,
565 ComplexPattern<i32, 1, "SelectAddrMode6Offset",
566 [], [SDNPWantRoot]> {
567 let PrintMethod = "printAddrMode6OffsetOperand";
568 let MIOperandInfo = (ops GPR);
569 let EncoderMethod = "getAddrMode6OffsetOpValue";
572 // Special version of addrmode6 to handle alignment encoding for VLD-dup
573 // instructions, specifically VLD4-dup.
574 def addrmode6dup : Operand<i32>,
575 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
576 let PrintMethod = "printAddrMode6Operand";
577 let MIOperandInfo = (ops GPR:$addr, i32imm);
578 let EncoderMethod = "getAddrMode6DupAddressOpValue";
581 // addrmodepc := pc + reg
583 def addrmodepc : Operand<i32>,
584 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
585 let PrintMethod = "printAddrModePCOperand";
586 let MIOperandInfo = (ops GPR, i32imm);
589 def nohash_imm : Operand<i32> {
590 let PrintMethod = "printNoHashImmediate";
593 def CoprocNumAsmOperand : AsmOperandClass {
594 let Name = "CoprocNum";
595 let SuperClasses = [];
596 let ParserMethod = "tryParseCoprocNumOperand";
599 def CoprocRegAsmOperand : AsmOperandClass {
600 let Name = "CoprocReg";
601 let SuperClasses = [];
602 let ParserMethod = "tryParseCoprocRegOperand";
605 def p_imm : Operand<i32> {
606 let PrintMethod = "printPImmediate";
607 let ParserMatchClass = CoprocNumAsmOperand;
610 def c_imm : Operand<i32> {
611 let PrintMethod = "printCImmediate";
612 let ParserMatchClass = CoprocRegAsmOperand;
615 //===----------------------------------------------------------------------===//
617 include "ARMInstrFormats.td"
619 //===----------------------------------------------------------------------===//
620 // Multiclass helpers...
623 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
624 /// binop that produces a value.
625 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
626 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
627 PatFrag opnode, bit Commutable = 0> {
628 // The register-immediate version is re-materializable. This is useful
629 // in particular for taking the address of a local.
630 let isReMaterializable = 1 in {
631 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
632 iii, opc, "\t$Rd, $Rn, $imm",
633 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
638 let Inst{19-16} = Rn;
639 let Inst{15-12} = Rd;
640 let Inst{11-0} = imm;
643 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
644 iir, opc, "\t$Rd, $Rn, $Rm",
645 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
650 let isCommutable = Commutable;
651 let Inst{19-16} = Rn;
652 let Inst{15-12} = Rd;
653 let Inst{11-4} = 0b00000000;
656 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
657 iis, opc, "\t$Rd, $Rn, $shift",
658 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
663 let Inst{19-16} = Rn;
664 let Inst{15-12} = Rd;
665 let Inst{11-0} = shift;
669 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
670 /// instruction modifies the CPSR register.
671 let isCodeGenOnly = 1, Defs = [CPSR] in {
672 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
673 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
674 PatFrag opnode, bit Commutable = 0> {
675 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
676 iii, opc, "\t$Rd, $Rn, $imm",
677 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
683 let Inst{19-16} = Rn;
684 let Inst{15-12} = Rd;
685 let Inst{11-0} = imm;
687 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
688 iir, opc, "\t$Rd, $Rn, $Rm",
689 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
693 let isCommutable = Commutable;
696 let Inst{19-16} = Rn;
697 let Inst{15-12} = Rd;
698 let Inst{11-4} = 0b00000000;
701 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
702 iis, opc, "\t$Rd, $Rn, $shift",
703 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
709 let Inst{19-16} = Rn;
710 let Inst{15-12} = Rd;
711 let Inst{11-0} = shift;
716 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
717 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
718 /// a explicit result, only implicitly set CPSR.
719 let isCompare = 1, Defs = [CPSR] in {
720 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
721 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
722 PatFrag opnode, bit Commutable = 0> {
723 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
725 [(opnode GPR:$Rn, so_imm:$imm)]> {
730 let Inst{19-16} = Rn;
731 let Inst{15-12} = 0b0000;
732 let Inst{11-0} = imm;
734 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
736 [(opnode GPR:$Rn, GPR:$Rm)]> {
739 let isCommutable = Commutable;
742 let Inst{19-16} = Rn;
743 let Inst{15-12} = 0b0000;
744 let Inst{11-4} = 0b00000000;
747 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
748 opc, "\t$Rn, $shift",
749 [(opnode GPR:$Rn, so_reg:$shift)]> {
754 let Inst{19-16} = Rn;
755 let Inst{15-12} = 0b0000;
756 let Inst{11-0} = shift;
761 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
762 /// register and one whose operand is a register rotated by 8/16/24.
763 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
764 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
765 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
766 IIC_iEXTr, opc, "\t$Rd, $Rm",
767 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
768 Requires<[IsARM, HasV6]> {
771 let Inst{19-16} = 0b1111;
772 let Inst{15-12} = Rd;
773 let Inst{11-10} = 0b00;
776 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
777 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
778 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
779 Requires<[IsARM, HasV6]> {
783 let Inst{19-16} = 0b1111;
784 let Inst{15-12} = Rd;
785 let Inst{11-10} = rot;
790 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
791 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
792 IIC_iEXTr, opc, "\t$Rd, $Rm",
793 [/* For disassembly only; pattern left blank */]>,
794 Requires<[IsARM, HasV6]> {
795 let Inst{19-16} = 0b1111;
796 let Inst{11-10} = 0b00;
798 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
799 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
800 [/* For disassembly only; pattern left blank */]>,
801 Requires<[IsARM, HasV6]> {
803 let Inst{19-16} = 0b1111;
804 let Inst{11-10} = rot;
808 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
809 /// register and one whose operand is a register rotated by 8/16/24.
810 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
811 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
812 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
813 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
814 Requires<[IsARM, HasV6]> {
818 let Inst{19-16} = Rn;
819 let Inst{15-12} = Rd;
820 let Inst{11-10} = 0b00;
821 let Inst{9-4} = 0b000111;
824 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
826 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
827 [(set GPR:$Rd, (opnode GPR:$Rn,
828 (rotr GPR:$Rm, rot_imm:$rot)))]>,
829 Requires<[IsARM, HasV6]> {
834 let Inst{19-16} = Rn;
835 let Inst{15-12} = Rd;
836 let Inst{11-10} = rot;
837 let Inst{9-4} = 0b000111;
842 // For disassembly only.
843 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
844 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
845 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
846 [/* For disassembly only; pattern left blank */]>,
847 Requires<[IsARM, HasV6]> {
848 let Inst{11-10} = 0b00;
850 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
852 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
853 [/* For disassembly only; pattern left blank */]>,
854 Requires<[IsARM, HasV6]> {
857 let Inst{19-16} = Rn;
858 let Inst{11-10} = rot;
862 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
863 let Uses = [CPSR] in {
864 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
865 bit Commutable = 0> {
866 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
867 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
868 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
874 let Inst{15-12} = Rd;
875 let Inst{19-16} = Rn;
876 let Inst{11-0} = imm;
878 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
879 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
880 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
885 let Inst{11-4} = 0b00000000;
887 let isCommutable = Commutable;
889 let Inst{15-12} = Rd;
890 let Inst{19-16} = Rn;
892 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
893 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
894 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
900 let Inst{11-0} = shift;
901 let Inst{15-12} = Rd;
902 let Inst{19-16} = Rn;
905 // Carry setting variants
906 let isCodeGenOnly = 1, Defs = [CPSR] in {
907 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
908 bit Commutable = 0> {
909 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
910 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
911 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
916 let Inst{15-12} = Rd;
917 let Inst{19-16} = Rn;
918 let Inst{11-0} = imm;
922 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
923 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
924 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
929 let Inst{11-4} = 0b00000000;
930 let isCommutable = Commutable;
932 let Inst{15-12} = Rd;
933 let Inst{19-16} = Rn;
937 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
938 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
939 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
944 let Inst{11-0} = shift;
945 let Inst{15-12} = Rd;
946 let Inst{19-16} = Rn;
954 let canFoldAsLoad = 1, isReMaterializable = 1 in {
955 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
956 InstrItinClass iir, PatFrag opnode> {
957 // Note: We use the complex addrmode_imm12 rather than just an input
958 // GPR and a constrained immediate so that we can use this to match
959 // frame index references and avoid matching constant pool references.
960 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
961 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
962 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
965 let Inst{23} = addr{12}; // U (add = ('U' == 1))
966 let Inst{19-16} = addr{16-13}; // Rn
967 let Inst{15-12} = Rt;
968 let Inst{11-0} = addr{11-0}; // imm12
970 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
971 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
972 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
975 let Inst{23} = shift{12}; // U (add = ('U' == 1))
976 let Inst{19-16} = shift{16-13}; // Rn
977 let Inst{15-12} = Rt;
978 let Inst{11-0} = shift{11-0};
983 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
984 InstrItinClass iir, PatFrag opnode> {
985 // Note: We use the complex addrmode_imm12 rather than just an input
986 // GPR and a constrained immediate so that we can use this to match
987 // frame index references and avoid matching constant pool references.
988 def i12 : AI2ldst<0b010, 0, isByte, (outs),
989 (ins GPR:$Rt, addrmode_imm12:$addr),
990 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
991 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
994 let Inst{23} = addr{12}; // U (add = ('U' == 1))
995 let Inst{19-16} = addr{16-13}; // Rn
996 let Inst{15-12} = Rt;
997 let Inst{11-0} = addr{11-0}; // imm12
999 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
1000 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
1001 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1004 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1005 let Inst{19-16} = shift{16-13}; // Rn
1006 let Inst{15-12} = Rt;
1007 let Inst{11-0} = shift{11-0};
1010 //===----------------------------------------------------------------------===//
1012 //===----------------------------------------------------------------------===//
1014 //===----------------------------------------------------------------------===//
1015 // Miscellaneous Instructions.
1018 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1019 /// the function. The first operand is the ID# for this instruction, the second
1020 /// is the index into the MachineConstantPool that this is, the third is the
1021 /// size in bytes of this constant pool entry.
1022 let neverHasSideEffects = 1, isNotDuplicable = 1 in
1023 def CONSTPOOL_ENTRY :
1024 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1025 i32imm:$size), NoItinerary, []>;
1027 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1028 // from removing one half of the matched pairs. That breaks PEI, which assumes
1029 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1030 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1031 def ADJCALLSTACKUP :
1032 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1033 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1035 def ADJCALLSTACKDOWN :
1036 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1037 [(ARMcallseq_start timm:$amt)]>;
1040 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
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} = 0b00000000;
1048 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
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} = 0b00000001;
1056 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1057 [/* For disassembly only; pattern left blank */]>,
1058 Requires<[IsARM, HasV6T2]> {
1059 let Inst{27-16} = 0b001100100000;
1060 let Inst{15-8} = 0b11110000;
1061 let Inst{7-0} = 0b00000010;
1064 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1065 [/* For disassembly only; pattern left blank */]>,
1066 Requires<[IsARM, HasV6T2]> {
1067 let Inst{27-16} = 0b001100100000;
1068 let Inst{15-8} = 0b11110000;
1069 let Inst{7-0} = 0b00000011;
1072 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1074 [/* For disassembly only; pattern left blank */]>,
1075 Requires<[IsARM, HasV6]> {
1080 let Inst{15-12} = Rd;
1081 let Inst{19-16} = Rn;
1082 let Inst{27-20} = 0b01101000;
1083 let Inst{7-4} = 0b1011;
1084 let Inst{11-8} = 0b1111;
1087 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1088 [/* For disassembly only; pattern left blank */]>,
1089 Requires<[IsARM, HasV6T2]> {
1090 let Inst{27-16} = 0b001100100000;
1091 let Inst{15-8} = 0b11110000;
1092 let Inst{7-0} = 0b00000100;
1095 // The i32imm operand $val can be used by a debugger to store more information
1096 // about the breakpoint.
1097 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1098 [/* For disassembly only; pattern left blank */]>,
1101 let Inst{3-0} = val{3-0};
1102 let Inst{19-8} = val{15-4};
1103 let Inst{27-20} = 0b00010010;
1104 let Inst{7-4} = 0b0111;
1107 // Change Processor State is a system instruction -- for disassembly and
1109 // FIXME: Since the asm parser has currently no clean way to handle optional
1110 // operands, create 3 versions of the same instruction. Once there's a clean
1111 // framework to represent optional operands, change this behavior.
1112 class CPS<dag iops, string asm_ops>
1113 : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
1114 [/* For disassembly only; pattern left blank */]>, Requires<[IsARM]> {
1120 let Inst{31-28} = 0b1111;
1121 let Inst{27-20} = 0b00010000;
1122 let Inst{19-18} = imod;
1123 let Inst{17} = M; // Enabled if mode is set;
1125 let Inst{8-6} = iflags;
1127 let Inst{4-0} = mode;
1131 def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
1132 "$imod\t$iflags, $mode">;
1133 let mode = 0, M = 0 in
1134 def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
1136 let imod = 0, iflags = 0, M = 1 in
1137 def CPS1p : CPS<(ins i32imm:$mode), "\t$mode">;
1139 // Preload signals the memory system of possible future data/instruction access.
1140 // These are for disassembly only.
1141 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1143 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1144 !strconcat(opc, "\t$addr"),
1145 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1148 let Inst{31-26} = 0b111101;
1149 let Inst{25} = 0; // 0 for immediate form
1150 let Inst{24} = data;
1151 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1152 let Inst{22} = read;
1153 let Inst{21-20} = 0b01;
1154 let Inst{19-16} = addr{16-13}; // Rn
1155 let Inst{15-12} = 0b1111;
1156 let Inst{11-0} = addr{11-0}; // imm12
1159 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1160 !strconcat(opc, "\t$shift"),
1161 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1163 let Inst{31-26} = 0b111101;
1164 let Inst{25} = 1; // 1 for register form
1165 let Inst{24} = data;
1166 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1167 let Inst{22} = read;
1168 let Inst{21-20} = 0b01;
1169 let Inst{19-16} = shift{16-13}; // Rn
1170 let Inst{15-12} = 0b1111;
1171 let Inst{11-0} = shift{11-0};
1175 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1176 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1177 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1179 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1181 [/* For disassembly only; pattern left blank */]>,
1184 let Inst{31-10} = 0b1111000100000001000000;
1189 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1190 [/* For disassembly only; pattern left blank */]>,
1191 Requires<[IsARM, HasV7]> {
1193 let Inst{27-4} = 0b001100100000111100001111;
1194 let Inst{3-0} = opt;
1197 // A5.4 Permanently UNDEFINED instructions.
1198 let isBarrier = 1, isTerminator = 1 in
1199 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1202 let Inst = 0xe7ffdefe;
1205 // Address computation and loads and stores in PIC mode.
1206 let isNotDuplicable = 1 in {
1207 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1208 Size4Bytes, IIC_iALUr,
1209 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1211 let AddedComplexity = 10 in {
1212 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1213 Size4Bytes, IIC_iLoad_r,
1214 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1216 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1217 Size4Bytes, IIC_iLoad_bh_r,
1218 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1220 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1221 Size4Bytes, IIC_iLoad_bh_r,
1222 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1224 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1225 Size4Bytes, IIC_iLoad_bh_r,
1226 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1228 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1229 Size4Bytes, IIC_iLoad_bh_r,
1230 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1232 let AddedComplexity = 10 in {
1233 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1234 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1236 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1237 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1238 addrmodepc:$addr)]>;
1240 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1241 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1243 } // isNotDuplicable = 1
1246 // LEApcrel - Load a pc-relative address into a register without offending the
1248 let neverHasSideEffects = 1, isReMaterializable = 1 in
1249 // The 'adr' mnemonic encodes differently if the label is before or after
1250 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1251 // know until then which form of the instruction will be used.
1252 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1253 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1256 let Inst{27-25} = 0b001;
1258 let Inst{19-16} = 0b1111;
1259 let Inst{15-12} = Rd;
1260 let Inst{11-0} = label;
1262 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1263 Size4Bytes, IIC_iALUi, []>;
1265 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1266 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1267 Size4Bytes, IIC_iALUi, []>;
1269 //===----------------------------------------------------------------------===//
1270 // Control Flow Instructions.
1273 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1275 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1276 "bx", "\tlr", [(ARMretflag)]>,
1277 Requires<[IsARM, HasV4T]> {
1278 let Inst{27-0} = 0b0001001011111111111100011110;
1282 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1283 "mov", "\tpc, lr", [(ARMretflag)]>,
1284 Requires<[IsARM, NoV4T]> {
1285 let Inst{27-0} = 0b0001101000001111000000001110;
1289 // Indirect branches
1290 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1292 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1293 [(brind GPR:$dst)]>,
1294 Requires<[IsARM, HasV4T]> {
1296 let Inst{31-4} = 0b1110000100101111111111110001;
1297 let Inst{3-0} = dst;
1301 // FIXME: We would really like to define this as a vanilla ARMPat like:
1302 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1303 // With that, however, we can't set isBranch, isTerminator, etc..
1304 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1305 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1306 Requires<[IsARM, NoV4T]>;
1309 // All calls clobber the non-callee saved registers. SP is marked as
1310 // a use to prevent stack-pointer assignments that appear immediately
1311 // before calls from potentially appearing dead.
1313 // On non-Darwin platforms R9 is callee-saved.
1314 Defs = [R0, R1, R2, R3, R12, LR,
1315 D0, D1, D2, D3, D4, D5, D6, D7,
1316 D16, D17, D18, D19, D20, D21, D22, D23,
1317 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1319 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1320 IIC_Br, "bl\t$func",
1321 [(ARMcall tglobaladdr:$func)]>,
1322 Requires<[IsARM, IsNotDarwin]> {
1323 let Inst{31-28} = 0b1110;
1325 let Inst{23-0} = func;
1328 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1329 IIC_Br, "bl", "\t$func",
1330 [(ARMcall_pred tglobaladdr:$func)]>,
1331 Requires<[IsARM, IsNotDarwin]> {
1333 let Inst{23-0} = func;
1337 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1338 IIC_Br, "blx\t$func",
1339 [(ARMcall GPR:$func)]>,
1340 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1342 let Inst{31-4} = 0b1110000100101111111111110011;
1343 let Inst{3-0} = func;
1347 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1348 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1349 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1350 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1353 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1354 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1355 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1359 // On Darwin R9 is call-clobbered.
1360 // R7 is marked as a use to prevent frame-pointer assignments from being
1361 // moved above / below calls.
1362 Defs = [R0, R1, R2, R3, R9, R12, LR,
1363 D0, D1, D2, D3, D4, D5, D6, D7,
1364 D16, D17, D18, D19, D20, D21, D22, D23,
1365 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1366 Uses = [R7, SP] in {
1367 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1368 IIC_Br, "bl\t$func",
1369 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1370 let Inst{31-28} = 0b1110;
1372 let Inst{23-0} = func;
1375 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1376 IIC_Br, "bl", "\t$func",
1377 [(ARMcall_pred tglobaladdr:$func)]>,
1378 Requires<[IsARM, IsDarwin]> {
1380 let Inst{23-0} = func;
1384 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1385 IIC_Br, "blx\t$func",
1386 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1388 let Inst{31-4} = 0b1110000100101111111111110011;
1389 let Inst{3-0} = func;
1393 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1394 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1395 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1396 Requires<[IsARM, HasV4T, IsDarwin]>;
1399 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1400 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1401 Requires<[IsARM, NoV4T, IsDarwin]>;
1406 // FIXME: These should probably be xformed into the non-TC versions of the
1407 // instructions as part of MC lowering.
1408 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1409 // Thumb should have its own version since the instruction is actually
1410 // different, even though the mnemonic is the same.
1411 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1413 let Defs = [R0, R1, R2, R3, R9, R12,
1414 D0, D1, D2, D3, D4, D5, D6, D7,
1415 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1416 D27, D28, D29, D30, D31, PC],
1418 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1419 IIC_Br, []>, Requires<[IsDarwin]>;
1421 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1422 IIC_Br, []>, Requires<[IsDarwin]>;
1424 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1425 IIC_Br, "b\t$dst @ TAILCALL",
1426 []>, Requires<[IsARM, IsDarwin]>;
1428 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1429 IIC_Br, "b.w\t$dst @ TAILCALL",
1430 []>, Requires<[IsThumb, IsDarwin]>;
1432 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1433 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1434 []>, Requires<[IsDarwin]> {
1436 let Inst{31-4} = 0b1110000100101111111111110001;
1437 let Inst{3-0} = dst;
1441 // Non-Darwin versions (the difference is R9).
1442 let Defs = [R0, R1, R2, R3, R12,
1443 D0, D1, D2, D3, D4, D5, D6, D7,
1444 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1445 D27, D28, D29, D30, D31, PC],
1447 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1448 IIC_Br, []>, Requires<[IsNotDarwin]>;
1450 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1451 IIC_Br, []>, Requires<[IsNotDarwin]>;
1453 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1454 IIC_Br, "b\t$dst @ TAILCALL",
1455 []>, Requires<[IsARM, IsNotDarwin]>;
1457 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1458 IIC_Br, "b.w\t$dst @ TAILCALL",
1459 []>, Requires<[IsThumb, IsNotDarwin]>;
1461 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1462 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1463 []>, Requires<[IsNotDarwin]> {
1465 let Inst{31-4} = 0b1110000100101111111111110001;
1466 let Inst{3-0} = dst;
1471 let isBranch = 1, isTerminator = 1 in {
1472 // B is "predicable" since it can be xformed into a Bcc.
1473 let isBarrier = 1 in {
1474 let isPredicable = 1 in
1475 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1476 "b\t$target", [(br bb:$target)]> {
1478 let Inst{31-28} = 0b1110;
1479 let Inst{23-0} = target;
1482 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1483 def BR_JTr : ARMPseudoInst<(outs),
1484 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1485 SizeSpecial, IIC_Br,
1486 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1487 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1488 // into i12 and rs suffixed versions.
1489 def BR_JTm : ARMPseudoInst<(outs),
1490 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1491 SizeSpecial, IIC_Br,
1492 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1494 def BR_JTadd : ARMPseudoInst<(outs),
1495 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1496 SizeSpecial, IIC_Br,
1497 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1499 } // isNotDuplicable = 1, isIndirectBranch = 1
1502 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1503 // a two-value operand where a dag node expects two operands. :(
1504 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1505 IIC_Br, "b", "\t$target",
1506 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1508 let Inst{23-0} = target;
1512 // Branch and Exchange Jazelle -- for disassembly only
1513 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1514 [/* For disassembly only; pattern left blank */]> {
1515 let Inst{23-20} = 0b0010;
1516 //let Inst{19-8} = 0xfff;
1517 let Inst{7-4} = 0b0010;
1520 // Secure Monitor Call is a system instruction -- for disassembly only
1521 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1522 [/* For disassembly only; pattern left blank */]> {
1524 let Inst{23-4} = 0b01100000000000000111;
1525 let Inst{3-0} = opt;
1528 // Supervisor Call (Software Interrupt) -- for disassembly only
1529 let isCall = 1, Uses = [SP] in {
1530 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1531 [/* For disassembly only; pattern left blank */]> {
1533 let Inst{23-0} = svc;
1537 // Store Return State is a system instruction -- for disassembly only
1538 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1539 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1540 NoItinerary, "srs${amode}\tsp!, $mode",
1541 [/* For disassembly only; pattern left blank */]> {
1542 let Inst{31-28} = 0b1111;
1543 let Inst{22-20} = 0b110; // W = 1
1546 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1547 NoItinerary, "srs${amode}\tsp, $mode",
1548 [/* For disassembly only; pattern left blank */]> {
1549 let Inst{31-28} = 0b1111;
1550 let Inst{22-20} = 0b100; // W = 0
1553 // Return From Exception is a system instruction -- for disassembly only
1554 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1555 NoItinerary, "rfe${amode}\t$base!",
1556 [/* For disassembly only; pattern left blank */]> {
1557 let Inst{31-28} = 0b1111;
1558 let Inst{22-20} = 0b011; // W = 1
1561 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1562 NoItinerary, "rfe${amode}\t$base",
1563 [/* For disassembly only; pattern left blank */]> {
1564 let Inst{31-28} = 0b1111;
1565 let Inst{22-20} = 0b001; // W = 0
1567 } // isCodeGenOnly = 1
1569 //===----------------------------------------------------------------------===//
1570 // Load / store Instructions.
1576 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1577 UnOpFrag<(load node:$Src)>>;
1578 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1579 UnOpFrag<(zextloadi8 node:$Src)>>;
1580 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1581 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1582 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1583 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1585 // Special LDR for loads from non-pc-relative constpools.
1586 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1587 isReMaterializable = 1 in
1588 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1589 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1593 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1594 let Inst{19-16} = 0b1111;
1595 let Inst{15-12} = Rt;
1596 let Inst{11-0} = addr{11-0}; // imm12
1599 // Loads with zero extension
1600 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1601 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1602 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1604 // Loads with sign extension
1605 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1606 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1607 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1609 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1610 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1611 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1613 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1614 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1615 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1616 // how to represent that such that tblgen is happy and we don't
1617 // mark this codegen only?
1619 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1620 (ins addrmode3:$addr), LdMiscFrm,
1621 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1622 []>, Requires<[IsARM, HasV5TE]>;
1626 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1627 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1628 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1629 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1631 // {13} 1 == Rm, 0 == imm12
1635 let Inst{25} = addr{13};
1636 let Inst{23} = addr{12};
1637 let Inst{19-16} = addr{17-14};
1638 let Inst{11-0} = addr{11-0};
1640 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1641 (ins GPR:$Rn, am2offset:$offset),
1642 IndexModePost, LdFrm, itin,
1643 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1644 // {13} 1 == Rm, 0 == imm12
1649 let Inst{25} = offset{13};
1650 let Inst{23} = offset{12};
1651 let Inst{19-16} = Rn;
1652 let Inst{11-0} = offset{11-0};
1656 let mayLoad = 1, neverHasSideEffects = 1 in {
1657 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1658 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1661 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1662 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1663 (ins addrmode3:$addr), IndexModePre,
1665 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1667 let Inst{23} = addr{8}; // U bit
1668 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1669 let Inst{19-16} = addr{12-9}; // Rn
1670 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1671 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1673 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1674 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1676 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1679 let Inst{23} = offset{8}; // U bit
1680 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1681 let Inst{19-16} = Rn;
1682 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1683 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1687 let mayLoad = 1, neverHasSideEffects = 1 in {
1688 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1689 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1690 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1691 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1692 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1693 } // mayLoad = 1, neverHasSideEffects = 1
1695 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1696 let mayLoad = 1, neverHasSideEffects = 1 in {
1697 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1698 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1699 LdFrm, IIC_iLoad_ru,
1700 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1701 let Inst{21} = 1; // overwrite
1703 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1704 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1705 LdFrm, IIC_iLoad_bh_ru,
1706 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1707 let Inst{21} = 1; // overwrite
1709 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1710 (ins GPR:$base, am3offset:$offset), IndexModePost,
1711 LdMiscFrm, IIC_iLoad_bh_ru,
1712 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1713 let Inst{21} = 1; // overwrite
1715 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1716 (ins GPR:$base, am3offset:$offset), IndexModePost,
1717 LdMiscFrm, IIC_iLoad_bh_ru,
1718 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1719 let Inst{21} = 1; // overwrite
1721 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1722 (ins GPR:$base, am3offset:$offset), IndexModePost,
1723 LdMiscFrm, IIC_iLoad_bh_ru,
1724 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1725 let Inst{21} = 1; // overwrite
1731 // Stores with truncate
1732 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1733 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1734 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1737 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1738 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1739 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1740 StMiscFrm, IIC_iStore_d_r,
1741 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1744 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1745 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1746 IndexModePre, StFrm, IIC_iStore_ru,
1747 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1749 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1751 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1752 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1753 IndexModePost, StFrm, IIC_iStore_ru,
1754 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1756 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1758 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1759 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1760 IndexModePre, StFrm, IIC_iStore_bh_ru,
1761 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1762 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1763 GPR:$Rn, am2offset:$offset))]>;
1764 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1765 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1766 IndexModePost, StFrm, IIC_iStore_bh_ru,
1767 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1768 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1769 GPR:$Rn, am2offset:$offset))]>;
1771 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1772 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1773 IndexModePre, StMiscFrm, IIC_iStore_ru,
1774 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1776 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1778 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1779 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1780 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1781 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1782 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1783 GPR:$Rn, am3offset:$offset))]>;
1785 // For disassembly only
1786 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1787 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1788 StMiscFrm, IIC_iStore_d_ru,
1789 "strd", "\t$src1, $src2, [$base, $offset]!",
1790 "$base = $base_wb", []>;
1792 // For disassembly only
1793 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1794 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1795 StMiscFrm, IIC_iStore_d_ru,
1796 "strd", "\t$src1, $src2, [$base], $offset",
1797 "$base = $base_wb", []>;
1799 // STRT, STRBT, and STRHT are for disassembly only.
1801 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1802 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1803 IndexModeNone, StFrm, IIC_iStore_ru,
1804 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1805 [/* For disassembly only; pattern left blank */]> {
1806 let Inst{21} = 1; // overwrite
1809 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1810 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1811 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1812 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1813 [/* For disassembly only; pattern left blank */]> {
1814 let Inst{21} = 1; // overwrite
1817 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1818 (ins GPR:$src, GPR:$base,am3offset:$offset),
1819 StMiscFrm, IIC_iStore_bh_ru,
1820 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1821 [/* For disassembly only; pattern left blank */]> {
1822 let Inst{21} = 1; // overwrite
1825 //===----------------------------------------------------------------------===//
1826 // Load / store multiple Instructions.
1829 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1830 InstrItinClass itin, InstrItinClass itin_upd> {
1832 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1833 IndexModeNone, f, itin,
1834 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1835 let Inst{24-23} = 0b01; // Increment After
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, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1843 let Inst{24-23} = 0b01; // Increment After
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, "da${p}\t$Rn, $regs"), "", []> {
1851 let Inst{24-23} = 0b00; // Decrement After
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, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1859 let Inst{24-23} = 0b00; // Decrement After
1860 let Inst{21} = 1; // Writeback
1861 let Inst{20} = L_bit;
1864 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1865 IndexModeNone, f, itin,
1866 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1867 let Inst{24-23} = 0b10; // Decrement Before
1868 let Inst{21} = 0; // No writeback
1869 let Inst{20} = L_bit;
1872 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1873 IndexModeUpd, f, itin_upd,
1874 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1875 let Inst{24-23} = 0b10; // Decrement Before
1876 let Inst{21} = 1; // Writeback
1877 let Inst{20} = L_bit;
1880 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1881 IndexModeNone, f, itin,
1882 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1883 let Inst{24-23} = 0b11; // Increment Before
1884 let Inst{21} = 0; // No writeback
1885 let Inst{20} = L_bit;
1888 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1889 IndexModeUpd, f, itin_upd,
1890 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1891 let Inst{24-23} = 0b11; // Increment Before
1892 let Inst{21} = 1; // Writeback
1893 let Inst{20} = L_bit;
1897 let neverHasSideEffects = 1 in {
1899 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1900 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1902 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1903 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1905 } // neverHasSideEffects
1907 // Load / Store Multiple Mnemonic Aliases
1908 def : MnemonicAlias<"ldm", "ldmia">;
1909 def : MnemonicAlias<"stm", "stmia">;
1911 // FIXME: remove when we have a way to marking a MI with these properties.
1912 // FIXME: Should pc be an implicit operand like PICADD, etc?
1913 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1914 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1915 // FIXME: Should be a pseudo-instruction.
1916 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1917 reglist:$regs, variable_ops),
1918 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1919 "ldmia${p}\t$Rn!, $regs",
1921 let Inst{24-23} = 0b01; // Increment After
1922 let Inst{21} = 1; // Writeback
1923 let Inst{20} = 1; // Load
1926 //===----------------------------------------------------------------------===//
1927 // Move Instructions.
1930 let neverHasSideEffects = 1 in
1931 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1932 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1936 let Inst{11-4} = 0b00000000;
1939 let Inst{15-12} = Rd;
1942 // A version for the smaller set of tail call registers.
1943 let neverHasSideEffects = 1 in
1944 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1945 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1949 let Inst{11-4} = 0b00000000;
1952 let Inst{15-12} = Rd;
1955 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1956 DPSoRegFrm, IIC_iMOVsr,
1957 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1961 let Inst{15-12} = Rd;
1962 let Inst{11-0} = src;
1966 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1967 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1968 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1972 let Inst{15-12} = Rd;
1973 let Inst{19-16} = 0b0000;
1974 let Inst{11-0} = imm;
1977 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1978 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1980 "movw", "\t$Rd, $imm",
1981 [(set GPR:$Rd, imm0_65535:$imm)]>,
1982 Requires<[IsARM, HasV6T2]>, UnaryDP {
1985 let Inst{15-12} = Rd;
1986 let Inst{11-0} = imm{11-0};
1987 let Inst{19-16} = imm{15-12};
1992 def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1993 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1995 let Constraints = "$src = $Rd" in {
1996 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1998 "movt", "\t$Rd, $imm",
2000 (or (and GPR:$src, 0xffff),
2001 lo16AllZero:$imm))]>, UnaryDP,
2002 Requires<[IsARM, HasV6T2]> {
2005 let Inst{15-12} = Rd;
2006 let Inst{11-0} = imm{11-0};
2007 let Inst{19-16} = imm{15-12};
2012 def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2013 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2017 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2018 Requires<[IsARM, HasV6T2]>;
2020 let Uses = [CPSR] in
2021 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2022 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2025 // These aren't really mov instructions, but we have to define them this way
2026 // due to flag operands.
2028 let Defs = [CPSR] in {
2029 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2030 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2032 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2033 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2037 //===----------------------------------------------------------------------===//
2038 // Extend Instructions.
2043 defm SXTB : AI_ext_rrot<0b01101010,
2044 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2045 defm SXTH : AI_ext_rrot<0b01101011,
2046 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2048 defm SXTAB : AI_exta_rrot<0b01101010,
2049 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2050 defm SXTAH : AI_exta_rrot<0b01101011,
2051 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2053 // For disassembly only
2054 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2056 // For disassembly only
2057 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2061 let AddedComplexity = 16 in {
2062 defm UXTB : AI_ext_rrot<0b01101110,
2063 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2064 defm UXTH : AI_ext_rrot<0b01101111,
2065 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2066 defm UXTB16 : AI_ext_rrot<0b01101100,
2067 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2069 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2070 // The transformation should probably be done as a combiner action
2071 // instead so we can include a check for masking back in the upper
2072 // eight bits of the source into the lower eight bits of the result.
2073 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2074 // (UXTB16r_rot GPR:$Src, 24)>;
2075 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2076 (UXTB16r_rot GPR:$Src, 8)>;
2078 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2079 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2080 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2081 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2084 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2085 // For disassembly only
2086 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2089 def SBFX : I<(outs GPR:$Rd),
2090 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2091 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2092 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2093 Requires<[IsARM, HasV6T2]> {
2098 let Inst{27-21} = 0b0111101;
2099 let Inst{6-4} = 0b101;
2100 let Inst{20-16} = width;
2101 let Inst{15-12} = Rd;
2102 let Inst{11-7} = lsb;
2106 def UBFX : I<(outs GPR:$Rd),
2107 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2108 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2109 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2110 Requires<[IsARM, HasV6T2]> {
2115 let Inst{27-21} = 0b0111111;
2116 let Inst{6-4} = 0b101;
2117 let Inst{20-16} = width;
2118 let Inst{15-12} = Rd;
2119 let Inst{11-7} = lsb;
2123 //===----------------------------------------------------------------------===//
2124 // Arithmetic Instructions.
2127 defm ADD : AsI1_bin_irs<0b0100, "add",
2128 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2129 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2130 defm SUB : AsI1_bin_irs<0b0010, "sub",
2131 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2132 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2134 // ADD and SUB with 's' bit set.
2135 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2136 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2137 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2138 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2139 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2140 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2142 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2143 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2144 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2145 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2147 // ADC and SUBC with 's' bit set.
2148 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2149 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2150 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2151 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2153 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2154 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2155 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2160 let Inst{15-12} = Rd;
2161 let Inst{19-16} = Rn;
2162 let Inst{11-0} = imm;
2165 // The reg/reg form is only defined for the disassembler; for codegen it is
2166 // equivalent to SUBrr.
2167 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2168 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2169 [/* For disassembly only; pattern left blank */]> {
2173 let Inst{11-4} = 0b00000000;
2176 let Inst{15-12} = Rd;
2177 let Inst{19-16} = Rn;
2180 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2181 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2182 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2187 let Inst{11-0} = shift;
2188 let Inst{15-12} = Rd;
2189 let Inst{19-16} = Rn;
2192 // RSB with 's' bit set.
2193 let isCodeGenOnly = 1, Defs = [CPSR] in {
2194 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2195 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2196 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2202 let Inst{15-12} = Rd;
2203 let Inst{19-16} = Rn;
2204 let Inst{11-0} = imm;
2206 def RSBSrr : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2207 IIC_iALUr, "rsbs", "\t$Rd, $Rn, $Rm",
2208 [/* For disassembly only; pattern left blank */]> {
2212 let Inst{11-4} = 0b00000000;
2216 let Inst{15-12} = Rd;
2217 let Inst{19-16} = Rn;
2219 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2220 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2221 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2227 let Inst{11-0} = shift;
2228 let Inst{15-12} = Rd;
2229 let Inst{19-16} = Rn;
2233 let Uses = [CPSR] in {
2234 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2235 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2236 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2242 let Inst{15-12} = Rd;
2243 let Inst{19-16} = Rn;
2244 let Inst{11-0} = imm;
2246 // The reg/reg form is only defined for the disassembler; for codegen it is
2247 // equivalent to SUBrr.
2248 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2249 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2250 [/* For disassembly only; pattern left blank */]> {
2254 let Inst{11-4} = 0b00000000;
2257 let Inst{15-12} = Rd;
2258 let Inst{19-16} = Rn;
2260 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2261 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2262 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2268 let Inst{11-0} = shift;
2269 let Inst{15-12} = Rd;
2270 let Inst{19-16} = Rn;
2274 // FIXME: Allow these to be predicated.
2275 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2276 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2277 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2278 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2285 let Inst{15-12} = Rd;
2286 let Inst{19-16} = Rn;
2287 let Inst{11-0} = imm;
2289 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2290 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2291 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2298 let Inst{11-0} = shift;
2299 let Inst{15-12} = Rd;
2300 let Inst{19-16} = Rn;
2304 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2305 // The assume-no-carry-in form uses the negation of the input since add/sub
2306 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2307 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2309 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2310 (SUBri GPR:$src, so_imm_neg:$imm)>;
2311 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2312 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2313 // The with-carry-in form matches bitwise not instead of the negation.
2314 // Effectively, the inverse interpretation of the carry flag already accounts
2315 // for part of the negation.
2316 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2317 (SBCri GPR:$src, so_imm_not:$imm)>;
2319 // Note: These are implemented in C++ code, because they have to generate
2320 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2322 // (mul X, 2^n+1) -> (add (X << n), X)
2323 // (mul X, 2^n-1) -> (rsb X, (X << n))
2325 // ARM Arithmetic Instruction -- for disassembly only
2326 // GPR:$dst = GPR:$a op GPR:$b
2327 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2328 list<dag> pattern = [/* For disassembly only; pattern left blank */],
2329 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm">
2330 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
2334 let Inst{27-20} = op27_20;
2335 let Inst{11-4} = op11_4;
2336 let Inst{19-16} = Rn;
2337 let Inst{15-12} = Rd;
2341 // Saturating add/subtract -- for disassembly only
2343 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2344 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))],
2345 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2346 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2347 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))],
2348 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2349 def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn),
2351 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn),
2354 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2355 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2356 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2357 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2358 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2359 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2360 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2361 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2362 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2363 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2364 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2365 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2367 // Signed/Unsigned add/subtract -- for disassembly only
2369 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2370 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2371 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2372 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2373 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2374 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2375 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2376 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2377 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2378 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2379 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2380 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2382 // Signed/Unsigned halving add/subtract -- for disassembly only
2384 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2385 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2386 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2387 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2388 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2389 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2390 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2391 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2392 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2393 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2394 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2395 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2397 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2399 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2400 MulFrm /* for convenience */, NoItinerary, "usad8",
2401 "\t$Rd, $Rn, $Rm", []>,
2402 Requires<[IsARM, HasV6]> {
2406 let Inst{27-20} = 0b01111000;
2407 let Inst{15-12} = 0b1111;
2408 let Inst{7-4} = 0b0001;
2409 let Inst{19-16} = Rd;
2410 let Inst{11-8} = Rm;
2413 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2414 MulFrm /* for convenience */, NoItinerary, "usada8",
2415 "\t$Rd, $Rn, $Rm, $Ra", []>,
2416 Requires<[IsARM, HasV6]> {
2421 let Inst{27-20} = 0b01111000;
2422 let Inst{7-4} = 0b0001;
2423 let Inst{19-16} = Rd;
2424 let Inst{15-12} = Ra;
2425 let Inst{11-8} = Rm;
2429 // Signed/Unsigned saturate -- for disassembly only
2431 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2432 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2433 [/* For disassembly only; pattern left blank */]> {
2438 let Inst{27-21} = 0b0110101;
2439 let Inst{5-4} = 0b01;
2440 let Inst{20-16} = sat_imm;
2441 let Inst{15-12} = Rd;
2442 let Inst{11-7} = sh{7-3};
2443 let Inst{6} = sh{0};
2447 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2448 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2449 [/* For disassembly only; pattern left blank */]> {
2453 let Inst{27-20} = 0b01101010;
2454 let Inst{11-4} = 0b11110011;
2455 let Inst{15-12} = Rd;
2456 let Inst{19-16} = sat_imm;
2460 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2461 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2462 [/* For disassembly only; pattern left blank */]> {
2467 let Inst{27-21} = 0b0110111;
2468 let Inst{5-4} = 0b01;
2469 let Inst{15-12} = Rd;
2470 let Inst{11-7} = sh{7-3};
2471 let Inst{6} = sh{0};
2472 let Inst{20-16} = sat_imm;
2476 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2477 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2478 [/* For disassembly only; pattern left blank */]> {
2482 let Inst{27-20} = 0b01101110;
2483 let Inst{11-4} = 0b11110011;
2484 let Inst{15-12} = Rd;
2485 let Inst{19-16} = sat_imm;
2489 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2490 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2492 //===----------------------------------------------------------------------===//
2493 // Bitwise Instructions.
2496 defm AND : AsI1_bin_irs<0b0000, "and",
2497 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2498 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2499 defm ORR : AsI1_bin_irs<0b1100, "orr",
2500 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2501 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2502 defm EOR : AsI1_bin_irs<0b0001, "eor",
2503 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2504 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2505 defm BIC : AsI1_bin_irs<0b1110, "bic",
2506 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2507 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2509 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2510 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2511 "bfc", "\t$Rd, $imm", "$src = $Rd",
2512 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2513 Requires<[IsARM, HasV6T2]> {
2516 let Inst{27-21} = 0b0111110;
2517 let Inst{6-0} = 0b0011111;
2518 let Inst{15-12} = Rd;
2519 let Inst{11-7} = imm{4-0}; // lsb
2520 let Inst{20-16} = imm{9-5}; // width
2523 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2524 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2525 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2526 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2527 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2528 bf_inv_mask_imm:$imm))]>,
2529 Requires<[IsARM, HasV6T2]> {
2533 let Inst{27-21} = 0b0111110;
2534 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2535 let Inst{15-12} = Rd;
2536 let Inst{11-7} = imm{4-0}; // lsb
2537 let Inst{20-16} = imm{9-5}; // width
2541 // GNU as only supports this form of bfi (w/ 4 arguments)
2542 let isAsmParserOnly = 1 in
2543 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2544 lsb_pos_imm:$lsb, width_imm:$width),
2545 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2546 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2547 []>, Requires<[IsARM, HasV6T2]> {
2552 let Inst{27-21} = 0b0111110;
2553 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2554 let Inst{15-12} = Rd;
2555 let Inst{11-7} = lsb;
2556 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2560 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2561 "mvn", "\t$Rd, $Rm",
2562 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2566 let Inst{19-16} = 0b0000;
2567 let Inst{11-4} = 0b00000000;
2568 let Inst{15-12} = Rd;
2571 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2572 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2573 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2577 let Inst{19-16} = 0b0000;
2578 let Inst{15-12} = Rd;
2579 let Inst{11-0} = shift;
2581 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2582 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2583 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2584 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2588 let Inst{19-16} = 0b0000;
2589 let Inst{15-12} = Rd;
2590 let Inst{11-0} = imm;
2593 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2594 (BICri GPR:$src, so_imm_not:$imm)>;
2596 //===----------------------------------------------------------------------===//
2597 // Multiply Instructions.
2599 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2600 string opc, string asm, list<dag> pattern>
2601 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2605 let Inst{19-16} = Rd;
2606 let Inst{11-8} = Rm;
2609 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2610 string opc, string asm, list<dag> pattern>
2611 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2616 let Inst{19-16} = RdHi;
2617 let Inst{15-12} = RdLo;
2618 let Inst{11-8} = Rm;
2622 let isCommutable = 1 in {
2623 let Constraints = "@earlyclobber $Rd" in
2624 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2625 pred:$p, cc_out:$s),
2626 Size4Bytes, IIC_iMUL32,
2627 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2628 Requires<[IsARM, NoV6]>;
2630 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2631 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2632 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2633 Requires<[IsARM, HasV6]>;
2636 let Constraints = "@earlyclobber $Rd" in
2637 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2638 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2639 Size4Bytes, IIC_iMAC32,
2640 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2641 Requires<[IsARM, NoV6]> {
2643 let Inst{15-12} = Ra;
2645 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2646 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2647 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2648 Requires<[IsARM, HasV6]> {
2650 let Inst{15-12} = Ra;
2653 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2654 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2655 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2656 Requires<[IsARM, HasV6T2]> {
2661 let Inst{19-16} = Rd;
2662 let Inst{15-12} = Ra;
2663 let Inst{11-8} = Rm;
2667 // Extra precision multiplies with low / high results
2669 let neverHasSideEffects = 1 in {
2670 let isCommutable = 1 in {
2671 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2672 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2673 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2674 Size4Bytes, IIC_iMUL64, []>,
2675 Requires<[IsARM, NoV6]>;
2677 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2678 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2679 Size4Bytes, IIC_iMUL64, []>,
2680 Requires<[IsARM, NoV6]>;
2683 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2684 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2685 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2686 Requires<[IsARM, HasV6]>;
2688 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2689 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2690 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2691 Requires<[IsARM, HasV6]>;
2694 // Multiply + accumulate
2695 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2696 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2697 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2698 Size4Bytes, IIC_iMAC64, []>,
2699 Requires<[IsARM, NoV6]>;
2700 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2701 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2702 Size4Bytes, IIC_iMAC64, []>,
2703 Requires<[IsARM, NoV6]>;
2704 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2705 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2706 Size4Bytes, IIC_iMAC64, []>,
2707 Requires<[IsARM, NoV6]>;
2711 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2712 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2713 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2714 Requires<[IsARM, HasV6]>;
2715 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2716 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2717 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2718 Requires<[IsARM, HasV6]>;
2720 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2721 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2722 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2723 Requires<[IsARM, HasV6]> {
2728 let Inst{19-16} = RdLo;
2729 let Inst{15-12} = RdHi;
2730 let Inst{11-8} = Rm;
2733 } // neverHasSideEffects
2735 // Most significant word multiply
2736 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2737 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2738 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2739 Requires<[IsARM, HasV6]> {
2740 let Inst{15-12} = 0b1111;
2743 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2744 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2745 [/* For disassembly only; pattern left blank */]>,
2746 Requires<[IsARM, HasV6]> {
2747 let Inst{15-12} = 0b1111;
2750 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2751 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2752 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2753 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2754 Requires<[IsARM, HasV6]>;
2756 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2757 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2758 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2759 [/* For disassembly only; pattern left blank */]>,
2760 Requires<[IsARM, HasV6]>;
2762 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2763 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2764 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2765 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2766 Requires<[IsARM, HasV6]>;
2768 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2769 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2770 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2771 [/* For disassembly only; pattern left blank */]>,
2772 Requires<[IsARM, HasV6]>;
2774 multiclass AI_smul<string opc, PatFrag opnode> {
2775 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2776 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2777 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2778 (sext_inreg GPR:$Rm, i16)))]>,
2779 Requires<[IsARM, HasV5TE]>;
2781 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2782 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2783 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2784 (sra GPR:$Rm, (i32 16))))]>,
2785 Requires<[IsARM, HasV5TE]>;
2787 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2788 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2789 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2790 (sext_inreg GPR:$Rm, i16)))]>,
2791 Requires<[IsARM, HasV5TE]>;
2793 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2794 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2795 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2796 (sra GPR:$Rm, (i32 16))))]>,
2797 Requires<[IsARM, HasV5TE]>;
2799 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2800 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2801 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2802 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2803 Requires<[IsARM, HasV5TE]>;
2805 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2806 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2807 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2808 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2809 Requires<[IsARM, HasV5TE]>;
2813 multiclass AI_smla<string opc, PatFrag opnode> {
2814 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2815 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2816 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2817 [(set GPR:$Rd, (add GPR:$Ra,
2818 (opnode (sext_inreg GPR:$Rn, i16),
2819 (sext_inreg GPR:$Rm, i16))))]>,
2820 Requires<[IsARM, HasV5TE]>;
2822 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2823 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2824 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2825 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2826 (sra GPR:$Rm, (i32 16)))))]>,
2827 Requires<[IsARM, HasV5TE]>;
2829 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2830 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2831 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2832 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2833 (sext_inreg GPR:$Rm, i16))))]>,
2834 Requires<[IsARM, HasV5TE]>;
2836 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2837 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2838 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2839 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2840 (sra GPR:$Rm, (i32 16)))))]>,
2841 Requires<[IsARM, HasV5TE]>;
2843 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2844 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2845 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2846 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2847 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2848 Requires<[IsARM, HasV5TE]>;
2850 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2851 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2852 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2853 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2854 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2855 Requires<[IsARM, HasV5TE]>;
2858 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2859 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2861 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2862 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2863 (ins GPR:$Rn, GPR:$Rm),
2864 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2865 [/* For disassembly only; pattern left blank */]>,
2866 Requires<[IsARM, HasV5TE]>;
2868 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2869 (ins GPR:$Rn, GPR:$Rm),
2870 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2871 [/* For disassembly only; pattern left blank */]>,
2872 Requires<[IsARM, HasV5TE]>;
2874 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2875 (ins GPR:$Rn, GPR:$Rm),
2876 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2877 [/* For disassembly only; pattern left blank */]>,
2878 Requires<[IsARM, HasV5TE]>;
2880 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2881 (ins GPR:$Rn, GPR:$Rm),
2882 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2883 [/* For disassembly only; pattern left blank */]>,
2884 Requires<[IsARM, HasV5TE]>;
2886 // Helper class for AI_smld -- for disassembly only
2887 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2888 InstrItinClass itin, string opc, string asm>
2889 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2896 let Inst{21-20} = 0b00;
2897 let Inst{22} = long;
2898 let Inst{27-23} = 0b01110;
2899 let Inst{11-8} = Rm;
2902 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2903 InstrItinClass itin, string opc, string asm>
2904 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2906 let Inst{15-12} = 0b1111;
2907 let Inst{19-16} = Rd;
2909 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2910 InstrItinClass itin, string opc, string asm>
2911 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2913 let Inst{15-12} = Ra;
2915 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2916 InstrItinClass itin, string opc, string asm>
2917 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2920 let Inst{19-16} = RdHi;
2921 let Inst{15-12} = RdLo;
2924 multiclass AI_smld<bit sub, string opc> {
2926 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2927 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2929 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2930 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2932 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2933 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2934 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2936 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2937 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2938 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2942 defm SMLA : AI_smld<0, "smla">;
2943 defm SMLS : AI_smld<1, "smls">;
2945 multiclass AI_sdml<bit sub, string opc> {
2947 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2948 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2949 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2950 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2953 defm SMUA : AI_sdml<0, "smua">;
2954 defm SMUS : AI_sdml<1, "smus">;
2956 //===----------------------------------------------------------------------===//
2957 // Misc. Arithmetic Instructions.
2960 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2961 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2962 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2964 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2965 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2966 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2967 Requires<[IsARM, HasV6T2]>;
2969 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2970 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2971 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2973 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2974 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2976 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2977 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2978 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2979 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2980 Requires<[IsARM, HasV6]>;
2982 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2983 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2986 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2987 (shl GPR:$Rm, (i32 8))), i16))]>,
2988 Requires<[IsARM, HasV6]>;
2990 def lsl_shift_imm : SDNodeXForm<imm, [{
2991 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2992 return CurDAG->getTargetConstant(Sh, MVT::i32);
2995 def lsl_amt : PatLeaf<(i32 imm), [{
2996 return (N->getZExtValue() < 32);
2999 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
3000 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
3001 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
3002 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
3003 (and (shl GPR:$Rm, lsl_amt:$sh),
3005 Requires<[IsARM, HasV6]>;
3007 // Alternate cases for PKHBT where identities eliminate some nodes.
3008 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
3009 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
3010 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
3011 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
3013 def asr_shift_imm : SDNodeXForm<imm, [{
3014 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
3015 return CurDAG->getTargetConstant(Sh, MVT::i32);
3018 def asr_amt : PatLeaf<(i32 imm), [{
3019 return (N->getZExtValue() <= 32);
3022 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3023 // will match the pattern below.
3024 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
3025 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
3026 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3027 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
3028 (and (sra GPR:$Rm, asr_amt:$sh),
3030 Requires<[IsARM, HasV6]>;
3032 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
3033 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
3034 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
3035 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
3036 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
3037 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
3038 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
3040 //===----------------------------------------------------------------------===//
3041 // Comparison Instructions...
3044 defm CMP : AI1_cmp_irs<0b1010, "cmp",
3045 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3046 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3048 // ARMcmpZ can re-use the above instruction definitions.
3049 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3050 (CMPri GPR:$src, so_imm:$imm)>;
3051 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3052 (CMPrr GPR:$src, GPR:$rhs)>;
3053 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
3054 (CMPrs GPR:$src, so_reg:$rhs)>;
3056 // FIXME: We have to be careful when using the CMN instruction and comparison
3057 // with 0. One would expect these two pieces of code should give identical
3073 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3074 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3075 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3076 // value of r0 and the carry bit (because the "carry bit" parameter to
3077 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3078 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3079 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3080 // parameter to AddWithCarry is defined as 0).
3082 // When x is 0 and unsigned:
3086 // ~x + 1 = 0x1 0000 0000
3087 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3089 // Therefore, we should disable CMN when comparing against zero, until we can
3090 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3091 // when it's a comparison which doesn't look at the 'carry' flag).
3093 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3095 // This is related to <rdar://problem/7569620>.
3097 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3098 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3100 // Note that TST/TEQ don't set all the same flags that CMP does!
3101 defm TST : AI1_cmp_irs<0b1000, "tst",
3102 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3103 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3104 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3105 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3106 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3108 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3109 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3110 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3112 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3113 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3115 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3116 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3118 // Pseudo i64 compares for some floating point compares.
3119 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3121 def BCCi64 : PseudoInst<(outs),
3122 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3124 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3126 def BCCZi64 : PseudoInst<(outs),
3127 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3128 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3129 } // usesCustomInserter
3132 // Conditional moves
3133 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3134 // a two-value operand where a dag node expects two operands. :(
3135 // FIXME: These should all be pseudo-instructions that get expanded to
3136 // the normal MOV instructions. That would fix the dependency on
3137 // special casing them in tblgen.
3138 let neverHasSideEffects = 1 in {
3139 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3140 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3141 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3142 RegConstraint<"$false = $Rd">, UnaryDP {
3147 let Inst{15-12} = Rd;
3148 let Inst{11-4} = 0b00000000;
3152 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3153 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3154 "mov", "\t$Rd, $shift",
3155 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3156 RegConstraint<"$false = $Rd">, UnaryDP {
3161 let Inst{19-16} = 0;
3162 let Inst{15-12} = Rd;
3163 let Inst{11-0} = shift;
3166 let isMoveImm = 1 in
3167 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3169 "movw", "\t$Rd, $imm",
3171 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3177 let Inst{19-16} = imm{15-12};
3178 let Inst{15-12} = Rd;
3179 let Inst{11-0} = imm{11-0};
3182 let isMoveImm = 1 in
3183 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3184 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3185 "mov", "\t$Rd, $imm",
3186 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3187 RegConstraint<"$false = $Rd">, UnaryDP {
3192 let Inst{19-16} = 0b0000;
3193 let Inst{15-12} = Rd;
3194 let Inst{11-0} = imm;
3197 // Two instruction predicate mov immediate.
3198 let isMoveImm = 1 in
3199 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3200 (ins GPR:$false, i32imm:$src, pred:$p),
3201 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3203 let isMoveImm = 1 in
3204 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3205 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3206 "mvn", "\t$Rd, $imm",
3207 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3208 RegConstraint<"$false = $Rd">, UnaryDP {
3213 let Inst{19-16} = 0b0000;
3214 let Inst{15-12} = Rd;
3215 let Inst{11-0} = imm;
3217 } // neverHasSideEffects
3219 //===----------------------------------------------------------------------===//
3220 // Atomic operations intrinsics
3223 def memb_opt : Operand<i32> {
3224 let PrintMethod = "printMemBOption";
3225 let ParserMatchClass = MemBarrierOptOperand;
3228 // memory barriers protect the atomic sequences
3229 let hasSideEffects = 1 in {
3230 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3231 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3232 Requires<[IsARM, HasDB]> {
3234 let Inst{31-4} = 0xf57ff05;
3235 let Inst{3-0} = opt;
3238 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3239 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3240 [(ARMMemBarrierMCR GPR:$zero)]>,
3241 Requires<[IsARM, HasV6]> {
3242 // FIXME: add encoding
3246 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3248 [/* For disassembly only; pattern left blank */]>,
3249 Requires<[IsARM, HasDB]> {
3251 let Inst{31-4} = 0xf57ff04;
3252 let Inst{3-0} = opt;
3255 // ISB has only full system option -- for disassembly only
3256 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3257 Requires<[IsARM, HasDB]> {
3258 let Inst{31-4} = 0xf57ff06;
3259 let Inst{3-0} = 0b1111;
3262 let usesCustomInserter = 1 in {
3263 let Uses = [CPSR] in {
3264 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3265 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3266 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3267 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3268 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3269 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3270 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3271 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3272 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3273 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3274 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3275 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3276 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3277 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3278 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3279 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3280 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3281 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3282 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3283 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3284 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3285 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3286 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3287 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3288 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3289 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3290 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3291 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3292 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3293 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3294 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3295 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3296 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3297 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3298 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3299 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3300 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3301 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3302 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3303 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3304 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3305 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3306 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3307 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3308 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3309 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3310 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3311 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3312 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3313 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3314 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3315 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3316 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3317 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3319 def ATOMIC_SWAP_I8 : PseudoInst<
3320 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3321 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3322 def ATOMIC_SWAP_I16 : PseudoInst<
3323 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3324 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3325 def ATOMIC_SWAP_I32 : PseudoInst<
3326 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3327 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3329 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3330 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3331 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3332 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3333 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3334 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3335 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3336 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3337 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3341 let mayLoad = 1 in {
3342 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3343 "ldrexb", "\t$Rt, [$Rn]",
3345 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3346 "ldrexh", "\t$Rt, [$Rn]",
3348 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3349 "ldrex", "\t$Rt, [$Rn]",
3351 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3353 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3357 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3358 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3360 "strexb", "\t$Rd, $src, [$Rn]",
3362 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3364 "strexh", "\t$Rd, $Rt, [$Rn]",
3366 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3368 "strex", "\t$Rd, $Rt, [$Rn]",
3370 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3371 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3373 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3377 // Clear-Exclusive is for disassembly only.
3378 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3379 [/* For disassembly only; pattern left blank */]>,
3380 Requires<[IsARM, HasV7]> {
3381 let Inst{31-0} = 0b11110101011111111111000000011111;
3384 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3385 let mayLoad = 1 in {
3386 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3387 [/* For disassembly only; pattern left blank */]>;
3388 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3389 [/* For disassembly only; pattern left blank */]>;
3392 //===----------------------------------------------------------------------===//
3396 // __aeabi_read_tp preserves the registers r1-r3.
3397 // This is a pseudo inst so that we can get the encoding right,
3398 // complete with fixup for the aeabi_read_tp function.
3400 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3401 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3402 [(set R0, ARMthread_pointer)]>;
3405 //===----------------------------------------------------------------------===//
3406 // SJLJ Exception handling intrinsics
3407 // eh_sjlj_setjmp() is an instruction sequence to store the return
3408 // address and save #0 in R0 for the non-longjmp case.
3409 // Since by its nature we may be coming from some other function to get
3410 // here, and we're using the stack frame for the containing function to
3411 // save/restore registers, we can't keep anything live in regs across
3412 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3413 // when we get here from a longjmp(). We force everthing out of registers
3414 // except for our own input by listing the relevant registers in Defs. By
3415 // doing so, we also cause the prologue/epilogue code to actively preserve
3416 // all of the callee-saved resgisters, which is exactly what we want.
3417 // A constant value is passed in $val, and we use the location as a scratch.
3419 // These are pseudo-instructions and are lowered to individual MC-insts, so
3420 // no encoding information is necessary.
3422 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3423 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3424 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3425 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3426 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3428 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3429 Requires<[IsARM, HasVFP2]>;
3433 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3434 hasSideEffects = 1, isBarrier = 1 in {
3435 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3437 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3438 Requires<[IsARM, NoVFP]>;
3441 // FIXME: Non-Darwin version(s)
3442 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3443 Defs = [ R7, LR, SP ] in {
3444 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3446 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3447 Requires<[IsARM, IsDarwin]>;
3450 // eh.sjlj.dispatchsetup pseudo-instruction.
3451 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3452 // handled when the pseudo is expanded (which happens before any passes
3453 // that need the instruction size).
3454 let isBarrier = 1, hasSideEffects = 1 in
3455 def Int_eh_sjlj_dispatchsetup :
3456 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3457 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3458 Requires<[IsDarwin]>;
3460 //===----------------------------------------------------------------------===//
3461 // Non-Instruction Patterns
3464 // Large immediate handling.
3466 // 32-bit immediate using two piece so_imms or movw + movt.
3467 // This is a single pseudo instruction, the benefit is that it can be remat'd
3468 // as a single unit instead of having to handle reg inputs.
3469 // FIXME: Remove this when we can do generalized remat.
3470 let isReMaterializable = 1, isMoveImm = 1 in
3471 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3472 [(set GPR:$dst, (arm_i32imm:$src))]>,
3475 // Pseudo instruction that combines movw + movt + add pc (if PIC).
3476 // It also makes it possible to rematerialize the instructions.
3477 // FIXME: Remove this when we can do generalized remat and when machine licm
3478 // can properly the instructions.
3479 let isReMaterializable = 1 in {
3480 def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3482 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3483 Requires<[IsARM, UseMovt]>;
3485 def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3487 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3488 Requires<[IsARM, UseMovt]>;
3490 let AddedComplexity = 10 in
3491 def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3493 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
3494 Requires<[IsARM, UseMovt]>;
3495 } // isReMaterializable
3497 // ConstantPool, GlobalAddress, and JumpTable
3498 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3499 Requires<[IsARM, DontUseMovt]>;
3500 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3501 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3502 Requires<[IsARM, UseMovt]>;
3503 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3504 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3506 // TODO: add,sub,and, 3-instr forms?
3509 def : ARMPat<(ARMtcret tcGPR:$dst),
3510 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3512 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3513 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3515 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3516 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3518 def : ARMPat<(ARMtcret tcGPR:$dst),
3519 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3521 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3522 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3524 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3525 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3528 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3529 Requires<[IsARM, IsNotDarwin]>;
3530 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3531 Requires<[IsARM, IsDarwin]>;
3533 // zextload i1 -> zextload i8
3534 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3535 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3537 // extload -> zextload
3538 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3539 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3540 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3541 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3543 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3545 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3546 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3549 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3550 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3551 (SMULBB GPR:$a, GPR:$b)>;
3552 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3553 (SMULBB GPR:$a, GPR:$b)>;
3554 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3555 (sra GPR:$b, (i32 16))),
3556 (SMULBT GPR:$a, GPR:$b)>;
3557 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3558 (SMULBT GPR:$a, GPR:$b)>;
3559 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3560 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3561 (SMULTB GPR:$a, GPR:$b)>;
3562 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3563 (SMULTB GPR:$a, GPR:$b)>;
3564 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3566 (SMULWB GPR:$a, GPR:$b)>;
3567 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3568 (SMULWB GPR:$a, GPR:$b)>;
3570 def : ARMV5TEPat<(add GPR:$acc,
3571 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3572 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3573 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3574 def : ARMV5TEPat<(add GPR:$acc,
3575 (mul sext_16_node:$a, sext_16_node:$b)),
3576 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3577 def : ARMV5TEPat<(add GPR:$acc,
3578 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3579 (sra GPR:$b, (i32 16)))),
3580 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3581 def : ARMV5TEPat<(add GPR:$acc,
3582 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3583 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3584 def : ARMV5TEPat<(add GPR:$acc,
3585 (mul (sra GPR:$a, (i32 16)),
3586 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3587 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3588 def : ARMV5TEPat<(add GPR:$acc,
3589 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3590 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3591 def : ARMV5TEPat<(add GPR:$acc,
3592 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3594 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3595 def : ARMV5TEPat<(add GPR:$acc,
3596 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3597 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3599 //===----------------------------------------------------------------------===//
3603 include "ARMInstrThumb.td"
3605 //===----------------------------------------------------------------------===//
3609 include "ARMInstrThumb2.td"
3611 //===----------------------------------------------------------------------===//
3612 // Floating Point Support
3615 include "ARMInstrVFP.td"
3617 //===----------------------------------------------------------------------===//
3618 // Advanced SIMD (NEON) Support
3621 include "ARMInstrNEON.td"
3623 //===----------------------------------------------------------------------===//
3624 // Coprocessor Instructions. For disassembly only.
3627 def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3628 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3629 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3630 [/* For disassembly only; pattern left blank */]> {
3638 let Inst{3-0} = CRm;
3640 let Inst{7-5} = opc2;
3641 let Inst{11-8} = cop;
3642 let Inst{15-12} = CRd;
3643 let Inst{19-16} = CRn;
3644 let Inst{23-20} = opc1;
3647 def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3648 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3649 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3650 [/* For disassembly only; pattern left blank */]> {
3651 let Inst{31-28} = 0b1111;
3659 let Inst{3-0} = CRm;
3661 let Inst{7-5} = opc2;
3662 let Inst{11-8} = cop;
3663 let Inst{15-12} = CRd;
3664 let Inst{19-16} = CRn;
3665 let Inst{23-20} = opc1;
3668 class ACI<dag oops, dag iops, string opc, string asm>
3669 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3670 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3671 let Inst{27-25} = 0b110;
3674 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3676 def _OFFSET : ACI<(outs),
3677 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3678 opc, "\tp$cop, cr$CRd, $addr"> {
3679 let Inst{31-28} = op31_28;
3680 let Inst{24} = 1; // P = 1
3681 let Inst{21} = 0; // W = 0
3682 let Inst{22} = 0; // D = 0
3683 let Inst{20} = load;
3686 def _PRE : ACI<(outs),
3687 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3688 opc, "\tp$cop, cr$CRd, $addr!"> {
3689 let Inst{31-28} = op31_28;
3690 let Inst{24} = 1; // P = 1
3691 let Inst{21} = 1; // W = 1
3692 let Inst{22} = 0; // D = 0
3693 let Inst{20} = load;
3696 def _POST : ACI<(outs),
3697 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3698 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3699 let Inst{31-28} = op31_28;
3700 let Inst{24} = 0; // P = 0
3701 let Inst{21} = 1; // W = 1
3702 let Inst{22} = 0; // D = 0
3703 let Inst{20} = load;
3706 def _OPTION : ACI<(outs),
3707 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3708 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3709 let Inst{31-28} = op31_28;
3710 let Inst{24} = 0; // P = 0
3711 let Inst{23} = 1; // U = 1
3712 let Inst{21} = 0; // W = 0
3713 let Inst{22} = 0; // D = 0
3714 let Inst{20} = load;
3717 def L_OFFSET : ACI<(outs),
3718 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3719 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3720 let Inst{31-28} = op31_28;
3721 let Inst{24} = 1; // P = 1
3722 let Inst{21} = 0; // W = 0
3723 let Inst{22} = 1; // D = 1
3724 let Inst{20} = load;
3727 def L_PRE : ACI<(outs),
3728 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3729 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3730 let Inst{31-28} = op31_28;
3731 let Inst{24} = 1; // P = 1
3732 let Inst{21} = 1; // W = 1
3733 let Inst{22} = 1; // D = 1
3734 let Inst{20} = load;
3737 def L_POST : ACI<(outs),
3738 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3739 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3740 let Inst{31-28} = op31_28;
3741 let Inst{24} = 0; // P = 0
3742 let Inst{21} = 1; // W = 1
3743 let Inst{22} = 1; // D = 1
3744 let Inst{20} = load;
3747 def L_OPTION : ACI<(outs),
3748 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3749 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3750 let Inst{31-28} = op31_28;
3751 let Inst{24} = 0; // P = 0
3752 let Inst{23} = 1; // U = 1
3753 let Inst{21} = 0; // W = 0
3754 let Inst{22} = 1; // D = 1
3755 let Inst{20} = load;
3759 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3760 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3761 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3762 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3764 //===----------------------------------------------------------------------===//
3765 // Move between coprocessor and ARM core register -- for disassembly only
3768 class MovRCopro<string opc, bit direction>
3769 : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3770 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3771 NoItinerary, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3772 [/* For disassembly only; pattern left blank */]> {
3773 let Inst{20} = direction;
3783 let Inst{15-12} = Rt;
3784 let Inst{11-8} = cop;
3785 let Inst{23-21} = opc1;
3786 let Inst{7-5} = opc2;
3787 let Inst{3-0} = CRm;
3788 let Inst{19-16} = CRn;
3791 def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */>;
3792 def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */>;
3794 class MovRCopro2<string opc, bit direction>
3795 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3796 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3797 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3798 [/* For disassembly only; pattern left blank */]> {
3799 let Inst{31-28} = 0b1111;
3800 let Inst{20} = direction;
3810 let Inst{15-12} = Rt;
3811 let Inst{11-8} = cop;
3812 let Inst{23-21} = opc1;
3813 let Inst{7-5} = opc2;
3814 let Inst{3-0} = CRm;
3815 let Inst{19-16} = CRn;
3818 def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */>;
3819 def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */>;
3821 class MovRRCopro<string opc, bit direction>
3822 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3823 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3824 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
3825 [/* For disassembly only; pattern left blank */]> {
3826 let Inst{23-21} = 0b010;
3827 let Inst{20} = direction;
3835 let Inst{15-12} = Rt;
3836 let Inst{19-16} = Rt2;
3837 let Inst{11-8} = cop;
3838 let Inst{7-4} = opc1;
3839 let Inst{3-0} = CRm;
3842 def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
3843 def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
3845 class MovRRCopro2<string opc, bit direction>
3846 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3847 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3848 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3849 [/* For disassembly only; pattern left blank */]> {
3850 let Inst{31-28} = 0b1111;
3851 let Inst{23-21} = 0b010;
3852 let Inst{20} = direction;
3860 let Inst{15-12} = Rt;
3861 let Inst{19-16} = Rt2;
3862 let Inst{11-8} = cop;
3863 let Inst{7-4} = opc1;
3864 let Inst{3-0} = CRm;
3867 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
3868 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
3870 //===----------------------------------------------------------------------===//
3871 // Move between special register and ARM core register -- for disassembly only
3874 // Move to ARM core register from Special Register
3875 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3876 [/* For disassembly only; pattern left blank */]> {
3878 let Inst{23-16} = 0b00001111;
3879 let Inst{15-12} = Rd;
3880 let Inst{7-4} = 0b0000;
3883 def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr",
3884 [/* For disassembly only; pattern left blank */]> {
3886 let Inst{23-16} = 0b01001111;
3887 let Inst{15-12} = Rd;
3888 let Inst{7-4} = 0b0000;
3891 // Move from ARM core register to Special Register
3893 // No need to have both system and application versions, the encodings are the
3894 // same and the assembly parser has no way to distinguish between them. The mask
3895 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3896 // the mask with the fields to be accessed in the special register.
3897 def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
3898 "msr", "\t$mask, $Rn",
3899 [/* For disassembly only; pattern left blank */]> {
3904 let Inst{22} = mask{4}; // R bit
3905 let Inst{21-20} = 0b10;
3906 let Inst{19-16} = mask{3-0};
3907 let Inst{15-12} = 0b1111;
3908 let Inst{11-4} = 0b00000000;
3912 def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary,
3913 "msr", "\t$mask, $a",
3914 [/* For disassembly only; pattern left blank */]> {
3919 let Inst{22} = mask{4}; // R bit
3920 let Inst{21-20} = 0b10;
3921 let Inst{19-16} = mask{3-0};
3922 let Inst{15-12} = 0b1111;