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 // For movt/movw - sets the MC Encoder method.
446 // The imm is split into imm{15-12}, imm{11-0}
448 def movt_imm : Operand<i32> {
449 let EncoderMethod = "getMovtImmOpValue";
452 // Define ARM specific addressing modes.
455 // addrmode_imm12 := reg +/- imm12
457 def addrmode_imm12 : Operand<i32>,
458 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
459 // 12-bit immediate operand. Note that instructions using this encode
460 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
461 // immediate values are as normal.
463 let EncoderMethod = "getAddrModeImm12OpValue";
464 let PrintMethod = "printAddrModeImm12Operand";
465 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
467 // ldst_so_reg := reg +/- reg shop imm
469 def ldst_so_reg : Operand<i32>,
470 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
471 let EncoderMethod = "getLdStSORegOpValue";
472 // FIXME: Simplify the printer
473 let PrintMethod = "printAddrMode2Operand";
474 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
477 // addrmode2 := reg +/- imm12
478 // := reg +/- reg shop imm
480 def addrmode2 : Operand<i32>,
481 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
482 string EncoderMethod = "getAddrMode2OpValue";
483 let PrintMethod = "printAddrMode2Operand";
484 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
487 def am2offset : Operand<i32>,
488 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
489 [], [SDNPWantRoot]> {
490 string EncoderMethod = "getAddrMode2OffsetOpValue";
491 let PrintMethod = "printAddrMode2OffsetOperand";
492 let MIOperandInfo = (ops GPR, i32imm);
495 // addrmode3 := reg +/- reg
496 // addrmode3 := reg +/- imm8
498 def addrmode3 : Operand<i32>,
499 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
500 let EncoderMethod = "getAddrMode3OpValue";
501 let PrintMethod = "printAddrMode3Operand";
502 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
505 def am3offset : Operand<i32>,
506 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
507 [], [SDNPWantRoot]> {
508 let EncoderMethod = "getAddrMode3OffsetOpValue";
509 let PrintMethod = "printAddrMode3OffsetOperand";
510 let MIOperandInfo = (ops GPR, i32imm);
513 // ldstm_mode := {ia, ib, da, db}
515 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
516 let EncoderMethod = "getLdStmModeOpValue";
517 let PrintMethod = "printLdStmModeOperand";
520 def MemMode5AsmOperand : AsmOperandClass {
521 let Name = "MemMode5";
522 let SuperClasses = [];
525 // addrmode5 := reg +/- imm8*4
527 def addrmode5 : Operand<i32>,
528 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
529 let PrintMethod = "printAddrMode5Operand";
530 let MIOperandInfo = (ops GPR:$base, i32imm);
531 let ParserMatchClass = MemMode5AsmOperand;
532 let EncoderMethod = "getAddrMode5OpValue";
535 // addrmode6 := reg with optional writeback
537 def addrmode6 : Operand<i32>,
538 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
539 let PrintMethod = "printAddrMode6Operand";
540 let MIOperandInfo = (ops GPR:$addr, i32imm);
541 let EncoderMethod = "getAddrMode6AddressOpValue";
544 def am6offset : Operand<i32> {
545 let PrintMethod = "printAddrMode6OffsetOperand";
546 let MIOperandInfo = (ops GPR);
547 let EncoderMethod = "getAddrMode6OffsetOpValue";
550 // addrmodepc := pc + reg
552 def addrmodepc : Operand<i32>,
553 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
554 let PrintMethod = "printAddrModePCOperand";
555 let MIOperandInfo = (ops GPR, i32imm);
558 def nohash_imm : Operand<i32> {
559 let PrintMethod = "printNoHashImmediate";
562 //===----------------------------------------------------------------------===//
564 include "ARMInstrFormats.td"
566 //===----------------------------------------------------------------------===//
567 // Multiclass helpers...
570 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
571 /// binop that produces a value.
572 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
573 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
574 PatFrag opnode, bit Commutable = 0> {
575 // The register-immediate version is re-materializable. This is useful
576 // in particular for taking the address of a local.
577 let isReMaterializable = 1 in {
578 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
579 iii, opc, "\t$Rd, $Rn, $imm",
580 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
585 let Inst{19-16} = Rn;
586 let Inst{15-12} = Rd;
587 let Inst{11-0} = imm;
590 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
591 iir, opc, "\t$Rd, $Rn, $Rm",
592 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
597 let isCommutable = Commutable;
598 let Inst{19-16} = Rn;
599 let Inst{15-12} = Rd;
600 let Inst{11-4} = 0b00000000;
603 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
604 iis, opc, "\t$Rd, $Rn, $shift",
605 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
610 let Inst{19-16} = Rn;
611 let Inst{15-12} = Rd;
612 let Inst{11-0} = shift;
616 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
617 /// instruction modifies the CPSR register.
618 let Defs = [CPSR] in {
619 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
620 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
621 PatFrag opnode, bit Commutable = 0> {
622 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
623 iii, opc, "\t$Rd, $Rn, $imm",
624 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
630 let Inst{19-16} = Rn;
631 let Inst{15-12} = Rd;
632 let Inst{11-0} = imm;
634 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
635 iir, opc, "\t$Rd, $Rn, $Rm",
636 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
640 let isCommutable = Commutable;
643 let Inst{19-16} = Rn;
644 let Inst{15-12} = Rd;
645 let Inst{11-4} = 0b00000000;
648 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
649 iis, opc, "\t$Rd, $Rn, $shift",
650 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
656 let Inst{19-16} = Rn;
657 let Inst{15-12} = Rd;
658 let Inst{11-0} = shift;
663 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
664 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
665 /// a explicit result, only implicitly set CPSR.
666 let isCompare = 1, Defs = [CPSR] in {
667 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
668 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
669 PatFrag opnode, bit Commutable = 0> {
670 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
672 [(opnode GPR:$Rn, so_imm:$imm)]> {
677 let Inst{19-16} = Rn;
678 let Inst{15-12} = 0b0000;
679 let Inst{11-0} = imm;
681 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
683 [(opnode GPR:$Rn, GPR:$Rm)]> {
686 let isCommutable = Commutable;
689 let Inst{19-16} = Rn;
690 let Inst{15-12} = 0b0000;
691 let Inst{11-4} = 0b00000000;
694 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
695 opc, "\t$Rn, $shift",
696 [(opnode GPR:$Rn, so_reg:$shift)]> {
701 let Inst{19-16} = Rn;
702 let Inst{15-12} = 0b0000;
703 let Inst{11-0} = shift;
708 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
709 /// register and one whose operand is a register rotated by 8/16/24.
710 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
711 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
712 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
713 IIC_iEXTr, opc, "\t$Rd, $Rm",
714 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
715 Requires<[IsARM, HasV6]> {
718 let Inst{19-16} = 0b1111;
719 let Inst{15-12} = Rd;
720 let Inst{11-10} = 0b00;
723 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
724 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
725 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
726 Requires<[IsARM, HasV6]> {
730 let Inst{19-16} = 0b1111;
731 let Inst{15-12} = Rd;
732 let Inst{11-10} = rot;
737 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
738 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
739 IIC_iEXTr, opc, "\t$Rd, $Rm",
740 [/* For disassembly only; pattern left blank */]>,
741 Requires<[IsARM, HasV6]> {
742 let Inst{19-16} = 0b1111;
743 let Inst{11-10} = 0b00;
745 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
746 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
747 [/* For disassembly only; pattern left blank */]>,
748 Requires<[IsARM, HasV6]> {
750 let Inst{19-16} = 0b1111;
751 let Inst{11-10} = rot;
755 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
756 /// register and one whose operand is a register rotated by 8/16/24.
757 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
758 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
759 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
760 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
761 Requires<[IsARM, HasV6]> {
765 let Inst{19-16} = Rn;
766 let Inst{15-12} = Rd;
767 let Inst{11-10} = 0b00;
768 let Inst{9-4} = 0b000111;
771 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
773 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
774 [(set GPR:$Rd, (opnode GPR:$Rn,
775 (rotr GPR:$Rm, rot_imm:$rot)))]>,
776 Requires<[IsARM, HasV6]> {
781 let Inst{19-16} = Rn;
782 let Inst{15-12} = Rd;
783 let Inst{11-10} = rot;
784 let Inst{9-4} = 0b000111;
789 // For disassembly only.
790 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
791 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
792 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
793 [/* For disassembly only; pattern left blank */]>,
794 Requires<[IsARM, HasV6]> {
795 let Inst{11-10} = 0b00;
797 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
799 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
800 [/* For disassembly only; pattern left blank */]>,
801 Requires<[IsARM, HasV6]> {
804 let Inst{19-16} = Rn;
805 let Inst{11-10} = rot;
809 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
810 let Uses = [CPSR] in {
811 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
812 bit Commutable = 0> {
813 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
814 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
815 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
821 let Inst{15-12} = Rd;
822 let Inst{19-16} = Rn;
823 let Inst{11-0} = imm;
825 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
826 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
827 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
832 let Inst{11-4} = 0b00000000;
834 let isCommutable = Commutable;
836 let Inst{15-12} = Rd;
837 let Inst{19-16} = Rn;
839 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
840 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
841 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
847 let Inst{11-0} = shift;
848 let Inst{15-12} = Rd;
849 let Inst{19-16} = Rn;
852 // Carry setting variants
853 let Defs = [CPSR] in {
854 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
855 bit Commutable = 0> {
856 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
857 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
858 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
863 let Inst{15-12} = Rd;
864 let Inst{19-16} = Rn;
865 let Inst{11-0} = imm;
869 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
870 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
871 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
876 let Inst{11-4} = 0b00000000;
877 let isCommutable = Commutable;
879 let Inst{15-12} = Rd;
880 let Inst{19-16} = Rn;
884 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
885 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
886 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
891 let Inst{11-0} = shift;
892 let Inst{15-12} = Rd;
893 let Inst{19-16} = Rn;
901 let canFoldAsLoad = 1, isReMaterializable = 1 in {
902 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
903 InstrItinClass iir, PatFrag opnode> {
904 // Note: We use the complex addrmode_imm12 rather than just an input
905 // GPR and a constrained immediate so that we can use this to match
906 // frame index references and avoid matching constant pool references.
907 def i12: AIldst1<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
908 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
909 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
912 let Inst{23} = addr{12}; // U (add = ('U' == 1))
913 let Inst{19-16} = addr{16-13}; // Rn
914 let Inst{15-12} = Rt;
915 let Inst{11-0} = addr{11-0}; // imm12
917 def rs : AIldst1<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
918 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
919 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
922 let Inst{23} = shift{12}; // U (add = ('U' == 1))
923 let Inst{19-16} = shift{16-13}; // Rn
924 let Inst{15-12} = Rt;
925 let Inst{11-0} = shift{11-0};
930 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
931 InstrItinClass iir, PatFrag opnode> {
932 // Note: We use the complex addrmode_imm12 rather than just an input
933 // GPR and a constrained immediate so that we can use this to match
934 // frame index references and avoid matching constant pool references.
935 def i12 : AIldst1<0b010, 0, isByte, (outs),
936 (ins GPR:$Rt, addrmode_imm12:$addr),
937 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
938 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
941 let Inst{23} = addr{12}; // U (add = ('U' == 1))
942 let Inst{19-16} = addr{16-13}; // Rn
943 let Inst{15-12} = Rt;
944 let Inst{11-0} = addr{11-0}; // imm12
946 def rs : AIldst1<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
947 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
948 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
951 let Inst{23} = shift{12}; // U (add = ('U' == 1))
952 let Inst{19-16} = shift{16-13}; // Rn
953 let Inst{15-12} = Rt;
954 let Inst{11-0} = shift{11-0};
957 //===----------------------------------------------------------------------===//
959 //===----------------------------------------------------------------------===//
961 //===----------------------------------------------------------------------===//
962 // Miscellaneous Instructions.
965 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
966 /// the function. The first operand is the ID# for this instruction, the second
967 /// is the index into the MachineConstantPool that this is, the third is the
968 /// size in bytes of this constant pool entry.
969 let neverHasSideEffects = 1, isNotDuplicable = 1 in
970 def CONSTPOOL_ENTRY :
971 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
972 i32imm:$size), NoItinerary, []>;
974 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
975 // from removing one half of the matched pairs. That breaks PEI, which assumes
976 // these will always be in pairs, and asserts if it finds otherwise. Better way?
977 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
979 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
980 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
982 def ADJCALLSTACKDOWN :
983 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
984 [(ARMcallseq_start timm:$amt)]>;
987 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
988 [/* For disassembly only; pattern left blank */]>,
989 Requires<[IsARM, HasV6T2]> {
990 let Inst{27-16} = 0b001100100000;
991 let Inst{15-8} = 0b11110000;
992 let Inst{7-0} = 0b00000000;
995 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
996 [/* For disassembly only; pattern left blank */]>,
997 Requires<[IsARM, HasV6T2]> {
998 let Inst{27-16} = 0b001100100000;
999 let Inst{15-8} = 0b11110000;
1000 let Inst{7-0} = 0b00000001;
1003 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
1004 [/* For disassembly only; pattern left blank */]>,
1005 Requires<[IsARM, HasV6T2]> {
1006 let Inst{27-16} = 0b001100100000;
1007 let Inst{15-8} = 0b11110000;
1008 let Inst{7-0} = 0b00000010;
1011 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
1012 [/* For disassembly only; pattern left blank */]>,
1013 Requires<[IsARM, HasV6T2]> {
1014 let Inst{27-16} = 0b001100100000;
1015 let Inst{15-8} = 0b11110000;
1016 let Inst{7-0} = 0b00000011;
1019 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
1021 [/* For disassembly only; pattern left blank */]>,
1022 Requires<[IsARM, HasV6]> {
1027 let Inst{15-12} = Rd;
1028 let Inst{19-16} = Rn;
1029 let Inst{27-20} = 0b01101000;
1030 let Inst{7-4} = 0b1011;
1031 let Inst{11-8} = 0b1111;
1034 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1035 [/* For disassembly only; pattern left blank */]>,
1036 Requires<[IsARM, HasV6T2]> {
1037 let Inst{27-16} = 0b001100100000;
1038 let Inst{15-8} = 0b11110000;
1039 let Inst{7-0} = 0b00000100;
1042 // The i32imm operand $val can be used by a debugger to store more information
1043 // about the breakpoint.
1044 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1045 [/* For disassembly only; pattern left blank */]>,
1048 let Inst{3-0} = val{3-0};
1049 let Inst{19-8} = val{15-4};
1050 let Inst{27-20} = 0b00010010;
1051 let Inst{7-4} = 0b0111;
1054 // Change Processor State is a system instruction -- for disassembly only.
1055 // The singleton $opt operand contains the following information:
1056 // opt{4-0} = mode from Inst{4-0}
1057 // opt{5} = changemode from Inst{17}
1058 // opt{8-6} = AIF from Inst{8-6}
1059 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1060 // FIXME: Integrated assembler will need these split out.
1061 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1062 [/* For disassembly only; pattern left blank */]>,
1064 let Inst{31-28} = 0b1111;
1065 let Inst{27-20} = 0b00010000;
1070 // Preload signals the memory system of possible future data/instruction access.
1071 // These are for disassembly only.
1072 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1074 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1075 !strconcat(opc, "\t$addr"),
1076 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1079 let Inst{31-26} = 0b111101;
1080 let Inst{25} = 0; // 0 for immediate form
1081 let Inst{24} = data;
1082 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1083 let Inst{22} = read;
1084 let Inst{21-20} = 0b01;
1085 let Inst{19-16} = addr{16-13}; // Rn
1086 let Inst{15-12} = Rt;
1087 let Inst{11-0} = addr{11-0}; // imm12
1090 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1091 !strconcat(opc, "\t$shift"),
1092 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1095 let Inst{31-26} = 0b111101;
1096 let Inst{25} = 1; // 1 for register form
1097 let Inst{24} = data;
1098 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1099 let Inst{22} = read;
1100 let Inst{21-20} = 0b01;
1101 let Inst{19-16} = shift{16-13}; // Rn
1102 let Inst{11-0} = shift{11-0};
1106 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1107 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1108 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1110 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1112 [/* For disassembly only; pattern left blank */]>,
1115 let Inst{31-10} = 0b1111000100000001000000;
1120 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1121 [/* For disassembly only; pattern left blank */]>,
1122 Requires<[IsARM, HasV7]> {
1124 let Inst{27-4} = 0b001100100000111100001111;
1125 let Inst{3-0} = opt;
1128 // A5.4 Permanently UNDEFINED instructions.
1129 let isBarrier = 1, isTerminator = 1 in
1130 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1133 let Inst{27-25} = 0b011;
1134 let Inst{24-20} = 0b11111;
1135 let Inst{7-5} = 0b111;
1139 // Address computation and loads and stores in PIC mode.
1140 let isNotDuplicable = 1 in {
1141 def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1143 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1145 let AddedComplexity = 10 in {
1146 def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1148 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1150 def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1152 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
1154 def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1156 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
1158 def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1160 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
1162 def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
1164 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
1166 let AddedComplexity = 10 in {
1167 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1168 Pseudo, IIC_iStore_r, "",
1169 [(store GPR:$src, addrmodepc:$addr)]>;
1171 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1172 Pseudo, IIC_iStore_bh_r, "",
1173 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1175 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1176 Pseudo, IIC_iStore_bh_r, "",
1177 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1179 } // isNotDuplicable = 1
1182 // LEApcrel - Load a pc-relative address into a register without offending the
1184 let neverHasSideEffects = 1 in {
1185 let isReMaterializable = 1 in
1186 // FIXME: We want one cannonical LEApcrel instruction and to express one or
1187 // both of these as pseudo-instructions that get expanded to it.
1188 def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p),
1190 "adr$p\t$Rd, #$label", []>;
1192 } // neverHasSideEffects
1193 def LEApcrelJT : AXI1<0b0100, (outs GPR:$Rd),
1194 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1196 "adr$p\t$Rd, #${label}_${id}", []> {
1199 let Inst{31-28} = p;
1200 let Inst{27-25} = 0b001;
1202 let Inst{19-16} = 0b1111;
1203 let Inst{15-12} = Rd;
1204 // FIXME: Add label encoding/fixup
1207 //===----------------------------------------------------------------------===//
1208 // Control Flow Instructions.
1211 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1213 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1214 "bx", "\tlr", [(ARMretflag)]>,
1215 Requires<[IsARM, HasV4T]> {
1216 let Inst{27-0} = 0b0001001011111111111100011110;
1220 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1221 "mov", "\tpc, lr", [(ARMretflag)]>,
1222 Requires<[IsARM, NoV4T]> {
1223 let Inst{27-0} = 0b0001101000001111000000001110;
1227 // Indirect branches
1228 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1230 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1231 [(brind GPR:$dst)]>,
1232 Requires<[IsARM, HasV4T]> {
1234 let Inst{31-4} = 0b1110000100101111111111110001;
1235 let Inst{3-0} = dst;
1239 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1240 [(brind GPR:$dst)]>,
1241 Requires<[IsARM, NoV4T]> {
1243 let Inst{31-4} = 0b1110000110100000111100000000;
1244 let Inst{3-0} = dst;
1248 // On non-Darwin platforms R9 is callee-saved.
1250 Defs = [R0, R1, R2, R3, R12, LR,
1251 D0, D1, D2, D3, D4, D5, D6, D7,
1252 D16, D17, D18, D19, D20, D21, D22, D23,
1253 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1254 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1255 IIC_Br, "bl\t$func",
1256 [(ARMcall tglobaladdr:$func)]>,
1257 Requires<[IsARM, IsNotDarwin]> {
1258 let Inst{31-28} = 0b1110;
1260 let Inst{23-0} = func;
1263 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1264 IIC_Br, "bl", "\t$func",
1265 [(ARMcall_pred tglobaladdr:$func)]>,
1266 Requires<[IsARM, IsNotDarwin]> {
1268 let Inst{23-0} = func;
1272 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1273 IIC_Br, "blx\t$func",
1274 [(ARMcall GPR:$func)]>,
1275 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1277 let Inst{31-4} = 0b1110000100101111111111110011;
1278 let Inst{3-0} = func;
1282 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1283 // FIXME: x2 insn patterns like this need to be pseudo instructions.
1284 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1285 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1286 [(ARMcall_nolink tGPR:$func)]>,
1287 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1289 let Inst{27-4} = 0b000100101111111111110001;
1290 let Inst{3-0} = func;
1294 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1295 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1296 [(ARMcall_nolink tGPR:$func)]>,
1297 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1299 let Inst{27-4} = 0b000110100000111100000000;
1300 let Inst{3-0} = func;
1304 // On Darwin R9 is call-clobbered.
1306 Defs = [R0, R1, R2, R3, R9, R12, LR,
1307 D0, D1, D2, D3, D4, D5, D6, D7,
1308 D16, D17, D18, D19, D20, D21, D22, D23,
1309 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1310 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1311 IIC_Br, "bl\t$func",
1312 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1313 let Inst{31-28} = 0b1110;
1315 let Inst{23-0} = func;
1318 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1319 IIC_Br, "bl", "\t$func",
1320 [(ARMcall_pred tglobaladdr:$func)]>,
1321 Requires<[IsARM, IsDarwin]> {
1323 let Inst{23-0} = func;
1327 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1328 IIC_Br, "blx\t$func",
1329 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1331 let Inst{31-4} = 0b1110000100101111111111110011;
1332 let Inst{3-0} = func;
1336 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1337 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1338 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1339 [(ARMcall_nolink tGPR:$func)]>,
1340 Requires<[IsARM, HasV4T, IsDarwin]> {
1342 let Inst{27-4} = 0b000100101111111111110001;
1343 let Inst{3-0} = func;
1347 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1348 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1349 [(ARMcall_nolink tGPR:$func)]>,
1350 Requires<[IsARM, NoV4T, IsDarwin]> {
1352 let Inst{27-4} = 0b000110100000111100000000;
1353 let Inst{3-0} = func;
1359 // FIXME: These should probably be xformed into the non-TC versions of the
1360 // instructions as part of MC lowering.
1361 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1363 let Defs = [R0, R1, R2, R3, R9, R12,
1364 D0, D1, D2, D3, D4, D5, D6, D7,
1365 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1366 D27, D28, D29, D30, D31, PC],
1368 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1370 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1372 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1374 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1376 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1377 IIC_Br, "b\t$dst @ TAILCALL",
1378 []>, Requires<[IsDarwin]>;
1380 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1381 IIC_Br, "b.w\t$dst @ TAILCALL",
1382 []>, Requires<[IsDarwin]>;
1384 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1385 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1386 []>, Requires<[IsDarwin]> {
1388 let Inst{31-4} = 0b1110000100101111111111110001;
1389 let Inst{3-0} = dst;
1393 // Non-Darwin versions (the difference is R9).
1394 let Defs = [R0, R1, R2, R3, R12,
1395 D0, D1, D2, D3, D4, D5, D6, D7,
1396 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1397 D27, D28, D29, D30, D31, PC],
1399 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1401 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1403 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1405 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1407 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1408 IIC_Br, "b\t$dst @ TAILCALL",
1409 []>, Requires<[IsARM, IsNotDarwin]>;
1411 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1412 IIC_Br, "b.w\t$dst @ TAILCALL",
1413 []>, Requires<[IsThumb, IsNotDarwin]>;
1415 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1416 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1417 []>, Requires<[IsNotDarwin]> {
1419 let Inst{31-4} = 0b1110000100101111111111110001;
1420 let Inst{3-0} = dst;
1425 let isBranch = 1, isTerminator = 1 in {
1426 // B is "predicable" since it can be xformed into a Bcc.
1427 let isBarrier = 1 in {
1428 let isPredicable = 1 in
1429 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1430 "b\t$target", [(br bb:$target)]> {
1432 let Inst{31-28} = 0b1110;
1433 let Inst{23-0} = target;
1436 let isNotDuplicable = 1, isIndirectBranch = 1,
1437 // FIXME: $imm field is not specified by asm string. Mark as cgonly.
1438 isCodeGenOnly = 1 in {
1439 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1440 IIC_Br, "mov\tpc, $target$jt",
1441 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1442 let Inst{11-4} = 0b00000000;
1443 let Inst{15-12} = 0b1111;
1444 let Inst{20} = 0; // S Bit
1445 let Inst{24-21} = 0b1101;
1446 let Inst{27-25} = 0b000;
1448 def BR_JTm : JTI<(outs),
1449 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1450 IIC_Br, "ldr\tpc, $target$jt",
1451 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1453 let Inst{15-12} = 0b1111;
1454 let Inst{20} = 1; // L bit
1455 let Inst{21} = 0; // W bit
1456 let Inst{22} = 0; // B bit
1457 let Inst{24} = 1; // P bit
1458 let Inst{27-25} = 0b011;
1460 def BR_JTadd : PseudoInst<(outs),
1461 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1463 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1465 } // isNotDuplicable = 1, isIndirectBranch = 1
1468 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1469 // a two-value operand where a dag node expects two operands. :(
1470 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1471 IIC_Br, "b", "\t$target",
1472 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1474 let Inst{23-0} = target;
1478 // Branch and Exchange Jazelle -- for disassembly only
1479 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1480 [/* For disassembly only; pattern left blank */]> {
1481 let Inst{23-20} = 0b0010;
1482 //let Inst{19-8} = 0xfff;
1483 let Inst{7-4} = 0b0010;
1486 // Secure Monitor Call is a system instruction -- for disassembly only
1487 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1488 [/* For disassembly only; pattern left blank */]> {
1490 let Inst{23-4} = 0b01100000000000000111;
1491 let Inst{3-0} = opt;
1494 // Supervisor Call (Software Interrupt) -- for disassembly only
1496 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1497 [/* For disassembly only; pattern left blank */]> {
1499 let Inst{23-0} = svc;
1503 // Store Return State is a system instruction -- for disassembly only
1504 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1505 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1506 NoItinerary, "srs${amode}\tsp!, $mode",
1507 [/* For disassembly only; pattern left blank */]> {
1508 let Inst{31-28} = 0b1111;
1509 let Inst{22-20} = 0b110; // W = 1
1512 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1513 NoItinerary, "srs${amode}\tsp, $mode",
1514 [/* For disassembly only; pattern left blank */]> {
1515 let Inst{31-28} = 0b1111;
1516 let Inst{22-20} = 0b100; // W = 0
1519 // Return From Exception is a system instruction -- for disassembly only
1520 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1521 NoItinerary, "rfe${amode}\t$base!",
1522 [/* For disassembly only; pattern left blank */]> {
1523 let Inst{31-28} = 0b1111;
1524 let Inst{22-20} = 0b011; // W = 1
1527 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1528 NoItinerary, "rfe${amode}\t$base",
1529 [/* For disassembly only; pattern left blank */]> {
1530 let Inst{31-28} = 0b1111;
1531 let Inst{22-20} = 0b001; // W = 0
1533 } // isCodeGenOnly = 1
1535 //===----------------------------------------------------------------------===//
1536 // Load / store Instructions.
1542 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1543 UnOpFrag<(load node:$Src)>>;
1544 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1545 UnOpFrag<(zextloadi8 node:$Src)>>;
1546 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1547 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1548 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1549 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1551 // Special LDR for loads from non-pc-relative constpools.
1552 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1553 isReMaterializable = 1 in
1554 def LDRcp : AIldst1<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1555 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1559 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1560 let Inst{19-16} = 0b1111;
1561 let Inst{15-12} = Rt;
1562 let Inst{11-0} = addr{11-0}; // imm12
1565 // Loads with zero extension
1566 def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1567 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
1568 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
1570 // Loads with sign extension
1571 def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1572 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
1573 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
1575 def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
1576 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
1577 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
1579 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1580 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1581 // FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1)
1582 // how to represent that such that tblgen is happy and we don't
1583 // mark this codegen only?
1585 def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2),
1586 (ins addrmode3:$addr), LdMiscFrm,
1587 IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr",
1588 []>, Requires<[IsARM, HasV5TE]>;
1592 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1593 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1594 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1595 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1597 // {13} 1 == Rm, 0 == imm12
1601 let Inst{25} = addr{13};
1602 let Inst{23} = addr{12};
1603 let Inst{19-16} = addr{17-14};
1604 let Inst{11-0} = addr{11-0};
1606 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1607 (ins GPR:$Rn, am2offset:$offset),
1608 IndexModePost, LdFrm, itin,
1609 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1610 // {13} 1 == Rm, 0 == imm12
1615 let Inst{25} = offset{13};
1616 let Inst{23} = offset{12};
1617 let Inst{19-16} = Rn;
1618 let Inst{11-0} = offset{11-0};
1622 let mayLoad = 1, neverHasSideEffects = 1 in {
1623 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1624 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1627 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
1628 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1629 (ins addrmode3:$addr), IndexModePre,
1631 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1633 let Inst{23} = addr{8}; // U bit
1634 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
1635 let Inst{19-16} = addr{12-9}; // Rn
1636 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1637 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1639 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1640 (ins GPR:$Rn, am3offset:$offset), IndexModePost,
1642 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1645 let Inst{23} = addr{8}; // U bit
1646 let Inst{22} = addr{9}; // 1 == imm8, 0 == Rm
1647 let Inst{19-16} = Rn;
1648 let Inst{11-8} = addr{7-4}; // imm7_4/zero
1649 let Inst{3-0} = addr{3-0}; // imm3_0/Rm
1653 let mayLoad = 1, neverHasSideEffects = 1 in {
1654 defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
1655 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
1656 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
1657 let hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1658 defm LDRD : AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
1659 } // mayLoad = 1, neverHasSideEffects = 1
1661 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1662 let mayLoad = 1, neverHasSideEffects = 1 in {
1663 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1664 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1665 LdFrm, IIC_iLoad_ru,
1666 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1667 let Inst{21} = 1; // overwrite
1669 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1670 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1671 LdFrm, IIC_iLoad_bh_ru,
1672 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1673 let Inst{21} = 1; // overwrite
1675 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1676 (ins GPR:$base, am3offset:$offset), IndexModePost,
1677 LdMiscFrm, IIC_iLoad_bh_ru,
1678 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1679 let Inst{21} = 1; // overwrite
1681 def LDRHT : AI3ldstidx<0b1011, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1682 (ins GPR:$base, am3offset:$offset), IndexModePost,
1683 LdMiscFrm, IIC_iLoad_bh_ru,
1684 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1685 let Inst{21} = 1; // overwrite
1687 def LDRSHT : AI3ldstidx<0b1111, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1688 (ins GPR:$base, am3offset:$offset), IndexModePost,
1689 LdMiscFrm, IIC_iLoad_bh_ru,
1690 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1691 let Inst{21} = 1; // overwrite
1697 // Stores with truncate
1698 def STRH : AI3sth<(outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1699 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1700 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1703 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1704 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1705 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1706 StMiscFrm, IIC_iStore_d_r,
1707 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1710 def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$Rn_wb),
1711 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1712 IndexModePre, StFrm, IIC_iStore_ru,
1713 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1715 (pre_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 STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
1728 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1729 IndexModePost, StFrm, IIC_iStore_ru,
1730 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1732 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
1733 // {13} 1 == Rm, 0 == imm12
1738 let Inst{25} = offset{13};
1739 let Inst{23} = offset{12};
1740 let Inst{19-16} = Rn;
1741 let Inst{11-0} = offset{11-0};
1744 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1745 (ins GPR:$src, GPR:$base,am3offset:$offset),
1746 StMiscFrm, IIC_iStore_ru,
1747 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1749 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1751 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1752 (ins GPR:$src, GPR:$base,am3offset:$offset),
1753 StMiscFrm, IIC_iStore_bh_ru,
1754 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1755 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1756 GPR:$base, am3offset:$offset))]>;
1758 def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$Rn_wb),
1759 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1760 IndexModePre, StFrm, IIC_iStore_bh_ru,
1761 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1762 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1763 GPR:$Rn, am2offset:$offset))]> {
1764 // {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 def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
1776 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1777 IndexModePost, StFrm, IIC_iStore_bh_ru,
1778 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1779 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1780 GPR:$Rn, am2offset:$offset))]> {
1781 // {13} 1 == Rm, 0 == imm12
1786 let Inst{25} = offset{13};
1787 let Inst{23} = offset{12};
1788 let Inst{19-16} = Rn;
1789 let Inst{11-0} = offset{11-0};
1792 // For disassembly only
1793 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1794 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1795 StMiscFrm, IIC_iStore_d_ru,
1796 "strd", "\t$src1, $src2, [$base, $offset]!",
1797 "$base = $base_wb", []>;
1799 // For disassembly only
1800 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1801 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1802 StMiscFrm, IIC_iStore_d_ru,
1803 "strd", "\t$src1, $src2, [$base], $offset",
1804 "$base = $base_wb", []>;
1806 // STRT, STRBT, and STRHT are for disassembly only.
1808 def STRT : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
1809 (ins GPR:$src, GPR:$base,am2offset:$offset),
1810 IndexModeNone, StFrm, IIC_iStore_ru,
1811 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1812 [/* For disassembly only; pattern left blank */]> {
1813 let Inst{21} = 1; // overwrite
1816 def STRBT : AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
1817 (ins GPR:$src, GPR:$base,am2offset:$offset),
1818 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1819 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1820 [/* For disassembly only; pattern left blank */]> {
1821 let Inst{21} = 1; // overwrite
1824 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1825 (ins GPR:$src, GPR:$base,am3offset:$offset),
1826 StMiscFrm, IIC_iStore_bh_ru,
1827 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1828 [/* For disassembly only; pattern left blank */]> {
1829 let Inst{21} = 1; // overwrite
1832 //===----------------------------------------------------------------------===//
1833 // Load / store multiple Instructions.
1836 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1837 InstrItinClass itin, InstrItinClass itin_upd> {
1839 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1840 IndexModeNone, f, itin,
1841 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1842 let Inst{24-23} = 0b01; // Increment After
1843 let Inst{21} = 0; // No writeback
1844 let Inst{20} = L_bit;
1847 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1848 IndexModeUpd, f, itin_upd,
1849 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1850 let Inst{24-23} = 0b01; // Increment After
1851 let Inst{21} = 1; // Writeback
1852 let Inst{20} = L_bit;
1855 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1856 IndexModeNone, f, itin,
1857 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1858 let Inst{24-23} = 0b00; // Decrement After
1859 let Inst{21} = 0; // No writeback
1860 let Inst{20} = L_bit;
1863 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1864 IndexModeUpd, f, itin_upd,
1865 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1866 let Inst{24-23} = 0b00; // Decrement After
1867 let Inst{21} = 1; // Writeback
1868 let Inst{20} = L_bit;
1871 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1872 IndexModeNone, f, itin,
1873 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1874 let Inst{24-23} = 0b10; // Decrement Before
1875 let Inst{21} = 0; // No writeback
1876 let Inst{20} = L_bit;
1879 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1880 IndexModeUpd, f, itin_upd,
1881 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1882 let Inst{24-23} = 0b10; // Decrement Before
1883 let Inst{21} = 1; // Writeback
1884 let Inst{20} = L_bit;
1887 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1888 IndexModeNone, f, itin,
1889 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1890 let Inst{24-23} = 0b11; // Increment Before
1891 let Inst{21} = 0; // No writeback
1892 let Inst{20} = L_bit;
1895 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1896 IndexModeUpd, f, itin_upd,
1897 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1898 let Inst{24-23} = 0b11; // Increment Before
1899 let Inst{21} = 1; // Writeback
1900 let Inst{20} = L_bit;
1904 let neverHasSideEffects = 1 in {
1906 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1907 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1909 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1910 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1912 } // neverHasSideEffects
1914 // Load / Store Multiple Mnemnoic Aliases
1915 def : MnemonicAlias<"ldm", "ldmia">;
1916 def : MnemonicAlias<"stm", "stmia">;
1918 // FIXME: remove when we have a way to marking a MI with these properties.
1919 // FIXME: Should pc be an implicit operand like PICADD, etc?
1920 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1921 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1922 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1923 reglist:$regs, variable_ops),
1924 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1925 "ldmia${p}\t$Rn!, $regs",
1927 let Inst{24-23} = 0b01; // Increment After
1928 let Inst{21} = 1; // Writeback
1929 let Inst{20} = 1; // Load
1932 //===----------------------------------------------------------------------===//
1933 // Move Instructions.
1936 let neverHasSideEffects = 1 in
1937 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1938 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1942 let Inst{11-4} = 0b00000000;
1945 let Inst{15-12} = Rd;
1948 // A version for the smaller set of tail call registers.
1949 let neverHasSideEffects = 1 in
1950 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1951 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1955 let Inst{11-4} = 0b00000000;
1958 let Inst{15-12} = Rd;
1961 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1962 DPSoRegFrm, IIC_iMOVsr,
1963 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1967 let Inst{15-12} = Rd;
1968 let Inst{11-0} = src;
1972 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1973 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1974 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1978 let Inst{15-12} = Rd;
1979 let Inst{19-16} = 0b0000;
1980 let Inst{11-0} = imm;
1983 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1984 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins movt_imm:$imm),
1986 "movw", "\t$Rd, $imm",
1987 [(set GPR:$Rd, imm0_65535:$imm)]>,
1988 Requires<[IsARM, HasV6T2]>, UnaryDP {
1991 let Inst{15-12} = Rd;
1992 let Inst{11-0} = imm{11-0};
1993 let Inst{19-16} = imm{15-12};
1998 let Constraints = "$src = $Rd" in
1999 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, movt_imm:$imm),
2001 "movt", "\t$Rd, $imm",
2003 (or (and GPR:$src, 0xffff),
2004 lo16AllZero:$imm))]>, UnaryDP,
2005 Requires<[IsARM, HasV6T2]> {
2008 let Inst{15-12} = Rd;
2009 let Inst{11-0} = imm{11-0};
2010 let Inst{19-16} = imm{15-12};
2015 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
2016 Requires<[IsARM, HasV6T2]>;
2018 let Uses = [CPSR] in
2019 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
2020 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
2023 // These aren't really mov instructions, but we have to define them this way
2024 // due to flag operands.
2026 let Defs = [CPSR] in {
2027 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2028 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2030 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
2031 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2035 //===----------------------------------------------------------------------===//
2036 // Extend Instructions.
2041 defm SXTB : AI_ext_rrot<0b01101010,
2042 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2043 defm SXTH : AI_ext_rrot<0b01101011,
2044 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2046 defm SXTAB : AI_exta_rrot<0b01101010,
2047 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2048 defm SXTAH : AI_exta_rrot<0b01101011,
2049 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2051 // For disassembly only
2052 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2054 // For disassembly only
2055 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2059 let AddedComplexity = 16 in {
2060 defm UXTB : AI_ext_rrot<0b01101110,
2061 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2062 defm UXTH : AI_ext_rrot<0b01101111,
2063 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2064 defm UXTB16 : AI_ext_rrot<0b01101100,
2065 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2067 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2068 // The transformation should probably be done as a combiner action
2069 // instead so we can include a check for masking back in the upper
2070 // eight bits of the source into the lower eight bits of the result.
2071 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2072 // (UXTB16r_rot GPR:$Src, 24)>;
2073 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2074 (UXTB16r_rot GPR:$Src, 8)>;
2076 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2077 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2078 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2079 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2082 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2083 // For disassembly only
2084 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2087 def SBFX : I<(outs GPR:$Rd),
2088 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2089 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2090 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2091 Requires<[IsARM, HasV6T2]> {
2096 let Inst{27-21} = 0b0111101;
2097 let Inst{6-4} = 0b101;
2098 let Inst{20-16} = width;
2099 let Inst{15-12} = Rd;
2100 let Inst{11-7} = lsb;
2104 def UBFX : I<(outs GPR:$Rd),
2105 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2106 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2107 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2108 Requires<[IsARM, HasV6T2]> {
2113 let Inst{27-21} = 0b0111111;
2114 let Inst{6-4} = 0b101;
2115 let Inst{20-16} = width;
2116 let Inst{15-12} = Rd;
2117 let Inst{11-7} = lsb;
2121 //===----------------------------------------------------------------------===//
2122 // Arithmetic Instructions.
2125 defm ADD : AsI1_bin_irs<0b0100, "add",
2126 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2127 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2128 defm SUB : AsI1_bin_irs<0b0010, "sub",
2129 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2130 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2132 // ADD and SUB with 's' bit set.
2133 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2134 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2135 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2136 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2137 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2138 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2140 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2141 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2142 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2143 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2144 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2145 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2146 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2147 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2149 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2150 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2151 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2156 let Inst{15-12} = Rd;
2157 let Inst{19-16} = Rn;
2158 let Inst{11-0} = imm;
2161 // The reg/reg form is only defined for the disassembler; for codegen it is
2162 // equivalent to SUBrr.
2163 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2164 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2165 [/* For disassembly only; pattern left blank */]> {
2169 let Inst{11-4} = 0b00000000;
2172 let Inst{15-12} = Rd;
2173 let Inst{19-16} = Rn;
2176 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2177 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2178 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2183 let Inst{11-0} = shift;
2184 let Inst{15-12} = Rd;
2185 let Inst{19-16} = Rn;
2188 // RSB with 's' bit set.
2189 let Defs = [CPSR] in {
2190 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2191 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2192 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2198 let Inst{15-12} = Rd;
2199 let Inst{19-16} = Rn;
2200 let Inst{11-0} = imm;
2202 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2203 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2204 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2210 let Inst{11-0} = shift;
2211 let Inst{15-12} = Rd;
2212 let Inst{19-16} = Rn;
2216 let Uses = [CPSR] in {
2217 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2218 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2219 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2225 let Inst{15-12} = Rd;
2226 let Inst{19-16} = Rn;
2227 let Inst{11-0} = imm;
2229 // The reg/reg form is only defined for the disassembler; for codegen it is
2230 // equivalent to SUBrr.
2231 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2232 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2233 [/* For disassembly only; pattern left blank */]> {
2237 let Inst{11-4} = 0b00000000;
2240 let Inst{15-12} = Rd;
2241 let Inst{19-16} = Rn;
2243 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2244 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2245 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2251 let Inst{11-0} = shift;
2252 let Inst{15-12} = Rd;
2253 let Inst{19-16} = Rn;
2257 // FIXME: Allow these to be predicated.
2258 let Defs = [CPSR], Uses = [CPSR] in {
2259 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2260 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2261 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2268 let Inst{15-12} = Rd;
2269 let Inst{19-16} = Rn;
2270 let Inst{11-0} = imm;
2272 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2273 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2274 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2281 let Inst{11-0} = shift;
2282 let Inst{15-12} = Rd;
2283 let Inst{19-16} = Rn;
2287 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2288 // The assume-no-carry-in form uses the negation of the input since add/sub
2289 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2290 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2292 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2293 (SUBri GPR:$src, so_imm_neg:$imm)>;
2294 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2295 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2296 // The with-carry-in form matches bitwise not instead of the negation.
2297 // Effectively, the inverse interpretation of the carry flag already accounts
2298 // for part of the negation.
2299 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2300 (SBCri GPR:$src, so_imm_not:$imm)>;
2302 // Note: These are implemented in C++ code, because they have to generate
2303 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2305 // (mul X, 2^n+1) -> (add (X << n), X)
2306 // (mul X, 2^n-1) -> (rsb X, (X << n))
2308 // ARM Arithmetic Instruction -- for disassembly only
2309 // GPR:$dst = GPR:$a op GPR:$b
2310 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2311 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2312 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2313 opc, "\t$Rd, $Rn, $Rm", pattern> {
2317 let Inst{27-20} = op27_20;
2318 let Inst{11-4} = op11_4;
2319 let Inst{19-16} = Rn;
2320 let Inst{15-12} = Rd;
2324 // Saturating add/subtract -- for disassembly only
2326 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2327 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2328 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2329 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2330 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2331 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2333 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2334 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2335 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2336 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2337 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2338 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2339 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2340 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2341 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2342 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2343 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2344 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2346 // Signed/Unsigned add/subtract -- for disassembly only
2348 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2349 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2350 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2351 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2352 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2353 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2354 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2355 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2356 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2357 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2358 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2359 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2361 // Signed/Unsigned halving add/subtract -- for disassembly only
2363 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2364 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2365 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2366 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2367 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2368 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2369 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2370 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2371 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2372 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2373 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2374 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2376 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2378 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2379 MulFrm /* for convenience */, NoItinerary, "usad8",
2380 "\t$Rd, $Rn, $Rm", []>,
2381 Requires<[IsARM, HasV6]> {
2385 let Inst{27-20} = 0b01111000;
2386 let Inst{15-12} = 0b1111;
2387 let Inst{7-4} = 0b0001;
2388 let Inst{19-16} = Rd;
2389 let Inst{11-8} = Rm;
2392 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2393 MulFrm /* for convenience */, NoItinerary, "usada8",
2394 "\t$Rd, $Rn, $Rm, $Ra", []>,
2395 Requires<[IsARM, HasV6]> {
2400 let Inst{27-20} = 0b01111000;
2401 let Inst{7-4} = 0b0001;
2402 let Inst{19-16} = Rd;
2403 let Inst{15-12} = Ra;
2404 let Inst{11-8} = Rm;
2408 // Signed/Unsigned saturate -- for disassembly only
2410 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2411 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2412 [/* For disassembly only; pattern left blank */]> {
2417 let Inst{27-21} = 0b0110101;
2418 let Inst{5-4} = 0b01;
2419 let Inst{20-16} = sat_imm;
2420 let Inst{15-12} = Rd;
2421 let Inst{11-7} = sh{7-3};
2422 let Inst{6} = sh{0};
2426 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2427 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2428 [/* For disassembly only; pattern left blank */]> {
2432 let Inst{27-20} = 0b01101010;
2433 let Inst{11-4} = 0b11110011;
2434 let Inst{15-12} = Rd;
2435 let Inst{19-16} = sat_imm;
2439 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2440 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2441 [/* For disassembly only; pattern left blank */]> {
2446 let Inst{27-21} = 0b0110111;
2447 let Inst{5-4} = 0b01;
2448 let Inst{15-12} = Rd;
2449 let Inst{11-7} = sh{7-3};
2450 let Inst{6} = sh{0};
2451 let Inst{20-16} = sat_imm;
2455 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2456 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2457 [/* For disassembly only; pattern left blank */]> {
2461 let Inst{27-20} = 0b01101110;
2462 let Inst{11-4} = 0b11110011;
2463 let Inst{15-12} = Rd;
2464 let Inst{19-16} = sat_imm;
2468 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2469 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2471 //===----------------------------------------------------------------------===//
2472 // Bitwise Instructions.
2475 defm AND : AsI1_bin_irs<0b0000, "and",
2476 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2477 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2478 defm ORR : AsI1_bin_irs<0b1100, "orr",
2479 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2480 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2481 defm EOR : AsI1_bin_irs<0b0001, "eor",
2482 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2483 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2484 defm BIC : AsI1_bin_irs<0b1110, "bic",
2485 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2486 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2488 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2489 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2490 "bfc", "\t$Rd, $imm", "$src = $Rd",
2491 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2492 Requires<[IsARM, HasV6T2]> {
2495 let Inst{27-21} = 0b0111110;
2496 let Inst{6-0} = 0b0011111;
2497 let Inst{15-12} = Rd;
2498 let Inst{11-7} = imm{4-0}; // lsb
2499 let Inst{20-16} = imm{9-5}; // width
2502 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2503 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2504 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2505 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2506 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2507 bf_inv_mask_imm:$imm))]>,
2508 Requires<[IsARM, HasV6T2]> {
2512 let Inst{27-21} = 0b0111110;
2513 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2514 let Inst{15-12} = Rd;
2515 let Inst{11-7} = imm{4-0}; // lsb
2516 let Inst{20-16} = imm{9-5}; // width
2520 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2521 "mvn", "\t$Rd, $Rm",
2522 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2526 let Inst{19-16} = 0b0000;
2527 let Inst{11-4} = 0b00000000;
2528 let Inst{15-12} = Rd;
2531 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2532 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2533 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2537 let Inst{19-16} = 0b0000;
2538 let Inst{15-12} = Rd;
2539 let Inst{11-0} = shift;
2541 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
2542 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2543 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2544 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2548 let Inst{19-16} = 0b0000;
2549 let Inst{15-12} = Rd;
2550 let Inst{11-0} = imm;
2553 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2554 (BICri GPR:$src, so_imm_not:$imm)>;
2556 //===----------------------------------------------------------------------===//
2557 // Multiply Instructions.
2559 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2560 string opc, string asm, list<dag> pattern>
2561 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2565 let Inst{19-16} = Rd;
2566 let Inst{11-8} = Rm;
2569 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2570 string opc, string asm, list<dag> pattern>
2571 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2576 let Inst{19-16} = RdHi;
2577 let Inst{15-12} = RdLo;
2578 let Inst{11-8} = Rm;
2582 let isCommutable = 1 in
2583 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2584 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2585 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2587 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2588 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2589 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2591 let Inst{15-12} = Ra;
2594 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2595 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2596 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2597 Requires<[IsARM, HasV6T2]> {
2601 let Inst{19-16} = Rd;
2602 let Inst{11-8} = Rm;
2606 // Extra precision multiplies with low / high results
2608 let neverHasSideEffects = 1 in {
2609 let isCommutable = 1 in {
2610 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2611 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2612 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2614 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2615 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2616 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2619 // Multiply + accumulate
2620 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2621 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2622 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2624 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2625 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2626 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2628 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2629 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2630 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2631 Requires<[IsARM, HasV6]> {
2636 let Inst{19-16} = RdLo;
2637 let Inst{15-12} = RdHi;
2638 let Inst{11-8} = Rm;
2641 } // neverHasSideEffects
2643 // Most significant word multiply
2644 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2645 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2646 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2647 Requires<[IsARM, HasV6]> {
2648 let Inst{15-12} = 0b1111;
2651 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2652 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2653 [/* For disassembly only; pattern left blank */]>,
2654 Requires<[IsARM, HasV6]> {
2655 let Inst{15-12} = 0b1111;
2658 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2659 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2660 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2661 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2662 Requires<[IsARM, HasV6]>;
2664 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2665 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2666 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2667 [/* For disassembly only; pattern left blank */]>,
2668 Requires<[IsARM, HasV6]>;
2670 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2671 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2672 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2673 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2674 Requires<[IsARM, HasV6]>;
2676 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2677 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2678 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2679 [/* For disassembly only; pattern left blank */]>,
2680 Requires<[IsARM, HasV6]>;
2682 multiclass AI_smul<string opc, PatFrag opnode> {
2683 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2684 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2685 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2686 (sext_inreg GPR:$Rm, i16)))]>,
2687 Requires<[IsARM, HasV5TE]>;
2689 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2690 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2691 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2692 (sra GPR:$Rm, (i32 16))))]>,
2693 Requires<[IsARM, HasV5TE]>;
2695 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2696 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2697 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2698 (sext_inreg GPR:$Rm, i16)))]>,
2699 Requires<[IsARM, HasV5TE]>;
2701 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2702 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2703 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2704 (sra GPR:$Rm, (i32 16))))]>,
2705 Requires<[IsARM, HasV5TE]>;
2707 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2708 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2709 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2710 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2711 Requires<[IsARM, HasV5TE]>;
2713 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2714 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2715 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2716 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2717 Requires<[IsARM, HasV5TE]>;
2721 multiclass AI_smla<string opc, PatFrag opnode> {
2722 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2723 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2724 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2725 [(set GPR:$Rd, (add GPR:$Ra,
2726 (opnode (sext_inreg GPR:$Rn, i16),
2727 (sext_inreg GPR:$Rm, i16))))]>,
2728 Requires<[IsARM, HasV5TE]>;
2730 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2731 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2732 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2733 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2734 (sra GPR:$Rm, (i32 16)))))]>,
2735 Requires<[IsARM, HasV5TE]>;
2737 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2738 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2739 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2740 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2741 (sext_inreg GPR:$Rm, i16))))]>,
2742 Requires<[IsARM, HasV5TE]>;
2744 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2745 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2746 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2747 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2748 (sra GPR:$Rm, (i32 16)))))]>,
2749 Requires<[IsARM, HasV5TE]>;
2751 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2752 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2753 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2754 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2755 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2756 Requires<[IsARM, HasV5TE]>;
2758 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2759 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2760 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2761 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2762 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2763 Requires<[IsARM, HasV5TE]>;
2766 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2767 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2769 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2770 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2771 (ins GPR:$Rn, GPR:$Rm),
2772 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2773 [/* For disassembly only; pattern left blank */]>,
2774 Requires<[IsARM, HasV5TE]>;
2776 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2777 (ins GPR:$Rn, GPR:$Rm),
2778 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2779 [/* For disassembly only; pattern left blank */]>,
2780 Requires<[IsARM, HasV5TE]>;
2782 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2783 (ins GPR:$Rn, GPR:$Rm),
2784 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2785 [/* For disassembly only; pattern left blank */]>,
2786 Requires<[IsARM, HasV5TE]>;
2788 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2789 (ins GPR:$Rn, GPR:$Rm),
2790 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2791 [/* For disassembly only; pattern left blank */]>,
2792 Requires<[IsARM, HasV5TE]>;
2794 // Helper class for AI_smld -- for disassembly only
2795 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2796 InstrItinClass itin, string opc, string asm>
2797 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2804 let Inst{21-20} = 0b00;
2805 let Inst{22} = long;
2806 let Inst{27-23} = 0b01110;
2807 let Inst{11-8} = Rm;
2810 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2811 InstrItinClass itin, string opc, string asm>
2812 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2814 let Inst{15-12} = 0b1111;
2815 let Inst{19-16} = Rd;
2817 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2818 InstrItinClass itin, string opc, string asm>
2819 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2821 let Inst{15-12} = Ra;
2823 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2824 InstrItinClass itin, string opc, string asm>
2825 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2828 let Inst{19-16} = RdHi;
2829 let Inst{15-12} = RdLo;
2832 multiclass AI_smld<bit sub, string opc> {
2834 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2835 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2837 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2838 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2840 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2841 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2842 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2844 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2845 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2846 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2850 defm SMLA : AI_smld<0, "smla">;
2851 defm SMLS : AI_smld<1, "smls">;
2853 multiclass AI_sdml<bit sub, string opc> {
2855 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2856 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2857 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2858 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2861 defm SMUA : AI_sdml<0, "smua">;
2862 defm SMUS : AI_sdml<1, "smus">;
2864 //===----------------------------------------------------------------------===//
2865 // Misc. Arithmetic Instructions.
2868 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2869 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2870 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2872 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2873 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2874 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2875 Requires<[IsARM, HasV6T2]>;
2877 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2878 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2879 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2881 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2882 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2884 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2885 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2886 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2887 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2888 Requires<[IsARM, HasV6]>;
2890 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2891 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2894 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2895 (shl GPR:$Rm, (i32 8))), i16))]>,
2896 Requires<[IsARM, HasV6]>;
2898 def lsl_shift_imm : SDNodeXForm<imm, [{
2899 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2900 return CurDAG->getTargetConstant(Sh, MVT::i32);
2903 def lsl_amt : PatLeaf<(i32 imm), [{
2904 return (N->getZExtValue() < 32);
2907 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2908 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2909 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2910 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2911 (and (shl GPR:$Rm, lsl_amt:$sh),
2913 Requires<[IsARM, HasV6]>;
2915 // Alternate cases for PKHBT where identities eliminate some nodes.
2916 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2917 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2918 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2919 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2921 def asr_shift_imm : SDNodeXForm<imm, [{
2922 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2923 return CurDAG->getTargetConstant(Sh, MVT::i32);
2926 def asr_amt : PatLeaf<(i32 imm), [{
2927 return (N->getZExtValue() <= 32);
2930 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2931 // will match the pattern below.
2932 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2933 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2934 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2935 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2936 (and (sra GPR:$Rm, asr_amt:$sh),
2938 Requires<[IsARM, HasV6]>;
2940 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2941 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2942 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2943 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2944 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2945 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2946 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2948 //===----------------------------------------------------------------------===//
2949 // Comparison Instructions...
2952 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2953 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2954 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2956 // FIXME: We have to be careful when using the CMN instruction and comparison
2957 // with 0. One would expect these two pieces of code should give identical
2973 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2974 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2975 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2976 // value of r0 and the carry bit (because the "carry bit" parameter to
2977 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2978 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2979 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2980 // parameter to AddWithCarry is defined as 0).
2982 // When x is 0 and unsigned:
2986 // ~x + 1 = 0x1 0000 0000
2987 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2989 // Therefore, we should disable CMN when comparing against zero, until we can
2990 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2991 // when it's a comparison which doesn't look at the 'carry' flag).
2993 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2995 // This is related to <rdar://problem/7569620>.
2997 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2998 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
3000 // Note that TST/TEQ don't set all the same flags that CMP does!
3001 defm TST : AI1_cmp_irs<0b1000, "tst",
3002 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3003 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>;
3004 defm TEQ : AI1_cmp_irs<0b1001, "teq",
3005 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
3006 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
3008 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
3009 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3010 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
3011 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
3012 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
3013 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
3015 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
3016 // (CMNri GPR:$src, so_imm_neg:$imm)>;
3018 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
3019 (CMNzri GPR:$src, so_imm_neg:$imm)>;
3021 // Pseudo i64 compares for some floating point compares.
3022 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
3024 def BCCi64 : PseudoInst<(outs),
3025 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
3027 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3029 def BCCZi64 : PseudoInst<(outs),
3030 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
3031 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3032 } // usesCustomInserter
3035 // Conditional moves
3036 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3037 // a two-value operand where a dag node expects two operands. :(
3038 // FIXME: These should all be pseudo-instructions that get expanded to
3039 // the normal MOV instructions. That would fix the dependency on
3040 // special casing them in tblgen.
3041 let neverHasSideEffects = 1 in {
3042 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3043 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3044 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3045 RegConstraint<"$false = $Rd">, UnaryDP {
3050 let Inst{15-12} = Rd;
3051 let Inst{11-4} = 0b00000000;
3055 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3056 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3057 "mov", "\t$Rd, $shift",
3058 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3059 RegConstraint<"$false = $Rd">, UnaryDP {
3064 let Inst{19-16} = 0;
3065 let Inst{15-12} = Rd;
3066 let Inst{11-0} = shift;
3069 let isMoveImm = 1 in
3070 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, movt_imm:$imm),
3072 "movw", "\t$Rd, $imm",
3074 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3080 let Inst{19-16} = imm{15-12};
3081 let Inst{15-12} = Rd;
3082 let Inst{11-0} = imm{11-0};
3085 let isMoveImm = 1 in
3086 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3087 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3088 "mov", "\t$Rd, $imm",
3089 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3090 RegConstraint<"$false = $Rd">, UnaryDP {
3095 let Inst{19-16} = 0b0000;
3096 let Inst{15-12} = Rd;
3097 let Inst{11-0} = imm;
3100 // Two instruction predicate mov immediate.
3101 let isMoveImm = 1 in
3102 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3103 (ins GPR:$false, i32imm:$src, pred:$p),
3104 IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">;
3106 let isMoveImm = 1 in
3107 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3108 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3109 "mvn", "\t$Rd, $imm",
3110 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3111 RegConstraint<"$false = $Rd">, UnaryDP {
3116 let Inst{19-16} = 0b0000;
3117 let Inst{15-12} = Rd;
3118 let Inst{11-0} = imm;
3120 } // neverHasSideEffects
3122 //===----------------------------------------------------------------------===//
3123 // Atomic operations intrinsics
3126 def memb_opt : Operand<i32> {
3127 let PrintMethod = "printMemBOption";
3130 // memory barriers protect the atomic sequences
3131 let hasSideEffects = 1 in {
3132 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3133 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3134 Requires<[IsARM, HasDB]> {
3136 let Inst{31-4} = 0xf57ff05;
3137 let Inst{3-0} = opt;
3140 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3141 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3142 [(ARMMemBarrierMCR GPR:$zero)]>,
3143 Requires<[IsARM, HasV6]> {
3144 // FIXME: add encoding
3148 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3150 [/* For disassembly only; pattern left blank */]>,
3151 Requires<[IsARM, HasDB]> {
3153 let Inst{31-4} = 0xf57ff04;
3154 let Inst{3-0} = opt;
3157 // ISB has only full system option -- for disassembly only
3158 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3159 Requires<[IsARM, HasDB]> {
3160 let Inst{31-4} = 0xf57ff06;
3161 let Inst{3-0} = 0b1111;
3164 let usesCustomInserter = 1 in {
3165 let Uses = [CPSR] in {
3166 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3167 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3168 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3169 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3170 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3171 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3172 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3173 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3174 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3175 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3176 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3177 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3178 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3179 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3180 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3181 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3182 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3183 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3184 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3185 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3186 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3187 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3188 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3189 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3190 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3191 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3192 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3193 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3194 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3195 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3196 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3197 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3198 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3199 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3200 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3201 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3202 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3203 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3204 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3205 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3206 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3207 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3208 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3209 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3210 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3211 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3212 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3213 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3214 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3215 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3216 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3217 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3218 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
3219 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3221 def ATOMIC_SWAP_I8 : PseudoInst<
3222 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3223 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3224 def ATOMIC_SWAP_I16 : PseudoInst<
3225 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3226 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3227 def ATOMIC_SWAP_I32 : PseudoInst<
3228 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
3229 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3231 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3232 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3233 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3234 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3235 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3236 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3237 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3238 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
3239 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3243 let mayLoad = 1 in {
3244 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3245 "ldrexb", "\t$Rt, [$Rn]",
3247 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3248 "ldrexh", "\t$Rt, [$Rn]",
3250 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3251 "ldrex", "\t$Rt, [$Rn]",
3253 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3255 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3259 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3260 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3262 "strexb", "\t$Rd, $src, [$Rn]",
3264 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3266 "strexh", "\t$Rd, $Rt, [$Rn]",
3268 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3270 "strex", "\t$Rd, $Rt, [$Rn]",
3272 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3273 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3275 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3279 // Clear-Exclusive is for disassembly only.
3280 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3281 [/* For disassembly only; pattern left blank */]>,
3282 Requires<[IsARM, HasV7]> {
3283 let Inst{31-0} = 0b11110101011111111111000000011111;
3286 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3287 let mayLoad = 1 in {
3288 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3289 [/* For disassembly only; pattern left blank */]>;
3290 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3291 [/* For disassembly only; pattern left blank */]>;
3294 //===----------------------------------------------------------------------===//
3298 // __aeabi_read_tp preserves the registers r1-r3.
3299 // FIXME: This needs to be a pseudo of some sort so that we can get the
3300 // encoding right, complete with fixup for the aeabi_read_tp function.
3302 Defs = [R0, R12, LR, CPSR] in {
3303 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3304 "bl\t__aeabi_read_tp",
3305 [(set R0, ARMthread_pointer)]>;
3308 //===----------------------------------------------------------------------===//
3309 // SJLJ Exception handling intrinsics
3310 // eh_sjlj_setjmp() is an instruction sequence to store the return
3311 // address and save #0 in R0 for the non-longjmp case.
3312 // Since by its nature we may be coming from some other function to get
3313 // here, and we're using the stack frame for the containing function to
3314 // save/restore registers, we can't keep anything live in regs across
3315 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3316 // when we get here from a longjmp(). We force everthing out of registers
3317 // except for our own input by listing the relevant registers in Defs. By
3318 // doing so, we also cause the prologue/epilogue code to actively preserve
3319 // all of the callee-saved resgisters, which is exactly what we want.
3320 // A constant value is passed in $val, and we use the location as a scratch.
3322 // These are pseudo-instructions and are lowered to individual MC-insts, so
3323 // no encoding information is necessary.
3325 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3326 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3327 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3328 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3329 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3330 AddrModeNone, SizeSpecial, IndexModeNone,
3331 Pseudo, NoItinerary, "", "",
3332 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3333 Requires<[IsARM, HasVFP2]>;
3337 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3338 hasSideEffects = 1, isBarrier = 1 in {
3339 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3340 AddrModeNone, SizeSpecial, IndexModeNone,
3341 Pseudo, NoItinerary, "", "",
3342 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3343 Requires<[IsARM, NoVFP]>;
3346 // FIXME: Non-Darwin version(s)
3347 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3348 Defs = [ R7, LR, SP ] in {
3349 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3350 AddrModeNone, SizeSpecial, IndexModeNone,
3351 Pseudo, NoItinerary, "", "",
3352 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3353 Requires<[IsARM, IsDarwin]>;
3356 // eh.sjlj.dispatchsetup pseudo-instruction.
3357 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3358 // handled when the pseudo is expanded (which happens before any passes
3359 // that need the instruction size).
3360 let isBarrier = 1, hasSideEffects = 1 in
3361 def Int_eh_sjlj_dispatchsetup :
3362 PseudoInst<(outs), (ins GPR:$src), NoItinerary,
3363 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3364 Requires<[IsDarwin]>;
3366 //===----------------------------------------------------------------------===//
3367 // Non-Instruction Patterns
3370 // Large immediate handling.
3372 // 32-bit immediate using two piece so_imms or movw + movt.
3373 // This is a single pseudo instruction, the benefit is that it can be remat'd
3374 // as a single unit instead of having to handle reg inputs.
3375 // FIXME: Remove this when we can do generalized remat.
3376 let isReMaterializable = 1, isMoveImm = 1 in
3377 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3378 [(set GPR:$dst, (arm_i32imm:$src))]>,
3381 // ConstantPool, GlobalAddress, and JumpTable
3382 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3383 Requires<[IsARM, DontUseMovt]>;
3384 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3385 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3386 Requires<[IsARM, UseMovt]>;
3387 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3388 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3390 // TODO: add,sub,and, 3-instr forms?
3393 def : ARMPat<(ARMtcret tcGPR:$dst),
3394 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3396 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3397 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3399 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3400 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3402 def : ARMPat<(ARMtcret tcGPR:$dst),
3403 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3405 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3406 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3408 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3409 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3412 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3413 Requires<[IsARM, IsNotDarwin]>;
3414 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3415 Requires<[IsARM, IsDarwin]>;
3417 // zextload i1 -> zextload i8
3418 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3419 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3421 // extload -> zextload
3422 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3423 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3424 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3425 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3427 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3429 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3430 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3433 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3434 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3435 (SMULBB GPR:$a, GPR:$b)>;
3436 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3437 (SMULBB GPR:$a, GPR:$b)>;
3438 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3439 (sra GPR:$b, (i32 16))),
3440 (SMULBT GPR:$a, GPR:$b)>;
3441 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3442 (SMULBT GPR:$a, GPR:$b)>;
3443 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3444 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3445 (SMULTB GPR:$a, GPR:$b)>;
3446 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3447 (SMULTB GPR:$a, GPR:$b)>;
3448 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3450 (SMULWB GPR:$a, GPR:$b)>;
3451 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3452 (SMULWB GPR:$a, GPR:$b)>;
3454 def : ARMV5TEPat<(add GPR:$acc,
3455 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3456 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3457 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3458 def : ARMV5TEPat<(add GPR:$acc,
3459 (mul sext_16_node:$a, sext_16_node:$b)),
3460 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3461 def : ARMV5TEPat<(add GPR:$acc,
3462 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3463 (sra GPR:$b, (i32 16)))),
3464 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3465 def : ARMV5TEPat<(add GPR:$acc,
3466 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3467 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3468 def : ARMV5TEPat<(add GPR:$acc,
3469 (mul (sra GPR:$a, (i32 16)),
3470 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3471 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3472 def : ARMV5TEPat<(add GPR:$acc,
3473 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3474 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3475 def : ARMV5TEPat<(add GPR:$acc,
3476 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3478 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3479 def : ARMV5TEPat<(add GPR:$acc,
3480 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3481 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3483 //===----------------------------------------------------------------------===//
3487 include "ARMInstrThumb.td"
3489 //===----------------------------------------------------------------------===//
3493 include "ARMInstrThumb2.td"
3495 //===----------------------------------------------------------------------===//
3496 // Floating Point Support
3499 include "ARMInstrVFP.td"
3501 //===----------------------------------------------------------------------===//
3502 // Advanced SIMD (NEON) Support
3505 include "ARMInstrNEON.td"
3507 //===----------------------------------------------------------------------===//
3508 // Coprocessor Instructions. For disassembly only.
3511 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3512 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3513 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3514 [/* For disassembly only; pattern left blank */]> {
3518 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3519 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3520 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3521 [/* For disassembly only; pattern left blank */]> {
3522 let Inst{31-28} = 0b1111;
3526 class ACI<dag oops, dag iops, string opc, string asm>
3527 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3528 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3529 let Inst{27-25} = 0b110;
3532 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3534 def _OFFSET : ACI<(outs),
3535 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3536 opc, "\tp$cop, cr$CRd, $addr"> {
3537 let Inst{31-28} = op31_28;
3538 let Inst{24} = 1; // P = 1
3539 let Inst{21} = 0; // W = 0
3540 let Inst{22} = 0; // D = 0
3541 let Inst{20} = load;
3544 def _PRE : ACI<(outs),
3545 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3546 opc, "\tp$cop, cr$CRd, $addr!"> {
3547 let Inst{31-28} = op31_28;
3548 let Inst{24} = 1; // P = 1
3549 let Inst{21} = 1; // W = 1
3550 let Inst{22} = 0; // D = 0
3551 let Inst{20} = load;
3554 def _POST : ACI<(outs),
3555 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3556 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3557 let Inst{31-28} = op31_28;
3558 let Inst{24} = 0; // P = 0
3559 let Inst{21} = 1; // W = 1
3560 let Inst{22} = 0; // D = 0
3561 let Inst{20} = load;
3564 def _OPTION : ACI<(outs),
3565 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3566 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3567 let Inst{31-28} = op31_28;
3568 let Inst{24} = 0; // P = 0
3569 let Inst{23} = 1; // U = 1
3570 let Inst{21} = 0; // W = 0
3571 let Inst{22} = 0; // D = 0
3572 let Inst{20} = load;
3575 def L_OFFSET : ACI<(outs),
3576 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3577 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3578 let Inst{31-28} = op31_28;
3579 let Inst{24} = 1; // P = 1
3580 let Inst{21} = 0; // W = 0
3581 let Inst{22} = 1; // D = 1
3582 let Inst{20} = load;
3585 def L_PRE : ACI<(outs),
3586 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3587 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3588 let Inst{31-28} = op31_28;
3589 let Inst{24} = 1; // P = 1
3590 let Inst{21} = 1; // W = 1
3591 let Inst{22} = 1; // D = 1
3592 let Inst{20} = load;
3595 def L_POST : ACI<(outs),
3596 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3597 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3598 let Inst{31-28} = op31_28;
3599 let Inst{24} = 0; // P = 0
3600 let Inst{21} = 1; // W = 1
3601 let Inst{22} = 1; // D = 1
3602 let Inst{20} = load;
3605 def L_OPTION : ACI<(outs),
3606 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3607 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3608 let Inst{31-28} = op31_28;
3609 let Inst{24} = 0; // P = 0
3610 let Inst{23} = 1; // U = 1
3611 let Inst{21} = 0; // W = 0
3612 let Inst{22} = 1; // D = 1
3613 let Inst{20} = load;
3617 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3618 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3619 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3620 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3622 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3623 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3624 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3625 [/* For disassembly only; pattern left blank */]> {
3630 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3631 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3632 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3633 [/* For disassembly only; pattern left blank */]> {
3634 let Inst{31-28} = 0b1111;
3639 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3640 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3641 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3642 [/* For disassembly only; pattern left blank */]> {
3647 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3648 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3649 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3650 [/* For disassembly only; pattern left blank */]> {
3651 let Inst{31-28} = 0b1111;
3656 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3657 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3658 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3659 [/* For disassembly only; pattern left blank */]> {
3660 let Inst{23-20} = 0b0100;
3663 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3664 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3665 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3666 [/* For disassembly only; pattern left blank */]> {
3667 let Inst{31-28} = 0b1111;
3668 let Inst{23-20} = 0b0100;
3671 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3672 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3673 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3674 [/* For disassembly only; pattern left blank */]> {
3675 let Inst{23-20} = 0b0101;
3678 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3679 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3680 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3681 [/* For disassembly only; pattern left blank */]> {
3682 let Inst{31-28} = 0b1111;
3683 let Inst{23-20} = 0b0101;
3686 //===----------------------------------------------------------------------===//
3687 // Move between special register and ARM core register -- for disassembly only
3690 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3691 [/* For disassembly only; pattern left blank */]> {
3692 let Inst{23-20} = 0b0000;
3693 let Inst{7-4} = 0b0000;
3696 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3697 [/* For disassembly only; pattern left blank */]> {
3698 let Inst{23-20} = 0b0100;
3699 let Inst{7-4} = 0b0000;
3702 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3703 "msr", "\tcpsr$mask, $src",
3704 [/* For disassembly only; pattern left blank */]> {
3705 let Inst{23-20} = 0b0010;
3706 let Inst{7-4} = 0b0000;
3709 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3710 "msr", "\tcpsr$mask, $a",
3711 [/* For disassembly only; pattern left blank */]> {
3712 let Inst{23-20} = 0b0010;
3713 let Inst{7-4} = 0b0000;
3716 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3717 "msr", "\tspsr$mask, $src",
3718 [/* For disassembly only; pattern left blank */]> {
3719 let Inst{23-20} = 0b0110;
3720 let Inst{7-4} = 0b0000;
3723 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3724 "msr", "\tspsr$mask, $a",
3725 [/* For disassembly only; pattern left blank */]> {
3726 let Inst{23-20} = 0b0110;
3727 let Inst{7-4} = 0b0000;