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, SDNPOutFlag]>;
76 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
77 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
79 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
80 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
82 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
85 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
89 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
90 [SDNPHasChain, SDNPOptInFlag]>;
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, SDNPInFlag, SDNPOutFlag]>;
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 [SDNPOutFlag, SDNPCommutative]>;
114 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
117 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
118 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
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, SDNPOptInFlag, 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 HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
153 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
154 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
155 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
156 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
157 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
158 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
159 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
160 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
162 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
164 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
166 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
167 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
168 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
169 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
170 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
171 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
172 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
173 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
175 // FIXME: Eventually this will be just "hasV6T2Ops".
176 def UseMovt : Predicate<"Subtarget->useMovt()">;
177 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
178 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
180 //===----------------------------------------------------------------------===//
181 // ARM Flag Definitions.
183 class RegConstraint<string C> {
184 string Constraints = C;
187 //===----------------------------------------------------------------------===//
188 // ARM specific transformation functions and pattern fragments.
191 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
192 // so_imm_neg def below.
193 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
194 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
197 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
198 // so_imm_not def below.
199 def so_imm_not_XFORM : SDNodeXForm<imm, [{
200 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
203 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
204 def imm1_15 : PatLeaf<(i32 imm), [{
205 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
208 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
209 def imm16_31 : PatLeaf<(i32 imm), [{
210 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
215 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
216 }], so_imm_neg_XFORM>;
220 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
221 }], so_imm_not_XFORM>;
223 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
224 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
225 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
228 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
230 def bf_inv_mask_imm : Operand<i32>,
232 return ARM::isBitFieldInvertedMask(N->getZExtValue());
234 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
235 let PrintMethod = "printBitfieldInvMaskImmOperand";
238 /// Split a 32-bit immediate into two 16 bit parts.
239 def hi16 : SDNodeXForm<imm, [{
240 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
243 def lo16AllZero : PatLeaf<(i32 imm), [{
244 // Returns true if all low 16-bits are 0.
245 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
248 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
250 def imm0_65535 : PatLeaf<(i32 imm), [{
251 return (uint32_t)N->getZExtValue() < 65536;
254 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
255 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
257 /// adde and sube predicates - True based on whether the carry flag output
258 /// will be needed or not.
259 def adde_dead_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return !N->hasAnyUseOfValue(1);}]>;
262 def sube_dead_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return !N->hasAnyUseOfValue(1);}]>;
265 def adde_live_carry :
266 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
267 [{return N->hasAnyUseOfValue(1);}]>;
268 def sube_live_carry :
269 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
270 [{return N->hasAnyUseOfValue(1);}]>;
272 // An 'and' node with a single use.
273 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
274 return N->hasOneUse();
277 // An 'xor' node with a single use.
278 def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
279 return N->hasOneUse();
282 //===----------------------------------------------------------------------===//
283 // Operand Definitions.
287 def brtarget : Operand<OtherVT> {
288 let EncoderMethod = "getBranchTargetOpValue";
292 def bltarget : Operand<i32> {
293 // Encoded the same as branch targets.
294 let EncoderMethod = "getBranchTargetOpValue";
297 // A list of registers separated by comma. Used by load/store multiple.
298 def RegListAsmOperand : AsmOperandClass {
299 let Name = "RegList";
300 let SuperClasses = [];
303 def DPRRegListAsmOperand : AsmOperandClass {
304 let Name = "DPRRegList";
305 let SuperClasses = [];
308 def SPRRegListAsmOperand : AsmOperandClass {
309 let Name = "SPRRegList";
310 let SuperClasses = [];
313 def reglist : Operand<i32> {
314 let EncoderMethod = "getRegisterListOpValue";
315 let ParserMatchClass = RegListAsmOperand;
316 let PrintMethod = "printRegisterList";
319 def dpr_reglist : Operand<i32> {
320 let EncoderMethod = "getRegisterListOpValue";
321 let ParserMatchClass = DPRRegListAsmOperand;
322 let PrintMethod = "printRegisterList";
325 def spr_reglist : Operand<i32> {
326 let EncoderMethod = "getRegisterListOpValue";
327 let ParserMatchClass = SPRRegListAsmOperand;
328 let PrintMethod = "printRegisterList";
331 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
332 def cpinst_operand : Operand<i32> {
333 let PrintMethod = "printCPInstOperand";
336 def jtblock_operand : Operand<i32> {
337 let PrintMethod = "printJTBlockOperand";
339 def jt2block_operand : Operand<i32> {
340 let PrintMethod = "printJT2BlockOperand";
344 def pclabel : Operand<i32> {
345 let PrintMethod = "printPCLabel";
348 def neon_vcvt_imm32 : Operand<i32> {
349 let EncoderMethod = "getNEONVcvtImm32OpValue";
352 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
353 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
354 int32_t v = (int32_t)N->getZExtValue();
355 return v == 8 || v == 16 || v == 24; }]> {
356 let EncoderMethod = "getRotImmOpValue";
359 // shift_imm: An integer that encodes a shift amount and the type of shift
360 // (currently either asr or lsl) using the same encoding used for the
361 // immediates in so_reg operands.
362 def shift_imm : Operand<i32> {
363 let PrintMethod = "printShiftImmOperand";
366 // shifter_operand operands: so_reg and so_imm.
367 def so_reg : Operand<i32>, // reg reg imm
368 ComplexPattern<i32, 3, "SelectShifterOperandReg",
369 [shl,srl,sra,rotr]> {
370 let EncoderMethod = "getSORegOpValue";
371 let PrintMethod = "printSORegOperand";
372 let MIOperandInfo = (ops GPR, GPR, i32imm);
374 def shift_so_reg : Operand<i32>, // reg reg imm
375 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
376 [shl,srl,sra,rotr]> {
377 let EncoderMethod = "getSORegOpValue";
378 let PrintMethod = "printSORegOperand";
379 let MIOperandInfo = (ops GPR, GPR, i32imm);
382 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
383 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
384 // represented in the imm field in the same 12-bit form that they are encoded
385 // into so_imm instructions: the 8-bit immediate is the least significant bits
386 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
387 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
388 let EncoderMethod = "getSOImmOpValue";
389 let PrintMethod = "printSOImmOperand";
392 // Break so_imm's up into two pieces. This handles immediates with up to 16
393 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
394 // get the first/second pieces.
395 def so_imm2part : PatLeaf<(imm), [{
396 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
399 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
401 def arm_i32imm : PatLeaf<(imm), [{
402 if (Subtarget->hasV6T2Ops())
404 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
407 def so_imm2part_1 : SDNodeXForm<imm, [{
408 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
409 return CurDAG->getTargetConstant(V, MVT::i32);
412 def so_imm2part_2 : SDNodeXForm<imm, [{
413 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
414 return CurDAG->getTargetConstant(V, MVT::i32);
417 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
418 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
420 let PrintMethod = "printSOImm2PartOperand";
423 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
424 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
425 return CurDAG->getTargetConstant(V, MVT::i32);
428 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
429 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
430 return CurDAG->getTargetConstant(V, MVT::i32);
433 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
434 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
435 return (int32_t)N->getZExtValue() < 32;
438 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
439 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
440 return (int32_t)N->getZExtValue() < 32;
442 let EncoderMethod = "getImmMinusOneOpValue";
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 string 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 string 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 // addrmodepc := pc + reg
545 def addrmodepc : Operand<i32>,
546 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
547 let PrintMethod = "printAddrModePCOperand";
548 let MIOperandInfo = (ops GPR, i32imm);
551 def nohash_imm : Operand<i32> {
552 let PrintMethod = "printNoHashImmediate";
555 //===----------------------------------------------------------------------===//
557 include "ARMInstrFormats.td"
559 //===----------------------------------------------------------------------===//
560 // Multiclass helpers...
563 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
564 /// binop that produces a value.
565 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
566 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
567 PatFrag opnode, bit Commutable = 0> {
568 // The register-immediate version is re-materializable. This is useful
569 // in particular for taking the address of a local.
570 let isReMaterializable = 1 in {
571 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
572 iii, opc, "\t$Rd, $Rn, $imm",
573 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
578 let Inst{19-16} = Rn;
579 let Inst{15-12} = Rd;
580 let Inst{11-0} = imm;
583 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
584 iir, opc, "\t$Rd, $Rn, $Rm",
585 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
590 let isCommutable = Commutable;
591 let Inst{19-16} = Rn;
592 let Inst{15-12} = Rd;
593 let Inst{11-4} = 0b00000000;
596 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
597 iis, opc, "\t$Rd, $Rn, $shift",
598 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
603 let Inst{19-16} = Rn;
604 let Inst{15-12} = Rd;
605 let Inst{11-0} = shift;
609 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
610 /// instruction modifies the CPSR register.
611 let Defs = [CPSR] in {
612 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
613 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
614 PatFrag opnode, bit Commutable = 0> {
615 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
616 iii, opc, "\t$Rd, $Rn, $imm",
617 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
623 let Inst{19-16} = Rn;
624 let Inst{15-12} = Rd;
625 let Inst{11-0} = imm;
627 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
628 iir, opc, "\t$Rd, $Rn, $Rm",
629 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
633 let isCommutable = Commutable;
636 let Inst{19-16} = Rn;
637 let Inst{15-12} = Rd;
638 let Inst{11-4} = 0b00000000;
641 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
642 iis, opc, "\t$Rd, $Rn, $shift",
643 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
649 let Inst{19-16} = Rn;
650 let Inst{15-12} = Rd;
651 let Inst{11-0} = shift;
656 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
657 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
658 /// a explicit result, only implicitly set CPSR.
659 let isCompare = 1, Defs = [CPSR] in {
660 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
661 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
662 PatFrag opnode, bit Commutable = 0> {
663 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
665 [(opnode GPR:$Rn, so_imm:$imm)]> {
670 let Inst{19-16} = Rn;
671 let Inst{15-12} = 0b0000;
672 let Inst{11-0} = imm;
674 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
676 [(opnode GPR:$Rn, GPR:$Rm)]> {
679 let isCommutable = Commutable;
682 let Inst{19-16} = Rn;
683 let Inst{15-12} = 0b0000;
684 let Inst{11-4} = 0b00000000;
687 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
688 opc, "\t$Rn, $shift",
689 [(opnode GPR:$Rn, so_reg:$shift)]> {
694 let Inst{19-16} = Rn;
695 let Inst{15-12} = 0b0000;
696 let Inst{11-0} = shift;
701 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
702 /// register and one whose operand is a register rotated by 8/16/24.
703 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
704 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
705 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
706 IIC_iEXTr, opc, "\t$Rd, $Rm",
707 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
708 Requires<[IsARM, HasV6]> {
711 let Inst{19-16} = 0b1111;
712 let Inst{15-12} = Rd;
713 let Inst{11-10} = 0b00;
716 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
717 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
718 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
719 Requires<[IsARM, HasV6]> {
723 let Inst{19-16} = 0b1111;
724 let Inst{15-12} = Rd;
725 let Inst{11-10} = rot;
730 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
731 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
732 IIC_iEXTr, opc, "\t$Rd, $Rm",
733 [/* For disassembly only; pattern left blank */]>,
734 Requires<[IsARM, HasV6]> {
735 let Inst{19-16} = 0b1111;
736 let Inst{11-10} = 0b00;
738 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
739 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
740 [/* For disassembly only; pattern left blank */]>,
741 Requires<[IsARM, HasV6]> {
743 let Inst{19-16} = 0b1111;
744 let Inst{11-10} = rot;
748 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
749 /// register and one whose operand is a register rotated by 8/16/24.
750 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
751 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
752 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
753 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
754 Requires<[IsARM, HasV6]> {
755 let Inst{11-10} = 0b00;
757 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
759 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
760 [(set GPR:$Rd, (opnode GPR:$Rn,
761 (rotr GPR:$Rm, rot_imm:$rot)))]>,
762 Requires<[IsARM, HasV6]> {
765 let Inst{19-16} = Rn;
766 let Inst{11-10} = rot;
770 // For disassembly only.
771 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
772 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
773 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
774 [/* For disassembly only; pattern left blank */]>,
775 Requires<[IsARM, HasV6]> {
776 let Inst{11-10} = 0b00;
778 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
780 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
781 [/* For disassembly only; pattern left blank */]>,
782 Requires<[IsARM, HasV6]> {
785 let Inst{19-16} = Rn;
786 let Inst{11-10} = rot;
790 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
791 let Uses = [CPSR] in {
792 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
793 bit Commutable = 0> {
794 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
795 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
796 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
802 let Inst{15-12} = Rd;
803 let Inst{19-16} = Rn;
804 let Inst{11-0} = imm;
806 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
807 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
808 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
813 let Inst{11-4} = 0b00000000;
815 let isCommutable = Commutable;
817 let Inst{15-12} = Rd;
818 let Inst{19-16} = Rn;
820 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
821 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
822 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
828 let Inst{11-0} = shift;
829 let Inst{15-12} = Rd;
830 let Inst{19-16} = Rn;
833 // Carry setting variants
834 let Defs = [CPSR] in {
835 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
836 bit Commutable = 0> {
837 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
838 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
839 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
844 let Inst{15-12} = Rd;
845 let Inst{19-16} = Rn;
846 let Inst{11-0} = imm;
850 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
851 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
852 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
857 let Inst{11-4} = 0b00000000;
858 let isCommutable = Commutable;
860 let Inst{15-12} = Rd;
861 let Inst{19-16} = Rn;
865 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
866 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
867 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
872 let Inst{11-0} = shift;
873 let Inst{15-12} = Rd;
874 let Inst{19-16} = Rn;
882 let canFoldAsLoad = 1, isReMaterializable = 1 in {
883 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
884 InstrItinClass iir, PatFrag opnode> {
885 // Note: We use the complex addrmode_imm12 rather than just an input
886 // GPR and a constrained immediate so that we can use this to match
887 // frame index references and avoid matching constant pool references.
888 def i12: AIldst1<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
889 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
890 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
893 let Inst{23} = addr{12}; // U (add = ('U' == 1))
894 let Inst{19-16} = addr{16-13}; // Rn
895 let Inst{15-12} = Rt;
896 let Inst{11-0} = addr{11-0}; // imm12
898 def rs : AIldst1<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
899 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
900 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
903 let Inst{23} = shift{12}; // U (add = ('U' == 1))
904 let Inst{19-16} = shift{16-13}; // Rn
905 let Inst{15-12} = Rt;
906 let Inst{11-0} = shift{11-0};
911 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
912 InstrItinClass iir, PatFrag opnode> {
913 // Note: We use the complex addrmode_imm12 rather than just an input
914 // GPR and a constrained immediate so that we can use this to match
915 // frame index references and avoid matching constant pool references.
916 def i12 : AIldst1<0b010, 0, isByte, (outs),
917 (ins GPR:$Rt, addrmode_imm12:$addr),
918 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
919 [(opnode GPR:$Rt, 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 : AIldst1<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
928 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
929 [(opnode GPR:$Rt, 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};
938 //===----------------------------------------------------------------------===//
940 //===----------------------------------------------------------------------===//
942 //===----------------------------------------------------------------------===//
943 // Miscellaneous Instructions.
946 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
947 /// the function. The first operand is the ID# for this instruction, the second
948 /// is the index into the MachineConstantPool that this is, the third is the
949 /// size in bytes of this constant pool entry.
950 let neverHasSideEffects = 1, isNotDuplicable = 1 in
951 def CONSTPOOL_ENTRY :
952 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
953 i32imm:$size), NoItinerary, "", []>;
955 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
956 // from removing one half of the matched pairs. That breaks PEI, which assumes
957 // these will always be in pairs, and asserts if it finds otherwise. Better way?
958 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
960 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
961 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
963 def ADJCALLSTACKDOWN :
964 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
965 [(ARMcallseq_start timm:$amt)]>;
968 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
969 [/* For disassembly only; pattern left blank */]>,
970 Requires<[IsARM, HasV6T2]> {
971 let Inst{27-16} = 0b001100100000;
972 let Inst{15-8} = 0b11110000;
973 let Inst{7-0} = 0b00000000;
976 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
977 [/* For disassembly only; pattern left blank */]>,
978 Requires<[IsARM, HasV6T2]> {
979 let Inst{27-16} = 0b001100100000;
980 let Inst{15-8} = 0b11110000;
981 let Inst{7-0} = 0b00000001;
984 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
985 [/* For disassembly only; pattern left blank */]>,
986 Requires<[IsARM, HasV6T2]> {
987 let Inst{27-16} = 0b001100100000;
988 let Inst{15-8} = 0b11110000;
989 let Inst{7-0} = 0b00000010;
992 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
993 [/* For disassembly only; pattern left blank */]>,
994 Requires<[IsARM, HasV6T2]> {
995 let Inst{27-16} = 0b001100100000;
996 let Inst{15-8} = 0b11110000;
997 let Inst{7-0} = 0b00000011;
1000 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1002 [/* For disassembly only; pattern left blank */]>,
1003 Requires<[IsARM, HasV6]> {
1008 let Inst{15-12} = Rd;
1009 let Inst{19-16} = Rn;
1010 let Inst{27-20} = 0b01101000;
1011 let Inst{7-4} = 0b1011;
1012 let Inst{11-8} = 0b1111;
1015 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1016 [/* For disassembly only; pattern left blank */]>,
1017 Requires<[IsARM, HasV6T2]> {
1018 let Inst{27-16} = 0b001100100000;
1019 let Inst{15-8} = 0b11110000;
1020 let Inst{7-0} = 0b00000100;
1023 // The i32imm operand $val can be used by a debugger to store more information
1024 // about the breakpoint.
1025 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1026 [/* For disassembly only; pattern left blank */]>,
1029 let Inst{3-0} = val{3-0};
1030 let Inst{19-8} = val{15-4};
1031 let Inst{27-20} = 0b00010010;
1032 let Inst{7-4} = 0b0111;
1035 // Change Processor State is a system instruction -- for disassembly only.
1036 // The singleton $opt operand contains the following information:
1037 // opt{4-0} = mode from Inst{4-0}
1038 // opt{5} = changemode from Inst{17}
1039 // opt{8-6} = AIF from Inst{8-6}
1040 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1041 // FIXME: Integrated assembler will need these split out.
1042 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1043 [/* For disassembly only; pattern left blank */]>,
1045 let Inst{31-28} = 0b1111;
1046 let Inst{27-20} = 0b00010000;
1051 // Preload signals the memory system of possible future data/instruction access.
1052 // These are for disassembly only.
1053 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1055 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1056 !strconcat(opc, "\t$addr"),
1057 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1060 let Inst{31-26} = 0b111101;
1061 let Inst{25} = 0; // 0 for immediate form
1062 let Inst{24} = data;
1063 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1064 let Inst{22} = read;
1065 let Inst{21-20} = 0b01;
1066 let Inst{19-16} = addr{16-13}; // Rn
1067 let Inst{15-12} = Rt;
1068 let Inst{11-0} = addr{11-0}; // imm12
1071 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1072 !strconcat(opc, "\t$shift"),
1073 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1076 let Inst{31-26} = 0b111101;
1077 let Inst{25} = 1; // 1 for register form
1078 let Inst{24} = data;
1079 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1080 let Inst{22} = read;
1081 let Inst{21-20} = 0b01;
1082 let Inst{19-16} = shift{16-13}; // Rn
1083 let Inst{11-0} = shift{11-0};
1087 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1088 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1089 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1091 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1093 [/* For disassembly only; pattern left blank */]>,
1096 let Inst{31-10} = 0b1111000100000001000000;
1101 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1102 [/* For disassembly only; pattern left blank */]>,
1103 Requires<[IsARM, HasV7]> {
1105 let Inst{27-4} = 0b001100100000111100001111;
1106 let Inst{3-0} = opt;
1109 // A5.4 Permanently UNDEFINED instructions.
1110 let isBarrier = 1, isTerminator = 1 in
1111 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1114 let Inst{27-25} = 0b011;
1115 let Inst{24-20} = 0b11111;
1116 let Inst{7-5} = 0b111;
1120 // Address computation and loads and stores in PIC mode.
1121 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1122 // classes (AXI1, et.al.) and so have encoding information and such,
1123 // which is suboptimal. Once the rest of the code emitter (including
1124 // JIT) is MC-ized we should look at refactoring these into true
1125 // pseudos. As is, the encoding information ends up being ignored,
1126 // as these instructions are lowered to individual MC-insts.
1127 let isNotDuplicable = 1 in {
1128 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1129 Pseudo, IIC_iALUr, "",
1130 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1132 let AddedComplexity = 10 in {
1133 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1134 Pseudo, IIC_iLoad_r, "",
1135 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1137 def PICLDRH : AXI3ld<0b1011, (outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1138 Pseudo, IIC_iLoad_bh_r, "",
1139 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1141 def PICLDRB : AXI2ldb<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1142 Pseudo, IIC_iLoad_bh_r, "",
1143 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1145 def PICLDRSH : AXI3ld<0b1111, (outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1146 Pseudo, IIC_iLoad_bh_r, "",
1147 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1149 def PICLDRSB : AXI3ld<0b1101, (outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1150 Pseudo, IIC_iLoad_bh_r, "",
1151 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1153 let AddedComplexity = 10 in {
1154 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1155 Pseudo, IIC_iStore_r, "",
1156 [(store GPR:$src, addrmodepc:$addr)]>;
1158 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1159 Pseudo, IIC_iStore_bh_r, "",
1160 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1162 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1163 Pseudo, IIC_iStore_bh_r, "",
1164 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1166 } // isNotDuplicable = 1
1169 // LEApcrel - Load a pc-relative address into a register without offending the
1171 let neverHasSideEffects = 1 in {
1172 let isReMaterializable = 1 in
1173 // FIXME: We want one cannonical LEApcrel instruction and to express one or
1174 // both of these as pseudo-instructions that get expanded to it.
1175 def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1177 "adr$p\t$Rd, #$label", []>;
1179 } // neverHasSideEffects
1180 def LEApcrelJT : AXI1<0b0100, (outs GPR:$Rd),
1181 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1183 "adr$p\t$Rd, #${label}_${id}", []> {
1186 let Inst{31-28} = p;
1187 let Inst{27-25} = 0b001;
1189 let Inst{19-16} = 0b1111;
1190 let Inst{15-12} = Rd;
1191 // FIXME: Add label encoding/fixup
1194 //===----------------------------------------------------------------------===//
1195 // Control Flow Instructions.
1198 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1200 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1201 "bx", "\tlr", [(ARMretflag)]>,
1202 Requires<[IsARM, HasV4T]> {
1203 let Inst{27-0} = 0b0001001011111111111100011110;
1207 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1208 "mov", "\tpc, lr", [(ARMretflag)]>,
1209 Requires<[IsARM, NoV4T]> {
1210 let Inst{27-0} = 0b0001101000001111000000001110;
1214 // Indirect branches
1215 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1217 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1218 [(brind GPR:$dst)]>,
1219 Requires<[IsARM, HasV4T]> {
1221 let Inst{31-4} = 0b1110000100101111111111110001;
1222 let Inst{3-0} = dst;
1226 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1227 [(brind GPR:$dst)]>,
1228 Requires<[IsARM, NoV4T]> {
1230 let Inst{31-4} = 0b1110000110100000111100000000;
1231 let Inst{3-0} = dst;
1235 // On non-Darwin platforms R9 is callee-saved.
1237 Defs = [R0, R1, R2, R3, R12, LR,
1238 D0, D1, D2, D3, D4, D5, D6, D7,
1239 D16, D17, D18, D19, D20, D21, D22, D23,
1240 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1241 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1242 IIC_Br, "bl\t$func",
1243 [(ARMcall tglobaladdr:$func)]>,
1244 Requires<[IsARM, IsNotDarwin]> {
1245 let Inst{31-28} = 0b1110;
1247 let Inst{23-0} = func;
1250 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1251 IIC_Br, "bl", "\t$func",
1252 [(ARMcall_pred tglobaladdr:$func)]>,
1253 Requires<[IsARM, IsNotDarwin]> {
1255 let Inst{23-0} = func;
1259 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1260 IIC_Br, "blx\t$func",
1261 [(ARMcall GPR:$func)]>,
1262 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1264 let Inst{27-4} = 0b000100101111111111110011;
1265 let Inst{3-0} = func;
1269 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1270 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1271 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1272 [(ARMcall_nolink tGPR:$func)]>,
1273 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1275 let Inst{27-4} = 0b000100101111111111110001;
1276 let Inst{3-0} = func;
1280 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1281 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1282 [(ARMcall_nolink tGPR:$func)]>,
1283 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1285 let Inst{27-4} = 0b000110100000111100000000;
1286 let Inst{3-0} = func;
1290 // On Darwin R9 is call-clobbered.
1292 Defs = [R0, R1, R2, R3, R9, R12, LR,
1293 D0, D1, D2, D3, D4, D5, D6, D7,
1294 D16, D17, D18, D19, D20, D21, D22, D23,
1295 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1296 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1297 IIC_Br, "bl\t$func",
1298 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1299 let Inst{31-28} = 0b1110;
1301 let Inst{23-0} = func;
1304 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1305 IIC_Br, "bl", "\t$func",
1306 [(ARMcall_pred tglobaladdr:$func)]>,
1307 Requires<[IsARM, IsDarwin]> {
1309 let Inst{23-0} = func;
1313 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1314 IIC_Br, "blx\t$func",
1315 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1317 let Inst{27-4} = 0b000100101111111111110011;
1318 let Inst{3-0} = func;
1322 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1323 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1324 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1325 [(ARMcall_nolink tGPR:$func)]>,
1326 Requires<[IsARM, HasV4T, IsDarwin]> {
1328 let Inst{27-4} = 0b000100101111111111110001;
1329 let Inst{3-0} = func;
1333 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1334 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1335 [(ARMcall_nolink tGPR:$func)]>,
1336 Requires<[IsARM, NoV4T, IsDarwin]> {
1338 let Inst{27-4} = 0b000110100000111100000000;
1339 let Inst{3-0} = func;
1345 // FIXME: These should probably be xformed into the non-TC versions of the
1346 // instructions as part of MC lowering.
1347 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1349 let Defs = [R0, R1, R2, R3, R9, R12,
1350 D0, D1, D2, D3, D4, D5, D6, D7,
1351 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1352 D27, D28, D29, D30, D31, PC],
1354 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1356 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1358 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1360 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1362 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1363 IIC_Br, "b\t$dst @ TAILCALL",
1364 []>, Requires<[IsDarwin]>;
1366 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1367 IIC_Br, "b.w\t$dst @ TAILCALL",
1368 []>, Requires<[IsDarwin]>;
1370 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1371 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1372 []>, Requires<[IsDarwin]> {
1374 let Inst{31-4} = 0b1110000100101111111111110001;
1375 let Inst{3-0} = dst;
1379 // Non-Darwin versions (the difference is R9).
1380 let Defs = [R0, R1, R2, R3, R12,
1381 D0, D1, D2, D3, D4, D5, D6, D7,
1382 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1383 D27, D28, D29, D30, D31, PC],
1385 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1387 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1389 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1391 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1393 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1394 IIC_Br, "b\t$dst @ TAILCALL",
1395 []>, Requires<[IsARM, IsNotDarwin]>;
1397 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1398 IIC_Br, "b.w\t$dst @ TAILCALL",
1399 []>, Requires<[IsThumb, IsNotDarwin]>;
1401 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1402 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1403 []>, Requires<[IsNotDarwin]> {
1405 let Inst{31-4} = 0b1110000100101111111111110001;
1406 let Inst{3-0} = dst;
1411 let isBranch = 1, isTerminator = 1 in {
1412 // B is "predicable" since it can be xformed into a Bcc.
1413 let isBarrier = 1 in {
1414 let isPredicable = 1 in
1415 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1416 "b\t$target", [(br bb:$target)]> {
1418 let Inst{31-28} = 0b1110;
1419 let Inst{23-0} = target;
1422 let isNotDuplicable = 1, isIndirectBranch = 1,
1423 // FIXME: $imm field is not specified by asm string. Mark as cgonly.
1424 isCodeGenOnly = 1 in {
1425 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1426 IIC_Br, "mov\tpc, $target$jt",
1427 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1428 let Inst{11-4} = 0b00000000;
1429 let Inst{15-12} = 0b1111;
1430 let Inst{20} = 0; // S Bit
1431 let Inst{24-21} = 0b1101;
1432 let Inst{27-25} = 0b000;
1434 def BR_JTm : JTI<(outs),
1435 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1436 IIC_Br, "ldr\tpc, $target$jt",
1437 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1439 let Inst{15-12} = 0b1111;
1440 let Inst{20} = 1; // L bit
1441 let Inst{21} = 0; // W bit
1442 let Inst{22} = 0; // B bit
1443 let Inst{24} = 1; // P bit
1444 let Inst{27-25} = 0b011;
1446 def BR_JTadd : PseudoInst<(outs),
1447 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1449 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1451 } // isNotDuplicable = 1, isIndirectBranch = 1
1454 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1455 // a two-value operand where a dag node expects two operands. :(
1456 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1457 IIC_Br, "b", "\t$target",
1458 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1460 let Inst{23-0} = target;
1464 // Branch and Exchange Jazelle -- for disassembly only
1465 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1466 [/* For disassembly only; pattern left blank */]> {
1467 let Inst{23-20} = 0b0010;
1468 //let Inst{19-8} = 0xfff;
1469 let Inst{7-4} = 0b0010;
1472 // Secure Monitor Call is a system instruction -- for disassembly only
1473 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1474 [/* For disassembly only; pattern left blank */]> {
1476 let Inst{23-4} = 0b01100000000000000111;
1477 let Inst{3-0} = opt;
1480 // Supervisor Call (Software Interrupt) -- for disassembly only
1482 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1483 [/* For disassembly only; pattern left blank */]> {
1485 let Inst{23-0} = svc;
1489 // Store Return State is a system instruction -- for disassembly only
1490 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1491 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1492 NoItinerary, "srs${amode}\tsp!, $mode",
1493 [/* For disassembly only; pattern left blank */]> {
1494 let Inst{31-28} = 0b1111;
1495 let Inst{22-20} = 0b110; // W = 1
1498 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1499 NoItinerary, "srs${amode}\tsp, $mode",
1500 [/* For disassembly only; pattern left blank */]> {
1501 let Inst{31-28} = 0b1111;
1502 let Inst{22-20} = 0b100; // W = 0
1505 // Return From Exception is a system instruction -- for disassembly only
1506 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1507 NoItinerary, "rfe${amode}\t$base!",
1508 [/* For disassembly only; pattern left blank */]> {
1509 let Inst{31-28} = 0b1111;
1510 let Inst{22-20} = 0b011; // W = 1
1513 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1514 NoItinerary, "rfe${amode}\t$base",
1515 [/* For disassembly only; pattern left blank */]> {
1516 let Inst{31-28} = 0b1111;
1517 let Inst{22-20} = 0b001; // W = 0
1519 } // isCodeGenOnly = 1
1521 //===----------------------------------------------------------------------===//
1522 // Load / store Instructions.
1528 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1529 UnOpFrag<(load node:$Src)>>;
1530 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1531 UnOpFrag<(zextloadi8 node:$Src)>>;
1532 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1533 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1534 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1535 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1537 // Special LDR for loads from non-pc-relative constpools.
1538 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1539 isReMaterializable = 1 in
1540 def LDRcp : AIldst1<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1541 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1545 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1546 let Inst{19-16} = 0b1111;
1547 let Inst{15-12} = Rt;
1548 let Inst{11-0} = addr{11-0}; // imm12
1551 // Loads with zero extension
1552 def LDRH : AI3ld<0b1011, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1553 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1554 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1556 // Loads with sign extension
1557 def LDRSH : AI3ld<0b1111, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1558 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1559 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1561 def LDRSB : AI3ld<0b1101, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1562 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1563 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1565 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1566 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1568 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1569 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1570 []>, Requires<[IsARM, HasV5TE]>;
1573 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1574 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1575 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1576 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1578 // {13} 1 == Rm, 0 == imm12
1582 let Inst{25} = addr{13};
1583 let Inst{23} = addr{12};
1584 let Inst{19-16} = addr{17-14};
1585 let Inst{11-0} = addr{11-0};
1587 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1588 (ins GPR:$Rn, am2offset:$offset),
1589 IndexModePost, LdFrm, itin,
1590 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1591 // {13} 1 == Rm, 0 == imm12
1596 let Inst{25} = offset{13};
1597 let Inst{23} = offset{12};
1598 let Inst{19-16} = Rn;
1599 let Inst{11-0} = offset{11-0};
1603 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1604 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1606 def LDRH_PRE : AI3ldhpr<(outs GPR:$Rt, GPR:$Rn_wb),
1607 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1608 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1610 def LDRH_POST : AI3ldhpo<(outs GPR:$Rt, GPR:$Rn_wb),
1611 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1612 "ldrh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1614 def LDRSH_PRE : AI3ldshpr<(outs GPR:$Rt, GPR:$Rn_wb),
1615 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1616 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1618 def LDRSH_POST: AI3ldshpo<(outs GPR:$Rt, GPR:$Rn_wb),
1619 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1620 "ldrsh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1622 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$Rt, GPR:$Rn_wb),
1623 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1624 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1626 def LDRSB_POST: AI3ldsbpo<(outs GPR:$Rt, GPR:$Rn_wb),
1627 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1628 "ldrsb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1630 // For disassembly only
1631 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1632 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1633 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1634 Requires<[IsARM, HasV5TE]>;
1636 // For disassembly only
1637 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1638 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1639 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1640 Requires<[IsARM, HasV5TE]>;
1642 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1644 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1646 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1647 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1648 LdFrm, IIC_iLoad_ru,
1649 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1650 let Inst{21} = 1; // overwrite
1653 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1654 (ins GPR:$base,am2offset:$offset), IndexModeNone,
1655 LdFrm, IIC_iLoad_bh_ru,
1656 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1657 let Inst{21} = 1; // overwrite
1660 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1661 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1662 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1663 let Inst{21} = 1; // overwrite
1666 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1667 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1668 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1669 let Inst{21} = 1; // overwrite
1672 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1673 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1674 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1675 let Inst{21} = 1; // overwrite
1680 // Stores with truncate
1681 def STRH : AI3sth<(outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1682 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1683 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1686 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1687 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1688 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1689 StMiscFrm, IIC_iStore_d_r,
1690 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1693 def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$Rn_wb),
1694 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1695 IndexModePre, StFrm, IIC_iStore_ru,
1696 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1698 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
1699 // {13} 1 == Rm, 0 == imm12
1704 let Inst{25} = offset{13};
1705 let Inst{23} = offset{12};
1706 let Inst{19-16} = Rn;
1707 let Inst{11-0} = offset{11-0};
1710 def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
1711 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1712 IndexModePost, StFrm, IIC_iStore_ru,
1713 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1715 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
1716 // {13} 1 == Rm, 0 == imm12
1721 let Inst{25} = offset{13};
1722 let Inst{23} = offset{12};
1723 let Inst{19-16} = Rn;
1724 let Inst{11-0} = offset{11-0};
1727 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1728 (ins GPR:$src, GPR:$base,am3offset:$offset),
1729 StMiscFrm, IIC_iStore_ru,
1730 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1732 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1734 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1735 (ins GPR:$src, GPR:$base,am3offset:$offset),
1736 StMiscFrm, IIC_iStore_bh_ru,
1737 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1738 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1739 GPR:$base, am3offset:$offset))]>;
1741 def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$Rn_wb),
1742 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1743 IndexModePre, StFrm, IIC_iStore_bh_ru,
1744 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1745 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1746 GPR:$Rn, am2offset:$offset))]> {
1747 // {13} 1 == Rm, 0 == imm12
1752 let Inst{25} = offset{13};
1753 let Inst{23} = offset{12};
1754 let Inst{19-16} = Rn;
1755 let Inst{11-0} = offset{11-0};
1758 def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
1759 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1760 IndexModePost, StFrm, IIC_iStore_bh_ru,
1761 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1762 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1763 GPR:$Rn, am2offset:$offset))]> {
1764 // {13} 1 == Rm, 0 == imm12
1769 let Inst{25} = offset{13};
1770 let Inst{23} = offset{12};
1771 let Inst{19-16} = Rn;
1772 let Inst{11-0} = offset{11-0};
1775 // For disassembly only
1776 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1777 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1778 StMiscFrm, IIC_iStore_d_ru,
1779 "strd", "\t$src1, $src2, [$base, $offset]!",
1780 "$base = $base_wb", []>;
1782 // For disassembly only
1783 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1784 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1785 StMiscFrm, IIC_iStore_d_ru,
1786 "strd", "\t$src1, $src2, [$base], $offset",
1787 "$base = $base_wb", []>;
1789 // STRT, STRBT, and STRHT are for disassembly only.
1791 def STRT : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
1792 (ins GPR:$src, GPR:$base,am2offset:$offset),
1793 IndexModeNone, StFrm, IIC_iStore_ru,
1794 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1795 [/* For disassembly only; pattern left blank */]> {
1796 let Inst{21} = 1; // overwrite
1799 def STRBT : AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
1800 (ins GPR:$src, GPR:$base,am2offset:$offset),
1801 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1802 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1803 [/* For disassembly only; pattern left blank */]> {
1804 let Inst{21} = 1; // overwrite
1807 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1808 (ins GPR:$src, GPR:$base,am3offset:$offset),
1809 StMiscFrm, IIC_iStore_bh_ru,
1810 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1811 [/* For disassembly only; pattern left blank */]> {
1812 let Inst{21} = 1; // overwrite
1815 //===----------------------------------------------------------------------===//
1816 // Load / store multiple Instructions.
1819 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1820 InstrItinClass itin, InstrItinClass itin_upd> {
1822 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1823 IndexModeNone, f, itin,
1824 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1825 let Inst{24-23} = 0b01; // Increment After
1826 let Inst{21} = 0; // No writeback
1827 let Inst{20} = L_bit;
1830 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1831 IndexModeUpd, f, itin_upd,
1832 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1833 let Inst{24-23} = 0b01; // Increment After
1834 let Inst{21} = 1; // Writeback
1835 let Inst{20} = L_bit;
1838 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1839 IndexModeNone, f, itin,
1840 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1841 let Inst{24-23} = 0b00; // Decrement After
1842 let Inst{21} = 0; // No writeback
1843 let Inst{20} = L_bit;
1846 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1847 IndexModeUpd, f, itin_upd,
1848 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1849 let Inst{24-23} = 0b00; // Decrement After
1850 let Inst{21} = 1; // Writeback
1851 let Inst{20} = L_bit;
1854 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1855 IndexModeNone, f, itin,
1856 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1857 let Inst{24-23} = 0b10; // Decrement Before
1858 let Inst{21} = 0; // No writeback
1859 let Inst{20} = L_bit;
1862 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1863 IndexModeUpd, f, itin_upd,
1864 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1865 let Inst{24-23} = 0b10; // Decrement Before
1866 let Inst{21} = 1; // Writeback
1867 let Inst{20} = L_bit;
1870 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1871 IndexModeNone, f, itin,
1872 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1873 let Inst{24-23} = 0b11; // Increment Before
1874 let Inst{21} = 0; // No writeback
1875 let Inst{20} = L_bit;
1878 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1879 IndexModeUpd, f, itin_upd,
1880 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1881 let Inst{24-23} = 0b11; // Increment Before
1882 let Inst{21} = 1; // Writeback
1883 let Inst{20} = L_bit;
1887 let neverHasSideEffects = 1 in {
1889 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1890 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1892 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1893 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1895 } // neverHasSideEffects
1897 // Load / Store Multiple Mnemnoic Aliases
1898 def : MnemonicAlias<"ldm", "ldmia">;
1899 def : MnemonicAlias<"stm", "stmia">;
1901 // FIXME: remove when we have a way to marking a MI with these properties.
1902 // FIXME: Should pc be an implicit operand like PICADD, etc?
1903 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1904 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1905 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1906 reglist:$regs, variable_ops),
1907 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1908 "ldmia${p}\t$Rn!, $regs",
1910 let Inst{24-23} = 0b01; // Increment After
1911 let Inst{21} = 1; // Writeback
1912 let Inst{20} = 1; // Load
1915 //===----------------------------------------------------------------------===//
1916 // Move Instructions.
1919 let neverHasSideEffects = 1 in
1920 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1921 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1925 let Inst{11-4} = 0b00000000;
1928 let Inst{15-12} = Rd;
1931 // A version for the smaller set of tail call registers.
1932 let neverHasSideEffects = 1 in
1933 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1934 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1938 let Inst{11-4} = 0b00000000;
1941 let Inst{15-12} = Rd;
1944 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1945 DPSoRegFrm, IIC_iMOVsr,
1946 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1950 let Inst{15-12} = Rd;
1951 let Inst{11-0} = src;
1955 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1956 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1957 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1961 let Inst{15-12} = Rd;
1962 let Inst{19-16} = 0b0000;
1963 let Inst{11-0} = imm;
1966 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1967 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1969 "movw", "\t$Rd, $imm",
1970 [(set GPR:$Rd, imm0_65535:$imm)]>,
1971 Requires<[IsARM, HasV6T2]>, UnaryDP {
1974 let Inst{15-12} = Rd;
1975 let Inst{11-0} = imm{11-0};
1976 let Inst{19-16} = imm{15-12};
1981 let Constraints = "$src = $Rd" in
1982 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1984 "movt", "\t$Rd, $imm",
1986 (or (and GPR:$src, 0xffff),
1987 lo16AllZero:$imm))]>, UnaryDP,
1988 Requires<[IsARM, HasV6T2]> {
1991 let Inst{15-12} = Rd;
1992 let Inst{11-0} = imm{11-0};
1993 let Inst{19-16} = imm{15-12};
1998 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1999 Requires<[IsARM, HasV6T2]>;
2001 let Uses = [CPSR] in
2002 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
2003 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2006 // These aren't really mov instructions, but we have to define them this way
2007 // due to flag operands.
2009 let Defs = [CPSR] in {
2010 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
2011 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2013 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
2014 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2018 //===----------------------------------------------------------------------===//
2019 // Extend Instructions.
2024 defm SXTB : AI_ext_rrot<0b01101010,
2025 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2026 defm SXTH : AI_ext_rrot<0b01101011,
2027 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2029 defm SXTAB : AI_exta_rrot<0b01101010,
2030 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2031 defm SXTAH : AI_exta_rrot<0b01101011,
2032 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2034 // For disassembly only
2035 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2037 // For disassembly only
2038 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2042 let AddedComplexity = 16 in {
2043 defm UXTB : AI_ext_rrot<0b01101110,
2044 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2045 defm UXTH : AI_ext_rrot<0b01101111,
2046 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2047 defm UXTB16 : AI_ext_rrot<0b01101100,
2048 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2050 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2051 // The transformation should probably be done as a combiner action
2052 // instead so we can include a check for masking back in the upper
2053 // eight bits of the source into the lower eight bits of the result.
2054 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2055 // (UXTB16r_rot GPR:$Src, 24)>;
2056 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2057 (UXTB16r_rot GPR:$Src, 8)>;
2059 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2060 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2061 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2062 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2065 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2066 // For disassembly only
2067 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2070 def SBFX : I<(outs GPR:$Rd),
2071 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2072 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2073 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2074 Requires<[IsARM, HasV6T2]> {
2079 let Inst{27-21} = 0b0111101;
2080 let Inst{6-4} = 0b101;
2081 let Inst{20-16} = width;
2082 let Inst{15-12} = Rd;
2083 let Inst{11-7} = lsb;
2087 def UBFX : I<(outs GPR:$Rd),
2088 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2089 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2090 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2091 Requires<[IsARM, HasV6T2]> {
2096 let Inst{27-21} = 0b0111111;
2097 let Inst{6-4} = 0b101;
2098 let Inst{20-16} = width;
2099 let Inst{15-12} = Rd;
2100 let Inst{11-7} = lsb;
2104 //===----------------------------------------------------------------------===//
2105 // Arithmetic Instructions.
2108 defm ADD : AsI1_bin_irs<0b0100, "add",
2109 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2110 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2111 defm SUB : AsI1_bin_irs<0b0010, "sub",
2112 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2113 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2115 // ADD and SUB with 's' bit set.
2116 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2117 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2118 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2119 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2120 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2121 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2123 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2124 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2125 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2126 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2127 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2128 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2129 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2130 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2132 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2133 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2134 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2139 let Inst{15-12} = Rd;
2140 let Inst{19-16} = Rn;
2141 let Inst{11-0} = imm;
2144 // The reg/reg form is only defined for the disassembler; for codegen it is
2145 // equivalent to SUBrr.
2146 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2147 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2148 [/* For disassembly only; pattern left blank */]> {
2152 let Inst{11-4} = 0b00000000;
2155 let Inst{15-12} = Rd;
2156 let Inst{19-16} = Rn;
2159 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2160 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2161 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2166 let Inst{11-0} = shift;
2167 let Inst{15-12} = Rd;
2168 let Inst{19-16} = Rn;
2171 // RSB with 's' bit set.
2172 let Defs = [CPSR] in {
2173 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2174 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2175 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2181 let Inst{15-12} = Rd;
2182 let Inst{19-16} = Rn;
2183 let Inst{11-0} = imm;
2185 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2186 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2187 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2193 let Inst{11-0} = shift;
2194 let Inst{15-12} = Rd;
2195 let Inst{19-16} = Rn;
2199 let Uses = [CPSR] in {
2200 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2201 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2202 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2208 let Inst{15-12} = Rd;
2209 let Inst{19-16} = Rn;
2210 let Inst{11-0} = imm;
2212 // The reg/reg form is only defined for the disassembler; for codegen it is
2213 // equivalent to SUBrr.
2214 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2215 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2216 [/* For disassembly only; pattern left blank */]> {
2220 let Inst{11-4} = 0b00000000;
2223 let Inst{15-12} = Rd;
2224 let Inst{19-16} = Rn;
2226 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2227 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2228 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2234 let Inst{11-0} = shift;
2235 let Inst{15-12} = Rd;
2236 let Inst{19-16} = Rn;
2240 // FIXME: Allow these to be predicated.
2241 let Defs = [CPSR], Uses = [CPSR] in {
2242 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2243 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2244 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2251 let Inst{15-12} = Rd;
2252 let Inst{19-16} = Rn;
2253 let Inst{11-0} = imm;
2255 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2256 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2257 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2264 let Inst{11-0} = shift;
2265 let Inst{15-12} = Rd;
2266 let Inst{19-16} = Rn;
2270 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2271 // The assume-no-carry-in form uses the negation of the input since add/sub
2272 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2273 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2275 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2276 (SUBri GPR:$src, so_imm_neg:$imm)>;
2277 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2278 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2279 // The with-carry-in form matches bitwise not instead of the negation.
2280 // Effectively, the inverse interpretation of the carry flag already accounts
2281 // for part of the negation.
2282 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2283 (SBCri GPR:$src, so_imm_not:$imm)>;
2285 // Note: These are implemented in C++ code, because they have to generate
2286 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2288 // (mul X, 2^n+1) -> (add (X << n), X)
2289 // (mul X, 2^n-1) -> (rsb X, (X << n))
2291 // ARM Arithmetic Instruction -- for disassembly only
2292 // GPR:$dst = GPR:$a op GPR:$b
2293 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2294 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2295 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2296 opc, "\t$Rd, $Rn, $Rm", pattern> {
2300 let Inst{27-20} = op27_20;
2301 let Inst{11-4} = op11_4;
2302 let Inst{19-16} = Rn;
2303 let Inst{15-12} = Rd;
2307 // Saturating add/subtract -- for disassembly only
2309 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2310 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2311 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2312 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2313 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2314 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2316 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2317 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2318 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2319 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2320 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2321 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2322 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2323 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2324 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2325 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2326 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2327 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2329 // Signed/Unsigned add/subtract -- for disassembly only
2331 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2332 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2333 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2334 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2335 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2336 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2337 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2338 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2339 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2340 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2341 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2342 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2344 // Signed/Unsigned halving add/subtract -- for disassembly only
2346 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2347 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2348 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2349 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2350 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2351 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2352 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2353 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2354 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2355 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2356 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2357 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2359 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2361 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2362 MulFrm /* for convenience */, NoItinerary, "usad8",
2363 "\t$Rd, $Rn, $Rm", []>,
2364 Requires<[IsARM, HasV6]> {
2368 let Inst{27-20} = 0b01111000;
2369 let Inst{15-12} = 0b1111;
2370 let Inst{7-4} = 0b0001;
2371 let Inst{19-16} = Rd;
2372 let Inst{11-8} = Rm;
2375 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2376 MulFrm /* for convenience */, NoItinerary, "usada8",
2377 "\t$Rd, $Rn, $Rm, $Ra", []>,
2378 Requires<[IsARM, HasV6]> {
2383 let Inst{27-20} = 0b01111000;
2384 let Inst{7-4} = 0b0001;
2385 let Inst{19-16} = Rd;
2386 let Inst{15-12} = Ra;
2387 let Inst{11-8} = Rm;
2391 // Signed/Unsigned saturate -- for disassembly only
2393 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2394 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2395 [/* For disassembly only; pattern left blank */]> {
2400 let Inst{27-21} = 0b0110101;
2401 let Inst{5-4} = 0b01;
2402 let Inst{20-16} = sat_imm;
2403 let Inst{15-12} = Rd;
2404 let Inst{11-7} = sh{7-3};
2405 let Inst{6} = sh{0};
2409 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2410 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2411 [/* For disassembly only; pattern left blank */]> {
2415 let Inst{27-20} = 0b01101010;
2416 let Inst{11-4} = 0b11110011;
2417 let Inst{15-12} = Rd;
2418 let Inst{19-16} = sat_imm;
2422 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2423 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2424 [/* For disassembly only; pattern left blank */]> {
2429 let Inst{27-21} = 0b0110111;
2430 let Inst{5-4} = 0b01;
2431 let Inst{15-12} = Rd;
2432 let Inst{11-7} = sh{7-3};
2433 let Inst{6} = sh{0};
2434 let Inst{20-16} = sat_imm;
2438 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2439 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2440 [/* For disassembly only; pattern left blank */]> {
2444 let Inst{27-20} = 0b01101110;
2445 let Inst{11-4} = 0b11110011;
2446 let Inst{15-12} = Rd;
2447 let Inst{19-16} = sat_imm;
2451 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2452 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2454 //===----------------------------------------------------------------------===//
2455 // Bitwise Instructions.
2458 defm AND : AsI1_bin_irs<0b0000, "and",
2459 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2460 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2461 defm ORR : AsI1_bin_irs<0b1100, "orr",
2462 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2463 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2464 defm EOR : AsI1_bin_irs<0b0001, "eor",
2465 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2466 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2467 defm BIC : AsI1_bin_irs<0b1110, "bic",
2468 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2469 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2471 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2472 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2473 "bfc", "\t$Rd, $imm", "$src = $Rd",
2474 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2475 Requires<[IsARM, HasV6T2]> {
2478 let Inst{27-21} = 0b0111110;
2479 let Inst{6-0} = 0b0011111;
2480 let Inst{15-12} = Rd;
2481 let Inst{11-7} = imm{4-0}; // lsb
2482 let Inst{20-16} = imm{9-5}; // width
2485 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2486 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2487 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2488 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2489 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2490 bf_inv_mask_imm:$imm))]>,
2491 Requires<[IsARM, HasV6T2]> {
2495 let Inst{27-21} = 0b0111110;
2496 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2497 let Inst{15-12} = Rd;
2498 let Inst{11-7} = imm{4-0}; // lsb
2499 let Inst{20-16} = imm{9-5}; // width
2503 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2504 "mvn", "\t$Rd, $Rm",
2505 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2509 let Inst{19-16} = 0b0000;
2510 let Inst{11-4} = 0b00000000;
2511 let Inst{15-12} = Rd;
2514 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2515 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2516 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2520 let Inst{19-16} = 0b0000;
2521 let Inst{15-12} = Rd;
2522 let Inst{11-0} = shift;
2524 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2525 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2526 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2527 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2531 let Inst{19-16} = 0b0000;
2532 let Inst{15-12} = Rd;
2533 let Inst{11-0} = imm;
2536 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2537 (BICri GPR:$src, so_imm_not:$imm)>;
2539 //===----------------------------------------------------------------------===//
2540 // Multiply Instructions.
2542 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2543 string opc, string asm, list<dag> pattern>
2544 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2548 let Inst{19-16} = Rd;
2549 let Inst{11-8} = Rm;
2552 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2553 string opc, string asm, list<dag> pattern>
2554 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2559 let Inst{19-16} = RdHi;
2560 let Inst{15-12} = RdLo;
2561 let Inst{11-8} = Rm;
2565 let isCommutable = 1 in
2566 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2567 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2568 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2570 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2571 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2572 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2574 let Inst{15-12} = Ra;
2577 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2578 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2579 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2580 Requires<[IsARM, HasV6T2]> {
2584 let Inst{19-16} = Rd;
2585 let Inst{11-8} = Rm;
2589 // Extra precision multiplies with low / high results
2591 let neverHasSideEffects = 1 in {
2592 let isCommutable = 1 in {
2593 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2594 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2595 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2597 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2598 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2599 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2602 // Multiply + accumulate
2603 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2604 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2605 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2607 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2608 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2609 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2611 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2612 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2613 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2614 Requires<[IsARM, HasV6]> {
2619 let Inst{19-16} = RdLo;
2620 let Inst{15-12} = RdHi;
2621 let Inst{11-8} = Rm;
2624 } // neverHasSideEffects
2626 // Most significant word multiply
2627 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2628 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2629 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2630 Requires<[IsARM, HasV6]> {
2631 let Inst{15-12} = 0b1111;
2634 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2635 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2636 [/* For disassembly only; pattern left blank */]>,
2637 Requires<[IsARM, HasV6]> {
2638 let Inst{15-12} = 0b1111;
2641 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2642 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2643 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2644 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2645 Requires<[IsARM, HasV6]>;
2647 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2648 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2649 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2650 [/* For disassembly only; pattern left blank */]>,
2651 Requires<[IsARM, HasV6]>;
2653 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2654 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2655 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2656 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2657 Requires<[IsARM, HasV6]>;
2659 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2660 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2661 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2662 [/* For disassembly only; pattern left blank */]>,
2663 Requires<[IsARM, HasV6]>;
2665 multiclass AI_smul<string opc, PatFrag opnode> {
2666 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2667 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2668 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2669 (sext_inreg GPR:$Rm, i16)))]>,
2670 Requires<[IsARM, HasV5TE]>;
2672 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2673 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2674 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2675 (sra GPR:$Rm, (i32 16))))]>,
2676 Requires<[IsARM, HasV5TE]>;
2678 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2679 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2680 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2681 (sext_inreg GPR:$Rm, i16)))]>,
2682 Requires<[IsARM, HasV5TE]>;
2684 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2685 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2686 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2687 (sra GPR:$Rm, (i32 16))))]>,
2688 Requires<[IsARM, HasV5TE]>;
2690 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2691 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2692 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2693 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2694 Requires<[IsARM, HasV5TE]>;
2696 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2697 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2698 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2699 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2700 Requires<[IsARM, HasV5TE]>;
2704 multiclass AI_smla<string opc, PatFrag opnode> {
2705 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2706 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2707 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2708 [(set GPR:$Rd, (add GPR:$Ra,
2709 (opnode (sext_inreg GPR:$Rn, i16),
2710 (sext_inreg GPR:$Rm, i16))))]>,
2711 Requires<[IsARM, HasV5TE]>;
2713 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2714 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2715 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2716 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2717 (sra GPR:$Rm, (i32 16)))))]>,
2718 Requires<[IsARM, HasV5TE]>;
2720 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2721 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2722 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2723 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2724 (sext_inreg GPR:$Rm, i16))))]>,
2725 Requires<[IsARM, HasV5TE]>;
2727 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2728 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2729 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2730 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2731 (sra GPR:$Rm, (i32 16)))))]>,
2732 Requires<[IsARM, HasV5TE]>;
2734 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2735 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2736 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2737 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2738 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2739 Requires<[IsARM, HasV5TE]>;
2741 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2742 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2743 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2744 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2745 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2746 Requires<[IsARM, HasV5TE]>;
2749 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2750 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2752 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2753 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2754 (ins GPR:$Rn, GPR:$Rm),
2755 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2756 [/* For disassembly only; pattern left blank */]>,
2757 Requires<[IsARM, HasV5TE]>;
2759 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2760 (ins GPR:$Rn, GPR:$Rm),
2761 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2762 [/* For disassembly only; pattern left blank */]>,
2763 Requires<[IsARM, HasV5TE]>;
2765 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2766 (ins GPR:$Rn, GPR:$Rm),
2767 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2768 [/* For disassembly only; pattern left blank */]>,
2769 Requires<[IsARM, HasV5TE]>;
2771 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2772 (ins GPR:$Rn, GPR:$Rm),
2773 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2774 [/* For disassembly only; pattern left blank */]>,
2775 Requires<[IsARM, HasV5TE]>;
2777 // Helper class for AI_smld -- for disassembly only
2778 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2779 InstrItinClass itin, string opc, string asm>
2780 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2787 let Inst{21-20} = 0b00;
2788 let Inst{22} = long;
2789 let Inst{27-23} = 0b01110;
2790 let Inst{11-8} = Rm;
2793 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2794 InstrItinClass itin, string opc, string asm>
2795 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2797 let Inst{15-12} = 0b1111;
2798 let Inst{19-16} = Rd;
2800 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2801 InstrItinClass itin, string opc, string asm>
2802 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2804 let Inst{15-12} = Ra;
2806 class AMulDualI64<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> {
2811 let Inst{19-16} = RdHi;
2812 let Inst{15-12} = RdLo;
2815 multiclass AI_smld<bit sub, string opc> {
2817 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2818 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2820 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2821 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2823 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2824 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2825 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2827 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2828 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2829 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2833 defm SMLA : AI_smld<0, "smla">;
2834 defm SMLS : AI_smld<1, "smls">;
2836 multiclass AI_sdml<bit sub, string opc> {
2838 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2839 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2840 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2841 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2844 defm SMUA : AI_sdml<0, "smua">;
2845 defm SMUS : AI_sdml<1, "smus">;
2847 //===----------------------------------------------------------------------===//
2848 // Misc. Arithmetic Instructions.
2851 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2852 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2853 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2855 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2856 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2857 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2858 Requires<[IsARM, HasV6T2]>;
2860 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2861 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2862 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2864 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2865 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2867 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2868 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2869 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2870 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2871 Requires<[IsARM, HasV6]>;
2873 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2874 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2877 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2878 (shl GPR:$Rm, (i32 8))), i16))]>,
2879 Requires<[IsARM, HasV6]>;
2881 def lsl_shift_imm : SDNodeXForm<imm, [{
2882 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2883 return CurDAG->getTargetConstant(Sh, MVT::i32);
2886 def lsl_amt : PatLeaf<(i32 imm), [{
2887 return (N->getZExtValue() < 32);
2890 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2891 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2892 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2893 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2894 (and (shl GPR:$Rm, lsl_amt:$sh),
2896 Requires<[IsARM, HasV6]>;
2898 // Alternate cases for PKHBT where identities eliminate some nodes.
2899 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2900 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2901 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2902 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2904 def asr_shift_imm : SDNodeXForm<imm, [{
2905 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2906 return CurDAG->getTargetConstant(Sh, MVT::i32);
2909 def asr_amt : PatLeaf<(i32 imm), [{
2910 return (N->getZExtValue() <= 32);
2913 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2914 // will match the pattern below.
2915 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2916 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2917 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2918 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2919 (and (sra GPR:$Rm, asr_amt:$sh),
2921 Requires<[IsARM, HasV6]>;
2923 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2924 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2925 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2926 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2927 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2928 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2929 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2931 //===----------------------------------------------------------------------===//
2932 // Comparison Instructions...
2935 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2936 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2937 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2939 // FIXME: We have to be careful when using the CMN instruction and comparison
2940 // with 0. One would expect these two pieces of code should give identical
2956 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2957 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2958 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2959 // value of r0 and the carry bit (because the "carry bit" parameter to
2960 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2961 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2962 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2963 // parameter to AddWithCarry is defined as 0).
2965 // When x is 0 and unsigned:
2969 // ~x + 1 = 0x1 0000 0000
2970 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2972 // Therefore, we should disable CMN when comparing against zero, until we can
2973 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2974 // when it's a comparison which doesn't look at the 'carry' flag).
2976 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2978 // This is related to <rdar://problem/7569620>.
2980 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2981 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2983 // Note that TST/TEQ don't set all the same flags that CMP does!
2984 defm TST : AI1_cmp_irs<0b1000, "tst",
2985 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2986 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
2987 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2988 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2989 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
2991 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2992 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2993 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2994 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2995 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2996 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2998 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2999 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3001 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3002 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3004 // Pseudo i64 compares for some floating point compares.
3005 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3007 def BCCi64 : PseudoInst<(outs),
3008 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3010 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3012 def BCCZi64 : PseudoInst<(outs),
3013 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
3014 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3015 } // usesCustomInserter
3018 // Conditional moves
3019 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3020 // a two-value operand where a dag node expects two operands. :(
3021 // FIXME: These should all be pseudo-instructions that get expanded to
3022 // the normal MOV instructions. That would fix the dependency on
3023 // special casing them in tblgen.
3024 let neverHasSideEffects = 1 in {
3025 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3026 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3027 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3028 RegConstraint<"$false = $Rd">, UnaryDP {
3033 let Inst{15-12} = Rd;
3034 let Inst{11-4} = 0b00000000;
3038 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3039 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3040 "mov", "\t$Rd, $shift",
3041 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3042 RegConstraint<"$false = $Rd">, UnaryDP {
3047 let Inst{19-16} = 0;
3048 let Inst{15-12} = Rd;
3049 let Inst{11-0} = shift;
3052 let isMoveImm = 1 in
3053 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
3055 "movw", "\t$Rd, $imm",
3057 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3063 let Inst{19-16} = imm{15-12};
3064 let Inst{15-12} = Rd;
3065 let Inst{11-0} = imm{11-0};
3068 let isMoveImm = 1 in
3069 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3070 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3071 "mov", "\t$Rd, $imm",
3072 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3073 RegConstraint<"$false = $Rd">, UnaryDP {
3078 let Inst{19-16} = 0b0000;
3079 let Inst{15-12} = Rd;
3080 let Inst{11-0} = imm;
3083 // Two instruction predicate mov immediate.
3084 let isMoveImm = 1 in
3085 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3086 (ins GPR:$false, i32imm:$src, pred:$p),
3087 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $Rd">;
3089 let isMoveImm = 1 in
3090 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3091 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3092 "mvn", "\t$Rd, $imm",
3093 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3094 RegConstraint<"$false = $Rd">, UnaryDP {
3099 let Inst{19-16} = 0b0000;
3100 let Inst{15-12} = Rd;
3101 let Inst{11-0} = imm;
3103 } // neverHasSideEffects
3105 //===----------------------------------------------------------------------===//
3106 // Atomic operations intrinsics
3109 def memb_opt : Operand<i32> {
3110 let PrintMethod = "printMemBOption";
3113 // memory barriers protect the atomic sequences
3114 let hasSideEffects = 1 in {
3115 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3116 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3117 Requires<[IsARM, HasDB]> {
3119 let Inst{31-4} = 0xf57ff05;
3120 let Inst{3-0} = opt;
3123 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3124 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3125 [(ARMMemBarrierMCR GPR:$zero)]>,
3126 Requires<[IsARM, HasV6]> {
3127 // FIXME: add encoding
3131 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3133 [/* For disassembly only; pattern left blank */]>,
3134 Requires<[IsARM, HasDB]> {
3136 let Inst{31-4} = 0xf57ff04;
3137 let Inst{3-0} = opt;
3140 // ISB has only full system option -- for disassembly only
3141 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3142 Requires<[IsARM, HasDB]> {
3143 let Inst{31-4} = 0xf57ff06;
3144 let Inst{3-0} = 0b1111;
3147 let usesCustomInserter = 1 in {
3148 let Uses = [CPSR] in {
3149 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3150 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3151 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3152 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3153 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3154 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3155 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3156 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3157 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3158 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3159 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3160 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3161 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3162 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3163 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3164 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3165 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3166 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3167 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3168 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3169 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3170 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3171 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3172 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3173 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3174 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3175 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3176 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3177 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3178 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3179 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3180 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3181 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3182 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3183 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3184 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3185 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3186 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3187 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3188 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3189 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3190 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3191 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3192 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3193 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3194 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3195 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3196 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3197 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3198 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3199 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3200 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3201 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3202 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3204 def ATOMIC_SWAP_I8 : PseudoInst<
3205 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3206 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3207 def ATOMIC_SWAP_I16 : PseudoInst<
3208 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3209 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3210 def ATOMIC_SWAP_I32 : PseudoInst<
3211 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3212 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3214 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3215 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3216 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3217 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3218 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3219 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3220 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3221 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3222 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3226 let mayLoad = 1 in {
3227 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3228 "ldrexb", "\t$Rt, [$Rn]",
3230 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3231 "ldrexh", "\t$Rt, [$Rn]",
3233 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3234 "ldrex", "\t$Rt, [$Rn]",
3236 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3238 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3242 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3243 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3245 "strexb", "\t$Rd, $src, [$Rn]",
3247 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3249 "strexh", "\t$Rd, $Rt, [$Rn]",
3251 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3253 "strex", "\t$Rd, $Rt, [$Rn]",
3255 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3256 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3258 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3262 // Clear-Exclusive is for disassembly only.
3263 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3264 [/* For disassembly only; pattern left blank */]>,
3265 Requires<[IsARM, HasV7]> {
3266 let Inst{31-0} = 0b11110101011111111111000000011111;
3269 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3270 let mayLoad = 1 in {
3271 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3272 [/* For disassembly only; pattern left blank */]>;
3273 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3274 [/* For disassembly only; pattern left blank */]>;
3277 //===----------------------------------------------------------------------===//
3281 // __aeabi_read_tp preserves the registers r1-r3.
3282 // FIXME: This needs to be a pseudo of some sort so that we can get the
3283 // encoding right, complete with fixup for the aeabi_read_tp function.
3285 Defs = [R0, R12, LR, CPSR] in {
3286 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3287 "bl\t__aeabi_read_tp",
3288 [(set R0, ARMthread_pointer)]>;
3291 //===----------------------------------------------------------------------===//
3292 // SJLJ Exception handling intrinsics
3293 // eh_sjlj_setjmp() is an instruction sequence to store the return
3294 // address and save #0 in R0 for the non-longjmp case.
3295 // Since by its nature we may be coming from some other function to get
3296 // here, and we're using the stack frame for the containing function to
3297 // save/restore registers, we can't keep anything live in regs across
3298 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3299 // when we get here from a longjmp(). We force everthing out of registers
3300 // except for our own input by listing the relevant registers in Defs. By
3301 // doing so, we also cause the prologue/epilogue code to actively preserve
3302 // all of the callee-saved resgisters, which is exactly what we want.
3303 // A constant value is passed in $val, and we use the location as a scratch.
3305 // These are pseudo-instructions and are lowered to individual MC-insts, so
3306 // no encoding information is necessary.
3308 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3309 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3310 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3311 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3312 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3313 AddrModeNone, SizeSpecial, IndexModeNone,
3314 Pseudo, NoItinerary, "", "",
3315 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3316 Requires<[IsARM, HasVFP2]>;
3320 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3321 hasSideEffects = 1, isBarrier = 1 in {
3322 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3323 AddrModeNone, SizeSpecial, IndexModeNone,
3324 Pseudo, NoItinerary, "", "",
3325 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3326 Requires<[IsARM, NoVFP]>;
3329 // FIXME: Non-Darwin version(s)
3330 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3331 Defs = [ R7, LR, SP ] in {
3332 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3333 AddrModeNone, SizeSpecial, IndexModeNone,
3334 Pseudo, NoItinerary, "", "",
3335 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3336 Requires<[IsARM, IsDarwin]>;
3339 // eh.sjlj.dispatchsetup pseudo-instruction.
3340 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3341 // handled when the pseudo is expanded (which happens before any passes
3342 // that need the instruction size).
3343 let isBarrier = 1, hasSideEffects = 1 in
3344 def Int_eh_sjlj_dispatchsetup :
3345 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3346 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3347 Requires<[IsDarwin]>;
3349 //===----------------------------------------------------------------------===//
3350 // Non-Instruction Patterns
3353 // Large immediate handling.
3355 // 32-bit immediate using two piece so_imms or movw + movt.
3356 // This is a single pseudo instruction, the benefit is that it can be remat'd
3357 // as a single unit instead of having to handle reg inputs.
3358 // FIXME: Remove this when we can do generalized remat.
3359 let isReMaterializable = 1, isMoveImm = 1 in
3360 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3361 [(set GPR:$dst, (arm_i32imm:$src))]>,
3364 // ConstantPool, GlobalAddress, and JumpTable
3365 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3366 Requires<[IsARM, DontUseMovt]>;
3367 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3368 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3369 Requires<[IsARM, UseMovt]>;
3370 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3371 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3373 // TODO: add,sub,and, 3-instr forms?
3376 def : ARMPat<(ARMtcret tcGPR:$dst),
3377 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3379 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3380 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3382 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3383 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3385 def : ARMPat<(ARMtcret tcGPR:$dst),
3386 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3388 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3389 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3391 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3392 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3395 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3396 Requires<[IsARM, IsNotDarwin]>;
3397 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3398 Requires<[IsARM, IsDarwin]>;
3400 // zextload i1 -> zextload i8
3401 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3402 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3404 // extload -> zextload
3405 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3406 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3407 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3408 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3410 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3412 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3413 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3416 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3417 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3418 (SMULBB GPR:$a, GPR:$b)>;
3419 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3420 (SMULBB GPR:$a, GPR:$b)>;
3421 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3422 (sra GPR:$b, (i32 16))),
3423 (SMULBT GPR:$a, GPR:$b)>;
3424 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3425 (SMULBT GPR:$a, GPR:$b)>;
3426 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3427 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3428 (SMULTB GPR:$a, GPR:$b)>;
3429 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3430 (SMULTB GPR:$a, GPR:$b)>;
3431 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3433 (SMULWB GPR:$a, GPR:$b)>;
3434 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3435 (SMULWB GPR:$a, GPR:$b)>;
3437 def : ARMV5TEPat<(add GPR:$acc,
3438 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3439 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3440 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3441 def : ARMV5TEPat<(add GPR:$acc,
3442 (mul sext_16_node:$a, sext_16_node:$b)),
3443 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3444 def : ARMV5TEPat<(add GPR:$acc,
3445 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3446 (sra GPR:$b, (i32 16)))),
3447 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3448 def : ARMV5TEPat<(add GPR:$acc,
3449 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3450 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3451 def : ARMV5TEPat<(add GPR:$acc,
3452 (mul (sra GPR:$a, (i32 16)),
3453 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3454 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3455 def : ARMV5TEPat<(add GPR:$acc,
3456 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3457 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3458 def : ARMV5TEPat<(add GPR:$acc,
3459 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3461 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3462 def : ARMV5TEPat<(add GPR:$acc,
3463 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3464 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3466 //===----------------------------------------------------------------------===//
3470 include "ARMInstrThumb.td"
3472 //===----------------------------------------------------------------------===//
3476 include "ARMInstrThumb2.td"
3478 //===----------------------------------------------------------------------===//
3479 // Floating Point Support
3482 include "ARMInstrVFP.td"
3484 //===----------------------------------------------------------------------===//
3485 // Advanced SIMD (NEON) Support
3488 include "ARMInstrNEON.td"
3490 //===----------------------------------------------------------------------===//
3491 // Coprocessor Instructions. For disassembly only.
3494 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3495 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3496 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3497 [/* For disassembly only; pattern left blank */]> {
3501 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3502 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3503 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3504 [/* For disassembly only; pattern left blank */]> {
3505 let Inst{31-28} = 0b1111;
3509 class ACI<dag oops, dag iops, string opc, string asm>
3510 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3511 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3512 let Inst{27-25} = 0b110;
3515 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3517 def _OFFSET : ACI<(outs),
3518 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3519 opc, "\tp$cop, cr$CRd, $addr"> {
3520 let Inst{31-28} = op31_28;
3521 let Inst{24} = 1; // P = 1
3522 let Inst{21} = 0; // W = 0
3523 let Inst{22} = 0; // D = 0
3524 let Inst{20} = load;
3527 def _PRE : ACI<(outs),
3528 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3529 opc, "\tp$cop, cr$CRd, $addr!"> {
3530 let Inst{31-28} = op31_28;
3531 let Inst{24} = 1; // P = 1
3532 let Inst{21} = 1; // W = 1
3533 let Inst{22} = 0; // D = 0
3534 let Inst{20} = load;
3537 def _POST : ACI<(outs),
3538 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3539 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3540 let Inst{31-28} = op31_28;
3541 let Inst{24} = 0; // P = 0
3542 let Inst{21} = 1; // W = 1
3543 let Inst{22} = 0; // D = 0
3544 let Inst{20} = load;
3547 def _OPTION : ACI<(outs),
3548 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3549 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3550 let Inst{31-28} = op31_28;
3551 let Inst{24} = 0; // P = 0
3552 let Inst{23} = 1; // U = 1
3553 let Inst{21} = 0; // W = 0
3554 let Inst{22} = 0; // D = 0
3555 let Inst{20} = load;
3558 def L_OFFSET : ACI<(outs),
3559 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3560 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3561 let Inst{31-28} = op31_28;
3562 let Inst{24} = 1; // P = 1
3563 let Inst{21} = 0; // W = 0
3564 let Inst{22} = 1; // D = 1
3565 let Inst{20} = load;
3568 def L_PRE : ACI<(outs),
3569 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3570 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3571 let Inst{31-28} = op31_28;
3572 let Inst{24} = 1; // P = 1
3573 let Inst{21} = 1; // W = 1
3574 let Inst{22} = 1; // D = 1
3575 let Inst{20} = load;
3578 def L_POST : ACI<(outs),
3579 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3580 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3581 let Inst{31-28} = op31_28;
3582 let Inst{24} = 0; // P = 0
3583 let Inst{21} = 1; // W = 1
3584 let Inst{22} = 1; // D = 1
3585 let Inst{20} = load;
3588 def L_OPTION : ACI<(outs),
3589 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3590 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3591 let Inst{31-28} = op31_28;
3592 let Inst{24} = 0; // P = 0
3593 let Inst{23} = 1; // U = 1
3594 let Inst{21} = 0; // W = 0
3595 let Inst{22} = 1; // D = 1
3596 let Inst{20} = load;
3600 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3601 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3602 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3603 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3605 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3606 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3607 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3608 [/* For disassembly only; pattern left blank */]> {
3613 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3614 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3615 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3616 [/* For disassembly only; pattern left blank */]> {
3617 let Inst{31-28} = 0b1111;
3622 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3623 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3624 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3625 [/* For disassembly only; pattern left blank */]> {
3630 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3631 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3632 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3633 [/* For disassembly only; pattern left blank */]> {
3634 let Inst{31-28} = 0b1111;
3639 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3640 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3641 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3642 [/* For disassembly only; pattern left blank */]> {
3643 let Inst{23-20} = 0b0100;
3646 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3647 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3648 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3649 [/* For disassembly only; pattern left blank */]> {
3650 let Inst{31-28} = 0b1111;
3651 let Inst{23-20} = 0b0100;
3654 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3655 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3656 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3657 [/* For disassembly only; pattern left blank */]> {
3658 let Inst{23-20} = 0b0101;
3661 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3662 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3663 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3664 [/* For disassembly only; pattern left blank */]> {
3665 let Inst{31-28} = 0b1111;
3666 let Inst{23-20} = 0b0101;
3669 //===----------------------------------------------------------------------===//
3670 // Move between special register and ARM core register -- for disassembly only
3673 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3674 [/* For disassembly only; pattern left blank */]> {
3675 let Inst{23-20} = 0b0000;
3676 let Inst{7-4} = 0b0000;
3679 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3680 [/* For disassembly only; pattern left blank */]> {
3681 let Inst{23-20} = 0b0100;
3682 let Inst{7-4} = 0b0000;
3685 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3686 "msr", "\tcpsr$mask, $src",
3687 [/* For disassembly only; pattern left blank */]> {
3688 let Inst{23-20} = 0b0010;
3689 let Inst{7-4} = 0b0000;
3692 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3693 "msr", "\tcpsr$mask, $a",
3694 [/* For disassembly only; pattern left blank */]> {
3695 let Inst{23-20} = 0b0010;
3696 let Inst{7-4} = 0b0000;
3699 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3700 "msr", "\tspsr$mask, $src",
3701 [/* For disassembly only; pattern left blank */]> {
3702 let Inst{23-20} = 0b0110;
3703 let Inst{7-4} = 0b0000;
3706 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3707 "msr", "\tspsr$mask, $a",
3708 [/* For disassembly only; pattern left blank */]> {
3709 let Inst{23-20} = 0b0110;
3710 let Inst{7-4} = 0b0000;