1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>;
73 def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
74 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
76 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
77 [SDNPHasChain, SDNPOutGlue]>;
78 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
79 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
81 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
82 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
84 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
85 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
87 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
88 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
91 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
92 [SDNPHasChain, SDNPOptInGlue]>;
94 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
96 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
99 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
100 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
102 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
104 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
107 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
110 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
113 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
114 [SDNPOutGlue, SDNPCommutative]>;
116 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
118 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
119 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
120 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
122 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
123 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
124 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
126 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
127 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
128 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
131 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
133 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
135 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
136 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
138 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
140 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
141 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
144 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
146 //===----------------------------------------------------------------------===//
147 // ARM Instruction Predicate Definitions.
149 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
150 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
151 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
152 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
153 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
154 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
155 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
156 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
157 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
158 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
159 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
160 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
161 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
162 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
163 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
164 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
166 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
168 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
170 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
171 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
172 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
173 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
174 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
175 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
176 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
177 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
179 // FIXME: Eventually this will be just "hasV6T2Ops".
180 def UseMovt : Predicate<"Subtarget->useMovt()">;
181 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
182 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
184 //===----------------------------------------------------------------------===//
185 // ARM Flag Definitions.
187 class RegConstraint<string C> {
188 string Constraints = C;
191 //===----------------------------------------------------------------------===//
192 // ARM specific transformation functions and pattern fragments.
195 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
196 // so_imm_neg def below.
197 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
198 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
201 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
202 // so_imm_not def below.
203 def so_imm_not_XFORM : SDNodeXForm<imm, [{
204 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
207 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
208 def imm1_15 : PatLeaf<(i32 imm), [{
209 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
212 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
213 def imm16_31 : PatLeaf<(i32 imm), [{
214 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
219 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
220 }], so_imm_neg_XFORM>;
224 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
225 }], so_imm_not_XFORM>;
227 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
228 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
229 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
232 /// Split a 32-bit immediate into two 16 bit parts.
233 def hi16 : SDNodeXForm<imm, [{
234 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
237 def lo16AllZero : PatLeaf<(i32 imm), [{
238 // Returns true if all low 16-bits are 0.
239 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
242 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
244 def imm0_65535 : PatLeaf<(i32 imm), [{
245 return (uint32_t)N->getZExtValue() < 65536;
248 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
249 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
251 /// adde and sube predicates - True based on whether the carry flag output
252 /// will be needed or not.
253 def adde_dead_carry :
254 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
255 [{return !N->hasAnyUseOfValue(1);}]>;
256 def sube_dead_carry :
257 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
258 [{return !N->hasAnyUseOfValue(1);}]>;
259 def adde_live_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return N->hasAnyUseOfValue(1);}]>;
262 def sube_live_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return N->hasAnyUseOfValue(1);}]>;
266 // An 'and' node with a single use.
267 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
268 return N->hasOneUse();
271 // An 'xor' node with a single use.
272 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
273 return N->hasOneUse();
276 // An 'fmul' node with a single use.
277 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
278 return N->hasOneUse();
281 // An 'fadd' node which checks for single non-hazardous use.
282 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
283 return hasNoVMLxHazardUse(N);
286 // An 'fsub' node which checks for single non-hazardous use.
287 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
288 return hasNoVMLxHazardUse(N);
291 //===----------------------------------------------------------------------===//
292 // Operand Definitions.
296 // FIXME: rename brtarget to t2_brtarget
297 def brtarget : Operand<OtherVT> {
298 let EncoderMethod = "getBranchTargetOpValue";
301 // FIXME: get rid of this one?
302 def uncondbrtarget : Operand<OtherVT> {
303 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
306 // Branch target for ARM. Handles conditional/unconditional
307 def br_target : Operand<OtherVT> {
308 let EncoderMethod = "getARMBranchTargetOpValue";
312 // FIXME: rename bltarget to t2_bl_target?
313 def bltarget : Operand<i32> {
314 // Encoded the same as branch targets.
315 let EncoderMethod = "getBranchTargetOpValue";
318 // Call target for ARM. Handles conditional/unconditional
319 // FIXME: rename bl_target to t2_bltarget?
320 def bl_target : Operand<i32> {
321 // Encoded the same as branch targets.
322 let EncoderMethod = "getARMBranchTargetOpValue";
326 // A list of registers separated by comma. Used by load/store multiple.
327 def RegListAsmOperand : AsmOperandClass {
328 let Name = "RegList";
329 let SuperClasses = [];
332 def DPRRegListAsmOperand : AsmOperandClass {
333 let Name = "DPRRegList";
334 let SuperClasses = [];
337 def SPRRegListAsmOperand : AsmOperandClass {
338 let Name = "SPRRegList";
339 let SuperClasses = [];
342 def reglist : Operand<i32> {
343 let EncoderMethod = "getRegisterListOpValue";
344 let ParserMatchClass = RegListAsmOperand;
345 let PrintMethod = "printRegisterList";
348 def dpr_reglist : Operand<i32> {
349 let EncoderMethod = "getRegisterListOpValue";
350 let ParserMatchClass = DPRRegListAsmOperand;
351 let PrintMethod = "printRegisterList";
354 def spr_reglist : Operand<i32> {
355 let EncoderMethod = "getRegisterListOpValue";
356 let ParserMatchClass = SPRRegListAsmOperand;
357 let PrintMethod = "printRegisterList";
360 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
361 def cpinst_operand : Operand<i32> {
362 let PrintMethod = "printCPInstOperand";
366 def pclabel : Operand<i32> {
367 let PrintMethod = "printPCLabel";
370 // ADR instruction labels.
371 def adrlabel : Operand<i32> {
372 let EncoderMethod = "getAdrLabelOpValue";
375 def neon_vcvt_imm32 : Operand<i32> {
376 let EncoderMethod = "getNEONVcvtImm32OpValue";
379 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
380 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
381 int32_t v = (int32_t)N->getZExtValue();
382 return v == 8 || v == 16 || v == 24; }]> {
383 let EncoderMethod = "getRotImmOpValue";
386 // shift_imm: An integer that encodes a shift amount and the type of shift
387 // (currently either asr or lsl) using the same encoding used for the
388 // immediates in so_reg operands.
389 def shift_imm : Operand<i32> {
390 let PrintMethod = "printShiftImmOperand";
393 // shifter_operand operands: so_reg and so_imm.
394 def so_reg : Operand<i32>, // reg reg imm
395 ComplexPattern<i32, 3, "SelectShifterOperandReg",
396 [shl,srl,sra,rotr]> {
397 let EncoderMethod = "getSORegOpValue";
398 let PrintMethod = "printSORegOperand";
399 let MIOperandInfo = (ops GPR, GPR, i32imm);
401 def shift_so_reg : Operand<i32>, // reg reg imm
402 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
403 [shl,srl,sra,rotr]> {
404 let EncoderMethod = "getSORegOpValue";
405 let PrintMethod = "printSORegOperand";
406 let MIOperandInfo = (ops GPR, GPR, i32imm);
409 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
410 // 8-bit immediate rotated by an arbitrary number of bits.
411 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
412 let EncoderMethod = "getSOImmOpValue";
413 let PrintMethod = "printSOImmOperand";
416 // Break so_imm's up into two pieces. This handles immediates with up to 16
417 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
418 // get the first/second pieces.
419 def so_imm2part : PatLeaf<(imm), [{
420 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
423 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
425 def arm_i32imm : PatLeaf<(imm), [{
426 if (Subtarget->hasV6T2Ops())
428 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
431 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
432 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
433 return (int32_t)N->getZExtValue() < 32;
436 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
437 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
438 return (int32_t)N->getZExtValue() < 32;
440 let EncoderMethod = "getImmMinusOneOpValue";
443 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
444 // The imm is split into imm{15-12}, imm{11-0}
446 def i32imm_hilo16 : Operand<i32> {
447 let EncoderMethod = "getHiLo16ImmOpValue";
450 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
452 def bf_inv_mask_imm : Operand<i32>,
454 return ARM::isBitFieldInvertedMask(N->getZExtValue());
456 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
457 let PrintMethod = "printBitfieldInvMaskImmOperand";
460 /// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
461 def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
462 return isInt<5>(N->getSExtValue());
465 /// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
466 def width_imm : Operand<i32>, PatLeaf<(imm), [{
467 return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
469 let EncoderMethod = "getMsbOpValue";
472 // Define ARM specific addressing modes.
475 // addrmode_imm12 := reg +/- imm12
477 def addrmode_imm12 : Operand<i32>,
478 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
479 // 12-bit immediate operand. Note that instructions using this encode
480 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
481 // immediate values are as normal.
483 let EncoderMethod = "getAddrModeImm12OpValue";
484 let PrintMethod = "printAddrModeImm12Operand";
485 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
487 // ldst_so_reg := reg +/- reg shop imm
489 def ldst_so_reg : Operand<i32>,
490 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
491 let EncoderMethod = "getLdStSORegOpValue";
492 // FIXME: Simplify the printer
493 let PrintMethod = "printAddrMode2Operand";
494 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
497 // addrmode2 := reg +/- imm12
498 // := reg +/- reg shop imm
500 def addrmode2 : Operand<i32>,
501 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
502 let EncoderMethod = "getAddrMode2OpValue";
503 let PrintMethod = "printAddrMode2Operand";
504 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
507 def am2offset : Operand<i32>,
508 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
509 [], [SDNPWantRoot]> {
510 let EncoderMethod = "getAddrMode2OffsetOpValue";
511 let PrintMethod = "printAddrMode2OffsetOperand";
512 let MIOperandInfo = (ops GPR, i32imm);
515 // addrmode3 := reg +/- reg
516 // addrmode3 := reg +/- imm8
518 def addrmode3 : Operand<i32>,
519 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
520 let EncoderMethod = "getAddrMode3OpValue";
521 let PrintMethod = "printAddrMode3Operand";
522 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
525 def am3offset : Operand<i32>,
526 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
527 [], [SDNPWantRoot]> {
528 let EncoderMethod = "getAddrMode3OffsetOpValue";
529 let PrintMethod = "printAddrMode3OffsetOperand";
530 let MIOperandInfo = (ops GPR, i32imm);
533 // ldstm_mode := {ia, ib, da, db}
535 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
536 let EncoderMethod = "getLdStmModeOpValue";
537 let PrintMethod = "printLdStmModeOperand";
540 def MemMode5AsmOperand : AsmOperandClass {
541 let Name = "MemMode5";
542 let SuperClasses = [];
545 // addrmode5 := reg +/- imm8*4
547 def addrmode5 : Operand<i32>,
548 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
549 let PrintMethod = "printAddrMode5Operand";
550 let MIOperandInfo = (ops GPR:$base, i32imm);
551 let ParserMatchClass = MemMode5AsmOperand;
552 let EncoderMethod = "getAddrMode5OpValue";
555 // addrmode6 := reg with optional alignment
557 def addrmode6 : Operand<i32>,
558 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
559 let PrintMethod = "printAddrMode6Operand";
560 let MIOperandInfo = (ops GPR:$addr, i32imm);
561 let EncoderMethod = "getAddrMode6AddressOpValue";
564 def am6offset : Operand<i32> {
565 let PrintMethod = "printAddrMode6OffsetOperand";
566 let MIOperandInfo = (ops GPR);
567 let EncoderMethod = "getAddrMode6OffsetOpValue";
570 // Special version of addrmode6 to handle alignment encoding for VLD-dup
571 // instructions, specifically VLD4-dup.
572 def addrmode6dup : Operand<i32>,
573 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
574 let PrintMethod = "printAddrMode6Operand";
575 let MIOperandInfo = (ops GPR:$addr, i32imm);
576 let EncoderMethod = "getAddrMode6DupAddressOpValue";
579 // addrmodepc := pc + reg
581 def addrmodepc : Operand<i32>,
582 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
583 let PrintMethod = "printAddrModePCOperand";
584 let MIOperandInfo = (ops GPR, i32imm);
587 def nohash_imm : Operand<i32> {
588 let PrintMethod = "printNoHashImmediate";
591 def CoprocNumAsmOperand : AsmOperandClass {
592 let Name = "CoprocNum";
593 let SuperClasses = [];
594 let ParserMethod = "tryParseCoprocNumOperand";
597 def CoprocRegAsmOperand : AsmOperandClass {
598 let Name = "CoprocReg";
599 let SuperClasses = [];
600 let ParserMethod = "tryParseCoprocRegOperand";
603 def p_imm : Operand<i32> {
604 let PrintMethod = "printPImmediate";
605 let ParserMatchClass = CoprocNumAsmOperand;
608 def c_imm : Operand<i32> {
609 let PrintMethod = "printCImmediate";
610 let ParserMatchClass = CoprocRegAsmOperand;
613 //===----------------------------------------------------------------------===//
615 include "ARMInstrFormats.td"
617 //===----------------------------------------------------------------------===//
618 // Multiclass helpers...
621 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
622 /// binop that produces a value.
623 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
624 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
625 PatFrag opnode, bit Commutable = 0> {
626 // The register-immediate version is re-materializable. This is useful
627 // in particular for taking the address of a local.
628 let isReMaterializable = 1 in {
629 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
630 iii, opc, "\t$Rd, $Rn, $imm",
631 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
636 let Inst{19-16} = Rn;
637 let Inst{15-12} = Rd;
638 let Inst{11-0} = imm;
641 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
642 iir, opc, "\t$Rd, $Rn, $Rm",
643 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
648 let isCommutable = Commutable;
649 let Inst{19-16} = Rn;
650 let Inst{15-12} = Rd;
651 let Inst{11-4} = 0b00000000;
654 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
655 iis, opc, "\t$Rd, $Rn, $shift",
656 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
661 let Inst{19-16} = Rn;
662 let Inst{15-12} = Rd;
663 let Inst{11-0} = shift;
667 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
668 /// instruction modifies the CPSR register.
669 let isCodeGenOnly = 1, Defs = [CPSR] in {
670 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
671 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
672 PatFrag opnode, bit Commutable = 0> {
673 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
674 iii, opc, "\t$Rd, $Rn, $imm",
675 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
681 let Inst{19-16} = Rn;
682 let Inst{15-12} = Rd;
683 let Inst{11-0} = imm;
685 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
686 iir, opc, "\t$Rd, $Rn, $Rm",
687 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
691 let isCommutable = Commutable;
694 let Inst{19-16} = Rn;
695 let Inst{15-12} = Rd;
696 let Inst{11-4} = 0b00000000;
699 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
700 iis, opc, "\t$Rd, $Rn, $shift",
701 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
707 let Inst{19-16} = Rn;
708 let Inst{15-12} = Rd;
709 let Inst{11-0} = shift;
714 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
715 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
716 /// a explicit result, only implicitly set CPSR.
717 let isCompare = 1, Defs = [CPSR] in {
718 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
719 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
720 PatFrag opnode, bit Commutable = 0> {
721 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
723 [(opnode GPR:$Rn, so_imm:$imm)]> {
728 let Inst{19-16} = Rn;
729 let Inst{15-12} = 0b0000;
730 let Inst{11-0} = imm;
732 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
734 [(opnode GPR:$Rn, GPR:$Rm)]> {
737 let isCommutable = Commutable;
740 let Inst{19-16} = Rn;
741 let Inst{15-12} = 0b0000;
742 let Inst{11-4} = 0b00000000;
745 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
746 opc, "\t$Rn, $shift",
747 [(opnode GPR:$Rn, so_reg:$shift)]> {
752 let Inst{19-16} = Rn;
753 let Inst{15-12} = 0b0000;
754 let Inst{11-0} = shift;
759 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
760 /// register and one whose operand is a register rotated by 8/16/24.
761 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
762 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
763 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
764 IIC_iEXTr, opc, "\t$Rd, $Rm",
765 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
766 Requires<[IsARM, HasV6]> {
769 let Inst{19-16} = 0b1111;
770 let Inst{15-12} = Rd;
771 let Inst{11-10} = 0b00;
774 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
775 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
776 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
777 Requires<[IsARM, HasV6]> {
781 let Inst{19-16} = 0b1111;
782 let Inst{15-12} = Rd;
783 let Inst{11-10} = rot;
788 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
789 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
790 IIC_iEXTr, opc, "\t$Rd, $Rm",
791 [/* For disassembly only; pattern left blank */]>,
792 Requires<[IsARM, HasV6]> {
793 let Inst{19-16} = 0b1111;
794 let Inst{11-10} = 0b00;
796 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
797 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
798 [/* For disassembly only; pattern left blank */]>,
799 Requires<[IsARM, HasV6]> {
801 let Inst{19-16} = 0b1111;
802 let Inst{11-10} = rot;
806 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
807 /// register and one whose operand is a register rotated by 8/16/24.
808 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
809 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
810 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
811 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
812 Requires<[IsARM, HasV6]> {
816 let Inst{19-16} = Rn;
817 let Inst{15-12} = Rd;
818 let Inst{11-10} = 0b00;
819 let Inst{9-4} = 0b000111;
822 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
824 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
825 [(set GPR:$Rd, (opnode GPR:$Rn,
826 (rotr GPR:$Rm, rot_imm:$rot)))]>,
827 Requires<[IsARM, HasV6]> {
832 let Inst{19-16} = Rn;
833 let Inst{15-12} = Rd;
834 let Inst{11-10} = rot;
835 let Inst{9-4} = 0b000111;
840 // For disassembly only.
841 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
842 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
843 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
844 [/* For disassembly only; pattern left blank */]>,
845 Requires<[IsARM, HasV6]> {
846 let Inst{11-10} = 0b00;
848 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
850 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
851 [/* For disassembly only; pattern left blank */]>,
852 Requires<[IsARM, HasV6]> {
855 let Inst{19-16} = Rn;
856 let Inst{11-10} = rot;
860 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
861 let Uses = [CPSR] in {
862 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
863 bit Commutable = 0> {
864 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
865 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
866 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
872 let Inst{15-12} = Rd;
873 let Inst{19-16} = Rn;
874 let Inst{11-0} = imm;
876 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
877 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
878 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
883 let Inst{11-4} = 0b00000000;
885 let isCommutable = Commutable;
887 let Inst{15-12} = Rd;
888 let Inst{19-16} = Rn;
890 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
891 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
892 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
898 let Inst{11-0} = shift;
899 let Inst{15-12} = Rd;
900 let Inst{19-16} = Rn;
903 // Carry setting variants
904 let isCodeGenOnly = 1, Defs = [CPSR] in {
905 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
906 bit Commutable = 0> {
907 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
908 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
909 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
914 let Inst{15-12} = Rd;
915 let Inst{19-16} = Rn;
916 let Inst{11-0} = imm;
920 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
921 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
922 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
927 let Inst{11-4} = 0b00000000;
928 let isCommutable = Commutable;
930 let Inst{15-12} = Rd;
931 let Inst{19-16} = Rn;
935 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
936 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
937 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
942 let Inst{11-0} = shift;
943 let Inst{15-12} = Rd;
944 let Inst{19-16} = Rn;
952 let canFoldAsLoad = 1, isReMaterializable = 1 in {
953 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
954 InstrItinClass iir, PatFrag opnode> {
955 // Note: We use the complex addrmode_imm12 rather than just an input
956 // GPR and a constrained immediate so that we can use this to match
957 // frame index references and avoid matching constant pool references.
958 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
959 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
960 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
963 let Inst{23} = addr{12}; // U (add = ('U' == 1))
964 let Inst{19-16} = addr{16-13}; // Rn
965 let Inst{15-12} = Rt;
966 let Inst{11-0} = addr{11-0}; // imm12
968 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
969 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
970 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
973 let Inst{23} = shift{12}; // U (add = ('U' == 1))
974 let Inst{19-16} = shift{16-13}; // Rn
975 let Inst{15-12} = Rt;
976 let Inst{11-0} = shift{11-0};
981 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
982 InstrItinClass iir, PatFrag opnode> {
983 // Note: We use the complex addrmode_imm12 rather than just an input
984 // GPR and a constrained immediate so that we can use this to match
985 // frame index references and avoid matching constant pool references.
986 def i12 : AI2ldst<0b010, 0, isByte, (outs),
987 (ins GPR:$Rt, addrmode_imm12:$addr),
988 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
989 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
992 let Inst{23} = addr{12}; // U (add = ('U' == 1))
993 let Inst{19-16} = addr{16-13}; // Rn
994 let Inst{15-12} = Rt;
995 let Inst{11-0} = addr{11-0}; // imm12
997 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
998 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
999 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
1002 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1003 let Inst{19-16} = shift{16-13}; // Rn
1004 let Inst{15-12} = Rt;
1005 let Inst{11-0} = shift{11-0};
1008 //===----------------------------------------------------------------------===//
1010 //===----------------------------------------------------------------------===//
1012 //===----------------------------------------------------------------------===//
1013 // Miscellaneous Instructions.
1016 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1017 /// the function. The first operand is the ID# for this instruction, the second
1018 /// is the index into the MachineConstantPool that this is, the third is the
1019 /// size in bytes of this constant pool entry.
1020 let neverHasSideEffects = 1, isNotDuplicable = 1 in
1021 def CONSTPOOL_ENTRY :
1022 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1023 i32imm:$size), NoItinerary, []>;
1025 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
1026 // from removing one half of the matched pairs. That breaks PEI, which assumes
1027 // these will always be in pairs, and asserts if it finds otherwise. Better way?
1028 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1029 def ADJCALLSTACKUP :
1030 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
1031 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
1033 def ADJCALLSTACKDOWN :
1034 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
1035 [(ARMcallseq_start timm:$amt)]>;
1038 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
1039 [/* For disassembly only; pattern left blank */]>,
1040 Requires<[IsARM, HasV6T2]> {
1041 let Inst{27-16} = 0b001100100000;
1042 let Inst{15-8} = 0b11110000;
1043 let Inst{7-0} = 0b00000000;
1046 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1047 [/* For disassembly only; pattern left blank */]>,
1048 Requires<[IsARM, HasV6T2]> {
1049 let Inst{27-16} = 0b001100100000;
1050 let Inst{15-8} = 0b11110000;
1051 let Inst{7-0} = 0b00000001;
1054 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1055 [/* For disassembly only; pattern left blank */]>,
1056 Requires<[IsARM, HasV6T2]> {
1057 let Inst{27-16} = 0b001100100000;
1058 let Inst{15-8} = 0b11110000;
1059 let Inst{7-0} = 0b00000010;
1062 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1063 [/* For disassembly only; pattern left blank */]>,
1064 Requires<[IsARM, HasV6T2]> {
1065 let Inst{27-16} = 0b001100100000;
1066 let Inst{15-8} = 0b11110000;
1067 let Inst{7-0} = 0b00000011;
1070 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1072 [/* For disassembly only; pattern left blank */]>,
1073 Requires<[IsARM, HasV6]> {
1078 let Inst{15-12} = Rd;
1079 let Inst{19-16} = Rn;
1080 let Inst{27-20} = 0b01101000;
1081 let Inst{7-4} = 0b1011;
1082 let Inst{11-8} = 0b1111;
1085 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1086 [/* For disassembly only; pattern left blank */]>,
1087 Requires<[IsARM, HasV6T2]> {
1088 let Inst{27-16} = 0b001100100000;
1089 let Inst{15-8} = 0b11110000;
1090 let Inst{7-0} = 0b00000100;
1093 // The i32imm operand $val can be used by a debugger to store more information
1094 // about the breakpoint.
1095 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1096 [/* For disassembly only; pattern left blank */]>,
1099 let Inst{3-0} = val{3-0};
1100 let Inst{19-8} = val{15-4};
1101 let Inst{27-20} = 0b00010010;
1102 let Inst{7-4} = 0b0111;
1105 // Change Processor State is a system instruction -- for disassembly and
1107 // FIXME: Since the asm parser has currently no clean way to handle optional
1108 // operands, create 3 versions of the same instruction. Once there's a clean
1109 // framework to represent optional operands, change this behavior.
1110 class CPS<dag iops, string asm_ops>
1111 : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
1112 [/* For disassembly only; pattern left blank */]>, Requires<[IsARM]> {
1118 let Inst{31-28} = 0b1111;
1119 let Inst{27-20} = 0b00010000;
1120 let Inst{19-18} = imod;
1121 let Inst{17} = M; // Enabled if mode is set;
1123 let Inst{8-6} = iflags;
1125 let Inst{4-0} = mode;
1129 def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
1130 "$imod\t$iflags, $mode">;
1131 let mode = 0, M = 0 in
1132 def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
1134 let imod = 0, iflags = 0, M = 1 in
1135 def CPS1p : CPS<(ins i32imm:$mode), "\t$mode">;
1137 // Preload signals the memory system of possible future data/instruction access.
1138 // These are for disassembly only.
1139 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1141 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1142 !strconcat(opc, "\t$addr"),
1143 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1146 let Inst{31-26} = 0b111101;
1147 let Inst{25} = 0; // 0 for immediate form
1148 let Inst{24} = data;
1149 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1150 let Inst{22} = read;
1151 let Inst{21-20} = 0b01;
1152 let Inst{19-16} = addr{16-13}; // Rn
1153 let Inst{15-12} = 0b1111;
1154 let Inst{11-0} = addr{11-0}; // imm12
1157 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1158 !strconcat(opc, "\t$shift"),
1159 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1161 let Inst{31-26} = 0b111101;
1162 let Inst{25} = 1; // 1 for register form
1163 let Inst{24} = data;
1164 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1165 let Inst{22} = read;
1166 let Inst{21-20} = 0b01;
1167 let Inst{19-16} = shift{16-13}; // Rn
1168 let Inst{15-12} = 0b1111;
1169 let Inst{11-0} = shift{11-0};
1173 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1174 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1175 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1177 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1179 [/* For disassembly only; pattern left blank */]>,
1182 let Inst{31-10} = 0b1111000100000001000000;
1187 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1188 [/* For disassembly only; pattern left blank */]>,
1189 Requires<[IsARM, HasV7]> {
1191 let Inst{27-4} = 0b001100100000111100001111;
1192 let Inst{3-0} = opt;
1195 // A5.4 Permanently UNDEFINED instructions.
1196 let isBarrier = 1, isTerminator = 1 in
1197 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1200 let Inst = 0xe7ffdefe;
1203 // Address computation and loads and stores in PIC mode.
1204 let isNotDuplicable = 1 in {
1205 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1206 Size4Bytes, IIC_iALUr,
1207 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1209 let AddedComplexity = 10 in {
1210 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1211 Size4Bytes, IIC_iLoad_r,
1212 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1214 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1215 Size4Bytes, IIC_iLoad_bh_r,
1216 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1218 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1219 Size4Bytes, IIC_iLoad_bh_r,
1220 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1222 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1223 Size4Bytes, IIC_iLoad_bh_r,
1224 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1226 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1227 Size4Bytes, IIC_iLoad_bh_r,
1228 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1230 let AddedComplexity = 10 in {
1231 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1232 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1234 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1235 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1236 addrmodepc:$addr)]>;
1238 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1239 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1241 } // isNotDuplicable = 1
1244 // LEApcrel - Load a pc-relative address into a register without offending the
1246 let neverHasSideEffects = 1, isReMaterializable = 1 in
1247 // The 'adr' mnemonic encodes differently if the label is before or after
1248 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1249 // know until then which form of the instruction will be used.
1250 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1251 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1254 let Inst{27-25} = 0b001;
1256 let Inst{19-16} = 0b1111;
1257 let Inst{15-12} = Rd;
1258 let Inst{11-0} = label;
1260 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1261 Size4Bytes, IIC_iALUi, []>;
1263 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1264 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1265 Size4Bytes, IIC_iALUi, []>;
1267 //===----------------------------------------------------------------------===//
1268 // Control Flow Instructions.
1271 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1273 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1274 "bx", "\tlr", [(ARMretflag)]>,
1275 Requires<[IsARM, HasV4T]> {
1276 let Inst{27-0} = 0b0001001011111111111100011110;
1280 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1281 "mov", "\tpc, lr", [(ARMretflag)]>,
1282 Requires<[IsARM, NoV4T]> {
1283 let Inst{27-0} = 0b0001101000001111000000001110;
1287 // Indirect branches
1288 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1290 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1291 [(brind GPR:$dst)]>,
1292 Requires<[IsARM, HasV4T]> {
1294 let Inst{31-4} = 0b1110000100101111111111110001;
1295 let Inst{3-0} = dst;
1299 // FIXME: We would really like to define this as a vanilla ARMPat like:
1300 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1301 // With that, however, we can't set isBranch, isTerminator, etc..
1302 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1303 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1304 Requires<[IsARM, NoV4T]>;
1307 // All calls clobber the non-callee saved registers. SP is marked as
1308 // a use to prevent stack-pointer assignments that appear immediately
1309 // before calls from potentially appearing dead.
1311 // On non-Darwin platforms R9 is callee-saved.
1312 Defs = [R0, R1, R2, R3, R12, LR,
1313 D0, D1, D2, D3, D4, D5, D6, D7,
1314 D16, D17, D18, D19, D20, D21, D22, D23,
1315 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1317 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1318 IIC_Br, "bl\t$func",
1319 [(ARMcall tglobaladdr:$func)]>,
1320 Requires<[IsARM, IsNotDarwin]> {
1321 let Inst{31-28} = 0b1110;
1323 let Inst{23-0} = func;
1326 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
1327 IIC_Br, "bl", "\t$func",
1328 [(ARMcall_pred tglobaladdr:$func)]>,
1329 Requires<[IsARM, IsNotDarwin]> {
1331 let Inst{23-0} = func;
1335 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1336 IIC_Br, "blx\t$func",
1337 [(ARMcall GPR:$func)]>,
1338 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1340 let Inst{31-4} = 0b1110000100101111111111110011;
1341 let Inst{3-0} = func;
1345 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1346 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1347 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1348 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1351 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1352 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1353 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1357 // On Darwin R9 is call-clobbered.
1358 // R7 is marked as a use to prevent frame-pointer assignments from being
1359 // moved above / below calls.
1360 Defs = [R0, R1, R2, R3, R9, R12, LR,
1361 D0, D1, D2, D3, D4, D5, D6, D7,
1362 D16, D17, D18, D19, D20, D21, D22, D23,
1363 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1364 Uses = [R7, SP] in {
1365 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1366 IIC_Br, "bl\t$func",
1367 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1368 let Inst{31-28} = 0b1110;
1370 let Inst{23-0} = func;
1373 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1374 IIC_Br, "bl", "\t$func",
1375 [(ARMcall_pred tglobaladdr:$func)]>,
1376 Requires<[IsARM, IsDarwin]> {
1378 let Inst{23-0} = func;
1382 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1383 IIC_Br, "blx\t$func",
1384 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1386 let Inst{31-4} = 0b1110000100101111111111110011;
1387 let Inst{3-0} = func;
1391 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1392 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1393 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1394 Requires<[IsARM, HasV4T, IsDarwin]>;
1397 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1398 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1399 Requires<[IsARM, NoV4T, IsDarwin]>;
1404 // FIXME: These should probably be xformed into the non-TC versions of the
1405 // instructions as part of MC lowering.
1406 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1407 // Thumb should have its own version since the instruction is actually
1408 // different, even though the mnemonic is the same.
1409 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1411 let Defs = [R0, R1, R2, R3, R9, R12,
1412 D0, D1, D2, D3, D4, D5, D6, D7,
1413 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1414 D27, D28, D29, D30, D31, PC],
1416 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1417 IIC_Br, []>, Requires<[IsDarwin]>;
1419 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1420 IIC_Br, []>, Requires<[IsDarwin]>;
1422 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1423 IIC_Br, "b\t$dst @ TAILCALL",
1424 []>, Requires<[IsARM, IsDarwin]>;
1426 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1427 IIC_Br, "b.w\t$dst @ TAILCALL",
1428 []>, Requires<[IsThumb, IsDarwin]>;
1430 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1431 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1432 []>, Requires<[IsDarwin]> {
1434 let Inst{31-4} = 0b1110000100101111111111110001;
1435 let Inst{3-0} = dst;
1439 // Non-Darwin versions (the difference is R9).
1440 let Defs = [R0, R1, R2, R3, R12,
1441 D0, D1, D2, D3, D4, D5, D6, D7,
1442 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1443 D27, D28, D29, D30, D31, PC],
1445 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1446 IIC_Br, []>, Requires<[IsNotDarwin]>;
1448 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1449 IIC_Br, []>, Requires<[IsNotDarwin]>;
1451 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1452 IIC_Br, "b\t$dst @ TAILCALL",
1453 []>, Requires<[IsARM, IsNotDarwin]>;
1455 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1456 IIC_Br, "b.w\t$dst @ TAILCALL",
1457 []>, Requires<[IsThumb, IsNotDarwin]>;
1459 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1460 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1461 []>, Requires<[IsNotDarwin]> {
1463 let Inst{31-4} = 0b1110000100101111111111110001;
1464 let Inst{3-0} = dst;
1469 let isBranch = 1, isTerminator = 1 in {
1470 // B is "predicable" since it can be xformed into a Bcc.
1471 let isBarrier = 1 in {
1472 let isPredicable = 1 in
1473 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1474 "b\t$target", [(br bb:$target)]> {
1476 let Inst{31-28} = 0b1110;
1477 let Inst{23-0} = target;
1480 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1481 def BR_JTr : ARMPseudoInst<(outs),
1482 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1483 SizeSpecial, IIC_Br,
1484 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1485 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1486 // into i12 and rs suffixed versions.
1487 def BR_JTm : ARMPseudoInst<(outs),
1488 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1489 SizeSpecial, IIC_Br,
1490 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1492 def BR_JTadd : ARMPseudoInst<(outs),
1493 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1494 SizeSpecial, IIC_Br,
1495 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1497 } // isNotDuplicable = 1, isIndirectBranch = 1
1500 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1501 // a two-value operand where a dag node expects two operands. :(
1502 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1503 IIC_Br, "b", "\t$target",
1504 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1506 let Inst{23-0} = target;
1510 // Branch and Exchange Jazelle -- for disassembly only
1511 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1512 [/* For disassembly only; pattern left blank */]> {
1513 let Inst{23-20} = 0b0010;
1514 //let Inst{19-8} = 0xfff;
1515 let Inst{7-4} = 0b0010;
1518 // Secure Monitor Call is a system instruction -- for disassembly only
1519 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1520 [/* For disassembly only; pattern left blank */]> {
1522 let Inst{23-4} = 0b01100000000000000111;
1523 let Inst{3-0} = opt;
1526 // Supervisor Call (Software Interrupt) -- for disassembly only
1527 let isCall = 1, Uses = [SP] in {
1528 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1529 [/* For disassembly only; pattern left blank */]> {
1531 let Inst{23-0} = svc;
1535 // Store Return State is a system instruction -- for disassembly only
1536 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1537 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1538 NoItinerary, "srs${amode}\tsp!, $mode",
1539 [/* For disassembly only; pattern left blank */]> {
1540 let Inst{31-28} = 0b1111;
1541 let Inst{22-20} = 0b110; // W = 1
1544 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1545 NoItinerary, "srs${amode}\tsp, $mode",
1546 [/* For disassembly only; pattern left blank */]> {
1547 let Inst{31-28} = 0b1111;
1548 let Inst{22-20} = 0b100; // W = 0
1551 // Return From Exception is a system instruction -- for disassembly only
1552 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1553 NoItinerary, "rfe${amode}\t$base!",
1554 [/* For disassembly only; pattern left blank */]> {
1555 let Inst{31-28} = 0b1111;
1556 let Inst{22-20} = 0b011; // W = 1
1559 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1560 NoItinerary, "rfe${amode}\t$base",
1561 [/* For disassembly only; pattern left blank */]> {
1562 let Inst{31-28} = 0b1111;
1563 let Inst{22-20} = 0b001; // W = 0
1565 } // isCodeGenOnly = 1
1567 //===----------------------------------------------------------------------===//
1568 // Load / store Instructions.
1574 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1575 UnOpFrag<(load node:$Src)>>;
1576 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1577 UnOpFrag<(zextloadi8 node:$Src)>>;
1578 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1579 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1580 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1581 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1583 // Special LDR for loads from non-pc-relative constpools.
1584 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1585 isReMaterializable = 1 in
1586 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1587 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1591 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1592 let Inst{19-16} = 0b1111;
1593 let Inst{15-12} = Rt;
1594 let Inst{11-0} = addr{11-0}; // imm12
1597 // Loads with zero extension
1598 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1599 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1600 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1602 // Loads with sign extension
1603 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1604 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1605 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1607 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1608 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1609 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1611 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1612 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1613 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1614 // how to represent that such that tblgen is happy and we don't
1615 // mark this codegen only?
1617 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1618 (ins addrmode3:$addr), LdMiscFrm,
1619 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1620 []>, Requires<[IsARM, HasV5TE]>;
1624 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1625 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1626 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1627 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1629 // {13} 1 == Rm, 0 == imm12
1633 let Inst{25} = addr{13};
1634 let Inst{23} = addr{12};
1635 let Inst{19-16} = addr{17-14};
1636 let Inst{11-0} = addr{11-0};
1638 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1639 (ins GPR:$Rn, am2offset:$offset),
1640 IndexModePost, LdFrm, itin,
1641 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1642 // {13} 1 == Rm, 0 == imm12
1647 let Inst{25} = offset{13};
1648 let Inst{23} = offset{12};
1649 let Inst{19-16} = Rn;
1650 let Inst{11-0} = offset{11-0};
1654 let mayLoad = 1, neverHasSideEffects = 1 in {
1655 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1656 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1659 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1660 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1661 (ins addrmode3:$addr), IndexModePre,
1663 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1665 let Inst{23} = addr{8}; // U bit
1666 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1667 let Inst{19-16} = addr{12-9}; // Rn
1668 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1669 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1671 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1672 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1674 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1677 let Inst{23} = offset{8}; // U bit
1678 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1679 let Inst{19-16} = Rn;
1680 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1681 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1685 let mayLoad = 1, neverHasSideEffects = 1 in {
1686 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1687 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1688 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1689 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1690 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1691 } // mayLoad = 1, neverHasSideEffects = 1
1693 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1694 let mayLoad = 1, neverHasSideEffects = 1 in {
1695 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1696 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1697 LdFrm, IIC_iLoad_ru,
1698 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1699 let Inst{21} = 1; // overwrite
1701 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1702 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1703 LdFrm, IIC_iLoad_bh_ru,
1704 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1705 let Inst{21} = 1; // overwrite
1707 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1708 (ins GPR:$base, am3offset:$offset), IndexModePost,
1709 LdMiscFrm, IIC_iLoad_bh_ru,
1710 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1711 let Inst{21} = 1; // overwrite
1713 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1714 (ins GPR:$base, am3offset:$offset), IndexModePost,
1715 LdMiscFrm, IIC_iLoad_bh_ru,
1716 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1717 let Inst{21} = 1; // overwrite
1719 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1720 (ins GPR:$base, am3offset:$offset), IndexModePost,
1721 LdMiscFrm, IIC_iLoad_bh_ru,
1722 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1723 let Inst{21} = 1; // overwrite
1729 // Stores with truncate
1730 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1731 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1732 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1735 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1736 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1737 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1738 StMiscFrm, IIC_iStore_d_r,
1739 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1742 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1743 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1744 IndexModePre, StFrm, IIC_iStore_ru,
1745 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1747 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1749 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1750 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1751 IndexModePost, StFrm, IIC_iStore_ru,
1752 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1754 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1756 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1757 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1758 IndexModePre, StFrm, IIC_iStore_bh_ru,
1759 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1760 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1761 GPR:$Rn, am2offset:$offset))]>;
1762 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1763 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1764 IndexModePost, StFrm, IIC_iStore_bh_ru,
1765 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1766 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1767 GPR:$Rn, am2offset:$offset))]>;
1769 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1770 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1771 IndexModePre, StMiscFrm, IIC_iStore_ru,
1772 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1774 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1776 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1777 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1778 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1779 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1780 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1781 GPR:$Rn, am3offset:$offset))]>;
1783 // For disassembly only
1784 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1785 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1786 StMiscFrm, IIC_iStore_d_ru,
1787 "strd", "\t$src1, $src2, [$base, $offset]!",
1788 "$base = $base_wb", []>;
1790 // For disassembly only
1791 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1792 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1793 StMiscFrm, IIC_iStore_d_ru,
1794 "strd", "\t$src1, $src2, [$base], $offset",
1795 "$base = $base_wb", []>;
1797 // STRT, STRBT, and STRHT are for disassembly only.
1799 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1800 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1801 IndexModeNone, StFrm, IIC_iStore_ru,
1802 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1803 [/* For disassembly only; pattern left blank */]> {
1804 let Inst{21} = 1; // overwrite
1807 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1808 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1809 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1810 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1811 [/* For disassembly only; pattern left blank */]> {
1812 let Inst{21} = 1; // overwrite
1815 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1816 (ins GPR:$src, GPR:$base,am3offset:$offset),
1817 StMiscFrm, IIC_iStore_bh_ru,
1818 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1819 [/* For disassembly only; pattern left blank */]> {
1820 let Inst{21} = 1; // overwrite
1823 //===----------------------------------------------------------------------===//
1824 // Load / store multiple Instructions.
1827 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1828 InstrItinClass itin, InstrItinClass itin_upd> {
1830 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1831 IndexModeNone, f, itin,
1832 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1833 let Inst{24-23} = 0b01; // Increment After
1834 let Inst{21} = 0; // No writeback
1835 let Inst{20} = L_bit;
1838 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1839 IndexModeUpd, f, itin_upd,
1840 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1841 let Inst{24-23} = 0b01; // Increment After
1842 let Inst{21} = 1; // Writeback
1843 let Inst{20} = L_bit;
1846 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1847 IndexModeNone, f, itin,
1848 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1849 let Inst{24-23} = 0b00; // Decrement After
1850 let Inst{21} = 0; // No writeback
1851 let Inst{20} = L_bit;
1854 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1855 IndexModeUpd, f, itin_upd,
1856 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1857 let Inst{24-23} = 0b00; // Decrement After
1858 let Inst{21} = 1; // Writeback
1859 let Inst{20} = L_bit;
1862 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1863 IndexModeNone, f, itin,
1864 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1865 let Inst{24-23} = 0b10; // Decrement Before
1866 let Inst{21} = 0; // No writeback
1867 let Inst{20} = L_bit;
1870 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1871 IndexModeUpd, f, itin_upd,
1872 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1873 let Inst{24-23} = 0b10; // Decrement Before
1874 let Inst{21} = 1; // Writeback
1875 let Inst{20} = L_bit;
1878 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1879 IndexModeNone, f, itin,
1880 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1881 let Inst{24-23} = 0b11; // Increment Before
1882 let Inst{21} = 0; // No writeback
1883 let Inst{20} = L_bit;
1886 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1887 IndexModeUpd, f, itin_upd,
1888 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1889 let Inst{24-23} = 0b11; // Increment Before
1890 let Inst{21} = 1; // Writeback
1891 let Inst{20} = L_bit;
1895 let neverHasSideEffects = 1 in {
1897 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1898 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1900 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1901 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1903 } // neverHasSideEffects
1905 // Load / Store Multiple Mnemonic Aliases
1906 def : MnemonicAlias<"ldm", "ldmia">;
1907 def : MnemonicAlias<"stm", "stmia">;
1909 // FIXME: remove when we have a way to marking a MI with these properties.
1910 // FIXME: Should pc be an implicit operand like PICADD, etc?
1911 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1912 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1913 // FIXME: Should be a pseudo-instruction.
1914 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1915 reglist:$regs, variable_ops),
1916 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1917 "ldmia${p}\t$Rn!, $regs",
1919 let Inst{24-23} = 0b01; // Increment After
1920 let Inst{21} = 1; // Writeback
1921 let Inst{20} = 1; // Load
1924 //===----------------------------------------------------------------------===//
1925 // Move Instructions.
1928 let neverHasSideEffects = 1 in
1929 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1930 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1934 let Inst{11-4} = 0b00000000;
1937 let Inst{15-12} = Rd;
1940 // A version for the smaller set of tail call registers.
1941 let neverHasSideEffects = 1 in
1942 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1943 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1947 let Inst{11-4} = 0b00000000;
1950 let Inst{15-12} = Rd;
1953 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1954 DPSoRegFrm, IIC_iMOVsr,
1955 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1959 let Inst{15-12} = Rd;
1960 let Inst{11-0} = src;
1964 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1965 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1966 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1970 let Inst{15-12} = Rd;
1971 let Inst{19-16} = 0b0000;
1972 let Inst{11-0} = imm;
1975 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1976 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1978 "movw", "\t$Rd, $imm",
1979 [(set GPR:$Rd, imm0_65535:$imm)]>,
1980 Requires<[IsARM, HasV6T2]>, UnaryDP {
1983 let Inst{15-12} = Rd;
1984 let Inst{11-0} = imm{11-0};
1985 let Inst{19-16} = imm{15-12};
1990 def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
1991 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1993 let Constraints = "$src = $Rd" in {
1994 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1996 "movt", "\t$Rd, $imm",
1998 (or (and GPR:$src, 0xffff),
1999 lo16AllZero:$imm))]>, UnaryDP,
2000 Requires<[IsARM, HasV6T2]> {
2003 let Inst{15-12} = Rd;
2004 let Inst{11-0} = imm{11-0};
2005 let Inst{19-16} = imm{15-12};
2010 def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
2011 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
2015 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2016 Requires<[IsARM, HasV6T2]>;
2018 let Uses = [CPSR] in
2019 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2020 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2023 // These aren't really mov instructions, but we have to define them this way
2024 // due to flag operands.
2026 let Defs = [CPSR] in {
2027 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2028 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2030 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2031 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2035 //===----------------------------------------------------------------------===//
2036 // Extend Instructions.
2041 defm SXTB : AI_ext_rrot<0b01101010,
2042 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2043 defm SXTH : AI_ext_rrot<0b01101011,
2044 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2046 defm SXTAB : AI_exta_rrot<0b01101010,
2047 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2048 defm SXTAH : AI_exta_rrot<0b01101011,
2049 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2051 // For disassembly only
2052 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2054 // For disassembly only
2055 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2059 let AddedComplexity = 16 in {
2060 defm UXTB : AI_ext_rrot<0b01101110,
2061 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2062 defm UXTH : AI_ext_rrot<0b01101111,
2063 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2064 defm UXTB16 : AI_ext_rrot<0b01101100,
2065 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2067 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2068 // The transformation should probably be done as a combiner action
2069 // instead so we can include a check for masking back in the upper
2070 // eight bits of the source into the lower eight bits of the result.
2071 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2072 // (UXTB16r_rot GPR:$Src, 24)>;
2073 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2074 (UXTB16r_rot GPR:$Src, 8)>;
2076 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2077 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2078 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2079 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2082 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2083 // For disassembly only
2084 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2087 def SBFX : I<(outs GPR:$Rd),
2088 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2089 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2090 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2091 Requires<[IsARM, HasV6T2]> {
2096 let Inst{27-21} = 0b0111101;
2097 let Inst{6-4} = 0b101;
2098 let Inst{20-16} = width;
2099 let Inst{15-12} = Rd;
2100 let Inst{11-7} = lsb;
2104 def UBFX : I<(outs GPR:$Rd),
2105 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2106 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2107 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2108 Requires<[IsARM, HasV6T2]> {
2113 let Inst{27-21} = 0b0111111;
2114 let Inst{6-4} = 0b101;
2115 let Inst{20-16} = width;
2116 let Inst{15-12} = Rd;
2117 let Inst{11-7} = lsb;
2121 //===----------------------------------------------------------------------===//
2122 // Arithmetic Instructions.
2125 defm ADD : AsI1_bin_irs<0b0100, "add",
2126 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2127 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2128 defm SUB : AsI1_bin_irs<0b0010, "sub",
2129 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2130 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2132 // ADD and SUB with 's' bit set.
2133 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2134 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2135 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2136 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2137 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2138 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2140 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2141 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2142 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2143 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2145 // ADC and SUBC with 's' bit set.
2146 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2147 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2148 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2149 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2151 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2152 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2153 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2158 let Inst{15-12} = Rd;
2159 let Inst{19-16} = Rn;
2160 let Inst{11-0} = imm;
2163 // The reg/reg form is only defined for the disassembler; for codegen it is
2164 // equivalent to SUBrr.
2165 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2166 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2167 [/* For disassembly only; pattern left blank */]> {
2171 let Inst{11-4} = 0b00000000;
2174 let Inst{15-12} = Rd;
2175 let Inst{19-16} = Rn;
2178 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2179 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2180 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2185 let Inst{11-0} = shift;
2186 let Inst{15-12} = Rd;
2187 let Inst{19-16} = Rn;
2190 // RSB with 's' bit set.
2191 let isCodeGenOnly = 1, Defs = [CPSR] in {
2192 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2193 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2194 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2200 let Inst{15-12} = Rd;
2201 let Inst{19-16} = Rn;
2202 let Inst{11-0} = imm;
2204 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2205 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2206 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2212 let Inst{11-0} = shift;
2213 let Inst{15-12} = Rd;
2214 let Inst{19-16} = Rn;
2218 let Uses = [CPSR] in {
2219 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2220 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2221 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2227 let Inst{15-12} = Rd;
2228 let Inst{19-16} = Rn;
2229 let Inst{11-0} = imm;
2231 // The reg/reg form is only defined for the disassembler; for codegen it is
2232 // equivalent to SUBrr.
2233 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2234 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2235 [/* For disassembly only; pattern left blank */]> {
2239 let Inst{11-4} = 0b00000000;
2242 let Inst{15-12} = Rd;
2243 let Inst{19-16} = Rn;
2245 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2246 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2247 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2253 let Inst{11-0} = shift;
2254 let Inst{15-12} = Rd;
2255 let Inst{19-16} = Rn;
2259 // FIXME: Allow these to be predicated.
2260 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2261 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2262 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2263 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2270 let Inst{15-12} = Rd;
2271 let Inst{19-16} = Rn;
2272 let Inst{11-0} = imm;
2274 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2275 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2276 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2283 let Inst{11-0} = shift;
2284 let Inst{15-12} = Rd;
2285 let Inst{19-16} = Rn;
2289 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2290 // The assume-no-carry-in form uses the negation of the input since add/sub
2291 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2292 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2294 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2295 (SUBri GPR:$src, so_imm_neg:$imm)>;
2296 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2297 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2298 // The with-carry-in form matches bitwise not instead of the negation.
2299 // Effectively, the inverse interpretation of the carry flag already accounts
2300 // for part of the negation.
2301 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2302 (SBCri GPR:$src, so_imm_not:$imm)>;
2304 // Note: These are implemented in C++ code, because they have to generate
2305 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2307 // (mul X, 2^n+1) -> (add (X << n), X)
2308 // (mul X, 2^n-1) -> (rsb X, (X << n))
2310 // ARM Arithmetic Instruction -- for disassembly only
2311 // GPR:$dst = GPR:$a op GPR:$b
2312 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2313 list<dag> pattern = [/* For disassembly only; pattern left blank */],
2314 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm">
2315 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> {
2319 let Inst{27-20} = op27_20;
2320 let Inst{11-4} = op11_4;
2321 let Inst{19-16} = Rn;
2322 let Inst{15-12} = Rd;
2326 // Saturating add/subtract -- for disassembly only
2328 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2329 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))],
2330 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2331 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2332 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))],
2333 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">;
2334 def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn),
2336 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn),
2339 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2340 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2341 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2342 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2343 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2344 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2345 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2346 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2347 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2348 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2349 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2350 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2352 // Signed/Unsigned add/subtract -- for disassembly only
2354 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2355 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2356 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2357 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2358 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2359 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2360 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2361 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2362 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2363 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2364 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2365 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2367 // Signed/Unsigned halving add/subtract -- for disassembly only
2369 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2370 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2371 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2372 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2373 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2374 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2375 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2376 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2377 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2378 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2379 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2380 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2382 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2384 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2385 MulFrm /* for convenience */, NoItinerary, "usad8",
2386 "\t$Rd, $Rn, $Rm", []>,
2387 Requires<[IsARM, HasV6]> {
2391 let Inst{27-20} = 0b01111000;
2392 let Inst{15-12} = 0b1111;
2393 let Inst{7-4} = 0b0001;
2394 let Inst{19-16} = Rd;
2395 let Inst{11-8} = Rm;
2398 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2399 MulFrm /* for convenience */, NoItinerary, "usada8",
2400 "\t$Rd, $Rn, $Rm, $Ra", []>,
2401 Requires<[IsARM, HasV6]> {
2406 let Inst{27-20} = 0b01111000;
2407 let Inst{7-4} = 0b0001;
2408 let Inst{19-16} = Rd;
2409 let Inst{15-12} = Ra;
2410 let Inst{11-8} = Rm;
2414 // Signed/Unsigned saturate -- for disassembly only
2416 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2417 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2418 [/* For disassembly only; pattern left blank */]> {
2423 let Inst{27-21} = 0b0110101;
2424 let Inst{5-4} = 0b01;
2425 let Inst{20-16} = sat_imm;
2426 let Inst{15-12} = Rd;
2427 let Inst{11-7} = sh{7-3};
2428 let Inst{6} = sh{0};
2432 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2433 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2434 [/* For disassembly only; pattern left blank */]> {
2438 let Inst{27-20} = 0b01101010;
2439 let Inst{11-4} = 0b11110011;
2440 let Inst{15-12} = Rd;
2441 let Inst{19-16} = sat_imm;
2445 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2446 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2447 [/* For disassembly only; pattern left blank */]> {
2452 let Inst{27-21} = 0b0110111;
2453 let Inst{5-4} = 0b01;
2454 let Inst{15-12} = Rd;
2455 let Inst{11-7} = sh{7-3};
2456 let Inst{6} = sh{0};
2457 let Inst{20-16} = sat_imm;
2461 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2462 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2463 [/* For disassembly only; pattern left blank */]> {
2467 let Inst{27-20} = 0b01101110;
2468 let Inst{11-4} = 0b11110011;
2469 let Inst{15-12} = Rd;
2470 let Inst{19-16} = sat_imm;
2474 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2475 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2477 //===----------------------------------------------------------------------===//
2478 // Bitwise Instructions.
2481 defm AND : AsI1_bin_irs<0b0000, "and",
2482 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2483 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2484 defm ORR : AsI1_bin_irs<0b1100, "orr",
2485 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2486 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2487 defm EOR : AsI1_bin_irs<0b0001, "eor",
2488 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2489 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2490 defm BIC : AsI1_bin_irs<0b1110, "bic",
2491 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2492 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2494 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2495 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2496 "bfc", "\t$Rd, $imm", "$src = $Rd",
2497 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2498 Requires<[IsARM, HasV6T2]> {
2501 let Inst{27-21} = 0b0111110;
2502 let Inst{6-0} = 0b0011111;
2503 let Inst{15-12} = Rd;
2504 let Inst{11-7} = imm{4-0}; // lsb
2505 let Inst{20-16} = imm{9-5}; // width
2508 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2509 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2510 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2511 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2512 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2513 bf_inv_mask_imm:$imm))]>,
2514 Requires<[IsARM, HasV6T2]> {
2518 let Inst{27-21} = 0b0111110;
2519 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2520 let Inst{15-12} = Rd;
2521 let Inst{11-7} = imm{4-0}; // lsb
2522 let Inst{20-16} = imm{9-5}; // width
2526 // GNU as only supports this form of bfi (w/ 4 arguments)
2527 let isAsmParserOnly = 1 in
2528 def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
2529 lsb_pos_imm:$lsb, width_imm:$width),
2530 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2531 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
2532 []>, Requires<[IsARM, HasV6T2]> {
2537 let Inst{27-21} = 0b0111110;
2538 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2539 let Inst{15-12} = Rd;
2540 let Inst{11-7} = lsb;
2541 let Inst{20-16} = width; // Custom encoder => lsb+width-1
2545 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2546 "mvn", "\t$Rd, $Rm",
2547 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2551 let Inst{19-16} = 0b0000;
2552 let Inst{11-4} = 0b00000000;
2553 let Inst{15-12} = Rd;
2556 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2557 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2558 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2562 let Inst{19-16} = 0b0000;
2563 let Inst{15-12} = Rd;
2564 let Inst{11-0} = shift;
2566 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2567 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2568 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2569 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2573 let Inst{19-16} = 0b0000;
2574 let Inst{15-12} = Rd;
2575 let Inst{11-0} = imm;
2578 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2579 (BICri GPR:$src, so_imm_not:$imm)>;
2581 //===----------------------------------------------------------------------===//
2582 // Multiply Instructions.
2584 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2585 string opc, string asm, list<dag> pattern>
2586 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2590 let Inst{19-16} = Rd;
2591 let Inst{11-8} = Rm;
2594 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2595 string opc, string asm, list<dag> pattern>
2596 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2601 let Inst{19-16} = RdHi;
2602 let Inst{15-12} = RdLo;
2603 let Inst{11-8} = Rm;
2607 let isCommutable = 1 in {
2608 let Constraints = "@earlyclobber $Rd" in
2609 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2610 pred:$p, cc_out:$s),
2611 Size4Bytes, IIC_iMUL32,
2612 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2613 Requires<[IsARM, NoV6]>;
2615 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2616 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2617 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2618 Requires<[IsARM, HasV6]>;
2621 let Constraints = "@earlyclobber $Rd" in
2622 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2623 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2624 Size4Bytes, IIC_iMAC32,
2625 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2626 Requires<[IsARM, NoV6]> {
2628 let Inst{15-12} = Ra;
2630 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2631 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2632 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2633 Requires<[IsARM, HasV6]> {
2635 let Inst{15-12} = Ra;
2638 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2639 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2640 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2641 Requires<[IsARM, HasV6T2]> {
2646 let Inst{19-16} = Rd;
2647 let Inst{15-12} = Ra;
2648 let Inst{11-8} = Rm;
2652 // Extra precision multiplies with low / high results
2654 let neverHasSideEffects = 1 in {
2655 let isCommutable = 1 in {
2656 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2657 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2658 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2659 Size4Bytes, IIC_iMUL64, []>,
2660 Requires<[IsARM, NoV6]>;
2662 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2663 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2664 Size4Bytes, IIC_iMUL64, []>,
2665 Requires<[IsARM, NoV6]>;
2668 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2669 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2670 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2671 Requires<[IsARM, HasV6]>;
2673 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2674 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2675 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2676 Requires<[IsARM, HasV6]>;
2679 // Multiply + accumulate
2680 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2681 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2682 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2683 Size4Bytes, IIC_iMAC64, []>,
2684 Requires<[IsARM, NoV6]>;
2685 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2686 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2687 Size4Bytes, IIC_iMAC64, []>,
2688 Requires<[IsARM, NoV6]>;
2689 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2690 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2691 Size4Bytes, IIC_iMAC64, []>,
2692 Requires<[IsARM, NoV6]>;
2696 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2697 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2698 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2699 Requires<[IsARM, HasV6]>;
2700 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2701 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2702 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2703 Requires<[IsARM, HasV6]>;
2705 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2706 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2707 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2708 Requires<[IsARM, HasV6]> {
2713 let Inst{19-16} = RdLo;
2714 let Inst{15-12} = RdHi;
2715 let Inst{11-8} = Rm;
2718 } // neverHasSideEffects
2720 // Most significant word multiply
2721 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2722 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2723 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2724 Requires<[IsARM, HasV6]> {
2725 let Inst{15-12} = 0b1111;
2728 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2729 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2730 [/* For disassembly only; pattern left blank */]>,
2731 Requires<[IsARM, HasV6]> {
2732 let Inst{15-12} = 0b1111;
2735 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2736 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2737 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2738 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2739 Requires<[IsARM, HasV6]>;
2741 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2742 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2743 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2744 [/* For disassembly only; pattern left blank */]>,
2745 Requires<[IsARM, HasV6]>;
2747 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2748 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2749 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2750 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2751 Requires<[IsARM, HasV6]>;
2753 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2754 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2755 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2756 [/* For disassembly only; pattern left blank */]>,
2757 Requires<[IsARM, HasV6]>;
2759 multiclass AI_smul<string opc, PatFrag opnode> {
2760 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2761 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2762 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2763 (sext_inreg GPR:$Rm, i16)))]>,
2764 Requires<[IsARM, HasV5TE]>;
2766 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2767 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2768 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2769 (sra GPR:$Rm, (i32 16))))]>,
2770 Requires<[IsARM, HasV5TE]>;
2772 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2773 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2774 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2775 (sext_inreg GPR:$Rm, i16)))]>,
2776 Requires<[IsARM, HasV5TE]>;
2778 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2779 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2780 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2781 (sra GPR:$Rm, (i32 16))))]>,
2782 Requires<[IsARM, HasV5TE]>;
2784 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2785 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2786 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2787 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2788 Requires<[IsARM, HasV5TE]>;
2790 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2791 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2792 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2793 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2794 Requires<[IsARM, HasV5TE]>;
2798 multiclass AI_smla<string opc, PatFrag opnode> {
2799 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2800 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2801 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2802 [(set GPR:$Rd, (add GPR:$Ra,
2803 (opnode (sext_inreg GPR:$Rn, i16),
2804 (sext_inreg GPR:$Rm, i16))))]>,
2805 Requires<[IsARM, HasV5TE]>;
2807 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2808 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2809 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2810 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2811 (sra GPR:$Rm, (i32 16)))))]>,
2812 Requires<[IsARM, HasV5TE]>;
2814 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2815 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2816 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2817 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2818 (sext_inreg GPR:$Rm, i16))))]>,
2819 Requires<[IsARM, HasV5TE]>;
2821 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2822 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2823 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2824 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2825 (sra GPR:$Rm, (i32 16)))))]>,
2826 Requires<[IsARM, HasV5TE]>;
2828 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2829 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2830 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2831 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2832 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2833 Requires<[IsARM, HasV5TE]>;
2835 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2836 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2837 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2838 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2839 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2840 Requires<[IsARM, HasV5TE]>;
2843 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2844 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2846 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2847 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2848 (ins GPR:$Rn, GPR:$Rm),
2849 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2850 [/* For disassembly only; pattern left blank */]>,
2851 Requires<[IsARM, HasV5TE]>;
2853 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2854 (ins GPR:$Rn, GPR:$Rm),
2855 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2856 [/* For disassembly only; pattern left blank */]>,
2857 Requires<[IsARM, HasV5TE]>;
2859 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2860 (ins GPR:$Rn, GPR:$Rm),
2861 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2862 [/* For disassembly only; pattern left blank */]>,
2863 Requires<[IsARM, HasV5TE]>;
2865 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2866 (ins GPR:$Rn, GPR:$Rm),
2867 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2868 [/* For disassembly only; pattern left blank */]>,
2869 Requires<[IsARM, HasV5TE]>;
2871 // Helper class for AI_smld -- for disassembly only
2872 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2873 InstrItinClass itin, string opc, string asm>
2874 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2881 let Inst{21-20} = 0b00;
2882 let Inst{22} = long;
2883 let Inst{27-23} = 0b01110;
2884 let Inst{11-8} = Rm;
2887 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2888 InstrItinClass itin, string opc, string asm>
2889 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2891 let Inst{15-12} = 0b1111;
2892 let Inst{19-16} = Rd;
2894 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2895 InstrItinClass itin, string opc, string asm>
2896 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2898 let Inst{15-12} = Ra;
2900 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2901 InstrItinClass itin, string opc, string asm>
2902 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2905 let Inst{19-16} = RdHi;
2906 let Inst{15-12} = RdLo;
2909 multiclass AI_smld<bit sub, string opc> {
2911 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2912 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2914 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2915 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2917 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2918 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2919 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2921 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2922 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2923 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2927 defm SMLA : AI_smld<0, "smla">;
2928 defm SMLS : AI_smld<1, "smls">;
2930 multiclass AI_sdml<bit sub, string opc> {
2932 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2933 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2934 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2935 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2938 defm SMUA : AI_sdml<0, "smua">;
2939 defm SMUS : AI_sdml<1, "smus">;
2941 //===----------------------------------------------------------------------===//
2942 // Misc. Arithmetic Instructions.
2945 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2946 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2947 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2949 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2950 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2951 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2952 Requires<[IsARM, HasV6T2]>;
2954 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2955 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2956 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2958 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2959 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2961 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2962 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2963 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2964 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2965 Requires<[IsARM, HasV6]>;
2967 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2968 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2971 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2972 (shl GPR:$Rm, (i32 8))), i16))]>,
2973 Requires<[IsARM, HasV6]>;
2975 def lsl_shift_imm : SDNodeXForm<imm, [{
2976 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2977 return CurDAG->getTargetConstant(Sh, MVT::i32);
2980 def lsl_amt : PatLeaf<(i32 imm), [{
2981 return (N->getZExtValue() < 32);
2984 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2985 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2986 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2987 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2988 (and (shl GPR:$Rm, lsl_amt:$sh),
2990 Requires<[IsARM, HasV6]>;
2992 // Alternate cases for PKHBT where identities eliminate some nodes.
2993 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2994 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2995 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2996 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2998 def asr_shift_imm : SDNodeXForm<imm, [{
2999 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
3000 return CurDAG->getTargetConstant(Sh, MVT::i32);
3003 def asr_amt : PatLeaf<(i32 imm), [{
3004 return (N->getZExtValue() <= 32);
3007 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3008 // will match the pattern below.
3009 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
3010 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
3011 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3012 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
3013 (and (sra GPR:$Rm, asr_amt:$sh),
3015 Requires<[IsARM, HasV6]>;
3017 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
3018 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
3019 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
3020 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
3021 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
3022 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
3023 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
3025 //===----------------------------------------------------------------------===//
3026 // Comparison Instructions...
3029 defm CMP : AI1_cmp_irs<0b1010, "cmp",
3030 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3031 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
3033 // ARMcmpZ can re-use the above instruction definitions.
3034 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
3035 (CMPri GPR:$src, so_imm:$imm)>;
3036 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
3037 (CMPrr GPR:$src, GPR:$rhs)>;
3038 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
3039 (CMPrs GPR:$src, so_reg:$rhs)>;
3041 // FIXME: We have to be careful when using the CMN instruction and comparison
3042 // with 0. One would expect these two pieces of code should give identical
3058 // However, the CMN gives the *opposite* result when r1 is 0. This is because
3059 // the carry flag is set in the CMP case but not in the CMN case. In short, the
3060 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
3061 // value of r0 and the carry bit (because the "carry bit" parameter to
3062 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
3063 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
3064 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
3065 // parameter to AddWithCarry is defined as 0).
3067 // When x is 0 and unsigned:
3071 // ~x + 1 = 0x1 0000 0000
3072 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
3074 // Therefore, we should disable CMN when comparing against zero, until we can
3075 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
3076 // when it's a comparison which doesn't look at the 'carry' flag).
3078 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
3080 // This is related to <rdar://problem/7569620>.
3082 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
3083 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3085 // Note that TST/TEQ don't set all the same flags that CMP does!
3086 defm TST : AI1_cmp_irs<0b1000, "tst",
3087 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3088 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3089 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3090 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3091 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3093 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3094 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3095 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3097 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3098 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3100 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3101 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3103 // Pseudo i64 compares for some floating point compares.
3104 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3106 def BCCi64 : PseudoInst<(outs),
3107 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3109 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3111 def BCCZi64 : PseudoInst<(outs),
3112 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3113 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3114 } // usesCustomInserter
3117 // Conditional moves
3118 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3119 // a two-value operand where a dag node expects two operands. :(
3120 // FIXME: These should all be pseudo-instructions that get expanded to
3121 // the normal MOV instructions. That would fix the dependency on
3122 // special casing them in tblgen.
3123 let neverHasSideEffects = 1 in {
3124 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3125 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3126 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3127 RegConstraint<"$false = $Rd">, UnaryDP {
3132 let Inst{15-12} = Rd;
3133 let Inst{11-4} = 0b00000000;
3137 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3138 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3139 "mov", "\t$Rd, $shift",
3140 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3141 RegConstraint<"$false = $Rd">, UnaryDP {
3146 let Inst{19-16} = 0;
3147 let Inst{15-12} = Rd;
3148 let Inst{11-0} = shift;
3151 let isMoveImm = 1 in
3152 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3154 "movw", "\t$Rd, $imm",
3156 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3162 let Inst{19-16} = imm{15-12};
3163 let Inst{15-12} = Rd;
3164 let Inst{11-0} = imm{11-0};
3167 let isMoveImm = 1 in
3168 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3169 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3170 "mov", "\t$Rd, $imm",
3171 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3172 RegConstraint<"$false = $Rd">, UnaryDP {
3177 let Inst{19-16} = 0b0000;
3178 let Inst{15-12} = Rd;
3179 let Inst{11-0} = imm;
3182 // Two instruction predicate mov immediate.
3183 let isMoveImm = 1 in
3184 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3185 (ins GPR:$false, i32imm:$src, pred:$p),
3186 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3188 let isMoveImm = 1 in
3189 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3190 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3191 "mvn", "\t$Rd, $imm",
3192 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3193 RegConstraint<"$false = $Rd">, UnaryDP {
3198 let Inst{19-16} = 0b0000;
3199 let Inst{15-12} = Rd;
3200 let Inst{11-0} = imm;
3202 } // neverHasSideEffects
3204 //===----------------------------------------------------------------------===//
3205 // Atomic operations intrinsics
3208 def memb_opt : Operand<i32> {
3209 let PrintMethod = "printMemBOption";
3210 let ParserMatchClass = MemBarrierOptOperand;
3213 // memory barriers protect the atomic sequences
3214 let hasSideEffects = 1 in {
3215 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3216 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3217 Requires<[IsARM, HasDB]> {
3219 let Inst{31-4} = 0xf57ff05;
3220 let Inst{3-0} = opt;
3223 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3224 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3225 [(ARMMemBarrierMCR GPR:$zero)]>,
3226 Requires<[IsARM, HasV6]> {
3227 // FIXME: add encoding
3231 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3233 [/* For disassembly only; pattern left blank */]>,
3234 Requires<[IsARM, HasDB]> {
3236 let Inst{31-4} = 0xf57ff04;
3237 let Inst{3-0} = opt;
3240 // ISB has only full system option -- for disassembly only
3241 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3242 Requires<[IsARM, HasDB]> {
3243 let Inst{31-4} = 0xf57ff06;
3244 let Inst{3-0} = 0b1111;
3247 let usesCustomInserter = 1 in {
3248 let Uses = [CPSR] in {
3249 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3250 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3251 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3252 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3253 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3254 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3255 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3256 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3257 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3258 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3259 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3260 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3261 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3262 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3263 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3264 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3265 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3266 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3267 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3268 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3269 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3270 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3271 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3272 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3273 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3274 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3275 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3276 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3277 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3278 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3279 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3280 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3281 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3282 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3283 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3284 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3285 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3286 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3287 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3288 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3289 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3290 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3291 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3292 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3293 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3294 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3295 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3296 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3297 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3298 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3299 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3300 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3301 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3302 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3304 def ATOMIC_SWAP_I8 : PseudoInst<
3305 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3306 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3307 def ATOMIC_SWAP_I16 : PseudoInst<
3308 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3309 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3310 def ATOMIC_SWAP_I32 : PseudoInst<
3311 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3312 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3314 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3315 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3316 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3317 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3318 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3319 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3320 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3321 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3322 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3326 let mayLoad = 1 in {
3327 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3328 "ldrexb", "\t$Rt, [$Rn]",
3330 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3331 "ldrexh", "\t$Rt, [$Rn]",
3333 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3334 "ldrex", "\t$Rt, [$Rn]",
3336 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3338 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3342 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3343 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3345 "strexb", "\t$Rd, $src, [$Rn]",
3347 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3349 "strexh", "\t$Rd, $Rt, [$Rn]",
3351 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3353 "strex", "\t$Rd, $Rt, [$Rn]",
3355 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3356 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3358 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3362 // Clear-Exclusive is for disassembly only.
3363 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3364 [/* For disassembly only; pattern left blank */]>,
3365 Requires<[IsARM, HasV7]> {
3366 let Inst{31-0} = 0b11110101011111111111000000011111;
3369 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3370 let mayLoad = 1 in {
3371 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3372 [/* For disassembly only; pattern left blank */]>;
3373 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3374 [/* For disassembly only; pattern left blank */]>;
3377 //===----------------------------------------------------------------------===//
3381 // __aeabi_read_tp preserves the registers r1-r3.
3382 // This is a pseudo inst so that we can get the encoding right,
3383 // complete with fixup for the aeabi_read_tp function.
3385 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3386 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3387 [(set R0, ARMthread_pointer)]>;
3390 //===----------------------------------------------------------------------===//
3391 // SJLJ Exception handling intrinsics
3392 // eh_sjlj_setjmp() is an instruction sequence to store the return
3393 // address and save #0 in R0 for the non-longjmp case.
3394 // Since by its nature we may be coming from some other function to get
3395 // here, and we're using the stack frame for the containing function to
3396 // save/restore registers, we can't keep anything live in regs across
3397 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3398 // when we get here from a longjmp(). We force everthing out of registers
3399 // except for our own input by listing the relevant registers in Defs. By
3400 // doing so, we also cause the prologue/epilogue code to actively preserve
3401 // all of the callee-saved resgisters, which is exactly what we want.
3402 // A constant value is passed in $val, and we use the location as a scratch.
3404 // These are pseudo-instructions and are lowered to individual MC-insts, so
3405 // no encoding information is necessary.
3407 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3408 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3409 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3410 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3411 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3413 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3414 Requires<[IsARM, HasVFP2]>;
3418 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3419 hasSideEffects = 1, isBarrier = 1 in {
3420 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3422 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3423 Requires<[IsARM, NoVFP]>;
3426 // FIXME: Non-Darwin version(s)
3427 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3428 Defs = [ R7, LR, SP ] in {
3429 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3431 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3432 Requires<[IsARM, IsDarwin]>;
3435 // eh.sjlj.dispatchsetup pseudo-instruction.
3436 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3437 // handled when the pseudo is expanded (which happens before any passes
3438 // that need the instruction size).
3439 let isBarrier = 1, hasSideEffects = 1 in
3440 def Int_eh_sjlj_dispatchsetup :
3441 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3442 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3443 Requires<[IsDarwin]>;
3445 //===----------------------------------------------------------------------===//
3446 // Non-Instruction Patterns
3449 // Large immediate handling.
3451 // 32-bit immediate using two piece so_imms or movw + movt.
3452 // This is a single pseudo instruction, the benefit is that it can be remat'd
3453 // as a single unit instead of having to handle reg inputs.
3454 // FIXME: Remove this when we can do generalized remat.
3455 let isReMaterializable = 1, isMoveImm = 1 in
3456 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3457 [(set GPR:$dst, (arm_i32imm:$src))]>,
3460 // Pseudo instruction that combines movw + movt + add pc (if PIC).
3461 // It also makes it possible to rematerialize the instructions.
3462 // FIXME: Remove this when we can do generalized remat and when machine licm
3463 // can properly the instructions.
3464 let isReMaterializable = 1 in {
3465 def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3467 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3468 Requires<[IsARM, UseMovt]>;
3470 def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3472 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
3473 Requires<[IsARM, UseMovt]>;
3475 let AddedComplexity = 10 in
3476 def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
3478 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
3479 Requires<[IsARM, UseMovt]>;
3480 } // isReMaterializable
3482 // ConstantPool, GlobalAddress, and JumpTable
3483 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3484 Requires<[IsARM, DontUseMovt]>;
3485 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3486 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3487 Requires<[IsARM, UseMovt]>;
3488 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3489 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3491 // TODO: add,sub,and, 3-instr forms?
3494 def : ARMPat<(ARMtcret tcGPR:$dst),
3495 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3497 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3498 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3500 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3501 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3503 def : ARMPat<(ARMtcret tcGPR:$dst),
3504 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3506 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3507 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3509 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3510 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3513 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3514 Requires<[IsARM, IsNotDarwin]>;
3515 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3516 Requires<[IsARM, IsDarwin]>;
3518 // zextload i1 -> zextload i8
3519 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3520 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3522 // extload -> zextload
3523 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3524 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3525 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3526 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3528 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3530 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3531 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3534 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3535 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3536 (SMULBB GPR:$a, GPR:$b)>;
3537 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3538 (SMULBB GPR:$a, GPR:$b)>;
3539 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3540 (sra GPR:$b, (i32 16))),
3541 (SMULBT GPR:$a, GPR:$b)>;
3542 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3543 (SMULBT GPR:$a, GPR:$b)>;
3544 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3545 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3546 (SMULTB GPR:$a, GPR:$b)>;
3547 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3548 (SMULTB GPR:$a, GPR:$b)>;
3549 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3551 (SMULWB GPR:$a, GPR:$b)>;
3552 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3553 (SMULWB GPR:$a, GPR:$b)>;
3555 def : ARMV5TEPat<(add GPR:$acc,
3556 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3557 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3558 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3559 def : ARMV5TEPat<(add GPR:$acc,
3560 (mul sext_16_node:$a, sext_16_node:$b)),
3561 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3562 def : ARMV5TEPat<(add GPR:$acc,
3563 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3564 (sra GPR:$b, (i32 16)))),
3565 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3566 def : ARMV5TEPat<(add GPR:$acc,
3567 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3568 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3569 def : ARMV5TEPat<(add GPR:$acc,
3570 (mul (sra GPR:$a, (i32 16)),
3571 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3572 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3573 def : ARMV5TEPat<(add GPR:$acc,
3574 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3575 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3576 def : ARMV5TEPat<(add GPR:$acc,
3577 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3579 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3580 def : ARMV5TEPat<(add GPR:$acc,
3581 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3582 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3584 //===----------------------------------------------------------------------===//
3588 include "ARMInstrThumb.td"
3590 //===----------------------------------------------------------------------===//
3594 include "ARMInstrThumb2.td"
3596 //===----------------------------------------------------------------------===//
3597 // Floating Point Support
3600 include "ARMInstrVFP.td"
3602 //===----------------------------------------------------------------------===//
3603 // Advanced SIMD (NEON) Support
3606 include "ARMInstrNEON.td"
3608 //===----------------------------------------------------------------------===//
3609 // Coprocessor Instructions. For disassembly only.
3612 def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3613 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3614 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3615 [/* For disassembly only; pattern left blank */]> {
3623 let Inst{3-0} = CRm;
3625 let Inst{7-5} = opc2;
3626 let Inst{11-8} = cop;
3627 let Inst{15-12} = CRd;
3628 let Inst{19-16} = CRn;
3629 let Inst{23-20} = opc1;
3632 def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3633 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3634 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
3635 [/* For disassembly only; pattern left blank */]> {
3636 let Inst{31-28} = 0b1111;
3644 let Inst{3-0} = CRm;
3646 let Inst{7-5} = opc2;
3647 let Inst{11-8} = cop;
3648 let Inst{15-12} = CRd;
3649 let Inst{19-16} = CRn;
3650 let Inst{23-20} = opc1;
3653 class ACI<dag oops, dag iops, string opc, string asm>
3654 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3655 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3656 let Inst{27-25} = 0b110;
3659 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3661 def _OFFSET : ACI<(outs),
3662 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3663 opc, "\tp$cop, cr$CRd, $addr"> {
3664 let Inst{31-28} = op31_28;
3665 let Inst{24} = 1; // P = 1
3666 let Inst{21} = 0; // W = 0
3667 let Inst{22} = 0; // D = 0
3668 let Inst{20} = load;
3671 def _PRE : ACI<(outs),
3672 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3673 opc, "\tp$cop, cr$CRd, $addr!"> {
3674 let Inst{31-28} = op31_28;
3675 let Inst{24} = 1; // P = 1
3676 let Inst{21} = 1; // W = 1
3677 let Inst{22} = 0; // D = 0
3678 let Inst{20} = load;
3681 def _POST : ACI<(outs),
3682 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3683 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3684 let Inst{31-28} = op31_28;
3685 let Inst{24} = 0; // P = 0
3686 let Inst{21} = 1; // W = 1
3687 let Inst{22} = 0; // D = 0
3688 let Inst{20} = load;
3691 def _OPTION : ACI<(outs),
3692 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3693 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3694 let Inst{31-28} = op31_28;
3695 let Inst{24} = 0; // P = 0
3696 let Inst{23} = 1; // U = 1
3697 let Inst{21} = 0; // W = 0
3698 let Inst{22} = 0; // D = 0
3699 let Inst{20} = load;
3702 def L_OFFSET : ACI<(outs),
3703 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3704 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3705 let Inst{31-28} = op31_28;
3706 let Inst{24} = 1; // P = 1
3707 let Inst{21} = 0; // W = 0
3708 let Inst{22} = 1; // D = 1
3709 let Inst{20} = load;
3712 def L_PRE : ACI<(outs),
3713 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3714 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3715 let Inst{31-28} = op31_28;
3716 let Inst{24} = 1; // P = 1
3717 let Inst{21} = 1; // W = 1
3718 let Inst{22} = 1; // D = 1
3719 let Inst{20} = load;
3722 def L_POST : ACI<(outs),
3723 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3724 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3725 let Inst{31-28} = op31_28;
3726 let Inst{24} = 0; // P = 0
3727 let Inst{21} = 1; // W = 1
3728 let Inst{22} = 1; // D = 1
3729 let Inst{20} = load;
3732 def L_OPTION : ACI<(outs),
3733 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3734 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3735 let Inst{31-28} = op31_28;
3736 let Inst{24} = 0; // P = 0
3737 let Inst{23} = 1; // U = 1
3738 let Inst{21} = 0; // W = 0
3739 let Inst{22} = 1; // D = 1
3740 let Inst{20} = load;
3744 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3745 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3746 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3747 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3749 //===----------------------------------------------------------------------===//
3750 // Move between coprocessor and ARM core register -- for disassembly only
3753 class MovRCopro<string opc, bit direction>
3754 : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3755 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3756 NoItinerary, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3757 [/* For disassembly only; pattern left blank */]> {
3758 let Inst{20} = direction;
3768 let Inst{15-12} = Rt;
3769 let Inst{11-8} = cop;
3770 let Inst{23-21} = opc1;
3771 let Inst{7-5} = opc2;
3772 let Inst{3-0} = CRm;
3773 let Inst{19-16} = CRn;
3776 def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */>;
3777 def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */>;
3779 class MovRCopro2<string opc, bit direction>
3780 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3781 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3782 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
3783 [/* For disassembly only; pattern left blank */]> {
3784 let Inst{31-28} = 0b1111;
3785 let Inst{20} = direction;
3795 let Inst{15-12} = Rt;
3796 let Inst{11-8} = cop;
3797 let Inst{23-21} = opc1;
3798 let Inst{7-5} = opc2;
3799 let Inst{3-0} = CRm;
3800 let Inst{19-16} = CRn;
3803 def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */>;
3804 def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */>;
3806 class MovRRCopro<string opc, bit direction>
3807 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3808 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3809 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
3810 [/* For disassembly only; pattern left blank */]> {
3811 let Inst{23-21} = 0b010;
3812 let Inst{20} = direction;
3820 let Inst{15-12} = Rt;
3821 let Inst{19-16} = Rt2;
3822 let Inst{11-8} = cop;
3823 let Inst{7-4} = opc1;
3824 let Inst{3-0} = CRm;
3827 def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
3828 def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
3830 class MovRRCopro2<string opc, bit direction>
3831 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
3832 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3833 NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
3834 [/* For disassembly only; pattern left blank */]> {
3835 let Inst{31-28} = 0b1111;
3836 let Inst{23-21} = 0b010;
3837 let Inst{20} = direction;
3845 let Inst{15-12} = Rt;
3846 let Inst{19-16} = Rt2;
3847 let Inst{11-8} = cop;
3848 let Inst{7-4} = opc1;
3849 let Inst{3-0} = CRm;
3852 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
3853 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
3855 //===----------------------------------------------------------------------===//
3856 // Move between special register and ARM core register -- for disassembly only
3859 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
3860 [/* For disassembly only; pattern left blank */]> {
3862 let Inst{23-16} = 0b00001111;
3863 let Inst{15-12} = Rd;
3864 let Inst{7-4} = 0b0000;
3867 def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr",
3868 [/* For disassembly only; pattern left blank */]> {
3870 let Inst{23-16} = 0b01001111;
3871 let Inst{15-12} = Rd;
3872 let Inst{7-4} = 0b0000;
3875 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3876 "msr", "\tcpsr$mask, $src",
3877 [/* For disassembly only; pattern left blank */]> {
3878 let Inst{23-20} = 0b0010;
3879 let Inst{7-4} = 0b0000;
3882 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3883 "msr", "\tcpsr$mask, $a",
3884 [/* For disassembly only; pattern left blank */]> {
3885 let Inst{23-20} = 0b0010;
3886 let Inst{7-4} = 0b0000;
3889 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3890 "msr", "\tspsr$mask, $src",
3891 [/* For disassembly only; pattern left blank */]> {
3892 let Inst{23-20} = 0b0110;
3893 let Inst{7-4} = 0b0000;
3896 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3897 "msr", "\tspsr$mask, $a",
3898 [/* For disassembly only; pattern left blank */]> {
3899 let Inst{23-20} = 0b0110;
3900 let Inst{7-4} = 0b0000;