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 string 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 //===----------------------------------------------------------------------===//
273 // Operand Definitions.
277 def brtarget : Operand<OtherVT> {
278 string EncoderMethod = "getBranchTargetOpValue";
282 def bltarget : Operand<i32> {
283 // Encoded the same as branch targets.
284 string EncoderMethod = "getBranchTargetOpValue";
287 // A list of registers separated by comma. Used by load/store multiple.
288 def reglist : Operand<i32> {
289 string EncoderMethod = "getRegisterListOpValue";
290 let PrintMethod = "printRegisterList";
293 def RegListAsmOperand : AsmOperandClass {
294 let Name = "RegList";
295 let SuperClasses = [];
298 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
299 def cpinst_operand : Operand<i32> {
300 let PrintMethod = "printCPInstOperand";
303 def jtblock_operand : Operand<i32> {
304 let PrintMethod = "printJTBlockOperand";
306 def jt2block_operand : Operand<i32> {
307 let PrintMethod = "printJT2BlockOperand";
311 def pclabel : Operand<i32> {
312 let PrintMethod = "printPCLabel";
315 def neon_vcvt_imm32 : Operand<i32> {
316 string EncoderMethod = "getNEONVcvtImm32OpValue";
319 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
320 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
321 int32_t v = (int32_t)N->getZExtValue();
322 return v == 8 || v == 16 || v == 24; }]> {
323 string EncoderMethod = "getRotImmOpValue";
326 // shift_imm: An integer that encodes a shift amount and the type of shift
327 // (currently either asr or lsl) using the same encoding used for the
328 // immediates in so_reg operands.
329 def shift_imm : Operand<i32> {
330 let PrintMethod = "printShiftImmOperand";
333 // shifter_operand operands: so_reg and so_imm.
334 def so_reg : Operand<i32>, // reg reg imm
335 ComplexPattern<i32, 3, "SelectShifterOperandReg",
336 [shl,srl,sra,rotr]> {
337 string EncoderMethod = "getSORegOpValue";
338 let PrintMethod = "printSORegOperand";
339 let MIOperandInfo = (ops GPR, GPR, i32imm);
341 def shift_so_reg : Operand<i32>, // reg reg imm
342 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
343 [shl,srl,sra,rotr]> {
344 string EncoderMethod = "getSORegOpValue";
345 let PrintMethod = "printSORegOperand";
346 let MIOperandInfo = (ops GPR, GPR, i32imm);
349 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
350 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
351 // represented in the imm field in the same 12-bit form that they are encoded
352 // into so_imm instructions: the 8-bit immediate is the least significant bits
353 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
354 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
355 string EncoderMethod = "getSOImmOpValue";
356 let PrintMethod = "printSOImmOperand";
359 // Break so_imm's up into two pieces. This handles immediates with up to 16
360 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
361 // get the first/second pieces.
362 def so_imm2part : PatLeaf<(imm), [{
363 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
366 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
368 def arm_i32imm : PatLeaf<(imm), [{
369 if (Subtarget->hasV6T2Ops())
371 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
374 def so_imm2part_1 : SDNodeXForm<imm, [{
375 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
376 return CurDAG->getTargetConstant(V, MVT::i32);
379 def so_imm2part_2 : SDNodeXForm<imm, [{
380 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
381 return CurDAG->getTargetConstant(V, MVT::i32);
384 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
385 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
387 let PrintMethod = "printSOImm2PartOperand";
390 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
391 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
392 return CurDAG->getTargetConstant(V, MVT::i32);
395 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
396 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
397 return CurDAG->getTargetConstant(V, MVT::i32);
400 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
401 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
402 return (int32_t)N->getZExtValue() < 32;
405 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
406 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
407 return (int32_t)N->getZExtValue() < 32;
409 string EncoderMethod = "getImmMinusOneOpValue";
412 // Define ARM specific addressing modes.
415 // addrmode_imm12 := reg +/- imm12
417 def addrmode_imm12 : Operand<i32>,
418 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
419 // 12-bit immediate operand. Note that instructions using this encode
420 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
421 // immediate values are as normal.
423 string EncoderMethod = "getAddrModeImm12OpValue";
424 let PrintMethod = "printAddrModeImm12Operand";
425 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
427 // ldst_so_reg := reg +/- reg shop imm
429 def ldst_so_reg : Operand<i32>,
430 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
431 string EncoderMethod = "getLdStSORegOpValue";
432 // FIXME: Simplify the printer
433 let PrintMethod = "printAddrMode2Operand";
434 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
437 // addrmode2 := reg +/- imm12
438 // := reg +/- reg shop imm
440 def addrmode2 : Operand<i32>,
441 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
442 let PrintMethod = "printAddrMode2Operand";
443 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
446 def am2offset : Operand<i32>,
447 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
448 [], [SDNPWantRoot]> {
449 let PrintMethod = "printAddrMode2OffsetOperand";
450 let MIOperandInfo = (ops GPR, i32imm);
453 // addrmode3 := reg +/- reg
454 // addrmode3 := reg +/- imm8
456 def addrmode3 : Operand<i32>,
457 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
458 string EncoderMethod = "getAddrMode3OpValue";
459 let PrintMethod = "printAddrMode3Operand";
460 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
463 def am3offset : Operand<i32>,
464 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
465 [], [SDNPWantRoot]> {
466 string EncoderMethod = "getAddrMode3OffsetOpValue";
467 let PrintMethod = "printAddrMode3OffsetOperand";
468 let MIOperandInfo = (ops GPR, i32imm);
471 // ldstm_mode := {ia, ib, da, db}
473 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
474 string EncoderMethod = "getLdStmModeOpValue";
475 let PrintMethod = "printLdStmModeOperand";
478 def MemMode5AsmOperand : AsmOperandClass {
479 let Name = "MemMode5";
480 let SuperClasses = [];
483 // addrmode5 := reg +/- imm8*4
485 def addrmode5 : Operand<i32>,
486 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
487 let PrintMethod = "printAddrMode5Operand";
488 let MIOperandInfo = (ops GPR:$base, i32imm);
489 let ParserMatchClass = MemMode5AsmOperand;
490 string EncoderMethod = "getAddrMode5OpValue";
493 // addrmode6 := reg with optional writeback
495 def addrmode6 : Operand<i32>,
496 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
497 let PrintMethod = "printAddrMode6Operand";
498 let MIOperandInfo = (ops GPR:$addr, i32imm);
499 string EncoderMethod = "getAddrMode6AddressOpValue";
502 def am6offset : Operand<i32> {
503 let PrintMethod = "printAddrMode6OffsetOperand";
504 let MIOperandInfo = (ops GPR);
505 string EncoderMethod = "getAddrMode6OffsetOpValue";
508 // addrmodepc := pc + reg
510 def addrmodepc : Operand<i32>,
511 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
512 let PrintMethod = "printAddrModePCOperand";
513 let MIOperandInfo = (ops GPR, i32imm);
516 def nohash_imm : Operand<i32> {
517 let PrintMethod = "printNoHashImmediate";
520 //===----------------------------------------------------------------------===//
522 include "ARMInstrFormats.td"
524 //===----------------------------------------------------------------------===//
525 // Multiclass helpers...
528 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
529 /// binop that produces a value.
530 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
531 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
532 PatFrag opnode, bit Commutable = 0> {
533 // The register-immediate version is re-materializable. This is useful
534 // in particular for taking the address of a local.
535 let isReMaterializable = 1 in {
536 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
537 iii, opc, "\t$Rd, $Rn, $imm",
538 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
543 let Inst{19-16} = Rn;
544 let Inst{15-12} = Rd;
545 let Inst{11-0} = imm;
548 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
549 iir, opc, "\t$Rd, $Rn, $Rm",
550 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
555 let isCommutable = Commutable;
556 let Inst{19-16} = Rn;
557 let Inst{15-12} = Rd;
558 let Inst{11-4} = 0b00000000;
561 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
562 iis, opc, "\t$Rd, $Rn, $shift",
563 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
568 let Inst{19-16} = Rn;
569 let Inst{15-12} = Rd;
570 let Inst{11-0} = shift;
574 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
575 /// instruction modifies the CPSR register.
576 let Defs = [CPSR] in {
577 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
578 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
579 PatFrag opnode, bit Commutable = 0> {
580 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
581 iii, opc, "\t$Rd, $Rn, $imm",
582 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
588 let Inst{19-16} = Rn;
589 let Inst{15-12} = Rd;
590 let Inst{11-0} = imm;
592 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
593 iir, opc, "\t$Rd, $Rn, $Rm",
594 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
598 let isCommutable = Commutable;
601 let Inst{19-16} = Rn;
602 let Inst{15-12} = Rd;
603 let Inst{11-4} = 0b00000000;
606 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
607 iis, opc, "\t$Rd, $Rn, $shift",
608 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
614 let Inst{19-16} = Rn;
615 let Inst{15-12} = Rd;
616 let Inst{11-0} = shift;
621 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
622 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
623 /// a explicit result, only implicitly set CPSR.
624 let isCompare = 1, Defs = [CPSR] in {
625 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
626 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
627 PatFrag opnode, bit Commutable = 0> {
628 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
630 [(opnode GPR:$Rn, so_imm:$imm)]> {
635 let Inst{19-16} = Rn;
636 let Inst{15-12} = 0b0000;
637 let Inst{11-0} = imm;
639 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
641 [(opnode GPR:$Rn, GPR:$Rm)]> {
644 let isCommutable = Commutable;
647 let Inst{19-16} = Rn;
648 let Inst{15-12} = 0b0000;
649 let Inst{11-4} = 0b00000000;
652 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
653 opc, "\t$Rn, $shift",
654 [(opnode GPR:$Rn, so_reg:$shift)]> {
659 let Inst{19-16} = Rn;
660 let Inst{15-12} = 0b0000;
661 let Inst{11-0} = shift;
666 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
667 /// register and one whose operand is a register rotated by 8/16/24.
668 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
669 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
670 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
671 IIC_iEXTr, opc, "\t$Rd, $Rm",
672 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
673 Requires<[IsARM, HasV6]> {
676 let Inst{19-16} = 0b1111;
677 let Inst{15-12} = Rd;
678 let Inst{11-10} = 0b00;
681 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
682 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
683 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
684 Requires<[IsARM, HasV6]> {
688 let Inst{19-16} = 0b1111;
689 let Inst{15-12} = Rd;
690 let Inst{11-10} = rot;
695 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
696 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
697 IIC_iEXTr, opc, "\t$Rd, $Rm",
698 [/* For disassembly only; pattern left blank */]>,
699 Requires<[IsARM, HasV6]> {
700 let Inst{19-16} = 0b1111;
701 let Inst{11-10} = 0b00;
703 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
704 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
705 [/* For disassembly only; pattern left blank */]>,
706 Requires<[IsARM, HasV6]> {
708 let Inst{19-16} = 0b1111;
709 let Inst{11-10} = rot;
713 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
714 /// register and one whose operand is a register rotated by 8/16/24.
715 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
716 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
717 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
718 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
719 Requires<[IsARM, HasV6]> {
720 let Inst{11-10} = 0b00;
722 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
724 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
725 [(set GPR:$Rd, (opnode GPR:$Rn,
726 (rotr GPR:$Rm, rot_imm:$rot)))]>,
727 Requires<[IsARM, HasV6]> {
730 let Inst{19-16} = Rn;
731 let Inst{11-10} = rot;
735 // For disassembly only.
736 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
737 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
738 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
739 [/* For disassembly only; pattern left blank */]>,
740 Requires<[IsARM, HasV6]> {
741 let Inst{11-10} = 0b00;
743 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
745 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
746 [/* For disassembly only; pattern left blank */]>,
747 Requires<[IsARM, HasV6]> {
750 let Inst{19-16} = Rn;
751 let Inst{11-10} = rot;
755 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
756 let Uses = [CPSR] in {
757 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
758 bit Commutable = 0> {
759 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
760 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
761 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
767 let Inst{15-12} = Rd;
768 let Inst{19-16} = Rn;
769 let Inst{11-0} = imm;
771 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
772 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
773 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
778 let Inst{11-4} = 0b00000000;
780 let isCommutable = Commutable;
782 let Inst{15-12} = Rd;
783 let Inst{19-16} = Rn;
785 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
786 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
787 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
793 let Inst{11-0} = shift;
794 let Inst{15-12} = Rd;
795 let Inst{19-16} = Rn;
798 // Carry setting variants
799 let Defs = [CPSR] in {
800 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
801 bit Commutable = 0> {
802 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
803 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
804 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
809 let Inst{15-12} = Rd;
810 let Inst{19-16} = Rn;
811 let Inst{11-0} = imm;
815 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
816 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
817 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
822 let Inst{11-4} = 0b00000000;
823 let isCommutable = Commutable;
825 let Inst{15-12} = Rd;
826 let Inst{19-16} = Rn;
830 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
831 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
832 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
837 let Inst{11-0} = shift;
838 let Inst{15-12} = Rd;
839 let Inst{19-16} = Rn;
847 let canFoldAsLoad = 1, isReMaterializable = 1 in {
848 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
849 InstrItinClass iir, PatFrag opnode> {
850 // Note: We use the complex addrmode_imm12 rather than just an input
851 // GPR and a constrained immediate so that we can use this to match
852 // frame index references and avoid matching constant pool references.
853 def i12: AIldst1<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
854 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
855 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
858 let Inst{23} = addr{12}; // U (add = ('U' == 1))
859 let Inst{19-16} = addr{16-13}; // Rn
860 let Inst{15-12} = Rt;
861 let Inst{11-0} = addr{11-0}; // imm12
863 def rs : AIldst1<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
864 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
865 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
868 let Inst{23} = shift{12}; // U (add = ('U' == 1))
869 let Inst{19-16} = shift{16-13}; // Rn
870 let Inst{15-12} = Rt;
871 let Inst{11-0} = shift{11-0};
876 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
877 InstrItinClass iir, PatFrag opnode> {
878 // Note: We use the complex addrmode_imm12 rather than just an input
879 // GPR and a constrained immediate so that we can use this to match
880 // frame index references and avoid matching constant pool references.
881 def i12 : AIldst1<0b010, 0, isByte, (outs),
882 (ins GPR:$Rt, addrmode_imm12:$addr),
883 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
884 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
887 let Inst{23} = addr{12}; // U (add = ('U' == 1))
888 let Inst{19-16} = addr{16-13}; // Rn
889 let Inst{15-12} = Rt;
890 let Inst{11-0} = addr{11-0}; // imm12
892 def rs : AIldst1<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
893 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
894 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
897 let Inst{23} = shift{12}; // U (add = ('U' == 1))
898 let Inst{19-16} = shift{16-13}; // Rn
899 let Inst{15-12} = Rt;
900 let Inst{11-0} = shift{11-0};
903 //===----------------------------------------------------------------------===//
905 //===----------------------------------------------------------------------===//
907 //===----------------------------------------------------------------------===//
908 // Miscellaneous Instructions.
911 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
912 /// the function. The first operand is the ID# for this instruction, the second
913 /// is the index into the MachineConstantPool that this is, the third is the
914 /// size in bytes of this constant pool entry.
915 let neverHasSideEffects = 1, isNotDuplicable = 1 in
916 def CONSTPOOL_ENTRY :
917 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
918 i32imm:$size), NoItinerary, "", []>;
920 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
921 // from removing one half of the matched pairs. That breaks PEI, which assumes
922 // these will always be in pairs, and asserts if it finds otherwise. Better way?
923 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
925 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
926 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
928 def ADJCALLSTACKDOWN :
929 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
930 [(ARMcallseq_start timm:$amt)]>;
933 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
934 [/* For disassembly only; pattern left blank */]>,
935 Requires<[IsARM, HasV6T2]> {
936 let Inst{27-16} = 0b001100100000;
937 let Inst{15-8} = 0b11110000;
938 let Inst{7-0} = 0b00000000;
941 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
942 [/* For disassembly only; pattern left blank */]>,
943 Requires<[IsARM, HasV6T2]> {
944 let Inst{27-16} = 0b001100100000;
945 let Inst{15-8} = 0b11110000;
946 let Inst{7-0} = 0b00000001;
949 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
950 [/* For disassembly only; pattern left blank */]>,
951 Requires<[IsARM, HasV6T2]> {
952 let Inst{27-16} = 0b001100100000;
953 let Inst{15-8} = 0b11110000;
954 let Inst{7-0} = 0b00000010;
957 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
958 [/* For disassembly only; pattern left blank */]>,
959 Requires<[IsARM, HasV6T2]> {
960 let Inst{27-16} = 0b001100100000;
961 let Inst{15-8} = 0b11110000;
962 let Inst{7-0} = 0b00000011;
965 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
967 [/* For disassembly only; pattern left blank */]>,
968 Requires<[IsARM, HasV6]> {
973 let Inst{15-12} = Rd;
974 let Inst{19-16} = Rn;
975 let Inst{27-20} = 0b01101000;
976 let Inst{7-4} = 0b1011;
977 let Inst{11-8} = 0b1111;
980 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
981 [/* For disassembly only; pattern left blank */]>,
982 Requires<[IsARM, HasV6T2]> {
983 let Inst{27-16} = 0b001100100000;
984 let Inst{15-8} = 0b11110000;
985 let Inst{7-0} = 0b00000100;
988 // The i32imm operand $val can be used by a debugger to store more information
989 // about the breakpoint.
990 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
991 [/* For disassembly only; pattern left blank */]>,
994 let Inst{3-0} = val{3-0};
995 let Inst{19-8} = val{15-4};
996 let Inst{27-20} = 0b00010010;
997 let Inst{7-4} = 0b0111;
1000 // Change Processor State is a system instruction -- for disassembly only.
1001 // The singleton $opt operand contains the following information:
1002 // opt{4-0} = mode from Inst{4-0}
1003 // opt{5} = changemode from Inst{17}
1004 // opt{8-6} = AIF from Inst{8-6}
1005 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1006 // FIXME: Integrated assembler will need these split out.
1007 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1008 [/* For disassembly only; pattern left blank */]>,
1010 let Inst{31-28} = 0b1111;
1011 let Inst{27-20} = 0b00010000;
1016 // Preload signals the memory system of possible future data/instruction access.
1017 // These are for disassembly only.
1018 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1020 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1021 !strconcat(opc, "\t$addr"),
1022 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1025 let Inst{31-26} = 0b111101;
1026 let Inst{25} = 0; // 0 for immediate form
1027 let Inst{24} = data;
1028 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1029 let Inst{22} = read;
1030 let Inst{21-20} = 0b01;
1031 let Inst{19-16} = addr{16-13}; // Rn
1032 let Inst{15-12} = Rt;
1033 let Inst{11-0} = addr{11-0}; // imm12
1036 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1037 !strconcat(opc, "\t$shift"),
1038 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1041 let Inst{31-26} = 0b111101;
1042 let Inst{25} = 1; // 1 for register form
1043 let Inst{24} = data;
1044 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1045 let Inst{22} = read;
1046 let Inst{21-20} = 0b01;
1047 let Inst{19-16} = shift{16-13}; // Rn
1048 let Inst{11-0} = shift{11-0};
1052 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1053 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1054 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1056 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1058 [/* For disassembly only; pattern left blank */]>,
1061 let Inst{31-10} = 0b1111000100000001000000;
1066 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1067 [/* For disassembly only; pattern left blank */]>,
1068 Requires<[IsARM, HasV7]> {
1070 let Inst{27-4} = 0b001100100000111100001111;
1071 let Inst{3-0} = opt;
1074 // A5.4 Permanently UNDEFINED instructions.
1075 let isBarrier = 1, isTerminator = 1 in
1076 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1079 let Inst{27-25} = 0b011;
1080 let Inst{24-20} = 0b11111;
1081 let Inst{7-5} = 0b111;
1085 // Address computation and loads and stores in PIC mode.
1086 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1087 // classes (AXI1, et.al.) and so have encoding information and such,
1088 // which is suboptimal. Once the rest of the code emitter (including
1089 // JIT) is MC-ized we should look at refactoring these into true
1090 // pseudos. As is, the encoding information ends up being ignored,
1091 // as these instructions are lowered to individual MC-insts.
1092 let isNotDuplicable = 1 in {
1093 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1094 Pseudo, IIC_iALUr, "",
1095 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1097 let AddedComplexity = 10 in {
1098 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1099 Pseudo, IIC_iLoad_r, "",
1100 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1102 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1103 Pseudo, IIC_iLoad_bh_r, "",
1104 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1106 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1107 Pseudo, IIC_iLoad_bh_r, "",
1108 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1110 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1111 Pseudo, IIC_iLoad_bh_r, "",
1112 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1114 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1115 Pseudo, IIC_iLoad_bh_r, "",
1116 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1118 let AddedComplexity = 10 in {
1119 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1120 Pseudo, IIC_iStore_r, "",
1121 [(store GPR:$src, addrmodepc:$addr)]>;
1123 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1124 Pseudo, IIC_iStore_bh_r, "",
1125 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1127 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1128 Pseudo, IIC_iStore_bh_r, "",
1129 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1131 } // isNotDuplicable = 1
1134 // LEApcrel - Load a pc-relative address into a register without offending the
1136 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1137 // the ADR instruction. Is this the right way to handle that? They need
1138 // encoding information regardless.
1139 let neverHasSideEffects = 1 in {
1140 let isReMaterializable = 1 in
1141 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1143 "adr$p\t$dst, #$label", []>;
1145 } // neverHasSideEffects
1146 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1147 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1149 "adr$p\t$dst, #${label}_${id}", []> {
1153 //===----------------------------------------------------------------------===//
1154 // Control Flow Instructions.
1157 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1159 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1160 "bx", "\tlr", [(ARMretflag)]>,
1161 Requires<[IsARM, HasV4T]> {
1162 let Inst{27-0} = 0b0001001011111111111100011110;
1166 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1167 "mov", "\tpc, lr", [(ARMretflag)]>,
1168 Requires<[IsARM, NoV4T]> {
1169 let Inst{27-0} = 0b0001101000001111000000001110;
1173 // Indirect branches
1174 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1176 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1177 [(brind GPR:$dst)]>,
1178 Requires<[IsARM, HasV4T]> {
1180 let Inst{31-4} = 0b1110000100101111111111110001;
1181 let Inst{3-0} = dst;
1185 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1186 [(brind GPR:$dst)]>,
1187 Requires<[IsARM, NoV4T]> {
1189 let Inst{31-4} = 0b1110000110100000111100000000;
1190 let Inst{3-0} = dst;
1194 // FIXME: remove when we have a way to marking a MI with these properties.
1195 // FIXME: Should pc be an implicit operand like PICADD, etc?
1196 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1197 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1198 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$mode, pred:$p,
1199 reglist:$dsts, variable_ops),
1200 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1201 "ldm${mode}${p}\t$Rn!, $dsts",
1206 // On non-Darwin platforms R9 is callee-saved.
1208 Defs = [R0, R1, R2, R3, R12, LR,
1209 D0, D1, D2, D3, D4, D5, D6, D7,
1210 D16, D17, D18, D19, D20, D21, D22, D23,
1211 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1212 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1213 IIC_Br, "bl\t$func",
1214 [(ARMcall tglobaladdr:$func)]>,
1215 Requires<[IsARM, IsNotDarwin]> {
1216 let Inst{31-28} = 0b1110;
1218 let Inst{23-0} = func;
1221 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1222 IIC_Br, "bl", "\t$func",
1223 [(ARMcall_pred tglobaladdr:$func)]>,
1224 Requires<[IsARM, IsNotDarwin]> {
1226 let Inst{23-0} = func;
1230 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1231 IIC_Br, "blx\t$func",
1232 [(ARMcall GPR:$func)]>,
1233 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1235 let Inst{27-4} = 0b000100101111111111110011;
1236 let Inst{3-0} = func;
1240 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1241 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1242 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1243 [(ARMcall_nolink tGPR:$func)]>,
1244 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1246 let Inst{27-4} = 0b000100101111111111110001;
1247 let Inst{3-0} = func;
1251 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1252 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1253 [(ARMcall_nolink tGPR:$func)]>,
1254 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1256 let Inst{27-4} = 0b000110100000111100000000;
1257 let Inst{3-0} = func;
1261 // On Darwin R9 is call-clobbered.
1263 Defs = [R0, R1, R2, R3, R9, R12, LR,
1264 D0, D1, D2, D3, D4, D5, D6, D7,
1265 D16, D17, D18, D19, D20, D21, D22, D23,
1266 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1267 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1268 IIC_Br, "bl\t$func",
1269 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1270 let Inst{31-28} = 0b1110;
1272 let Inst{23-0} = func;
1275 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1276 IIC_Br, "bl", "\t$func",
1277 [(ARMcall_pred tglobaladdr:$func)]>,
1278 Requires<[IsARM, IsDarwin]> {
1280 let Inst{23-0} = func;
1284 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1285 IIC_Br, "blx\t$func",
1286 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1288 let Inst{27-4} = 0b000100101111111111110011;
1289 let Inst{3-0} = func;
1293 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1294 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1295 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1296 [(ARMcall_nolink tGPR:$func)]>,
1297 Requires<[IsARM, HasV4T, IsDarwin]> {
1299 let Inst{27-4} = 0b000100101111111111110001;
1300 let Inst{3-0} = func;
1304 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1305 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1306 [(ARMcall_nolink tGPR:$func)]>,
1307 Requires<[IsARM, NoV4T, IsDarwin]> {
1309 let Inst{27-4} = 0b000110100000111100000000;
1310 let Inst{3-0} = func;
1316 // FIXME: These should probably be xformed into the non-TC versions of the
1317 // instructions as part of MC lowering.
1318 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1320 let Defs = [R0, R1, R2, R3, R9, R12,
1321 D0, D1, D2, D3, D4, D5, D6, D7,
1322 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1323 D27, D28, D29, D30, D31, PC],
1325 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1327 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1329 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1331 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1333 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1334 IIC_Br, "b\t$dst @ TAILCALL",
1335 []>, Requires<[IsDarwin]>;
1337 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1338 IIC_Br, "b.w\t$dst @ TAILCALL",
1339 []>, Requires<[IsDarwin]>;
1341 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1342 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1343 []>, Requires<[IsDarwin]> {
1345 let Inst{31-4} = 0b1110000100101111111111110001;
1346 let Inst{3-0} = dst;
1350 // Non-Darwin versions (the difference is R9).
1351 let Defs = [R0, R1, R2, R3, R12,
1352 D0, D1, D2, D3, D4, D5, D6, D7,
1353 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1354 D27, D28, D29, D30, D31, PC],
1356 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1358 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1360 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1362 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1364 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1365 IIC_Br, "b\t$dst @ TAILCALL",
1366 []>, Requires<[IsARM, IsNotDarwin]>;
1368 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1369 IIC_Br, "b.w\t$dst @ TAILCALL",
1370 []>, Requires<[IsThumb, IsNotDarwin]>;
1372 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1373 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1374 []>, Requires<[IsNotDarwin]> {
1376 let Inst{31-4} = 0b1110000100101111111111110001;
1377 let Inst{3-0} = dst;
1382 let isBranch = 1, isTerminator = 1 in {
1383 // B is "predicable" since it can be xformed into a Bcc.
1384 let isBarrier = 1 in {
1385 let isPredicable = 1 in
1386 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1387 "b\t$target", [(br bb:$target)]> {
1389 let Inst{31-28} = 0b1110;
1390 let Inst{23-0} = target;
1393 let isNotDuplicable = 1, isIndirectBranch = 1,
1394 // FIXME: $imm field is not specified by asm string. Mark as cgonly.
1395 isCodeGenOnly = 1 in {
1396 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1397 IIC_Br, "mov\tpc, $target$jt",
1398 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1399 let Inst{11-4} = 0b00000000;
1400 let Inst{15-12} = 0b1111;
1401 let Inst{20} = 0; // S Bit
1402 let Inst{24-21} = 0b1101;
1403 let Inst{27-25} = 0b000;
1405 def BR_JTm : JTI<(outs),
1406 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1407 IIC_Br, "ldr\tpc, $target$jt",
1408 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1410 let Inst{15-12} = 0b1111;
1411 let Inst{20} = 1; // L bit
1412 let Inst{21} = 0; // W bit
1413 let Inst{22} = 0; // B bit
1414 let Inst{24} = 1; // P bit
1415 let Inst{27-25} = 0b011;
1417 def BR_JTadd : JTI<(outs),
1418 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1419 IIC_Br, "add\tpc, $target, $idx$jt",
1420 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1422 let Inst{15-12} = 0b1111;
1423 let Inst{20} = 0; // S bit
1424 let Inst{24-21} = 0b0100;
1425 let Inst{27-25} = 0b000;
1427 } // isNotDuplicable = 1, isIndirectBranch = 1
1430 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1431 // a two-value operand where a dag node expects two operands. :(
1432 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1433 IIC_Br, "b", "\t$target",
1434 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1436 let Inst{23-0} = target;
1440 // Branch and Exchange Jazelle -- for disassembly only
1441 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1442 [/* For disassembly only; pattern left blank */]> {
1443 let Inst{23-20} = 0b0010;
1444 //let Inst{19-8} = 0xfff;
1445 let Inst{7-4} = 0b0010;
1448 // Secure Monitor Call is a system instruction -- for disassembly only
1449 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1450 [/* For disassembly only; pattern left blank */]> {
1452 let Inst{23-4} = 0b01100000000000000111;
1453 let Inst{3-0} = opt;
1456 // Supervisor Call (Software Interrupt) -- for disassembly only
1458 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1459 [/* For disassembly only; pattern left blank */]> {
1461 let Inst{23-0} = svc;
1465 // Store Return State is a system instruction -- for disassembly only
1466 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1467 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1468 NoItinerary, "srs${amode}\tsp!, $mode",
1469 [/* For disassembly only; pattern left blank */]> {
1470 let Inst{31-28} = 0b1111;
1471 let Inst{22-20} = 0b110; // W = 1
1474 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1475 NoItinerary, "srs${amode}\tsp, $mode",
1476 [/* For disassembly only; pattern left blank */]> {
1477 let Inst{31-28} = 0b1111;
1478 let Inst{22-20} = 0b100; // W = 0
1481 // Return From Exception is a system instruction -- for disassembly only
1482 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1483 NoItinerary, "rfe${amode}\t$base!",
1484 [/* For disassembly only; pattern left blank */]> {
1485 let Inst{31-28} = 0b1111;
1486 let Inst{22-20} = 0b011; // W = 1
1489 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1490 NoItinerary, "rfe${amode}\t$base",
1491 [/* For disassembly only; pattern left blank */]> {
1492 let Inst{31-28} = 0b1111;
1493 let Inst{22-20} = 0b001; // W = 0
1495 } // isCodeGenOnly = 1
1497 //===----------------------------------------------------------------------===//
1498 // Load / store Instructions.
1504 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1505 UnOpFrag<(load node:$Src)>>;
1506 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1507 UnOpFrag<(zextloadi8 node:$Src)>>;
1508 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1509 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1510 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1511 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1513 // Special LDR for loads from non-pc-relative constpools.
1514 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1515 isReMaterializable = 1 in
1516 def LDRcp : AIldst1<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1517 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1521 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1522 let Inst{19-16} = 0b1111;
1523 let Inst{15-12} = Rt;
1524 let Inst{11-0} = addr{11-0}; // imm12
1527 // Loads with zero extension
1528 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1529 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1530 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1532 // Loads with sign extension
1533 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1534 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1535 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1537 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1538 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1539 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1541 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1542 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1544 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1545 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1546 []>, Requires<[IsARM, HasV5TE]>;
1549 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1550 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1551 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1552 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1553 let Inst{21} = 1; // W bit (overwrite)
1555 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1556 (ins GPR:$Rn, am2offset:$offset),
1557 IndexModePost, LdFrm, itin,
1558 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1561 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1562 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1564 def LDRH_PRE : AI3ldhpr<(outs GPR:$Rt, GPR:$Rn_wb),
1565 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1566 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1568 def LDRH_POST : AI3ldhpo<(outs GPR:$Rt, GPR:$Rn_wb),
1569 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1570 "ldrh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1572 def LDRSH_PRE : AI3ldshpr<(outs GPR:$Rt, GPR:$Rn_wb),
1573 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1574 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1576 def LDRSH_POST: AI3ldshpo<(outs GPR:$Rt, GPR:$Rn_wb),
1577 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1578 "ldrsh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1580 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$Rt, GPR:$Rn_wb),
1581 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1582 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1584 def LDRSB_POST: AI3ldsbpo<(outs GPR:$Rt, GPR:$Rn_wb),
1585 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1586 "ldrsb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1588 // For disassembly only
1589 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1590 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1591 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1592 Requires<[IsARM, HasV5TE]>;
1594 // For disassembly only
1595 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1596 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1597 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1598 Requires<[IsARM, HasV5TE]>;
1600 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1602 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1604 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1605 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1606 LdFrm, IIC_iLoad_ru,
1607 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1608 let Inst{21} = 1; // overwrite
1611 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1612 (ins GPR:$base,am2offset:$offset), IndexModeNone,
1613 LdFrm, IIC_iLoad_bh_ru,
1614 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1615 let Inst{21} = 1; // overwrite
1618 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1619 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1620 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1621 let Inst{21} = 1; // overwrite
1624 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1625 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1626 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1627 let Inst{21} = 1; // overwrite
1630 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1631 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1632 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1633 let Inst{21} = 1; // overwrite
1638 // Stores with truncate
1639 def STRH : AI3sth<(outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1640 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1641 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1644 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1645 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1646 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1647 StMiscFrm, IIC_iStore_d_r,
1648 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1651 def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$base_wb),
1652 (ins GPR:$src, GPR:$base, am2offset:$offset),
1653 IndexModePre, StFrm, IIC_iStore_ru,
1654 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1656 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1658 def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
1659 (ins GPR:$src, GPR:$base,am2offset:$offset),
1660 IndexModePost, StFrm, IIC_iStore_ru,
1661 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1663 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1665 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1666 (ins GPR:$src, GPR:$base,am3offset:$offset),
1667 StMiscFrm, IIC_iStore_ru,
1668 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1670 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1672 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1673 (ins GPR:$src, GPR:$base,am3offset:$offset),
1674 StMiscFrm, IIC_iStore_bh_ru,
1675 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1676 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1677 GPR:$base, am3offset:$offset))]>;
1679 def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$base_wb),
1680 (ins GPR:$src, GPR:$base,am2offset:$offset),
1681 IndexModePre, StFrm, IIC_iStore_bh_ru,
1682 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1683 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1684 GPR:$base, am2offset:$offset))]>;
1686 def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
1687 (ins GPR:$src, GPR:$base,am2offset:$offset),
1688 IndexModePost, StFrm, IIC_iStore_bh_ru,
1689 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1690 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1691 GPR:$base, am2offset:$offset))]>;
1693 // For disassembly only
1694 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1695 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1696 StMiscFrm, IIC_iStore_d_ru,
1697 "strd", "\t$src1, $src2, [$base, $offset]!",
1698 "$base = $base_wb", []>;
1700 // For disassembly only
1701 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1702 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1703 StMiscFrm, IIC_iStore_d_ru,
1704 "strd", "\t$src1, $src2, [$base], $offset",
1705 "$base = $base_wb", []>;
1707 // STRT, STRBT, and STRHT are for disassembly only.
1709 def STRT : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
1710 (ins GPR:$src, GPR:$base,am2offset:$offset),
1711 IndexModeNone, StFrm, IIC_iStore_ru,
1712 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1713 [/* For disassembly only; pattern left blank */]> {
1714 let Inst{21} = 1; // overwrite
1717 def STRBT : AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
1718 (ins GPR:$src, GPR:$base,am2offset:$offset),
1719 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1720 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1721 [/* For disassembly only; pattern left blank */]> {
1722 let Inst{21} = 1; // overwrite
1725 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1726 (ins GPR:$src, GPR:$base,am3offset:$offset),
1727 StMiscFrm, IIC_iStore_bh_ru,
1728 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1729 [/* For disassembly only; pattern left blank */]> {
1730 let Inst{21} = 1; // overwrite
1733 //===----------------------------------------------------------------------===//
1734 // Load / store multiple Instructions.
1737 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1738 isCodeGenOnly = 1 in {
1739 def LDM : AXI4ld<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1740 reglist:$dsts, variable_ops),
1741 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1742 "ldm${amode}${p}\t$Rn, $dsts", "", []> {
1746 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1747 reglist:$dsts, variable_ops),
1748 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1749 "ldm${amode}${p}\t$Rn!, $dsts",
1753 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1755 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1756 isCodeGenOnly = 1 in {
1757 def STM : AXI4st<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1758 reglist:$srcs, variable_ops),
1759 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1760 "stm${amode}${p}\t$Rn, $srcs", "", []> {
1764 def STM_UPD : AXI4st<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1765 reglist:$srcs, variable_ops),
1766 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1767 "stm${amode}${p}\t$Rn!, $srcs",
1770 let Inst{31-28} = p;
1773 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1775 //===----------------------------------------------------------------------===//
1776 // Move Instructions.
1779 let neverHasSideEffects = 1 in
1780 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1781 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1785 let Inst{11-4} = 0b00000000;
1788 let Inst{15-12} = Rd;
1791 // A version for the smaller set of tail call registers.
1792 let neverHasSideEffects = 1 in
1793 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1794 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1798 let Inst{11-4} = 0b00000000;
1801 let Inst{15-12} = Rd;
1804 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1805 DPSoRegFrm, IIC_iMOVsr,
1806 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1810 let Inst{15-12} = Rd;
1811 let Inst{11-0} = src;
1815 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1816 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1817 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1821 let Inst{15-12} = Rd;
1822 let Inst{19-16} = 0b0000;
1823 let Inst{11-0} = imm;
1826 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1827 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1829 "movw", "\t$Rd, $imm",
1830 [(set GPR:$Rd, imm0_65535:$imm)]>,
1831 Requires<[IsARM, HasV6T2]>, UnaryDP {
1834 let Inst{15-12} = Rd;
1835 let Inst{11-0} = imm{11-0};
1836 let Inst{19-16} = imm{15-12};
1841 let Constraints = "$src = $Rd" in
1842 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1844 "movt", "\t$Rd, $imm",
1846 (or (and GPR:$src, 0xffff),
1847 lo16AllZero:$imm))]>, UnaryDP,
1848 Requires<[IsARM, HasV6T2]> {
1851 let Inst{15-12} = Rd;
1852 let Inst{11-0} = imm{11-0};
1853 let Inst{19-16} = imm{15-12};
1858 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1859 Requires<[IsARM, HasV6T2]>;
1861 let Uses = [CPSR] in
1862 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1863 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1866 // These aren't really mov instructions, but we have to define them this way
1867 // due to flag operands.
1869 let Defs = [CPSR] in {
1870 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1871 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1873 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1874 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1878 //===----------------------------------------------------------------------===//
1879 // Extend Instructions.
1884 defm SXTB : AI_ext_rrot<0b01101010,
1885 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1886 defm SXTH : AI_ext_rrot<0b01101011,
1887 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1889 defm SXTAB : AI_exta_rrot<0b01101010,
1890 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1891 defm SXTAH : AI_exta_rrot<0b01101011,
1892 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1894 // For disassembly only
1895 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1897 // For disassembly only
1898 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1902 let AddedComplexity = 16 in {
1903 defm UXTB : AI_ext_rrot<0b01101110,
1904 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1905 defm UXTH : AI_ext_rrot<0b01101111,
1906 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1907 defm UXTB16 : AI_ext_rrot<0b01101100,
1908 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1910 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1911 // The transformation should probably be done as a combiner action
1912 // instead so we can include a check for masking back in the upper
1913 // eight bits of the source into the lower eight bits of the result.
1914 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1915 // (UXTB16r_rot GPR:$Src, 24)>;
1916 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1917 (UXTB16r_rot GPR:$Src, 8)>;
1919 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1920 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1921 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1922 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1925 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1926 // For disassembly only
1927 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1930 def SBFX : I<(outs GPR:$Rd),
1931 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1932 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1933 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1934 Requires<[IsARM, HasV6T2]> {
1939 let Inst{27-21} = 0b0111101;
1940 let Inst{6-4} = 0b101;
1941 let Inst{20-16} = width;
1942 let Inst{15-12} = Rd;
1943 let Inst{11-7} = lsb;
1947 def UBFX : I<(outs GPR:$Rd),
1948 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1949 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1950 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1951 Requires<[IsARM, HasV6T2]> {
1956 let Inst{27-21} = 0b0111111;
1957 let Inst{6-4} = 0b101;
1958 let Inst{20-16} = width;
1959 let Inst{15-12} = Rd;
1960 let Inst{11-7} = lsb;
1964 //===----------------------------------------------------------------------===//
1965 // Arithmetic Instructions.
1968 defm ADD : AsI1_bin_irs<0b0100, "add",
1969 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1970 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1971 defm SUB : AsI1_bin_irs<0b0010, "sub",
1972 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1973 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1975 // ADD and SUB with 's' bit set.
1976 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1977 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1978 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1979 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1980 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1981 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1983 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1984 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1985 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1986 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1987 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1988 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1989 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1990 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1992 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1993 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
1994 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
1999 let Inst{15-12} = Rd;
2000 let Inst{19-16} = Rn;
2001 let Inst{11-0} = imm;
2004 // The reg/reg form is only defined for the disassembler; for codegen it is
2005 // equivalent to SUBrr.
2006 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2007 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2008 [/* For disassembly only; pattern left blank */]> {
2012 let Inst{11-4} = 0b00000000;
2015 let Inst{15-12} = Rd;
2016 let Inst{19-16} = Rn;
2019 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2020 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2021 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2026 let Inst{11-0} = shift;
2027 let Inst{15-12} = Rd;
2028 let Inst{19-16} = Rn;
2031 // RSB with 's' bit set.
2032 let Defs = [CPSR] in {
2033 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2034 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2035 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2041 let Inst{15-12} = Rd;
2042 let Inst{19-16} = Rn;
2043 let Inst{11-0} = imm;
2045 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2046 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2047 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2053 let Inst{11-0} = shift;
2054 let Inst{15-12} = Rd;
2055 let Inst{19-16} = Rn;
2059 let Uses = [CPSR] in {
2060 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2061 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2062 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2068 let Inst{15-12} = Rd;
2069 let Inst{19-16} = Rn;
2070 let Inst{11-0} = imm;
2072 // The reg/reg form is only defined for the disassembler; for codegen it is
2073 // equivalent to SUBrr.
2074 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2075 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2076 [/* For disassembly only; pattern left blank */]> {
2080 let Inst{11-4} = 0b00000000;
2083 let Inst{15-12} = Rd;
2084 let Inst{19-16} = Rn;
2086 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2087 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2088 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2094 let Inst{11-0} = shift;
2095 let Inst{15-12} = Rd;
2096 let Inst{19-16} = Rn;
2100 // FIXME: Allow these to be predicated.
2101 let Defs = [CPSR], Uses = [CPSR] in {
2102 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2103 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2104 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2111 let Inst{15-12} = Rd;
2112 let Inst{19-16} = Rn;
2113 let Inst{11-0} = imm;
2115 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2116 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2117 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2124 let Inst{11-0} = shift;
2125 let Inst{15-12} = Rd;
2126 let Inst{19-16} = Rn;
2130 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2131 // The assume-no-carry-in form uses the negation of the input since add/sub
2132 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2133 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2135 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2136 (SUBri GPR:$src, so_imm_neg:$imm)>;
2137 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2138 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2139 // The with-carry-in form matches bitwise not instead of the negation.
2140 // Effectively, the inverse interpretation of the carry flag already accounts
2141 // for part of the negation.
2142 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2143 (SBCri GPR:$src, so_imm_not:$imm)>;
2145 // Note: These are implemented in C++ code, because they have to generate
2146 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2148 // (mul X, 2^n+1) -> (add (X << n), X)
2149 // (mul X, 2^n-1) -> (rsb X, (X << n))
2151 // ARM Arithmetic Instruction -- for disassembly only
2152 // GPR:$dst = GPR:$a op GPR:$b
2153 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2154 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2155 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2156 opc, "\t$Rd, $Rn, $Rm", pattern> {
2160 let Inst{27-20} = op27_20;
2161 let Inst{11-4} = op11_4;
2162 let Inst{19-16} = Rn;
2163 let Inst{15-12} = Rd;
2167 // Saturating add/subtract -- for disassembly only
2169 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2170 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2171 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2172 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2173 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2174 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2176 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2177 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2178 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2179 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2180 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2181 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2182 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2183 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2184 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2185 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2186 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2187 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2189 // Signed/Unsigned add/subtract -- for disassembly only
2191 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2192 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2193 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2194 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2195 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2196 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2197 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2198 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2199 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2200 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2201 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2202 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2204 // Signed/Unsigned halving add/subtract -- for disassembly only
2206 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2207 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2208 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2209 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2210 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2211 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2212 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2213 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2214 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2215 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2216 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2217 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2219 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2221 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2222 MulFrm /* for convenience */, NoItinerary, "usad8",
2223 "\t$Rd, $Rn, $Rm", []>,
2224 Requires<[IsARM, HasV6]> {
2228 let Inst{27-20} = 0b01111000;
2229 let Inst{15-12} = 0b1111;
2230 let Inst{7-4} = 0b0001;
2231 let Inst{19-16} = Rd;
2232 let Inst{11-8} = Rm;
2235 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2236 MulFrm /* for convenience */, NoItinerary, "usada8",
2237 "\t$Rd, $Rn, $Rm, $Ra", []>,
2238 Requires<[IsARM, HasV6]> {
2243 let Inst{27-20} = 0b01111000;
2244 let Inst{7-4} = 0b0001;
2245 let Inst{19-16} = Rd;
2246 let Inst{15-12} = Ra;
2247 let Inst{11-8} = Rm;
2251 // Signed/Unsigned saturate -- for disassembly only
2253 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2254 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2255 [/* For disassembly only; pattern left blank */]> {
2260 let Inst{27-21} = 0b0110101;
2261 let Inst{5-4} = 0b01;
2262 let Inst{20-16} = sat_imm;
2263 let Inst{15-12} = Rd;
2264 let Inst{11-7} = sh{7-3};
2265 let Inst{6} = sh{0};
2269 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2270 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2271 [/* For disassembly only; pattern left blank */]> {
2275 let Inst{27-20} = 0b01101010;
2276 let Inst{11-4} = 0b11110011;
2277 let Inst{15-12} = Rd;
2278 let Inst{19-16} = sat_imm;
2282 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2283 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2284 [/* For disassembly only; pattern left blank */]> {
2289 let Inst{27-21} = 0b0110111;
2290 let Inst{5-4} = 0b01;
2291 let Inst{15-12} = Rd;
2292 let Inst{11-7} = sh{7-3};
2293 let Inst{6} = sh{0};
2294 let Inst{20-16} = sat_imm;
2298 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2299 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2300 [/* For disassembly only; pattern left blank */]> {
2304 let Inst{27-20} = 0b01101110;
2305 let Inst{11-4} = 0b11110011;
2306 let Inst{15-12} = Rd;
2307 let Inst{19-16} = sat_imm;
2311 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2312 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2314 //===----------------------------------------------------------------------===//
2315 // Bitwise Instructions.
2318 defm AND : AsI1_bin_irs<0b0000, "and",
2319 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2320 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2321 defm ORR : AsI1_bin_irs<0b1100, "orr",
2322 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2323 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2324 defm EOR : AsI1_bin_irs<0b0001, "eor",
2325 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2326 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2327 defm BIC : AsI1_bin_irs<0b1110, "bic",
2328 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2329 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2331 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2332 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2333 "bfc", "\t$Rd, $imm", "$src = $Rd",
2334 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2335 Requires<[IsARM, HasV6T2]> {
2338 let Inst{27-21} = 0b0111110;
2339 let Inst{6-0} = 0b0011111;
2340 let Inst{15-12} = Rd;
2341 let Inst{11-7} = imm{4-0}; // lsb
2342 let Inst{20-16} = imm{9-5}; // width
2345 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2346 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2347 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2348 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2349 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2350 bf_inv_mask_imm:$imm))]>,
2351 Requires<[IsARM, HasV6T2]> {
2355 let Inst{27-21} = 0b0111110;
2356 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2357 let Inst{15-12} = Rd;
2358 let Inst{11-7} = imm{4-0}; // lsb
2359 let Inst{20-16} = imm{9-5}; // width
2363 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2364 "mvn", "\t$Rd, $Rm",
2365 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2369 let Inst{19-16} = 0b0000;
2370 let Inst{11-4} = 0b00000000;
2371 let Inst{15-12} = Rd;
2374 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2375 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2376 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2380 let Inst{19-16} = 0b0000;
2381 let Inst{15-12} = Rd;
2382 let Inst{11-0} = shift;
2384 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2385 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2386 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2387 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2391 let Inst{19-16} = 0b0000;
2392 let Inst{15-12} = Rd;
2393 let Inst{11-0} = imm;
2396 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2397 (BICri GPR:$src, so_imm_not:$imm)>;
2399 //===----------------------------------------------------------------------===//
2400 // Multiply Instructions.
2402 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2403 string opc, string asm, list<dag> pattern>
2404 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2408 let Inst{19-16} = Rd;
2409 let Inst{11-8} = Rm;
2412 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2413 string opc, string asm, list<dag> pattern>
2414 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2419 let Inst{19-16} = RdHi;
2420 let Inst{15-12} = RdLo;
2421 let Inst{11-8} = Rm;
2425 let isCommutable = 1 in
2426 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2427 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2428 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2430 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2431 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2432 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2434 let Inst{15-12} = Ra;
2437 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2438 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2439 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2440 Requires<[IsARM, HasV6T2]> {
2444 let Inst{19-16} = Rd;
2445 let Inst{11-8} = Rm;
2449 // Extra precision multiplies with low / high results
2451 let neverHasSideEffects = 1 in {
2452 let isCommutable = 1 in {
2453 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2454 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2455 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2457 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2458 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2459 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2462 // Multiply + accumulate
2463 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2464 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2465 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2467 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2468 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2469 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2471 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2472 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2473 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2474 Requires<[IsARM, HasV6]> {
2479 let Inst{19-16} = RdLo;
2480 let Inst{15-12} = RdHi;
2481 let Inst{11-8} = Rm;
2484 } // neverHasSideEffects
2486 // Most significant word multiply
2487 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2488 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2489 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2490 Requires<[IsARM, HasV6]> {
2491 let Inst{15-12} = 0b1111;
2494 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2495 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2496 [/* For disassembly only; pattern left blank */]>,
2497 Requires<[IsARM, HasV6]> {
2498 let Inst{15-12} = 0b1111;
2501 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2502 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2503 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2504 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2505 Requires<[IsARM, HasV6]>;
2507 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2508 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2509 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2510 [/* For disassembly only; pattern left blank */]>,
2511 Requires<[IsARM, HasV6]>;
2513 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2514 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2515 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2516 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2517 Requires<[IsARM, HasV6]>;
2519 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2520 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2521 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2522 [/* For disassembly only; pattern left blank */]>,
2523 Requires<[IsARM, HasV6]>;
2525 multiclass AI_smul<string opc, PatFrag opnode> {
2526 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2527 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2528 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2529 (sext_inreg GPR:$Rm, i16)))]>,
2530 Requires<[IsARM, HasV5TE]>;
2532 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2533 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2534 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2535 (sra GPR:$Rm, (i32 16))))]>,
2536 Requires<[IsARM, HasV5TE]>;
2538 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2539 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2540 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2541 (sext_inreg GPR:$Rm, i16)))]>,
2542 Requires<[IsARM, HasV5TE]>;
2544 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2545 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2546 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2547 (sra GPR:$Rm, (i32 16))))]>,
2548 Requires<[IsARM, HasV5TE]>;
2550 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2551 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2552 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2553 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2554 Requires<[IsARM, HasV5TE]>;
2556 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2557 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2558 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2559 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2560 Requires<[IsARM, HasV5TE]>;
2564 multiclass AI_smla<string opc, PatFrag opnode> {
2565 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2566 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2567 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2568 [(set GPR:$Rd, (add GPR:$Ra,
2569 (opnode (sext_inreg GPR:$Rn, i16),
2570 (sext_inreg GPR:$Rm, i16))))]>,
2571 Requires<[IsARM, HasV5TE]>;
2573 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2574 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2575 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2576 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2577 (sra GPR:$Rm, (i32 16)))))]>,
2578 Requires<[IsARM, HasV5TE]>;
2580 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2581 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2582 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2583 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2584 (sext_inreg GPR:$Rm, i16))))]>,
2585 Requires<[IsARM, HasV5TE]>;
2587 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2588 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2589 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2590 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2591 (sra GPR:$Rm, (i32 16)))))]>,
2592 Requires<[IsARM, HasV5TE]>;
2594 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2595 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2596 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2597 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2598 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2599 Requires<[IsARM, HasV5TE]>;
2601 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2602 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2603 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2604 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2605 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2606 Requires<[IsARM, HasV5TE]>;
2609 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2610 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2612 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2613 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2614 (ins GPR:$Rn, GPR:$Rm),
2615 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2616 [/* For disassembly only; pattern left blank */]>,
2617 Requires<[IsARM, HasV5TE]>;
2619 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2620 (ins GPR:$Rn, GPR:$Rm),
2621 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2622 [/* For disassembly only; pattern left blank */]>,
2623 Requires<[IsARM, HasV5TE]>;
2625 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2626 (ins GPR:$Rn, GPR:$Rm),
2627 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2628 [/* For disassembly only; pattern left blank */]>,
2629 Requires<[IsARM, HasV5TE]>;
2631 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2632 (ins GPR:$Rn, GPR:$Rm),
2633 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2634 [/* For disassembly only; pattern left blank */]>,
2635 Requires<[IsARM, HasV5TE]>;
2637 // Helper class for AI_smld -- for disassembly only
2638 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2639 InstrItinClass itin, string opc, string asm>
2640 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2647 let Inst{21-20} = 0b00;
2648 let Inst{22} = long;
2649 let Inst{27-23} = 0b01110;
2650 let Inst{11-8} = Rm;
2653 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2654 InstrItinClass itin, string opc, string asm>
2655 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2657 let Inst{15-12} = 0b1111;
2658 let Inst{19-16} = Rd;
2660 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2661 InstrItinClass itin, string opc, string asm>
2662 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2664 let Inst{15-12} = Ra;
2666 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2667 InstrItinClass itin, string opc, string asm>
2668 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2671 let Inst{19-16} = RdHi;
2672 let Inst{15-12} = RdLo;
2675 multiclass AI_smld<bit sub, string opc> {
2677 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2678 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2680 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2681 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2683 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2684 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2685 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2687 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2688 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2689 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2693 defm SMLA : AI_smld<0, "smla">;
2694 defm SMLS : AI_smld<1, "smls">;
2696 multiclass AI_sdml<bit sub, string opc> {
2698 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2699 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2700 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2701 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2704 defm SMUA : AI_sdml<0, "smua">;
2705 defm SMUS : AI_sdml<1, "smus">;
2707 //===----------------------------------------------------------------------===//
2708 // Misc. Arithmetic Instructions.
2711 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2712 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2713 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2715 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2716 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2717 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2718 Requires<[IsARM, HasV6T2]>;
2720 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2721 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2722 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2724 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2725 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2727 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2728 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2729 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2730 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2731 Requires<[IsARM, HasV6]>;
2733 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2734 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2737 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2738 (shl GPR:$Rm, (i32 8))), i16))]>,
2739 Requires<[IsARM, HasV6]>;
2741 def lsl_shift_imm : SDNodeXForm<imm, [{
2742 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2743 return CurDAG->getTargetConstant(Sh, MVT::i32);
2746 def lsl_amt : PatLeaf<(i32 imm), [{
2747 return (N->getZExtValue() < 32);
2750 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2751 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2752 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2753 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2754 (and (shl GPR:$Rm, lsl_amt:$sh),
2756 Requires<[IsARM, HasV6]>;
2758 // Alternate cases for PKHBT where identities eliminate some nodes.
2759 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2760 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2761 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2762 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2764 def asr_shift_imm : SDNodeXForm<imm, [{
2765 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2766 return CurDAG->getTargetConstant(Sh, MVT::i32);
2769 def asr_amt : PatLeaf<(i32 imm), [{
2770 return (N->getZExtValue() <= 32);
2773 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2774 // will match the pattern below.
2775 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2776 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2777 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2778 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2779 (and (sra GPR:$Rm, asr_amt:$sh),
2781 Requires<[IsARM, HasV6]>;
2783 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2784 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2785 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2786 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2787 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2788 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2789 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2791 //===----------------------------------------------------------------------===//
2792 // Comparison Instructions...
2795 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2796 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2797 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2799 // FIXME: We have to be careful when using the CMN instruction and comparison
2800 // with 0. One would expect these two pieces of code should give identical
2816 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2817 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2818 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2819 // value of r0 and the carry bit (because the "carry bit" parameter to
2820 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2821 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2822 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2823 // parameter to AddWithCarry is defined as 0).
2825 // When x is 0 and unsigned:
2829 // ~x + 1 = 0x1 0000 0000
2830 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2832 // Therefore, we should disable CMN when comparing against zero, until we can
2833 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2834 // when it's a comparison which doesn't look at the 'carry' flag).
2836 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2838 // This is related to <rdar://problem/7569620>.
2840 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2841 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2843 // Note that TST/TEQ don't set all the same flags that CMP does!
2844 defm TST : AI1_cmp_irs<0b1000, "tst",
2845 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2846 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2847 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2848 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2849 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2851 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2852 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2853 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2854 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2855 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2856 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2858 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2859 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2861 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2862 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2864 // Pseudo i64 compares for some floating point compares.
2865 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2867 def BCCi64 : PseudoInst<(outs),
2868 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2870 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2872 def BCCZi64 : PseudoInst<(outs),
2873 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2874 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2875 } // usesCustomInserter
2878 // Conditional moves
2879 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2880 // a two-value operand where a dag node expects two operands. :(
2881 // FIXME: These should all be pseudo-instructions that get expanded to
2882 // the normal MOV instructions. That would fix the dependency on
2883 // special casing them in tblgen.
2884 let neverHasSideEffects = 1 in {
2885 let isAsCheapAsAMove = 1 in
2886 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2887 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2888 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2889 RegConstraint<"$false = $Rd">, UnaryDP {
2894 let Inst{15-12} = Rd;
2895 let Inst{11-4} = 0b00000000;
2899 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
2900 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
2901 "mov", "\t$Rd, $shift",
2902 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
2903 RegConstraint<"$false = $Rd">, UnaryDP {
2909 let Inst{19-16} = Rn;
2910 let Inst{15-12} = Rd;
2911 let Inst{11-0} = shift;
2914 let isAsCheapAsAMove = 1 in
2915 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
2917 "movw", "\t$Rd, $imm",
2919 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
2925 let Inst{19-16} = imm{15-12};
2926 let Inst{15-12} = Rd;
2927 let Inst{11-0} = imm{11-0};
2930 let isAsCheapAsAMove = 1 in
2931 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
2932 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
2933 "mov", "\t$Rd, $imm",
2934 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2935 RegConstraint<"$false = $Rd">, UnaryDP {
2940 let Inst{19-16} = 0b0000;
2941 let Inst{15-12} = Rd;
2942 let Inst{11-0} = imm;
2945 let isAsCheapAsAMove = 1 in
2946 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
2947 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
2948 "mvn", "\t$Rd, $imm",
2949 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
2950 RegConstraint<"$false = $Rd">, UnaryDP {
2955 let Inst{19-16} = 0b0000;
2956 let Inst{15-12} = Rd;
2957 let Inst{11-0} = imm;
2959 } // neverHasSideEffects
2961 //===----------------------------------------------------------------------===//
2962 // Atomic operations intrinsics
2965 def memb_opt : Operand<i32> {
2966 let PrintMethod = "printMemBOption";
2969 // memory barriers protect the atomic sequences
2970 let hasSideEffects = 1 in {
2971 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2972 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2973 Requires<[IsARM, HasDB]> {
2975 let Inst{31-4} = 0xf57ff05;
2976 let Inst{3-0} = opt;
2979 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2980 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2981 [(ARMMemBarrierMCR GPR:$zero)]>,
2982 Requires<[IsARM, HasV6]> {
2983 // FIXME: add encoding
2987 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2989 [/* For disassembly only; pattern left blank */]>,
2990 Requires<[IsARM, HasDB]> {
2992 let Inst{31-4} = 0xf57ff04;
2993 let Inst{3-0} = opt;
2996 // ISB has only full system option -- for disassembly only
2997 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2998 Requires<[IsARM, HasDB]> {
2999 let Inst{31-4} = 0xf57ff06;
3000 let Inst{3-0} = 0b1111;
3003 let usesCustomInserter = 1 in {
3004 let Uses = [CPSR] in {
3005 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3006 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3007 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3008 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3009 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3010 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3011 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3012 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3013 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3014 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3015 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3016 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3017 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3018 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3019 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3020 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3021 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3022 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3023 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3024 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3025 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3026 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3027 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3028 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3029 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3030 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3031 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3032 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3033 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3034 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3035 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3036 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3037 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3038 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3039 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3040 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3041 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3042 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3043 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3044 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3045 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3046 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3047 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3048 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3049 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3050 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3051 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3052 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3053 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3054 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3055 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3056 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3057 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3058 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3060 def ATOMIC_SWAP_I8 : PseudoInst<
3061 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3062 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3063 def ATOMIC_SWAP_I16 : PseudoInst<
3064 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3065 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3066 def ATOMIC_SWAP_I32 : PseudoInst<
3067 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3068 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3070 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3071 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3072 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3073 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3074 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3075 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3076 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3077 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3078 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3082 let mayLoad = 1 in {
3083 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3084 "ldrexb", "\t$Rt, [$Rn]",
3086 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3087 "ldrexh", "\t$Rt, [$Rn]",
3089 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3090 "ldrex", "\t$Rt, [$Rn]",
3092 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3094 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3098 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3099 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3101 "strexb", "\t$Rd, $src, [$Rn]",
3103 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3105 "strexh", "\t$Rd, $Rt, [$Rn]",
3107 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3109 "strex", "\t$Rd, $Rt, [$Rn]",
3111 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3112 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3114 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3118 // Clear-Exclusive is for disassembly only.
3119 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3120 [/* For disassembly only; pattern left blank */]>,
3121 Requires<[IsARM, HasV7]> {
3122 let Inst{31-0} = 0b11110101011111111111000000011111;
3125 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3126 let mayLoad = 1 in {
3127 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3128 [/* For disassembly only; pattern left blank */]>;
3129 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3130 [/* For disassembly only; pattern left blank */]>;
3133 //===----------------------------------------------------------------------===//
3137 // __aeabi_read_tp preserves the registers r1-r3.
3138 // FIXME: This needs to be a pseudo of some sort so that we can get the
3139 // encoding right, complete with fixup for the aeabi_read_tp function.
3141 Defs = [R0, R12, LR, CPSR] in {
3142 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3143 "bl\t__aeabi_read_tp",
3144 [(set R0, ARMthread_pointer)]>;
3147 //===----------------------------------------------------------------------===//
3148 // SJLJ Exception handling intrinsics
3149 // eh_sjlj_setjmp() is an instruction sequence to store the return
3150 // address and save #0 in R0 for the non-longjmp case.
3151 // Since by its nature we may be coming from some other function to get
3152 // here, and we're using the stack frame for the containing function to
3153 // save/restore registers, we can't keep anything live in regs across
3154 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3155 // when we get here from a longjmp(). We force everthing out of registers
3156 // except for our own input by listing the relevant registers in Defs. By
3157 // doing so, we also cause the prologue/epilogue code to actively preserve
3158 // all of the callee-saved resgisters, which is exactly what we want.
3159 // A constant value is passed in $val, and we use the location as a scratch.
3161 // These are pseudo-instructions and are lowered to individual MC-insts, so
3162 // no encoding information is necessary.
3164 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3165 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3166 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3167 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3168 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3169 AddrModeNone, SizeSpecial, IndexModeNone,
3170 Pseudo, NoItinerary, "", "",
3171 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3172 Requires<[IsARM, HasVFP2]>;
3176 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3177 hasSideEffects = 1, isBarrier = 1 in {
3178 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3179 AddrModeNone, SizeSpecial, IndexModeNone,
3180 Pseudo, NoItinerary, "", "",
3181 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3182 Requires<[IsARM, NoVFP]>;
3185 // FIXME: Non-Darwin version(s)
3186 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3187 Defs = [ R7, LR, SP ] in {
3188 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3189 AddrModeNone, SizeSpecial, IndexModeNone,
3190 Pseudo, NoItinerary, "", "",
3191 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3192 Requires<[IsARM, IsDarwin]>;
3195 // eh.sjlj.dispatchsetup pseudo-instruction.
3196 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3197 // handled when the pseudo is expanded (which happens before any passes
3198 // that need the instruction size).
3199 let isBarrier = 1, hasSideEffects = 1 in
3200 def Int_eh_sjlj_dispatchsetup :
3201 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3202 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3203 Requires<[IsDarwin]>;
3205 //===----------------------------------------------------------------------===//
3206 // Non-Instruction Patterns
3209 // Large immediate handling.
3211 // FIXME: Folding immediates into these logical operations aren't necessary
3212 // good ideas. If it's in a loop machine licm could have hoisted the immediate
3213 // computation out of the loop.
3214 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3215 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3216 (so_imm2part_2 imm:$RHS))>;
3217 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3218 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3219 (so_imm2part_2 imm:$RHS))>;
3220 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3221 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3222 (so_imm2part_2 imm:$RHS))>;
3223 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3224 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3225 (so_neg_imm2part_2 imm:$RHS))>;
3227 // 32-bit immediate using two piece so_imms or movw + movt.
3228 // This is a single pseudo instruction, the benefit is that it can be remat'd
3229 // as a single unit instead of having to handle reg inputs.
3230 // FIXME: Remove this when we can do generalized remat.
3231 let isReMaterializable = 1 in
3232 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3233 [(set GPR:$dst, (arm_i32imm:$src))]>,
3236 // ConstantPool, GlobalAddress, and JumpTable
3237 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3238 Requires<[IsARM, DontUseMovt]>;
3239 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3240 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3241 Requires<[IsARM, UseMovt]>;
3242 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3243 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3245 // TODO: add,sub,and, 3-instr forms?
3248 def : ARMPat<(ARMtcret tcGPR:$dst),
3249 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3251 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3252 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3254 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3255 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3257 def : ARMPat<(ARMtcret tcGPR:$dst),
3258 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3260 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3261 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3263 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3264 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3267 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3268 Requires<[IsARM, IsNotDarwin]>;
3269 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3270 Requires<[IsARM, IsDarwin]>;
3272 // zextload i1 -> zextload i8
3273 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3274 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3276 // extload -> zextload
3277 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3278 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3279 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3280 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3282 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3284 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3285 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3288 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3289 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3290 (SMULBB GPR:$a, GPR:$b)>;
3291 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3292 (SMULBB GPR:$a, GPR:$b)>;
3293 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3294 (sra GPR:$b, (i32 16))),
3295 (SMULBT GPR:$a, GPR:$b)>;
3296 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3297 (SMULBT GPR:$a, GPR:$b)>;
3298 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3299 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3300 (SMULTB GPR:$a, GPR:$b)>;
3301 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3302 (SMULTB GPR:$a, GPR:$b)>;
3303 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3305 (SMULWB GPR:$a, GPR:$b)>;
3306 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3307 (SMULWB GPR:$a, GPR:$b)>;
3309 def : ARMV5TEPat<(add GPR:$acc,
3310 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3311 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3312 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3313 def : ARMV5TEPat<(add GPR:$acc,
3314 (mul sext_16_node:$a, sext_16_node:$b)),
3315 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3316 def : ARMV5TEPat<(add GPR:$acc,
3317 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3318 (sra GPR:$b, (i32 16)))),
3319 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3320 def : ARMV5TEPat<(add GPR:$acc,
3321 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3322 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3323 def : ARMV5TEPat<(add GPR:$acc,
3324 (mul (sra GPR:$a, (i32 16)),
3325 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3326 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3327 def : ARMV5TEPat<(add GPR:$acc,
3328 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3329 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3330 def : ARMV5TEPat<(add GPR:$acc,
3331 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3333 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3334 def : ARMV5TEPat<(add GPR:$acc,
3335 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3336 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3338 //===----------------------------------------------------------------------===//
3342 include "ARMInstrThumb.td"
3344 //===----------------------------------------------------------------------===//
3348 include "ARMInstrThumb2.td"
3350 //===----------------------------------------------------------------------===//
3351 // Floating Point Support
3354 include "ARMInstrVFP.td"
3356 //===----------------------------------------------------------------------===//
3357 // Advanced SIMD (NEON) Support
3360 include "ARMInstrNEON.td"
3362 //===----------------------------------------------------------------------===//
3363 // Coprocessor Instructions. For disassembly only.
3366 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3367 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3368 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3369 [/* For disassembly only; pattern left blank */]> {
3373 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3374 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3375 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3376 [/* For disassembly only; pattern left blank */]> {
3377 let Inst{31-28} = 0b1111;
3381 class ACI<dag oops, dag iops, string opc, string asm>
3382 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3383 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3384 let Inst{27-25} = 0b110;
3387 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3389 def _OFFSET : ACI<(outs),
3390 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3391 opc, "\tp$cop, cr$CRd, $addr"> {
3392 let Inst{31-28} = op31_28;
3393 let Inst{24} = 1; // P = 1
3394 let Inst{21} = 0; // W = 0
3395 let Inst{22} = 0; // D = 0
3396 let Inst{20} = load;
3399 def _PRE : ACI<(outs),
3400 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3401 opc, "\tp$cop, cr$CRd, $addr!"> {
3402 let Inst{31-28} = op31_28;
3403 let Inst{24} = 1; // P = 1
3404 let Inst{21} = 1; // W = 1
3405 let Inst{22} = 0; // D = 0
3406 let Inst{20} = load;
3409 def _POST : ACI<(outs),
3410 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3411 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3412 let Inst{31-28} = op31_28;
3413 let Inst{24} = 0; // P = 0
3414 let Inst{21} = 1; // W = 1
3415 let Inst{22} = 0; // D = 0
3416 let Inst{20} = load;
3419 def _OPTION : ACI<(outs),
3420 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3421 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3422 let Inst{31-28} = op31_28;
3423 let Inst{24} = 0; // P = 0
3424 let Inst{23} = 1; // U = 1
3425 let Inst{21} = 0; // W = 0
3426 let Inst{22} = 0; // D = 0
3427 let Inst{20} = load;
3430 def L_OFFSET : ACI<(outs),
3431 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3432 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3433 let Inst{31-28} = op31_28;
3434 let Inst{24} = 1; // P = 1
3435 let Inst{21} = 0; // W = 0
3436 let Inst{22} = 1; // D = 1
3437 let Inst{20} = load;
3440 def L_PRE : ACI<(outs),
3441 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3442 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3443 let Inst{31-28} = op31_28;
3444 let Inst{24} = 1; // P = 1
3445 let Inst{21} = 1; // W = 1
3446 let Inst{22} = 1; // D = 1
3447 let Inst{20} = load;
3450 def L_POST : ACI<(outs),
3451 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3452 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3453 let Inst{31-28} = op31_28;
3454 let Inst{24} = 0; // P = 0
3455 let Inst{21} = 1; // W = 1
3456 let Inst{22} = 1; // D = 1
3457 let Inst{20} = load;
3460 def L_OPTION : ACI<(outs),
3461 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3462 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3463 let Inst{31-28} = op31_28;
3464 let Inst{24} = 0; // P = 0
3465 let Inst{23} = 1; // U = 1
3466 let Inst{21} = 0; // W = 0
3467 let Inst{22} = 1; // D = 1
3468 let Inst{20} = load;
3472 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3473 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3474 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3475 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3477 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3478 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3479 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3480 [/* For disassembly only; pattern left blank */]> {
3485 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3486 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3487 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3488 [/* For disassembly only; pattern left blank */]> {
3489 let Inst{31-28} = 0b1111;
3494 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3495 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3496 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3497 [/* For disassembly only; pattern left blank */]> {
3502 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3503 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3504 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3505 [/* For disassembly only; pattern left blank */]> {
3506 let Inst{31-28} = 0b1111;
3511 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3512 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3513 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3514 [/* For disassembly only; pattern left blank */]> {
3515 let Inst{23-20} = 0b0100;
3518 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3519 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3520 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3521 [/* For disassembly only; pattern left blank */]> {
3522 let Inst{31-28} = 0b1111;
3523 let Inst{23-20} = 0b0100;
3526 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3527 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3528 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3529 [/* For disassembly only; pattern left blank */]> {
3530 let Inst{23-20} = 0b0101;
3533 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3534 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3535 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3536 [/* For disassembly only; pattern left blank */]> {
3537 let Inst{31-28} = 0b1111;
3538 let Inst{23-20} = 0b0101;
3541 //===----------------------------------------------------------------------===//
3542 // Move between special register and ARM core register -- for disassembly only
3545 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3546 [/* For disassembly only; pattern left blank */]> {
3547 let Inst{23-20} = 0b0000;
3548 let Inst{7-4} = 0b0000;
3551 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3552 [/* For disassembly only; pattern left blank */]> {
3553 let Inst{23-20} = 0b0100;
3554 let Inst{7-4} = 0b0000;
3557 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3558 "msr", "\tcpsr$mask, $src",
3559 [/* For disassembly only; pattern left blank */]> {
3560 let Inst{23-20} = 0b0010;
3561 let Inst{7-4} = 0b0000;
3564 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3565 "msr", "\tcpsr$mask, $a",
3566 [/* For disassembly only; pattern left blank */]> {
3567 let Inst{23-20} = 0b0010;
3568 let Inst{7-4} = 0b0000;
3571 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3572 "msr", "\tspsr$mask, $src",
3573 [/* For disassembly only; pattern left blank */]> {
3574 let Inst{23-20} = 0b0110;
3575 let Inst{7-4} = 0b0000;
3578 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3579 "msr", "\tspsr$mask, $a",
3580 [/* For disassembly only; pattern left blank */]> {
3581 let Inst{23-20} = 0b0110;
3582 let Inst{7-4} = 0b0000;