1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
74 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
75 [SDNPHasChain, SDNPOutGlue]>;
76 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
77 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
79 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
80 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
82 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
85 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
89 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
90 [SDNPHasChain, SDNPOptInGlue]>;
92 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
94 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
97 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
98 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
100 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
102 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
105 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
108 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
111 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
112 [SDNPOutGlue, SDNPCommutative]>;
114 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
117 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
118 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
120 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
121 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
122 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
123 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
124 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
126 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
129 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
131 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
133 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
134 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
136 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
138 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
139 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
142 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
144 //===----------------------------------------------------------------------===//
145 // ARM Instruction Predicate Definitions.
147 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
148 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
149 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
150 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
151 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
152 def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
153 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
154 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
155 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
156 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
157 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
158 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
159 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
160 def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate;
161 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
162 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
164 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
166 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
168 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
169 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
170 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
171 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
172 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
173 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
174 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
175 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
177 // FIXME: Eventually this will be just "hasV6T2Ops".
178 def UseMovt : Predicate<"Subtarget->useMovt()">;
179 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
180 def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">;
182 //===----------------------------------------------------------------------===//
183 // ARM Flag Definitions.
185 class RegConstraint<string C> {
186 string Constraints = C;
189 //===----------------------------------------------------------------------===//
190 // ARM specific transformation functions and pattern fragments.
193 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
194 // so_imm_neg def below.
195 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
196 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
199 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
200 // so_imm_not def below.
201 def so_imm_not_XFORM : SDNodeXForm<imm, [{
202 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
205 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
206 def imm1_15 : PatLeaf<(i32 imm), [{
207 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
210 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
211 def imm16_31 : PatLeaf<(i32 imm), [{
212 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
217 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
218 }], so_imm_neg_XFORM>;
222 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
223 }], so_imm_not_XFORM>;
225 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
226 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
227 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
230 /// Split a 32-bit immediate into two 16 bit parts.
231 def hi16 : SDNodeXForm<imm, [{
232 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
235 def lo16AllZero : PatLeaf<(i32 imm), [{
236 // Returns true if all low 16-bits are 0.
237 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
240 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
242 def imm0_65535 : PatLeaf<(i32 imm), [{
243 return (uint32_t)N->getZExtValue() < 65536;
246 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
247 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
249 /// adde and sube predicates - True based on whether the carry flag output
250 /// will be needed or not.
251 def adde_dead_carry :
252 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
253 [{return !N->hasAnyUseOfValue(1);}]>;
254 def sube_dead_carry :
255 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
256 [{return !N->hasAnyUseOfValue(1);}]>;
257 def adde_live_carry :
258 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
259 [{return N->hasAnyUseOfValue(1);}]>;
260 def sube_live_carry :
261 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
262 [{return N->hasAnyUseOfValue(1);}]>;
264 // An 'and' node with a single use.
265 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
266 return N->hasOneUse();
269 // An 'xor' node with a single use.
270 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
271 return N->hasOneUse();
274 // An 'fmul' node with a single use.
275 def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
276 return N->hasOneUse();
279 // An 'fadd' node which checks for single non-hazardous use.
280 def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
281 return hasNoVMLxHazardUse(N);
284 // An 'fsub' node which checks for single non-hazardous use.
285 def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
286 return hasNoVMLxHazardUse(N);
289 //===----------------------------------------------------------------------===//
290 // Operand Definitions.
294 def brtarget : Operand<OtherVT> {
295 let EncoderMethod = "getBranchTargetOpValue";
298 def uncondbrtarget : Operand<OtherVT> {
299 let EncoderMethod = "getUnconditionalBranchTargetOpValue";
303 def bltarget : Operand<i32> {
304 // Encoded the same as branch targets.
305 let EncoderMethod = "getBranchTargetOpValue";
308 // A list of registers separated by comma. Used by load/store multiple.
309 def RegListAsmOperand : AsmOperandClass {
310 let Name = "RegList";
311 let SuperClasses = [];
314 def DPRRegListAsmOperand : AsmOperandClass {
315 let Name = "DPRRegList";
316 let SuperClasses = [];
319 def SPRRegListAsmOperand : AsmOperandClass {
320 let Name = "SPRRegList";
321 let SuperClasses = [];
324 def reglist : Operand<i32> {
325 let EncoderMethod = "getRegisterListOpValue";
326 let ParserMatchClass = RegListAsmOperand;
327 let PrintMethod = "printRegisterList";
330 def dpr_reglist : Operand<i32> {
331 let EncoderMethod = "getRegisterListOpValue";
332 let ParserMatchClass = DPRRegListAsmOperand;
333 let PrintMethod = "printRegisterList";
336 def spr_reglist : Operand<i32> {
337 let EncoderMethod = "getRegisterListOpValue";
338 let ParserMatchClass = SPRRegListAsmOperand;
339 let PrintMethod = "printRegisterList";
342 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
343 def cpinst_operand : Operand<i32> {
344 let PrintMethod = "printCPInstOperand";
348 def pclabel : Operand<i32> {
349 let PrintMethod = "printPCLabel";
352 // ADR instruction labels.
353 def adrlabel : Operand<i32> {
354 let EncoderMethod = "getAdrLabelOpValue";
357 def neon_vcvt_imm32 : Operand<i32> {
358 let EncoderMethod = "getNEONVcvtImm32OpValue";
361 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
362 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
363 int32_t v = (int32_t)N->getZExtValue();
364 return v == 8 || v == 16 || v == 24; }]> {
365 let EncoderMethod = "getRotImmOpValue";
368 // shift_imm: An integer that encodes a shift amount and the type of shift
369 // (currently either asr or lsl) using the same encoding used for the
370 // immediates in so_reg operands.
371 def shift_imm : Operand<i32> {
372 let PrintMethod = "printShiftImmOperand";
375 // shifter_operand operands: so_reg and so_imm.
376 def so_reg : Operand<i32>, // reg reg imm
377 ComplexPattern<i32, 3, "SelectShifterOperandReg",
378 [shl,srl,sra,rotr]> {
379 let EncoderMethod = "getSORegOpValue";
380 let PrintMethod = "printSORegOperand";
381 let MIOperandInfo = (ops GPR, GPR, i32imm);
383 def shift_so_reg : Operand<i32>, // reg reg imm
384 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
385 [shl,srl,sra,rotr]> {
386 let EncoderMethod = "getSORegOpValue";
387 let PrintMethod = "printSORegOperand";
388 let MIOperandInfo = (ops GPR, GPR, i32imm);
391 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
392 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
393 // represented in the imm field in the same 12-bit form that they are encoded
394 // into so_imm instructions: the 8-bit immediate is the least significant bits
395 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
396 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
397 let EncoderMethod = "getSOImmOpValue";
398 let PrintMethod = "printSOImmOperand";
401 // Break so_imm's up into two pieces. This handles immediates with up to 16
402 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
403 // get the first/second pieces.
404 def so_imm2part : PatLeaf<(imm), [{
405 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
408 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
410 def arm_i32imm : PatLeaf<(imm), [{
411 if (Subtarget->hasV6T2Ops())
413 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
416 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
417 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
418 return (int32_t)N->getZExtValue() < 32;
421 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
422 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
423 return (int32_t)N->getZExtValue() < 32;
425 let EncoderMethod = "getImmMinusOneOpValue";
428 // i32imm_hilo16 - For movt/movw - sets the MC Encoder method.
429 // The imm is split into imm{15-12}, imm{11-0}
431 def i32imm_hilo16 : Operand<i32> {
432 let EncoderMethod = "getHiLo16ImmOpValue";
435 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
437 def bf_inv_mask_imm : Operand<i32>,
439 return ARM::isBitFieldInvertedMask(N->getZExtValue());
441 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
442 let PrintMethod = "printBitfieldInvMaskImmOperand";
445 // Define ARM specific addressing modes.
448 // addrmode_imm12 := reg +/- imm12
450 def addrmode_imm12 : Operand<i32>,
451 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
452 // 12-bit immediate operand. Note that instructions using this encode
453 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
454 // immediate values are as normal.
456 let EncoderMethod = "getAddrModeImm12OpValue";
457 let PrintMethod = "printAddrModeImm12Operand";
458 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
460 // ldst_so_reg := reg +/- reg shop imm
462 def ldst_so_reg : Operand<i32>,
463 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
464 let EncoderMethod = "getLdStSORegOpValue";
465 // FIXME: Simplify the printer
466 let PrintMethod = "printAddrMode2Operand";
467 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
470 // addrmode2 := reg +/- imm12
471 // := reg +/- reg shop imm
473 def addrmode2 : Operand<i32>,
474 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
475 let EncoderMethod = "getAddrMode2OpValue";
476 let PrintMethod = "printAddrMode2Operand";
477 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
480 def am2offset : Operand<i32>,
481 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
482 [], [SDNPWantRoot]> {
483 let EncoderMethod = "getAddrMode2OffsetOpValue";
484 let PrintMethod = "printAddrMode2OffsetOperand";
485 let MIOperandInfo = (ops GPR, i32imm);
488 // addrmode3 := reg +/- reg
489 // addrmode3 := reg +/- imm8
491 def addrmode3 : Operand<i32>,
492 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
493 let EncoderMethod = "getAddrMode3OpValue";
494 let PrintMethod = "printAddrMode3Operand";
495 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
498 def am3offset : Operand<i32>,
499 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
500 [], [SDNPWantRoot]> {
501 let EncoderMethod = "getAddrMode3OffsetOpValue";
502 let PrintMethod = "printAddrMode3OffsetOperand";
503 let MIOperandInfo = (ops GPR, i32imm);
506 // ldstm_mode := {ia, ib, da, db}
508 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
509 let EncoderMethod = "getLdStmModeOpValue";
510 let PrintMethod = "printLdStmModeOperand";
513 def MemMode5AsmOperand : AsmOperandClass {
514 let Name = "MemMode5";
515 let SuperClasses = [];
518 // addrmode5 := reg +/- imm8*4
520 def addrmode5 : Operand<i32>,
521 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
522 let PrintMethod = "printAddrMode5Operand";
523 let MIOperandInfo = (ops GPR:$base, i32imm);
524 let ParserMatchClass = MemMode5AsmOperand;
525 let EncoderMethod = "getAddrMode5OpValue";
528 // addrmode6 := reg with optional writeback
530 def addrmode6 : Operand<i32>,
531 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
532 let PrintMethod = "printAddrMode6Operand";
533 let MIOperandInfo = (ops GPR:$addr, i32imm);
534 let EncoderMethod = "getAddrMode6AddressOpValue";
537 def am6offset : Operand<i32> {
538 let PrintMethod = "printAddrMode6OffsetOperand";
539 let MIOperandInfo = (ops GPR);
540 let EncoderMethod = "getAddrMode6OffsetOpValue";
543 // Special version of addrmode6 to handle alignment encoding for VLD-dup
544 // instructions, specifically VLD4-dup.
545 def addrmode6dup : Operand<i32>,
546 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
547 let PrintMethod = "printAddrMode6Operand";
548 let MIOperandInfo = (ops GPR:$addr, i32imm);
549 let EncoderMethod = "getAddrMode6DupAddressOpValue";
552 // addrmodepc := pc + reg
554 def addrmodepc : Operand<i32>,
555 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
556 let PrintMethod = "printAddrModePCOperand";
557 let MIOperandInfo = (ops GPR, i32imm);
560 def nohash_imm : Operand<i32> {
561 let PrintMethod = "printNoHashImmediate";
564 def p_imm : Operand<i32> {
565 let PrintMethod = "printPImmediate";
568 def c_imm : Operand<i32> {
569 let PrintMethod = "printCImmediate";
572 //===----------------------------------------------------------------------===//
574 include "ARMInstrFormats.td"
576 //===----------------------------------------------------------------------===//
577 // Multiclass helpers...
580 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
581 /// binop that produces a value.
582 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
583 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
584 PatFrag opnode, bit Commutable = 0> {
585 // The register-immediate version is re-materializable. This is useful
586 // in particular for taking the address of a local.
587 let isReMaterializable = 1 in {
588 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
589 iii, opc, "\t$Rd, $Rn, $imm",
590 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
595 let Inst{19-16} = Rn;
596 let Inst{15-12} = Rd;
597 let Inst{11-0} = imm;
600 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
601 iir, opc, "\t$Rd, $Rn, $Rm",
602 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
607 let isCommutable = Commutable;
608 let Inst{19-16} = Rn;
609 let Inst{15-12} = Rd;
610 let Inst{11-4} = 0b00000000;
613 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
614 iis, opc, "\t$Rd, $Rn, $shift",
615 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
620 let Inst{19-16} = Rn;
621 let Inst{15-12} = Rd;
622 let Inst{11-0} = shift;
626 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
627 /// instruction modifies the CPSR register.
628 let isCodeGenOnly = 1, Defs = [CPSR] in {
629 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
630 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
631 PatFrag opnode, bit Commutable = 0> {
632 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
633 iii, opc, "\t$Rd, $Rn, $imm",
634 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
640 let Inst{19-16} = Rn;
641 let Inst{15-12} = Rd;
642 let Inst{11-0} = imm;
644 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
645 iir, opc, "\t$Rd, $Rn, $Rm",
646 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
650 let isCommutable = Commutable;
653 let Inst{19-16} = Rn;
654 let Inst{15-12} = Rd;
655 let Inst{11-4} = 0b00000000;
658 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
659 iis, opc, "\t$Rd, $Rn, $shift",
660 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
666 let Inst{19-16} = Rn;
667 let Inst{15-12} = Rd;
668 let Inst{11-0} = shift;
673 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
674 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
675 /// a explicit result, only implicitly set CPSR.
676 let isCompare = 1, Defs = [CPSR] in {
677 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
678 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
679 PatFrag opnode, bit Commutable = 0> {
680 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
682 [(opnode GPR:$Rn, so_imm:$imm)]> {
687 let Inst{19-16} = Rn;
688 let Inst{15-12} = 0b0000;
689 let Inst{11-0} = imm;
691 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
693 [(opnode GPR:$Rn, GPR:$Rm)]> {
696 let isCommutable = Commutable;
699 let Inst{19-16} = Rn;
700 let Inst{15-12} = 0b0000;
701 let Inst{11-4} = 0b00000000;
704 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
705 opc, "\t$Rn, $shift",
706 [(opnode GPR:$Rn, so_reg:$shift)]> {
711 let Inst{19-16} = Rn;
712 let Inst{15-12} = 0b0000;
713 let Inst{11-0} = shift;
718 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
719 /// register and one whose operand is a register rotated by 8/16/24.
720 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
721 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
722 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
723 IIC_iEXTr, opc, "\t$Rd, $Rm",
724 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
725 Requires<[IsARM, HasV6]> {
728 let Inst{19-16} = 0b1111;
729 let Inst{15-12} = Rd;
730 let Inst{11-10} = 0b00;
733 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
734 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
735 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
736 Requires<[IsARM, HasV6]> {
740 let Inst{19-16} = 0b1111;
741 let Inst{15-12} = Rd;
742 let Inst{11-10} = rot;
747 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
748 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
749 IIC_iEXTr, opc, "\t$Rd, $Rm",
750 [/* For disassembly only; pattern left blank */]>,
751 Requires<[IsARM, HasV6]> {
752 let Inst{19-16} = 0b1111;
753 let Inst{11-10} = 0b00;
755 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
756 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
757 [/* For disassembly only; pattern left blank */]>,
758 Requires<[IsARM, HasV6]> {
760 let Inst{19-16} = 0b1111;
761 let Inst{11-10} = rot;
765 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
766 /// register and one whose operand is a register rotated by 8/16/24.
767 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
768 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
769 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
770 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
771 Requires<[IsARM, HasV6]> {
775 let Inst{19-16} = Rn;
776 let Inst{15-12} = Rd;
777 let Inst{11-10} = 0b00;
778 let Inst{9-4} = 0b000111;
781 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
783 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
784 [(set GPR:$Rd, (opnode GPR:$Rn,
785 (rotr GPR:$Rm, rot_imm:$rot)))]>,
786 Requires<[IsARM, HasV6]> {
791 let Inst{19-16} = Rn;
792 let Inst{15-12} = Rd;
793 let Inst{11-10} = rot;
794 let Inst{9-4} = 0b000111;
799 // For disassembly only.
800 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
801 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
802 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
803 [/* For disassembly only; pattern left blank */]>,
804 Requires<[IsARM, HasV6]> {
805 let Inst{11-10} = 0b00;
807 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
809 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
810 [/* For disassembly only; pattern left blank */]>,
811 Requires<[IsARM, HasV6]> {
814 let Inst{19-16} = Rn;
815 let Inst{11-10} = rot;
819 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
820 let Uses = [CPSR] in {
821 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
822 bit Commutable = 0> {
823 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
824 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
825 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
831 let Inst{15-12} = Rd;
832 let Inst{19-16} = Rn;
833 let Inst{11-0} = imm;
835 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
836 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
837 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
842 let Inst{11-4} = 0b00000000;
844 let isCommutable = Commutable;
846 let Inst{15-12} = Rd;
847 let Inst{19-16} = Rn;
849 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
850 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
851 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
857 let Inst{11-0} = shift;
858 let Inst{15-12} = Rd;
859 let Inst{19-16} = Rn;
862 // Carry setting variants
863 let isCodeGenOnly = 1, Defs = [CPSR] in {
864 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
865 bit Commutable = 0> {
866 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
867 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
868 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
873 let Inst{15-12} = Rd;
874 let Inst{19-16} = Rn;
875 let Inst{11-0} = imm;
879 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
880 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
881 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
886 let Inst{11-4} = 0b00000000;
887 let isCommutable = Commutable;
889 let Inst{15-12} = Rd;
890 let Inst{19-16} = Rn;
894 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
895 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
896 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
901 let Inst{11-0} = shift;
902 let Inst{15-12} = Rd;
903 let Inst{19-16} = Rn;
911 let canFoldAsLoad = 1, isReMaterializable = 1 in {
912 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
913 InstrItinClass iir, PatFrag opnode> {
914 // Note: We use the complex addrmode_imm12 rather than just an input
915 // GPR and a constrained immediate so that we can use this to match
916 // frame index references and avoid matching constant pool references.
917 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
918 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
919 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
922 let Inst{23} = addr{12}; // U (add = ('U' == 1))
923 let Inst{19-16} = addr{16-13}; // Rn
924 let Inst{15-12} = Rt;
925 let Inst{11-0} = addr{11-0}; // imm12
927 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
928 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
929 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
932 let Inst{23} = shift{12}; // U (add = ('U' == 1))
933 let Inst{19-16} = shift{16-13}; // Rn
934 let Inst{15-12} = Rt;
935 let Inst{11-0} = shift{11-0};
940 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
941 InstrItinClass iir, PatFrag opnode> {
942 // Note: We use the complex addrmode_imm12 rather than just an input
943 // GPR and a constrained immediate so that we can use this to match
944 // frame index references and avoid matching constant pool references.
945 def i12 : AI2ldst<0b010, 0, isByte, (outs),
946 (ins GPR:$Rt, addrmode_imm12:$addr),
947 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
948 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
951 let Inst{23} = addr{12}; // U (add = ('U' == 1))
952 let Inst{19-16} = addr{16-13}; // Rn
953 let Inst{15-12} = Rt;
954 let Inst{11-0} = addr{11-0}; // imm12
956 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
957 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
958 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
961 let Inst{23} = shift{12}; // U (add = ('U' == 1))
962 let Inst{19-16} = shift{16-13}; // Rn
963 let Inst{15-12} = Rt;
964 let Inst{11-0} = shift{11-0};
967 //===----------------------------------------------------------------------===//
969 //===----------------------------------------------------------------------===//
971 //===----------------------------------------------------------------------===//
972 // Miscellaneous Instructions.
975 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
976 /// the function. The first operand is the ID# for this instruction, the second
977 /// is the index into the MachineConstantPool that this is, the third is the
978 /// size in bytes of this constant pool entry.
979 let neverHasSideEffects = 1, isNotDuplicable = 1 in
980 def CONSTPOOL_ENTRY :
981 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
982 i32imm:$size), NoItinerary, []>;
984 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
985 // from removing one half of the matched pairs. That breaks PEI, which assumes
986 // these will always be in pairs, and asserts if it finds otherwise. Better way?
987 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
989 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
990 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
992 def ADJCALLSTACKDOWN :
993 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
994 [(ARMcallseq_start timm:$amt)]>;
997 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
998 [/* For disassembly only; pattern left blank */]>,
999 Requires<[IsARM, HasV6T2]> {
1000 let Inst{27-16} = 0b001100100000;
1001 let Inst{15-8} = 0b11110000;
1002 let Inst{7-0} = 0b00000000;
1005 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
1006 [/* For disassembly only; pattern left blank */]>,
1007 Requires<[IsARM, HasV6T2]> {
1008 let Inst{27-16} = 0b001100100000;
1009 let Inst{15-8} = 0b11110000;
1010 let Inst{7-0} = 0b00000001;
1013 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1014 [/* For disassembly only; pattern left blank */]>,
1015 Requires<[IsARM, HasV6T2]> {
1016 let Inst{27-16} = 0b001100100000;
1017 let Inst{15-8} = 0b11110000;
1018 let Inst{7-0} = 0b00000010;
1021 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1022 [/* For disassembly only; pattern left blank */]>,
1023 Requires<[IsARM, HasV6T2]> {
1024 let Inst{27-16} = 0b001100100000;
1025 let Inst{15-8} = 0b11110000;
1026 let Inst{7-0} = 0b00000011;
1029 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1031 [/* For disassembly only; pattern left blank */]>,
1032 Requires<[IsARM, HasV6]> {
1037 let Inst{15-12} = Rd;
1038 let Inst{19-16} = Rn;
1039 let Inst{27-20} = 0b01101000;
1040 let Inst{7-4} = 0b1011;
1041 let Inst{11-8} = 0b1111;
1044 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1045 [/* For disassembly only; pattern left blank */]>,
1046 Requires<[IsARM, HasV6T2]> {
1047 let Inst{27-16} = 0b001100100000;
1048 let Inst{15-8} = 0b11110000;
1049 let Inst{7-0} = 0b00000100;
1052 // The i32imm operand $val can be used by a debugger to store more information
1053 // about the breakpoint.
1054 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1055 [/* For disassembly only; pattern left blank */]>,
1058 let Inst{3-0} = val{3-0};
1059 let Inst{19-8} = val{15-4};
1060 let Inst{27-20} = 0b00010010;
1061 let Inst{7-4} = 0b0111;
1064 // Change Processor State is a system instruction -- for disassembly only.
1065 // The singleton $opt operand contains the following information:
1066 // opt{4-0} = mode from Inst{4-0}
1067 // opt{5} = changemode from Inst{17}
1068 // opt{8-6} = AIF from Inst{8-6}
1069 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1070 // FIXME: Integrated assembler will need these split out.
1071 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1072 [/* For disassembly only; pattern left blank */]>,
1074 let Inst{31-28} = 0b1111;
1075 let Inst{27-20} = 0b00010000;
1080 // Preload signals the memory system of possible future data/instruction access.
1081 // These are for disassembly only.
1082 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1084 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1085 !strconcat(opc, "\t$addr"),
1086 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1089 let Inst{31-26} = 0b111101;
1090 let Inst{25} = 0; // 0 for immediate form
1091 let Inst{24} = data;
1092 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1093 let Inst{22} = read;
1094 let Inst{21-20} = 0b01;
1095 let Inst{19-16} = addr{16-13}; // Rn
1096 let Inst{15-12} = Rt;
1097 let Inst{11-0} = addr{11-0}; // imm12
1100 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1101 !strconcat(opc, "\t$shift"),
1102 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1105 let Inst{31-26} = 0b111101;
1106 let Inst{25} = 1; // 1 for register form
1107 let Inst{24} = data;
1108 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1109 let Inst{22} = read;
1110 let Inst{21-20} = 0b01;
1111 let Inst{19-16} = shift{16-13}; // Rn
1112 let Inst{11-0} = shift{11-0};
1116 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1117 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1118 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1120 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1122 [/* For disassembly only; pattern left blank */]>,
1125 let Inst{31-10} = 0b1111000100000001000000;
1130 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1131 [/* For disassembly only; pattern left blank */]>,
1132 Requires<[IsARM, HasV7]> {
1134 let Inst{27-4} = 0b001100100000111100001111;
1135 let Inst{3-0} = opt;
1138 // A5.4 Permanently UNDEFINED instructions.
1139 let isBarrier = 1, isTerminator = 1 in
1140 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1143 let Inst = 0xe7ffdefe;
1146 // Address computation and loads and stores in PIC mode.
1147 let isNotDuplicable = 1 in {
1148 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1149 Size4Bytes, IIC_iALUr,
1150 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1152 let AddedComplexity = 10 in {
1153 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1154 Size4Bytes, IIC_iLoad_r,
1155 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1157 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1158 Size4Bytes, IIC_iLoad_bh_r,
1159 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1161 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1162 Size4Bytes, IIC_iLoad_bh_r,
1163 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1165 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1166 Size4Bytes, IIC_iLoad_bh_r,
1167 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1169 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1170 Size4Bytes, IIC_iLoad_bh_r,
1171 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1173 let AddedComplexity = 10 in {
1174 def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1175 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
1177 def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1178 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
1179 addrmodepc:$addr)]>;
1181 def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1182 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1184 } // isNotDuplicable = 1
1187 // LEApcrel - Load a pc-relative address into a register without offending the
1189 let neverHasSideEffects = 1, isReMaterializable = 1 in
1190 // The 'adr' mnemonic encodes differently if the label is before or after
1191 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
1192 // know until then which form of the instruction will be used.
1193 def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
1194 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
1197 let Inst{27-25} = 0b001;
1199 let Inst{19-16} = 0b1111;
1200 let Inst{15-12} = Rd;
1201 let Inst{11-0} = label;
1203 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1204 Size4Bytes, IIC_iALUi, []>;
1206 def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
1207 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1208 Size4Bytes, IIC_iALUi, []>;
1210 //===----------------------------------------------------------------------===//
1211 // Control Flow Instructions.
1214 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1216 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1217 "bx", "\tlr", [(ARMretflag)]>,
1218 Requires<[IsARM, HasV4T]> {
1219 let Inst{27-0} = 0b0001001011111111111100011110;
1223 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1224 "mov", "\tpc, lr", [(ARMretflag)]>,
1225 Requires<[IsARM, NoV4T]> {
1226 let Inst{27-0} = 0b0001101000001111000000001110;
1230 // Indirect branches
1231 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1233 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1234 [(brind GPR:$dst)]>,
1235 Requires<[IsARM, HasV4T]> {
1237 let Inst{31-4} = 0b1110000100101111111111110001;
1238 let Inst{3-0} = dst;
1242 // FIXME: We would really like to define this as a vanilla ARMPat like:
1243 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1244 // With that, however, we can't set isBranch, isTerminator, etc..
1245 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1246 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1247 Requires<[IsARM, NoV4T]>;
1250 // All calls clobber the non-callee saved registers. SP is marked as
1251 // a use to prevent stack-pointer assignments that appear immediately
1252 // before calls from potentially appearing dead.
1254 // On non-Darwin platforms R9 is callee-saved.
1255 Defs = [R0, R1, R2, R3, R12, LR,
1256 D0, D1, D2, D3, D4, D5, D6, D7,
1257 D16, D17, D18, D19, D20, D21, D22, D23,
1258 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1260 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1261 IIC_Br, "bl\t$func",
1262 [(ARMcall tglobaladdr:$func)]>,
1263 Requires<[IsARM, IsNotDarwin]> {
1264 let Inst{31-28} = 0b1110;
1266 let Inst{23-0} = func;
1269 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1270 IIC_Br, "bl", "\t$func",
1271 [(ARMcall_pred tglobaladdr:$func)]>,
1272 Requires<[IsARM, IsNotDarwin]> {
1274 let Inst{23-0} = func;
1278 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1279 IIC_Br, "blx\t$func",
1280 [(ARMcall GPR:$func)]>,
1281 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1283 let Inst{31-4} = 0b1110000100101111111111110011;
1284 let Inst{3-0} = func;
1288 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1289 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1290 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1291 Requires<[IsARM, HasV4T, IsNotDarwin]>;
1294 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1295 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1296 Requires<[IsARM, NoV4T, IsNotDarwin]>;
1300 // On Darwin R9 is call-clobbered.
1301 // R7 is marked as a use to prevent frame-pointer assignments from being
1302 // moved above / below calls.
1303 Defs = [R0, R1, R2, R3, R9, R12, LR,
1304 D0, D1, D2, D3, D4, D5, D6, D7,
1305 D16, D17, D18, D19, D20, D21, D22, D23,
1306 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
1307 Uses = [R7, SP] in {
1308 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1309 IIC_Br, "bl\t$func",
1310 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1311 let Inst{31-28} = 0b1110;
1313 let Inst{23-0} = func;
1316 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1317 IIC_Br, "bl", "\t$func",
1318 [(ARMcall_pred tglobaladdr:$func)]>,
1319 Requires<[IsARM, IsDarwin]> {
1321 let Inst{23-0} = func;
1325 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1326 IIC_Br, "blx\t$func",
1327 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1329 let Inst{31-4} = 0b1110000100101111111111110011;
1330 let Inst{3-0} = func;
1334 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1335 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1336 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1337 Requires<[IsARM, HasV4T, IsDarwin]>;
1340 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops),
1341 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
1342 Requires<[IsARM, NoV4T, IsDarwin]>;
1347 // FIXME: These should probably be xformed into the non-TC versions of the
1348 // instructions as part of MC lowering.
1349 // FIXME: These seem to be used for both Thumb and ARM instruction selection.
1350 // Thumb should have its own version since the instruction is actually
1351 // different, even though the mnemonic is the same.
1352 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1354 let Defs = [R0, R1, R2, R3, R9, R12,
1355 D0, D1, D2, D3, D4, D5, D6, D7,
1356 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1357 D27, D28, D29, D30, D31, PC],
1359 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1360 IIC_Br, []>, Requires<[IsDarwin]>;
1362 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1363 IIC_Br, []>, Requires<[IsDarwin]>;
1365 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1366 IIC_Br, "b\t$dst @ TAILCALL",
1367 []>, Requires<[IsARM, IsDarwin]>;
1369 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1370 IIC_Br, "b.w\t$dst @ TAILCALL",
1371 []>, Requires<[IsThumb, IsDarwin]>;
1373 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1374 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1375 []>, Requires<[IsDarwin]> {
1377 let Inst{31-4} = 0b1110000100101111111111110001;
1378 let Inst{3-0} = dst;
1382 // Non-Darwin versions (the difference is R9).
1383 let Defs = [R0, R1, R2, R3, R12,
1384 D0, D1, D2, D3, D4, D5, D6, D7,
1385 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1386 D27, D28, D29, D30, D31, PC],
1388 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
1389 IIC_Br, []>, Requires<[IsNotDarwin]>;
1391 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
1392 IIC_Br, []>, Requires<[IsNotDarwin]>;
1394 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1395 IIC_Br, "b\t$dst @ TAILCALL",
1396 []>, Requires<[IsARM, IsNotDarwin]>;
1398 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1399 IIC_Br, "b.w\t$dst @ TAILCALL",
1400 []>, Requires<[IsThumb, IsNotDarwin]>;
1402 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1403 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1404 []>, Requires<[IsNotDarwin]> {
1406 let Inst{31-4} = 0b1110000100101111111111110001;
1407 let Inst{3-0} = dst;
1412 let isBranch = 1, isTerminator = 1 in {
1413 // B is "predicable" since it can be xformed into a Bcc.
1414 let isBarrier = 1 in {
1415 let isPredicable = 1 in
1416 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1417 "b\t$target", [(br bb:$target)]> {
1419 let Inst{31-28} = 0b1110;
1420 let Inst{23-0} = target;
1423 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1424 def BR_JTr : ARMPseudoInst<(outs),
1425 (ins GPR:$target, i32imm:$jt, i32imm:$id),
1426 SizeSpecial, IIC_Br,
1427 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
1428 // FIXME: This shouldn't use the generic "addrmode2," but rather be split
1429 // into i12 and rs suffixed versions.
1430 def BR_JTm : ARMPseudoInst<(outs),
1431 (ins addrmode2:$target, i32imm:$jt, i32imm:$id),
1432 SizeSpecial, IIC_Br,
1433 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1435 def BR_JTadd : ARMPseudoInst<(outs),
1436 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id),
1437 SizeSpecial, IIC_Br,
1438 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1440 } // isNotDuplicable = 1, isIndirectBranch = 1
1443 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1444 // a two-value operand where a dag node expects two operands. :(
1445 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1446 IIC_Br, "b", "\t$target",
1447 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1449 let Inst{23-0} = target;
1453 // Branch and Exchange Jazelle -- for disassembly only
1454 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1455 [/* For disassembly only; pattern left blank */]> {
1456 let Inst{23-20} = 0b0010;
1457 //let Inst{19-8} = 0xfff;
1458 let Inst{7-4} = 0b0010;
1461 // Secure Monitor Call is a system instruction -- for disassembly only
1462 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1463 [/* For disassembly only; pattern left blank */]> {
1465 let Inst{23-4} = 0b01100000000000000111;
1466 let Inst{3-0} = opt;
1469 // Supervisor Call (Software Interrupt) -- for disassembly only
1470 let isCall = 1, Uses = [SP] in {
1471 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1472 [/* For disassembly only; pattern left blank */]> {
1474 let Inst{23-0} = svc;
1478 // Store Return State is a system instruction -- for disassembly only
1479 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1480 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1481 NoItinerary, "srs${amode}\tsp!, $mode",
1482 [/* For disassembly only; pattern left blank */]> {
1483 let Inst{31-28} = 0b1111;
1484 let Inst{22-20} = 0b110; // W = 1
1487 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1488 NoItinerary, "srs${amode}\tsp, $mode",
1489 [/* For disassembly only; pattern left blank */]> {
1490 let Inst{31-28} = 0b1111;
1491 let Inst{22-20} = 0b100; // W = 0
1494 // Return From Exception is a system instruction -- for disassembly only
1495 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1496 NoItinerary, "rfe${amode}\t$base!",
1497 [/* For disassembly only; pattern left blank */]> {
1498 let Inst{31-28} = 0b1111;
1499 let Inst{22-20} = 0b011; // W = 1
1502 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1503 NoItinerary, "rfe${amode}\t$base",
1504 [/* For disassembly only; pattern left blank */]> {
1505 let Inst{31-28} = 0b1111;
1506 let Inst{22-20} = 0b001; // W = 0
1508 } // isCodeGenOnly = 1
1510 //===----------------------------------------------------------------------===//
1511 // Load / store Instructions.
1517 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1518 UnOpFrag<(load node:$Src)>>;
1519 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1520 UnOpFrag<(zextloadi8 node:$Src)>>;
1521 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1522 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1523 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1524 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1526 // Special LDR for loads from non-pc-relative constpools.
1527 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1528 isReMaterializable = 1 in
1529 def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1530 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1534 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1535 let Inst{19-16} = 0b1111;
1536 let Inst{15-12} = Rt;
1537 let Inst{11-0} = addr{11-0}; // imm12
1540 // Loads with zero extension
1541 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1542 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1543 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1545 // Loads with sign extension
1546 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1547 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1548 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1550 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1551 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1552 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1554 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1555 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1556 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1557 // how to represent that such that tblgen is happy and we don't
1558 // mark this codegen only?
1560 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1561 (ins addrmode3:$addr), LdMiscFrm,
1562 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1563 []>, Requires<[IsARM, HasV5TE]>;
1567 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1568 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1569 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1570 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1572 // {13} 1 == Rm, 0 == imm12
1576 let Inst{25} = addr{13};
1577 let Inst{23} = addr{12};
1578 let Inst{19-16} = addr{17-14};
1579 let Inst{11-0} = addr{11-0};
1581 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1582 (ins GPR:$Rn, am2offset:$offset),
1583 IndexModePost, LdFrm, itin,
1584 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1585 // {13} 1 == Rm, 0 == imm12
1590 let Inst{25} = offset{13};
1591 let Inst{23} = offset{12};
1592 let Inst{19-16} = Rn;
1593 let Inst{11-0} = offset{11-0};
1597 let mayLoad = 1, neverHasSideEffects = 1 in {
1598 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1599 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1602 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1603 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1604 (ins addrmode3:$addr), IndexModePre,
1606 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1608 let Inst{23} = addr{8}; // U bit
1609 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1610 let Inst{19-16} = addr{12-9}; // Rn
1611 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1612 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1614 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1615 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1617 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1620 let Inst{23} = offset{8}; // U bit
1621 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
1622 let Inst{19-16} = Rn;
1623 let Inst{11-8} = offset{7-4}; // imm7_4/zero
1624 let Inst{3-0} = offset{3-0}; // imm3_0/Rm
1628 let mayLoad = 1, neverHasSideEffects = 1 in {
1629 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1630 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1631 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1632 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1633 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1634 } // mayLoad = 1, neverHasSideEffects = 1
1636 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1637 let mayLoad = 1, neverHasSideEffects = 1 in {
1638 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1639 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1640 LdFrm, IIC_iLoad_ru,
1641 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1642 let Inst{21} = 1; // overwrite
1644 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1645 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1646 LdFrm, IIC_iLoad_bh_ru,
1647 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1648 let Inst{21} = 1; // overwrite
1650 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1651 (ins GPR:$base, am3offset:$offset), IndexModePost,
1652 LdMiscFrm, IIC_iLoad_bh_ru,
1653 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1654 let Inst{21} = 1; // overwrite
1656 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1657 (ins GPR:$base, am3offset:$offset), IndexModePost,
1658 LdMiscFrm, IIC_iLoad_bh_ru,
1659 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1660 let Inst{21} = 1; // overwrite
1662 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1663 (ins GPR:$base, am3offset:$offset), IndexModePost,
1664 LdMiscFrm, IIC_iLoad_bh_ru,
1665 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1666 let Inst{21} = 1; // overwrite
1672 // Stores with truncate
1673 def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1674 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1675 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1678 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1679 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1680 def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1681 StMiscFrm, IIC_iStore_d_r,
1682 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1685 def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb),
1686 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1687 IndexModePre, StFrm, IIC_iStore_ru,
1688 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1690 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1692 def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1693 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1694 IndexModePost, StFrm, IIC_iStore_ru,
1695 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1697 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>;
1699 def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb),
1700 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1701 IndexModePre, StFrm, IIC_iStore_bh_ru,
1702 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1703 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1704 GPR:$Rn, am2offset:$offset))]>;
1705 def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb),
1706 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1707 IndexModePost, StFrm, IIC_iStore_bh_ru,
1708 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1709 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1710 GPR:$Rn, am2offset:$offset))]>;
1712 def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb),
1713 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1714 IndexModePre, StMiscFrm, IIC_iStore_ru,
1715 "strh", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1717 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
1719 def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
1720 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset),
1721 IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
1722 "strh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1723 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
1724 GPR:$Rn, am3offset:$offset))]>;
1726 // For disassembly only
1727 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1728 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1729 StMiscFrm, IIC_iStore_d_ru,
1730 "strd", "\t$src1, $src2, [$base, $offset]!",
1731 "$base = $base_wb", []>;
1733 // For disassembly only
1734 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1735 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1736 StMiscFrm, IIC_iStore_d_ru,
1737 "strd", "\t$src1, $src2, [$base], $offset",
1738 "$base = $base_wb", []>;
1740 // STRT, STRBT, and STRHT are for disassembly only.
1742 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1743 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1744 IndexModeNone, StFrm, IIC_iStore_ru,
1745 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1746 [/* For disassembly only; pattern left blank */]> {
1747 let Inst{21} = 1; // overwrite
1750 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1751 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1752 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1753 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1754 [/* For disassembly only; pattern left blank */]> {
1755 let Inst{21} = 1; // overwrite
1758 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1759 (ins GPR:$src, GPR:$base,am3offset:$offset),
1760 StMiscFrm, IIC_iStore_bh_ru,
1761 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1762 [/* For disassembly only; pattern left blank */]> {
1763 let Inst{21} = 1; // overwrite
1766 //===----------------------------------------------------------------------===//
1767 // Load / store multiple Instructions.
1770 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1771 InstrItinClass itin, InstrItinClass itin_upd> {
1773 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1774 IndexModeNone, f, itin,
1775 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1776 let Inst{24-23} = 0b01; // Increment After
1777 let Inst{21} = 0; // No writeback
1778 let Inst{20} = L_bit;
1781 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1782 IndexModeUpd, f, itin_upd,
1783 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1784 let Inst{24-23} = 0b01; // Increment After
1785 let Inst{21} = 1; // Writeback
1786 let Inst{20} = L_bit;
1789 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1790 IndexModeNone, f, itin,
1791 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1792 let Inst{24-23} = 0b00; // Decrement After
1793 let Inst{21} = 0; // No writeback
1794 let Inst{20} = L_bit;
1797 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1798 IndexModeUpd, f, itin_upd,
1799 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1800 let Inst{24-23} = 0b00; // Decrement After
1801 let Inst{21} = 1; // Writeback
1802 let Inst{20} = L_bit;
1805 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1806 IndexModeNone, f, itin,
1807 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1808 let Inst{24-23} = 0b10; // Decrement Before
1809 let Inst{21} = 0; // No writeback
1810 let Inst{20} = L_bit;
1813 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1814 IndexModeUpd, f, itin_upd,
1815 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1816 let Inst{24-23} = 0b10; // Decrement Before
1817 let Inst{21} = 1; // Writeback
1818 let Inst{20} = L_bit;
1821 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1822 IndexModeNone, f, itin,
1823 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1824 let Inst{24-23} = 0b11; // Increment Before
1825 let Inst{21} = 0; // No writeback
1826 let Inst{20} = L_bit;
1829 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1830 IndexModeUpd, f, itin_upd,
1831 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1832 let Inst{24-23} = 0b11; // Increment Before
1833 let Inst{21} = 1; // Writeback
1834 let Inst{20} = L_bit;
1838 let neverHasSideEffects = 1 in {
1840 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1841 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1843 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1844 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1846 } // neverHasSideEffects
1848 // Load / Store Multiple Mnemonic Aliases
1849 def : MnemonicAlias<"ldm", "ldmia">;
1850 def : MnemonicAlias<"stm", "stmia">;
1852 // FIXME: remove when we have a way to marking a MI with these properties.
1853 // FIXME: Should pc be an implicit operand like PICADD, etc?
1854 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1855 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1856 // FIXME: Should be a pseudo-instruction.
1857 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1858 reglist:$regs, variable_ops),
1859 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1860 "ldmia${p}\t$Rn!, $regs",
1862 let Inst{24-23} = 0b01; // Increment After
1863 let Inst{21} = 1; // Writeback
1864 let Inst{20} = 1; // Load
1867 //===----------------------------------------------------------------------===//
1868 // Move Instructions.
1871 let neverHasSideEffects = 1 in
1872 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1873 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1877 let Inst{11-4} = 0b00000000;
1880 let Inst{15-12} = Rd;
1883 // A version for the smaller set of tail call registers.
1884 let neverHasSideEffects = 1 in
1885 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1886 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1890 let Inst{11-4} = 0b00000000;
1893 let Inst{15-12} = Rd;
1896 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1897 DPSoRegFrm, IIC_iMOVsr,
1898 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1902 let Inst{15-12} = Rd;
1903 let Inst{11-0} = src;
1907 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1908 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1909 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1913 let Inst{15-12} = Rd;
1914 let Inst{19-16} = 0b0000;
1915 let Inst{11-0} = imm;
1918 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1919 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
1921 "movw", "\t$Rd, $imm",
1922 [(set GPR:$Rd, imm0_65535:$imm)]>,
1923 Requires<[IsARM, HasV6T2]>, UnaryDP {
1926 let Inst{15-12} = Rd;
1927 let Inst{11-0} = imm{11-0};
1928 let Inst{19-16} = imm{15-12};
1933 let Constraints = "$src = $Rd" in
1934 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
1936 "movt", "\t$Rd, $imm",
1938 (or (and GPR:$src, 0xffff),
1939 lo16AllZero:$imm))]>, UnaryDP,
1940 Requires<[IsARM, HasV6T2]> {
1943 let Inst{15-12} = Rd;
1944 let Inst{11-0} = imm{11-0};
1945 let Inst{19-16} = imm{15-12};
1950 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1951 Requires<[IsARM, HasV6T2]>;
1953 let Uses = [CPSR] in
1954 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
1955 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1958 // These aren't really mov instructions, but we have to define them this way
1959 // due to flag operands.
1961 let Defs = [CPSR] in {
1962 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1963 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1965 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
1966 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1970 //===----------------------------------------------------------------------===//
1971 // Extend Instructions.
1976 defm SXTB : AI_ext_rrot<0b01101010,
1977 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1978 defm SXTH : AI_ext_rrot<0b01101011,
1979 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1981 defm SXTAB : AI_exta_rrot<0b01101010,
1982 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1983 defm SXTAH : AI_exta_rrot<0b01101011,
1984 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1986 // For disassembly only
1987 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1989 // For disassembly only
1990 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1994 let AddedComplexity = 16 in {
1995 defm UXTB : AI_ext_rrot<0b01101110,
1996 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1997 defm UXTH : AI_ext_rrot<0b01101111,
1998 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1999 defm UXTB16 : AI_ext_rrot<0b01101100,
2000 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2002 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2003 // The transformation should probably be done as a combiner action
2004 // instead so we can include a check for masking back in the upper
2005 // eight bits of the source into the lower eight bits of the result.
2006 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2007 // (UXTB16r_rot GPR:$Src, 24)>;
2008 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2009 (UXTB16r_rot GPR:$Src, 8)>;
2011 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2012 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2013 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2014 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2017 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2018 // For disassembly only
2019 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2022 def SBFX : I<(outs GPR:$Rd),
2023 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2024 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2025 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2026 Requires<[IsARM, HasV6T2]> {
2031 let Inst{27-21} = 0b0111101;
2032 let Inst{6-4} = 0b101;
2033 let Inst{20-16} = width;
2034 let Inst{15-12} = Rd;
2035 let Inst{11-7} = lsb;
2039 def UBFX : I<(outs GPR:$Rd),
2040 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2041 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2042 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2043 Requires<[IsARM, HasV6T2]> {
2048 let Inst{27-21} = 0b0111111;
2049 let Inst{6-4} = 0b101;
2050 let Inst{20-16} = width;
2051 let Inst{15-12} = Rd;
2052 let Inst{11-7} = lsb;
2056 //===----------------------------------------------------------------------===//
2057 // Arithmetic Instructions.
2060 defm ADD : AsI1_bin_irs<0b0100, "add",
2061 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2062 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2063 defm SUB : AsI1_bin_irs<0b0010, "sub",
2064 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2065 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2067 // ADD and SUB with 's' bit set.
2068 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2069 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2070 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2071 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2072 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2073 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2075 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2076 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2077 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2078 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2080 // ADC and SUBC with 's' bit set.
2081 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2082 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2083 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2084 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2086 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2087 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2088 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2093 let Inst{15-12} = Rd;
2094 let Inst{19-16} = Rn;
2095 let Inst{11-0} = imm;
2098 // The reg/reg form is only defined for the disassembler; for codegen it is
2099 // equivalent to SUBrr.
2100 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2101 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2102 [/* For disassembly only; pattern left blank */]> {
2106 let Inst{11-4} = 0b00000000;
2109 let Inst{15-12} = Rd;
2110 let Inst{19-16} = Rn;
2113 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2114 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2115 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2120 let Inst{11-0} = shift;
2121 let Inst{15-12} = Rd;
2122 let Inst{19-16} = Rn;
2125 // RSB with 's' bit set.
2126 let isCodeGenOnly = 1, Defs = [CPSR] in {
2127 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2128 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2129 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2135 let Inst{15-12} = Rd;
2136 let Inst{19-16} = Rn;
2137 let Inst{11-0} = imm;
2139 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2140 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2141 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2147 let Inst{11-0} = shift;
2148 let Inst{15-12} = Rd;
2149 let Inst{19-16} = Rn;
2153 let Uses = [CPSR] in {
2154 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2155 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2156 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2162 let Inst{15-12} = Rd;
2163 let Inst{19-16} = Rn;
2164 let Inst{11-0} = imm;
2166 // The reg/reg form is only defined for the disassembler; for codegen it is
2167 // equivalent to SUBrr.
2168 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2169 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2170 [/* For disassembly only; pattern left blank */]> {
2174 let Inst{11-4} = 0b00000000;
2177 let Inst{15-12} = Rd;
2178 let Inst{19-16} = Rn;
2180 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2181 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2182 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2188 let Inst{11-0} = shift;
2189 let Inst{15-12} = Rd;
2190 let Inst{19-16} = Rn;
2194 // FIXME: Allow these to be predicated.
2195 let isCodeGenOnly = 1, Defs = [CPSR], Uses = [CPSR] in {
2196 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2197 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2198 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2205 let Inst{15-12} = Rd;
2206 let Inst{19-16} = Rn;
2207 let Inst{11-0} = imm;
2209 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2210 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2211 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2218 let Inst{11-0} = shift;
2219 let Inst{15-12} = Rd;
2220 let Inst{19-16} = Rn;
2224 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2225 // The assume-no-carry-in form uses the negation of the input since add/sub
2226 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2227 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2229 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2230 (SUBri GPR:$src, so_imm_neg:$imm)>;
2231 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2232 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2233 // The with-carry-in form matches bitwise not instead of the negation.
2234 // Effectively, the inverse interpretation of the carry flag already accounts
2235 // for part of the negation.
2236 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2237 (SBCri GPR:$src, so_imm_not:$imm)>;
2239 // Note: These are implemented in C++ code, because they have to generate
2240 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2242 // (mul X, 2^n+1) -> (add (X << n), X)
2243 // (mul X, 2^n-1) -> (rsb X, (X << n))
2245 // ARM Arithmetic Instruction -- for disassembly only
2246 // GPR:$dst = GPR:$a op GPR:$b
2247 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2248 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2249 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2250 opc, "\t$Rd, $Rn, $Rm", pattern> {
2254 let Inst{27-20} = op27_20;
2255 let Inst{11-4} = op11_4;
2256 let Inst{19-16} = Rn;
2257 let Inst{15-12} = Rd;
2261 // Saturating add/subtract -- for disassembly only
2263 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2264 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2265 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2266 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2267 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2268 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2270 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2271 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2272 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2273 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2274 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2275 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2276 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2277 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2278 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2279 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2280 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2281 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2283 // Signed/Unsigned add/subtract -- for disassembly only
2285 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2286 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2287 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2288 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2289 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2290 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2291 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2292 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2293 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2294 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2295 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2296 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2298 // Signed/Unsigned halving add/subtract -- for disassembly only
2300 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2301 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2302 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2303 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2304 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2305 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2306 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2307 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2308 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2309 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2310 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2311 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2313 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2315 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2316 MulFrm /* for convenience */, NoItinerary, "usad8",
2317 "\t$Rd, $Rn, $Rm", []>,
2318 Requires<[IsARM, HasV6]> {
2322 let Inst{27-20} = 0b01111000;
2323 let Inst{15-12} = 0b1111;
2324 let Inst{7-4} = 0b0001;
2325 let Inst{19-16} = Rd;
2326 let Inst{11-8} = Rm;
2329 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2330 MulFrm /* for convenience */, NoItinerary, "usada8",
2331 "\t$Rd, $Rn, $Rm, $Ra", []>,
2332 Requires<[IsARM, HasV6]> {
2337 let Inst{27-20} = 0b01111000;
2338 let Inst{7-4} = 0b0001;
2339 let Inst{19-16} = Rd;
2340 let Inst{15-12} = Ra;
2341 let Inst{11-8} = Rm;
2345 // Signed/Unsigned saturate -- for disassembly only
2347 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2348 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2349 [/* For disassembly only; pattern left blank */]> {
2354 let Inst{27-21} = 0b0110101;
2355 let Inst{5-4} = 0b01;
2356 let Inst{20-16} = sat_imm;
2357 let Inst{15-12} = Rd;
2358 let Inst{11-7} = sh{7-3};
2359 let Inst{6} = sh{0};
2363 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2364 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2365 [/* For disassembly only; pattern left blank */]> {
2369 let Inst{27-20} = 0b01101010;
2370 let Inst{11-4} = 0b11110011;
2371 let Inst{15-12} = Rd;
2372 let Inst{19-16} = sat_imm;
2376 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2377 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2378 [/* For disassembly only; pattern left blank */]> {
2383 let Inst{27-21} = 0b0110111;
2384 let Inst{5-4} = 0b01;
2385 let Inst{15-12} = Rd;
2386 let Inst{11-7} = sh{7-3};
2387 let Inst{6} = sh{0};
2388 let Inst{20-16} = sat_imm;
2392 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2393 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2394 [/* For disassembly only; pattern left blank */]> {
2398 let Inst{27-20} = 0b01101110;
2399 let Inst{11-4} = 0b11110011;
2400 let Inst{15-12} = Rd;
2401 let Inst{19-16} = sat_imm;
2405 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2406 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2408 //===----------------------------------------------------------------------===//
2409 // Bitwise Instructions.
2412 defm AND : AsI1_bin_irs<0b0000, "and",
2413 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2414 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2415 defm ORR : AsI1_bin_irs<0b1100, "orr",
2416 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2417 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2418 defm EOR : AsI1_bin_irs<0b0001, "eor",
2419 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2420 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2421 defm BIC : AsI1_bin_irs<0b1110, "bic",
2422 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2423 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2425 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2426 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2427 "bfc", "\t$Rd, $imm", "$src = $Rd",
2428 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2429 Requires<[IsARM, HasV6T2]> {
2432 let Inst{27-21} = 0b0111110;
2433 let Inst{6-0} = 0b0011111;
2434 let Inst{15-12} = Rd;
2435 let Inst{11-7} = imm{4-0}; // lsb
2436 let Inst{20-16} = imm{9-5}; // width
2439 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2440 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2441 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2442 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2443 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2444 bf_inv_mask_imm:$imm))]>,
2445 Requires<[IsARM, HasV6T2]> {
2449 let Inst{27-21} = 0b0111110;
2450 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2451 let Inst{15-12} = Rd;
2452 let Inst{11-7} = imm{4-0}; // lsb
2453 let Inst{20-16} = imm{9-5}; // width
2457 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2458 "mvn", "\t$Rd, $Rm",
2459 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2463 let Inst{19-16} = 0b0000;
2464 let Inst{11-4} = 0b00000000;
2465 let Inst{15-12} = Rd;
2468 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2469 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2470 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2474 let Inst{19-16} = 0b0000;
2475 let Inst{15-12} = Rd;
2476 let Inst{11-0} = shift;
2478 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2479 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2480 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2481 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2485 let Inst{19-16} = 0b0000;
2486 let Inst{15-12} = Rd;
2487 let Inst{11-0} = imm;
2490 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2491 (BICri GPR:$src, so_imm_not:$imm)>;
2493 //===----------------------------------------------------------------------===//
2494 // Multiply Instructions.
2496 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2497 string opc, string asm, list<dag> pattern>
2498 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2502 let Inst{19-16} = Rd;
2503 let Inst{11-8} = Rm;
2506 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2507 string opc, string asm, list<dag> pattern>
2508 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2513 let Inst{19-16} = RdHi;
2514 let Inst{15-12} = RdLo;
2515 let Inst{11-8} = Rm;
2519 let isCommutable = 1 in {
2520 let Constraints = "@earlyclobber $Rd" in
2521 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2522 pred:$p, cc_out:$s),
2523 Size4Bytes, IIC_iMUL32,
2524 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2525 Requires<[IsARM, NoV6]>;
2527 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2528 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2529 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2530 Requires<[IsARM, HasV6]>;
2533 let Constraints = "@earlyclobber $Rd" in
2534 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2535 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2536 Size4Bytes, IIC_iMAC32,
2537 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2538 Requires<[IsARM, NoV6]> {
2540 let Inst{15-12} = Ra;
2542 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2543 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2544 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2545 Requires<[IsARM, HasV6]> {
2547 let Inst{15-12} = Ra;
2550 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2551 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
2552 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
2553 Requires<[IsARM, HasV6T2]> {
2558 let Inst{19-16} = Rd;
2559 let Inst{15-12} = Ra;
2560 let Inst{11-8} = Rm;
2564 // Extra precision multiplies with low / high results
2566 let neverHasSideEffects = 1 in {
2567 let isCommutable = 1 in {
2568 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2569 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2570 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2571 Size4Bytes, IIC_iMUL64, []>,
2572 Requires<[IsARM, NoV6]>;
2574 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2575 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2576 Size4Bytes, IIC_iMUL64, []>,
2577 Requires<[IsARM, NoV6]>;
2580 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2581 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2582 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2583 Requires<[IsARM, HasV6]>;
2585 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2586 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2587 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2588 Requires<[IsARM, HasV6]>;
2591 // Multiply + accumulate
2592 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2593 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2594 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2595 Size4Bytes, IIC_iMAC64, []>,
2596 Requires<[IsARM, NoV6]>;
2597 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2598 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2599 Size4Bytes, IIC_iMAC64, []>,
2600 Requires<[IsARM, NoV6]>;
2601 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2602 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2603 Size4Bytes, IIC_iMAC64, []>,
2604 Requires<[IsARM, NoV6]>;
2608 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2609 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2610 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2611 Requires<[IsARM, HasV6]>;
2612 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2613 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2614 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2615 Requires<[IsARM, HasV6]>;
2617 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2618 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2619 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2620 Requires<[IsARM, HasV6]> {
2625 let Inst{19-16} = RdLo;
2626 let Inst{15-12} = RdHi;
2627 let Inst{11-8} = Rm;
2630 } // neverHasSideEffects
2632 // Most significant word multiply
2633 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2634 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2635 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2636 Requires<[IsARM, HasV6]> {
2637 let Inst{15-12} = 0b1111;
2640 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2641 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2642 [/* For disassembly only; pattern left blank */]>,
2643 Requires<[IsARM, HasV6]> {
2644 let Inst{15-12} = 0b1111;
2647 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2648 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2649 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2650 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2651 Requires<[IsARM, HasV6]>;
2653 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2654 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2655 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2656 [/* For disassembly only; pattern left blank */]>,
2657 Requires<[IsARM, HasV6]>;
2659 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2660 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2661 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2662 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2663 Requires<[IsARM, HasV6]>;
2665 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2666 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2667 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2668 [/* For disassembly only; pattern left blank */]>,
2669 Requires<[IsARM, HasV6]>;
2671 multiclass AI_smul<string opc, PatFrag opnode> {
2672 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2673 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2674 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2675 (sext_inreg GPR:$Rm, i16)))]>,
2676 Requires<[IsARM, HasV5TE]>;
2678 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2679 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2680 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2681 (sra GPR:$Rm, (i32 16))))]>,
2682 Requires<[IsARM, HasV5TE]>;
2684 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2685 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2686 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2687 (sext_inreg GPR:$Rm, i16)))]>,
2688 Requires<[IsARM, HasV5TE]>;
2690 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2691 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2692 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2693 (sra GPR:$Rm, (i32 16))))]>,
2694 Requires<[IsARM, HasV5TE]>;
2696 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2697 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2698 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2699 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2700 Requires<[IsARM, HasV5TE]>;
2702 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2703 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2704 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2705 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2706 Requires<[IsARM, HasV5TE]>;
2710 multiclass AI_smla<string opc, PatFrag opnode> {
2711 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2712 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2713 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2714 [(set GPR:$Rd, (add GPR:$Ra,
2715 (opnode (sext_inreg GPR:$Rn, i16),
2716 (sext_inreg GPR:$Rm, i16))))]>,
2717 Requires<[IsARM, HasV5TE]>;
2719 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2720 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2721 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2722 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2723 (sra GPR:$Rm, (i32 16)))))]>,
2724 Requires<[IsARM, HasV5TE]>;
2726 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2727 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2728 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2729 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2730 (sext_inreg GPR:$Rm, i16))))]>,
2731 Requires<[IsARM, HasV5TE]>;
2733 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2734 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2735 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2736 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2737 (sra GPR:$Rm, (i32 16)))))]>,
2738 Requires<[IsARM, HasV5TE]>;
2740 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2741 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2742 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2743 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2744 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2745 Requires<[IsARM, HasV5TE]>;
2747 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2748 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2749 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2750 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2751 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2752 Requires<[IsARM, HasV5TE]>;
2755 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2756 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2758 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2759 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2760 (ins GPR:$Rn, GPR:$Rm),
2761 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2762 [/* For disassembly only; pattern left blank */]>,
2763 Requires<[IsARM, HasV5TE]>;
2765 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2766 (ins GPR:$Rn, GPR:$Rm),
2767 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2768 [/* For disassembly only; pattern left blank */]>,
2769 Requires<[IsARM, HasV5TE]>;
2771 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2772 (ins GPR:$Rn, GPR:$Rm),
2773 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2774 [/* For disassembly only; pattern left blank */]>,
2775 Requires<[IsARM, HasV5TE]>;
2777 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2778 (ins GPR:$Rn, GPR:$Rm),
2779 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2780 [/* For disassembly only; pattern left blank */]>,
2781 Requires<[IsARM, HasV5TE]>;
2783 // Helper class for AI_smld -- for disassembly only
2784 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2785 InstrItinClass itin, string opc, string asm>
2786 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2793 let Inst{21-20} = 0b00;
2794 let Inst{22} = long;
2795 let Inst{27-23} = 0b01110;
2796 let Inst{11-8} = Rm;
2799 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2800 InstrItinClass itin, string opc, string asm>
2801 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2803 let Inst{15-12} = 0b1111;
2804 let Inst{19-16} = Rd;
2806 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2807 InstrItinClass itin, string opc, string asm>
2808 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2810 let Inst{15-12} = Ra;
2812 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2813 InstrItinClass itin, string opc, string asm>
2814 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2817 let Inst{19-16} = RdHi;
2818 let Inst{15-12} = RdLo;
2821 multiclass AI_smld<bit sub, string opc> {
2823 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2824 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2826 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2827 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2829 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2830 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2831 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2833 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2834 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2835 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2839 defm SMLA : AI_smld<0, "smla">;
2840 defm SMLS : AI_smld<1, "smls">;
2842 multiclass AI_sdml<bit sub, string opc> {
2844 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2845 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2846 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2847 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2850 defm SMUA : AI_sdml<0, "smua">;
2851 defm SMUS : AI_sdml<1, "smus">;
2853 //===----------------------------------------------------------------------===//
2854 // Misc. Arithmetic Instructions.
2857 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2858 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2859 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2861 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2862 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2863 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2864 Requires<[IsARM, HasV6T2]>;
2866 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2867 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2868 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2870 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2871 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2873 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2874 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2875 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2876 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2877 Requires<[IsARM, HasV6]>;
2879 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2880 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2883 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2884 (shl GPR:$Rm, (i32 8))), i16))]>,
2885 Requires<[IsARM, HasV6]>;
2887 def lsl_shift_imm : SDNodeXForm<imm, [{
2888 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2889 return CurDAG->getTargetConstant(Sh, MVT::i32);
2892 def lsl_amt : PatLeaf<(i32 imm), [{
2893 return (N->getZExtValue() < 32);
2896 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2897 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2898 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2899 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2900 (and (shl GPR:$Rm, lsl_amt:$sh),
2902 Requires<[IsARM, HasV6]>;
2904 // Alternate cases for PKHBT where identities eliminate some nodes.
2905 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2906 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2907 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2908 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2910 def asr_shift_imm : SDNodeXForm<imm, [{
2911 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2912 return CurDAG->getTargetConstant(Sh, MVT::i32);
2915 def asr_amt : PatLeaf<(i32 imm), [{
2916 return (N->getZExtValue() <= 32);
2919 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2920 // will match the pattern below.
2921 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2922 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2923 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2924 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2925 (and (sra GPR:$Rm, asr_amt:$sh),
2927 Requires<[IsARM, HasV6]>;
2929 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2930 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2931 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2932 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2933 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2934 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2935 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2937 //===----------------------------------------------------------------------===//
2938 // Comparison Instructions...
2941 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2942 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2943 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2945 // ARMcmpZ can re-use the above instruction definitions.
2946 def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm),
2947 (CMPri GPR:$src, so_imm:$imm)>;
2948 def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
2949 (CMPrr GPR:$src, GPR:$rhs)>;
2950 def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
2951 (CMPrs GPR:$src, so_reg:$rhs)>;
2953 // FIXME: We have to be careful when using the CMN instruction and comparison
2954 // with 0. One would expect these two pieces of code should give identical
2970 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2971 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2972 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2973 // value of r0 and the carry bit (because the "carry bit" parameter to
2974 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2975 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2976 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2977 // parameter to AddWithCarry is defined as 0).
2979 // When x is 0 and unsigned:
2983 // ~x + 1 = 0x1 0000 0000
2984 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2986 // Therefore, we should disable CMN when comparing against zero, until we can
2987 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2988 // when it's a comparison which doesn't look at the 'carry' flag).
2990 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2992 // This is related to <rdar://problem/7569620>.
2994 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2995 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2997 // Note that TST/TEQ don't set all the same flags that CMP does!
2998 defm TST : AI1_cmp_irs<0b1000, "tst",
2999 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3000 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3001 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3002 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3003 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3005 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3006 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3007 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3009 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3010 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3012 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3013 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3015 // Pseudo i64 compares for some floating point compares.
3016 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3018 def BCCi64 : PseudoInst<(outs),
3019 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3021 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3023 def BCCZi64 : PseudoInst<(outs),
3024 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3025 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3026 } // usesCustomInserter
3029 // Conditional moves
3030 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3031 // a two-value operand where a dag node expects two operands. :(
3032 // FIXME: These should all be pseudo-instructions that get expanded to
3033 // the normal MOV instructions. That would fix the dependency on
3034 // special casing them in tblgen.
3035 let neverHasSideEffects = 1 in {
3036 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3037 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3038 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3039 RegConstraint<"$false = $Rd">, UnaryDP {
3044 let Inst{15-12} = Rd;
3045 let Inst{11-4} = 0b00000000;
3049 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3050 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3051 "mov", "\t$Rd, $shift",
3052 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3053 RegConstraint<"$false = $Rd">, UnaryDP {
3058 let Inst{19-16} = 0;
3059 let Inst{15-12} = Rd;
3060 let Inst{11-0} = shift;
3063 let isMoveImm = 1 in
3064 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm_hilo16:$imm),
3066 "movw", "\t$Rd, $imm",
3068 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3074 let Inst{19-16} = imm{15-12};
3075 let Inst{15-12} = Rd;
3076 let Inst{11-0} = imm{11-0};
3079 let isMoveImm = 1 in
3080 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3081 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3082 "mov", "\t$Rd, $imm",
3083 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3084 RegConstraint<"$false = $Rd">, UnaryDP {
3089 let Inst{19-16} = 0b0000;
3090 let Inst{15-12} = Rd;
3091 let Inst{11-0} = imm;
3094 // Two instruction predicate mov immediate.
3095 let isMoveImm = 1 in
3096 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3097 (ins GPR:$false, i32imm:$src, pred:$p),
3098 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3100 let isMoveImm = 1 in
3101 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3102 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3103 "mvn", "\t$Rd, $imm",
3104 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3105 RegConstraint<"$false = $Rd">, UnaryDP {
3110 let Inst{19-16} = 0b0000;
3111 let Inst{15-12} = Rd;
3112 let Inst{11-0} = imm;
3114 } // neverHasSideEffects
3116 //===----------------------------------------------------------------------===//
3117 // Atomic operations intrinsics
3120 def memb_opt : Operand<i32> {
3121 let PrintMethod = "printMemBOption";
3124 // memory barriers protect the atomic sequences
3125 let hasSideEffects = 1 in {
3126 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3127 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3128 Requires<[IsARM, HasDB]> {
3130 let Inst{31-4} = 0xf57ff05;
3131 let Inst{3-0} = opt;
3134 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3135 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3136 [(ARMMemBarrierMCR GPR:$zero)]>,
3137 Requires<[IsARM, HasV6]> {
3138 // FIXME: add encoding
3142 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3144 [/* For disassembly only; pattern left blank */]>,
3145 Requires<[IsARM, HasDB]> {
3147 let Inst{31-4} = 0xf57ff04;
3148 let Inst{3-0} = opt;
3151 // ISB has only full system option -- for disassembly only
3152 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3153 Requires<[IsARM, HasDB]> {
3154 let Inst{31-4} = 0xf57ff06;
3155 let Inst{3-0} = 0b1111;
3158 let usesCustomInserter = 1 in {
3159 let Uses = [CPSR] in {
3160 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3161 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3162 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3163 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3164 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3165 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3166 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3167 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3168 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3169 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3170 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3171 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3172 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3173 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3174 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3175 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3176 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3177 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3178 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3179 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3180 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3181 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3182 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3183 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3184 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3185 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3186 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3187 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3188 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3189 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3190 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3191 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3192 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3193 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3194 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3195 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3196 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3197 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3198 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3199 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3200 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3201 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3202 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3203 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3204 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3205 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3206 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3207 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3208 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3209 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3210 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3211 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3212 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3213 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3215 def ATOMIC_SWAP_I8 : PseudoInst<
3216 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3217 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3218 def ATOMIC_SWAP_I16 : PseudoInst<
3219 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3220 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3221 def ATOMIC_SWAP_I32 : PseudoInst<
3222 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3223 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3225 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3226 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3227 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3228 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3229 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3230 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3231 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3232 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3233 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3237 let mayLoad = 1 in {
3238 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3239 "ldrexb", "\t$Rt, [$Rn]",
3241 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3242 "ldrexh", "\t$Rt, [$Rn]",
3244 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3245 "ldrex", "\t$Rt, [$Rn]",
3247 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3249 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3253 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3254 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3256 "strexb", "\t$Rd, $src, [$Rn]",
3258 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3260 "strexh", "\t$Rd, $Rt, [$Rn]",
3262 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3264 "strex", "\t$Rd, $Rt, [$Rn]",
3266 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3267 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3269 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3273 // Clear-Exclusive is for disassembly only.
3274 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3275 [/* For disassembly only; pattern left blank */]>,
3276 Requires<[IsARM, HasV7]> {
3277 let Inst{31-0} = 0b11110101011111111111000000011111;
3280 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3281 let mayLoad = 1 in {
3282 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3283 [/* For disassembly only; pattern left blank */]>;
3284 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3285 [/* For disassembly only; pattern left blank */]>;
3288 //===----------------------------------------------------------------------===//
3292 // __aeabi_read_tp preserves the registers r1-r3.
3293 // This is a pseudo inst so that we can get the encoding right,
3294 // complete with fixup for the aeabi_read_tp function.
3296 Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
3297 def TPsoft : PseudoInst<(outs), (ins), IIC_Br,
3298 [(set R0, ARMthread_pointer)]>;
3301 //===----------------------------------------------------------------------===//
3302 // SJLJ Exception handling intrinsics
3303 // eh_sjlj_setjmp() is an instruction sequence to store the return
3304 // address and save #0 in R0 for the non-longjmp case.
3305 // Since by its nature we may be coming from some other function to get
3306 // here, and we're using the stack frame for the containing function to
3307 // save/restore registers, we can't keep anything live in regs across
3308 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3309 // when we get here from a longjmp(). We force everthing out of registers
3310 // except for our own input by listing the relevant registers in Defs. By
3311 // doing so, we also cause the prologue/epilogue code to actively preserve
3312 // all of the callee-saved resgisters, which is exactly what we want.
3313 // A constant value is passed in $val, and we use the location as a scratch.
3315 // These are pseudo-instructions and are lowered to individual MC-insts, so
3316 // no encoding information is necessary.
3318 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3319 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3320 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3321 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3322 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3324 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3325 Requires<[IsARM, HasVFP2]>;
3329 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3330 hasSideEffects = 1, isBarrier = 1 in {
3331 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
3333 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3334 Requires<[IsARM, NoVFP]>;
3337 // FIXME: Non-Darwin version(s)
3338 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3339 Defs = [ R7, LR, SP ] in {
3340 def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
3342 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3343 Requires<[IsARM, IsDarwin]>;
3346 // eh.sjlj.dispatchsetup pseudo-instruction.
3347 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3348 // handled when the pseudo is expanded (which happens before any passes
3349 // that need the instruction size).
3350 let isBarrier = 1, hasSideEffects = 1 in
3351 def Int_eh_sjlj_dispatchsetup :
3352 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3353 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3354 Requires<[IsDarwin]>;
3356 //===----------------------------------------------------------------------===//
3357 // Non-Instruction Patterns
3360 // Large immediate handling.
3362 // 32-bit immediate using two piece so_imms or movw + movt.
3363 // This is a single pseudo instruction, the benefit is that it can be remat'd
3364 // as a single unit instead of having to handle reg inputs.
3365 // FIXME: Remove this when we can do generalized remat.
3366 let isReMaterializable = 1, isMoveImm = 1 in
3367 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3368 [(set GPR:$dst, (arm_i32imm:$src))]>,
3371 // ConstantPool, GlobalAddress, and JumpTable
3372 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3373 Requires<[IsARM, DontUseMovt]>;
3374 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3375 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3376 Requires<[IsARM, UseMovt]>;
3377 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3378 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3380 // TODO: add,sub,and, 3-instr forms?
3383 def : ARMPat<(ARMtcret tcGPR:$dst),
3384 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3386 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3387 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3389 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3390 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3392 def : ARMPat<(ARMtcret tcGPR:$dst),
3393 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3395 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3396 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3398 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3399 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3402 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3403 Requires<[IsARM, IsNotDarwin]>;
3404 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3405 Requires<[IsARM, IsDarwin]>;
3407 // zextload i1 -> zextload i8
3408 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3409 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3411 // extload -> zextload
3412 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3413 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3414 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3415 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3417 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3419 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3420 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3423 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3424 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3425 (SMULBB GPR:$a, GPR:$b)>;
3426 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3427 (SMULBB GPR:$a, GPR:$b)>;
3428 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3429 (sra GPR:$b, (i32 16))),
3430 (SMULBT GPR:$a, GPR:$b)>;
3431 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3432 (SMULBT GPR:$a, GPR:$b)>;
3433 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3434 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3435 (SMULTB GPR:$a, GPR:$b)>;
3436 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3437 (SMULTB GPR:$a, GPR:$b)>;
3438 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3440 (SMULWB GPR:$a, GPR:$b)>;
3441 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3442 (SMULWB GPR:$a, GPR:$b)>;
3444 def : ARMV5TEPat<(add GPR:$acc,
3445 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3446 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3447 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3448 def : ARMV5TEPat<(add GPR:$acc,
3449 (mul sext_16_node:$a, sext_16_node:$b)),
3450 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3451 def : ARMV5TEPat<(add GPR:$acc,
3452 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3453 (sra GPR:$b, (i32 16)))),
3454 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3455 def : ARMV5TEPat<(add GPR:$acc,
3456 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3457 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3458 def : ARMV5TEPat<(add GPR:$acc,
3459 (mul (sra GPR:$a, (i32 16)),
3460 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3461 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3462 def : ARMV5TEPat<(add GPR:$acc,
3463 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3464 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3465 def : ARMV5TEPat<(add GPR:$acc,
3466 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3468 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3469 def : ARMV5TEPat<(add GPR:$acc,
3470 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3471 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3473 //===----------------------------------------------------------------------===//
3477 include "ARMInstrThumb.td"
3479 //===----------------------------------------------------------------------===//
3483 include "ARMInstrThumb2.td"
3485 //===----------------------------------------------------------------------===//
3486 // Floating Point Support
3489 include "ARMInstrVFP.td"
3491 //===----------------------------------------------------------------------===//
3492 // Advanced SIMD (NEON) Support
3495 include "ARMInstrNEON.td"
3497 //===----------------------------------------------------------------------===//
3498 // Coprocessor Instructions. For disassembly only.
3501 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3502 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3503 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3504 [/* For disassembly only; pattern left blank */]> {
3508 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3509 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3510 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3511 [/* For disassembly only; pattern left blank */]> {
3512 let Inst{31-28} = 0b1111;
3516 class ACI<dag oops, dag iops, string opc, string asm>
3517 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3518 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3519 let Inst{27-25} = 0b110;
3522 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3524 def _OFFSET : ACI<(outs),
3525 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3526 opc, "\tp$cop, cr$CRd, $addr"> {
3527 let Inst{31-28} = op31_28;
3528 let Inst{24} = 1; // P = 1
3529 let Inst{21} = 0; // W = 0
3530 let Inst{22} = 0; // D = 0
3531 let Inst{20} = load;
3534 def _PRE : ACI<(outs),
3535 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3536 opc, "\tp$cop, cr$CRd, $addr!"> {
3537 let Inst{31-28} = op31_28;
3538 let Inst{24} = 1; // P = 1
3539 let Inst{21} = 1; // W = 1
3540 let Inst{22} = 0; // D = 0
3541 let Inst{20} = load;
3544 def _POST : ACI<(outs),
3545 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3546 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3547 let Inst{31-28} = op31_28;
3548 let Inst{24} = 0; // P = 0
3549 let Inst{21} = 1; // W = 1
3550 let Inst{22} = 0; // D = 0
3551 let Inst{20} = load;
3554 def _OPTION : ACI<(outs),
3555 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3556 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3557 let Inst{31-28} = op31_28;
3558 let Inst{24} = 0; // P = 0
3559 let Inst{23} = 1; // U = 1
3560 let Inst{21} = 0; // W = 0
3561 let Inst{22} = 0; // D = 0
3562 let Inst{20} = load;
3565 def L_OFFSET : ACI<(outs),
3566 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3567 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3568 let Inst{31-28} = op31_28;
3569 let Inst{24} = 1; // P = 1
3570 let Inst{21} = 0; // W = 0
3571 let Inst{22} = 1; // D = 1
3572 let Inst{20} = load;
3575 def L_PRE : ACI<(outs),
3576 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3577 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3578 let Inst{31-28} = op31_28;
3579 let Inst{24} = 1; // P = 1
3580 let Inst{21} = 1; // W = 1
3581 let Inst{22} = 1; // D = 1
3582 let Inst{20} = load;
3585 def L_POST : ACI<(outs),
3586 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3587 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3588 let Inst{31-28} = op31_28;
3589 let Inst{24} = 0; // P = 0
3590 let Inst{21} = 1; // W = 1
3591 let Inst{22} = 1; // D = 1
3592 let Inst{20} = load;
3595 def L_OPTION : ACI<(outs),
3596 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3597 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3598 let Inst{31-28} = op31_28;
3599 let Inst{24} = 0; // P = 0
3600 let Inst{23} = 1; // U = 1
3601 let Inst{21} = 0; // W = 0
3602 let Inst{22} = 1; // D = 1
3603 let Inst{20} = load;
3607 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3608 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3609 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3610 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3612 def MCR : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3613 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3614 NoItinerary, "mcr", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3615 [/* For disassembly only; pattern left blank */]> {
3626 let Inst{15-12} = Rt;
3627 let Inst{11-8} = cop;
3628 let Inst{23-21} = opc1;
3629 let Inst{7-5} = opc2;
3630 let Inst{3-0} = CRm;
3631 let Inst{19-16} = CRn;
3634 def MCR2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3635 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3636 NoItinerary, "mcr2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3637 [/* For disassembly only; pattern left blank */]> {
3638 let Inst{31-28} = 0b1111;
3649 let Inst{15-12} = Rt;
3650 let Inst{11-8} = cop;
3651 let Inst{23-21} = opc1;
3652 let Inst{7-5} = opc2;
3653 let Inst{3-0} = CRm;
3654 let Inst{19-16} = CRn;
3657 def MRC : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3658 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3659 NoItinerary, "mrc", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3660 [/* For disassembly only; pattern left blank */]> {
3671 let Inst{15-12} = Rt;
3672 let Inst{11-8} = cop;
3673 let Inst{23-21} = opc1;
3674 let Inst{7-5} = opc2;
3675 let Inst{3-0} = CRm;
3676 let Inst{19-16} = CRn;
3679 def MRC2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3680 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3681 NoItinerary, "mrc2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
3682 [/* For disassembly only; pattern left blank */]> {
3683 let Inst{31-28} = 0b1111;
3694 let Inst{15-12} = Rt;
3695 let Inst{11-8} = cop;
3696 let Inst{23-21} = opc1;
3697 let Inst{7-5} = opc2;
3698 let Inst{3-0} = CRm;
3699 let Inst{19-16} = CRn;
3702 def MCRR : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3703 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3704 NoItinerary, "mcrr", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3705 [/* For disassembly only; pattern left blank */]> {
3706 let Inst{23-20} = 0b0100;
3714 let Inst{15-12} = Rt;
3715 let Inst{19-16} = Rt2;
3716 let Inst{11-8} = cop;
3717 let Inst{7-5} = opc1;
3718 let Inst{3-0} = CRm;
3721 def MCRR2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3722 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3723 NoItinerary, "mcrr2\t$cop, $opc, $Rt, $Rt2, $CRm",
3724 [/* For disassembly only; pattern left blank */]> {
3725 let Inst{31-28} = 0b1111;
3726 let Inst{23-20} = 0b0100;
3734 let Inst{15-12} = Rt;
3735 let Inst{19-16} = Rt2;
3736 let Inst{11-8} = cop;
3737 let Inst{7-5} = opc1;
3738 let Inst{3-0} = CRm;
3741 def MRRC : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3742 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3743 NoItinerary, "mrrc", "\t$cop, $opc, $Rt, $Rt2, $CRm",
3744 [/* For disassembly only; pattern left blank */]> {
3745 let Inst{23-20} = 0b0101;
3753 let Inst{15-12} = Rt;
3754 let Inst{19-16} = Rt2;
3755 let Inst{11-8} = cop;
3756 let Inst{7-5} = opc1;
3757 let Inst{3-0} = CRm;
3760 def MRRC2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3761 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3762 NoItinerary, "mrrc2\t$cop, $opc, $Rt, $Rt2, $CRm",
3763 [/* For disassembly only; pattern left blank */]> {
3764 let Inst{31-28} = 0b1111;
3765 let Inst{23-20} = 0b0101;
3773 let Inst{15-12} = Rt;
3774 let Inst{19-16} = Rt2;
3775 let Inst{11-8} = cop;
3776 let Inst{7-5} = opc1;
3777 let Inst{3-0} = CRm;
3780 //===----------------------------------------------------------------------===//
3781 // Move between special register and ARM core register -- for disassembly only
3784 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3785 [/* For disassembly only; pattern left blank */]> {
3786 let Inst{23-20} = 0b0000;
3787 let Inst{7-4} = 0b0000;
3790 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3791 [/* For disassembly only; pattern left blank */]> {
3792 let Inst{23-20} = 0b0100;
3793 let Inst{7-4} = 0b0000;
3796 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3797 "msr", "\tcpsr$mask, $src",
3798 [/* For disassembly only; pattern left blank */]> {
3799 let Inst{23-20} = 0b0010;
3800 let Inst{7-4} = 0b0000;
3803 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3804 "msr", "\tcpsr$mask, $a",
3805 [/* For disassembly only; pattern left blank */]> {
3806 let Inst{23-20} = 0b0010;
3807 let Inst{7-4} = 0b0000;
3810 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3811 "msr", "\tspsr$mask, $src",
3812 [/* For disassembly only; pattern left blank */]> {
3813 let Inst{23-20} = 0b0110;
3814 let Inst{7-4} = 0b0000;
3817 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3818 "msr", "\tspsr$mask, $a",
3819 [/* For disassembly only; pattern left blank */]> {
3820 let Inst{23-20} = 0b0110;
3821 let Inst{7-4} = 0b0000;