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(-(int)N->getZExtValue()) != -1;
216 }], so_imm_neg_XFORM>;
220 return ARM_AM::getSOImmVal(~(int)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>;
279 // A list of registers separated by comma. Used by load/store multiple.
280 def reglist : Operand<i32> {
281 string EncoderMethod = "getRegisterListOpValue";
282 let PrintMethod = "printRegisterList";
285 def RegListAsmOperand : AsmOperandClass {
286 let Name = "RegList";
287 let SuperClasses = [];
290 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
291 def cpinst_operand : Operand<i32> {
292 let PrintMethod = "printCPInstOperand";
295 def jtblock_operand : Operand<i32> {
296 let PrintMethod = "printJTBlockOperand";
298 def jt2block_operand : Operand<i32> {
299 let PrintMethod = "printJT2BlockOperand";
303 def pclabel : Operand<i32> {
304 let PrintMethod = "printPCLabel";
307 def neon_vcvt_imm32 : Operand<i32> {
308 string EncoderMethod = "getNEONVcvtImm32OpValue";
311 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
312 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
313 int32_t v = (int32_t)N->getZExtValue();
314 return v == 8 || v == 16 || v == 24; }]> {
315 string EncoderMethod = "getRotImmOpValue";
318 // shift_imm: An integer that encodes a shift amount and the type of shift
319 // (currently either asr or lsl) using the same encoding used for the
320 // immediates in so_reg operands.
321 def shift_imm : Operand<i32> {
322 let PrintMethod = "printShiftImmOperand";
325 // shifter_operand operands: so_reg and so_imm.
326 def so_reg : Operand<i32>, // reg reg imm
327 ComplexPattern<i32, 3, "SelectShifterOperandReg",
328 [shl,srl,sra,rotr]> {
329 string EncoderMethod = "getSORegOpValue";
330 let PrintMethod = "printSORegOperand";
331 let MIOperandInfo = (ops GPR, GPR, i32imm);
333 def shift_so_reg : Operand<i32>, // reg reg imm
334 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
335 [shl,srl,sra,rotr]> {
336 string EncoderMethod = "getSORegOpValue";
337 let PrintMethod = "printSORegOperand";
338 let MIOperandInfo = (ops GPR, GPR, i32imm);
341 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
342 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
343 // represented in the imm field in the same 12-bit form that they are encoded
344 // into so_imm instructions: the 8-bit immediate is the least significant bits
345 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
346 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
347 string EncoderMethod = "getSOImmOpValue";
348 let PrintMethod = "printSOImmOperand";
351 // Break so_imm's up into two pieces. This handles immediates with up to 16
352 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
353 // get the first/second pieces.
354 def so_imm2part : Operand<i32>,
356 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
358 let PrintMethod = "printSOImm2PartOperand";
361 def so_imm2part_1 : SDNodeXForm<imm, [{
362 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
363 return CurDAG->getTargetConstant(V, MVT::i32);
366 def so_imm2part_2 : SDNodeXForm<imm, [{
367 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
368 return CurDAG->getTargetConstant(V, MVT::i32);
371 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
372 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
374 let PrintMethod = "printSOImm2PartOperand";
377 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
378 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
379 return CurDAG->getTargetConstant(V, MVT::i32);
382 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
383 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
384 return CurDAG->getTargetConstant(V, MVT::i32);
387 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
388 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
389 return (int32_t)N->getZExtValue() < 32;
392 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
393 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
394 return (int32_t)N->getZExtValue() < 32;
396 string EncoderMethod = "getImmMinusOneOpValue";
399 // Define ARM specific addressing modes.
402 // addrmode_imm12 := reg +/- imm12
404 def addrmode_imm12 : Operand<i32>,
405 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
406 // 12-bit immediate operand. Note that instructions using this encode
407 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
408 // immediate values are as normal.
410 string EncoderMethod = "getAddrModeImm12OpValue";
411 let PrintMethod = "printAddrModeImm12Operand";
412 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
414 // ldst_so_reg := reg +/- reg shop imm
416 def ldst_so_reg : Operand<i32>,
417 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
418 string EncoderMethod = "getLdStSORegOpValue";
419 // FIXME: Simplify the printer
420 let PrintMethod = "printAddrMode2Operand";
421 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
424 // addrmode2 := reg +/- imm12
425 // := reg +/- reg shop imm
427 def addrmode2 : Operand<i32>,
428 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
429 let PrintMethod = "printAddrMode2Operand";
430 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
433 def am2offset : Operand<i32>,
434 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
435 [], [SDNPWantRoot]> {
436 let PrintMethod = "printAddrMode2OffsetOperand";
437 let MIOperandInfo = (ops GPR, i32imm);
440 // addrmode3 := reg +/- reg
441 // addrmode3 := reg +/- imm8
443 def addrmode3 : Operand<i32>,
444 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
445 let PrintMethod = "printAddrMode3Operand";
446 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
449 def am3offset : Operand<i32>,
450 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
451 [], [SDNPWantRoot]> {
452 let PrintMethod = "printAddrMode3OffsetOperand";
453 let MIOperandInfo = (ops GPR, i32imm);
456 // ldstm_mode := {ia, ib, da, db}
458 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
459 string EncoderMethod = "getLdStmModeOpValue";
460 let PrintMethod = "printLdStmModeOperand";
463 def MemMode5AsmOperand : AsmOperandClass {
464 let Name = "MemMode5";
465 let SuperClasses = [];
468 // addrmode5 := reg +/- imm8*4
470 def addrmode5 : Operand<i32>,
471 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
472 let PrintMethod = "printAddrMode5Operand";
473 let MIOperandInfo = (ops GPR:$base, i32imm);
474 let ParserMatchClass = MemMode5AsmOperand;
475 string EncoderMethod = "getAddrMode5OpValue";
478 // addrmode6 := reg with optional writeback
480 def addrmode6 : Operand<i32>,
481 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
482 let PrintMethod = "printAddrMode6Operand";
483 let MIOperandInfo = (ops GPR:$addr, i32imm);
484 string EncoderMethod = "getAddrMode6AddressOpValue";
487 def am6offset : Operand<i32> {
488 let PrintMethod = "printAddrMode6OffsetOperand";
489 let MIOperandInfo = (ops GPR);
490 string EncoderMethod = "getAddrMode6OffsetOpValue";
493 // addrmodepc := pc + reg
495 def addrmodepc : Operand<i32>,
496 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
497 let PrintMethod = "printAddrModePCOperand";
498 let MIOperandInfo = (ops GPR, i32imm);
501 def nohash_imm : Operand<i32> {
502 let PrintMethod = "printNoHashImmediate";
505 //===----------------------------------------------------------------------===//
507 include "ARMInstrFormats.td"
509 //===----------------------------------------------------------------------===//
510 // Multiclass helpers...
513 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
514 /// binop that produces a value.
515 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
516 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
517 PatFrag opnode, bit Commutable = 0> {
518 // The register-immediate version is re-materializable. This is useful
519 // in particular for taking the address of a local.
520 let isReMaterializable = 1 in {
521 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
522 iii, opc, "\t$Rd, $Rn, $imm",
523 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
528 let Inst{19-16} = Rn;
529 let Inst{15-12} = Rd;
530 let Inst{11-0} = imm;
533 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
534 iir, opc, "\t$Rd, $Rn, $Rm",
535 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
540 let isCommutable = Commutable;
541 let Inst{19-16} = Rn;
542 let Inst{15-12} = Rd;
543 let Inst{11-4} = 0b00000000;
546 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
547 iis, opc, "\t$Rd, $Rn, $shift",
548 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
553 let Inst{19-16} = Rn;
554 let Inst{15-12} = Rd;
555 let Inst{11-0} = shift;
559 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
560 /// instruction modifies the CPSR register.
561 let Defs = [CPSR] in {
562 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
563 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
564 PatFrag opnode, bit Commutable = 0> {
565 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
566 iii, opc, "\t$Rd, $Rn, $imm",
567 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
573 let Inst{19-16} = Rn;
574 let Inst{15-12} = Rd;
575 let Inst{11-0} = imm;
577 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
578 iir, opc, "\t$Rd, $Rn, $Rm",
579 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
583 let isCommutable = Commutable;
586 let Inst{19-16} = Rn;
587 let Inst{15-12} = Rd;
588 let Inst{11-4} = 0b00000000;
591 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
592 iis, opc, "\t$Rd, $Rn, $shift",
593 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
599 let Inst{19-16} = Rn;
600 let Inst{15-12} = Rd;
601 let Inst{11-0} = shift;
606 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
607 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
608 /// a explicit result, only implicitly set CPSR.
609 let isCompare = 1, Defs = [CPSR] in {
610 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
611 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
612 PatFrag opnode, bit Commutable = 0> {
613 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
615 [(opnode GPR:$Rn, so_imm:$imm)]> {
620 let Inst{19-16} = Rn;
621 let Inst{15-12} = 0b0000;
622 let Inst{11-0} = imm;
624 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
626 [(opnode GPR:$Rn, GPR:$Rm)]> {
629 let isCommutable = Commutable;
632 let Inst{19-16} = Rn;
633 let Inst{15-12} = 0b0000;
634 let Inst{11-4} = 0b00000000;
637 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
638 opc, "\t$Rn, $shift",
639 [(opnode GPR:$Rn, so_reg:$shift)]> {
644 let Inst{19-16} = Rn;
645 let Inst{15-12} = 0b0000;
646 let Inst{11-0} = shift;
651 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
652 /// register and one whose operand is a register rotated by 8/16/24.
653 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
654 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
655 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
656 IIC_iEXTr, opc, "\t$Rd, $Rm",
657 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
658 Requires<[IsARM, HasV6]> {
661 let Inst{19-16} = 0b1111;
662 let Inst{15-12} = Rd;
663 let Inst{11-10} = 0b00;
666 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
667 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
668 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
669 Requires<[IsARM, HasV6]> {
673 let Inst{19-16} = 0b1111;
674 let Inst{15-12} = Rd;
675 let Inst{11-10} = rot;
680 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
681 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
682 IIC_iEXTr, opc, "\t$Rd, $Rm",
683 [/* For disassembly only; pattern left blank */]>,
684 Requires<[IsARM, HasV6]> {
685 let Inst{19-16} = 0b1111;
686 let Inst{11-10} = 0b00;
688 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
689 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
690 [/* For disassembly only; pattern left blank */]>,
691 Requires<[IsARM, HasV6]> {
693 let Inst{19-16} = 0b1111;
694 let Inst{11-10} = rot;
698 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
699 /// register and one whose operand is a register rotated by 8/16/24.
700 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
701 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
702 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
703 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
704 Requires<[IsARM, HasV6]> {
705 let Inst{11-10} = 0b00;
707 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
709 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
710 [(set GPR:$Rd, (opnode GPR:$Rn,
711 (rotr GPR:$Rm, rot_imm:$rot)))]>,
712 Requires<[IsARM, HasV6]> {
715 let Inst{19-16} = Rn;
716 let Inst{11-10} = rot;
720 // For disassembly only.
721 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
722 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
723 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
724 [/* For disassembly only; pattern left blank */]>,
725 Requires<[IsARM, HasV6]> {
726 let Inst{11-10} = 0b00;
728 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
730 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
731 [/* For disassembly only; pattern left blank */]>,
732 Requires<[IsARM, HasV6]> {
735 let Inst{19-16} = Rn;
736 let Inst{11-10} = rot;
740 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
741 let Uses = [CPSR] in {
742 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
743 bit Commutable = 0> {
744 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
745 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
746 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
752 let Inst{15-12} = Rd;
753 let Inst{19-16} = Rn;
754 let Inst{11-0} = imm;
756 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
757 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
758 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
763 let Inst{11-4} = 0b00000000;
765 let isCommutable = Commutable;
767 let Inst{15-12} = Rd;
768 let Inst{19-16} = Rn;
770 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
771 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
772 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
778 let Inst{11-0} = shift;
779 let Inst{15-12} = Rd;
780 let Inst{19-16} = Rn;
783 // Carry setting variants
784 let Defs = [CPSR] in {
785 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
786 bit Commutable = 0> {
787 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
788 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
789 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
794 let Inst{15-12} = Rd;
795 let Inst{19-16} = Rn;
796 let Inst{11-0} = imm;
800 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
801 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
802 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
807 let Inst{11-4} = 0b00000000;
808 let isCommutable = Commutable;
810 let Inst{15-12} = Rd;
811 let Inst{19-16} = Rn;
815 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
816 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
817 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
822 let Inst{11-0} = shift;
823 let Inst{15-12} = Rd;
824 let Inst{19-16} = Rn;
832 let canFoldAsLoad = 1, isReMaterializable = 1 in {
833 multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
834 InstrItinClass iir, PatFrag opnode> {
835 // Note: We use the complex addrmode_imm12 rather than just an input
836 // GPR and a constrained immediate so that we can use this to match
837 // frame index references and avoid matching constant pool references.
838 def i12 : AIldst1<0b010, opc22, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
839 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
840 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
843 let Inst{23} = addr{12}; // U (add = ('U' == 1))
844 let Inst{19-16} = addr{16-13}; // Rn
845 let Inst{15-12} = Rt;
846 let Inst{11-0} = addr{11-0}; // imm12
848 def rs : AIldst1<0b011, opc22, 1, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
849 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
850 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
853 let Inst{23} = shift{12}; // U (add = ('U' == 1))
854 let Inst{19-16} = shift{16-13}; // Rn
855 let Inst{15-12} = Rt;
856 let Inst{11-0} = shift{11-0};
861 multiclass AI_str1<bit opc22, string opc, InstrItinClass iii,
862 InstrItinClass iir, PatFrag opnode> {
863 // Note: We use the complex addrmode_imm12 rather than just an input
864 // GPR and a constrained immediate so that we can use this to match
865 // frame index references and avoid matching constant pool references.
866 def i12 : AIldst1<0b010, opc22, 0, (outs),
867 (ins GPR:$Rt, addrmode_imm12:$addr),
868 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
869 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
872 let Inst{23} = addr{12}; // U (add = ('U' == 1))
873 let Inst{19-16} = addr{16-13}; // Rn
874 let Inst{15-12} = Rt;
875 let Inst{11-0} = addr{11-0}; // imm12
877 def rs : AIldst1<0b011, opc22, 0, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
878 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
879 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
882 let Inst{23} = shift{12}; // U (add = ('U' == 1))
883 let Inst{19-16} = shift{16-13}; // Rn
884 let Inst{15-12} = Rt;
885 let Inst{11-0} = shift{11-0};
888 //===----------------------------------------------------------------------===//
890 //===----------------------------------------------------------------------===//
892 //===----------------------------------------------------------------------===//
893 // Miscellaneous Instructions.
896 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
897 /// the function. The first operand is the ID# for this instruction, the second
898 /// is the index into the MachineConstantPool that this is, the third is the
899 /// size in bytes of this constant pool entry.
900 let neverHasSideEffects = 1, isNotDuplicable = 1 in
901 def CONSTPOOL_ENTRY :
902 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
903 i32imm:$size), NoItinerary, "", []>;
905 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
906 // from removing one half of the matched pairs. That breaks PEI, which assumes
907 // these will always be in pairs, and asserts if it finds otherwise. Better way?
908 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
910 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
911 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
913 def ADJCALLSTACKDOWN :
914 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
915 [(ARMcallseq_start timm:$amt)]>;
918 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
919 [/* For disassembly only; pattern left blank */]>,
920 Requires<[IsARM, HasV6T2]> {
921 let Inst{27-16} = 0b001100100000;
922 let Inst{15-8} = 0b11110000;
923 let Inst{7-0} = 0b00000000;
926 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
927 [/* For disassembly only; pattern left blank */]>,
928 Requires<[IsARM, HasV6T2]> {
929 let Inst{27-16} = 0b001100100000;
930 let Inst{15-8} = 0b11110000;
931 let Inst{7-0} = 0b00000001;
934 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
935 [/* For disassembly only; pattern left blank */]>,
936 Requires<[IsARM, HasV6T2]> {
937 let Inst{27-16} = 0b001100100000;
938 let Inst{15-8} = 0b11110000;
939 let Inst{7-0} = 0b00000010;
942 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
943 [/* For disassembly only; pattern left blank */]>,
944 Requires<[IsARM, HasV6T2]> {
945 let Inst{27-16} = 0b001100100000;
946 let Inst{15-8} = 0b11110000;
947 let Inst{7-0} = 0b00000011;
950 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
952 [/* For disassembly only; pattern left blank */]>,
953 Requires<[IsARM, HasV6]> {
958 let Inst{15-12} = Rd;
959 let Inst{19-16} = Rn;
960 let Inst{27-20} = 0b01101000;
961 let Inst{7-4} = 0b1011;
962 let Inst{11-8} = 0b1111;
965 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
966 [/* For disassembly only; pattern left blank */]>,
967 Requires<[IsARM, HasV6T2]> {
968 let Inst{27-16} = 0b001100100000;
969 let Inst{15-8} = 0b11110000;
970 let Inst{7-0} = 0b00000100;
973 // The i32imm operand $val can be used by a debugger to store more information
974 // about the breakpoint.
975 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
976 [/* For disassembly only; pattern left blank */]>,
979 let Inst{3-0} = val{3-0};
980 let Inst{19-8} = val{15-4};
981 let Inst{27-20} = 0b00010010;
982 let Inst{7-4} = 0b0111;
985 // Change Processor State is a system instruction -- for disassembly only.
986 // The singleton $opt operand contains the following information:
987 // opt{4-0} = mode from Inst{4-0}
988 // opt{5} = changemode from Inst{17}
989 // opt{8-6} = AIF from Inst{8-6}
990 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
991 // FIXME: Integrated assembler will need these split out.
992 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
993 [/* For disassembly only; pattern left blank */]>,
995 let Inst{31-28} = 0b1111;
996 let Inst{27-20} = 0b00010000;
1001 // Preload signals the memory system of possible future data/instruction access.
1002 // These are for disassembly only.
1003 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1005 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1006 !strconcat(opc, "\t$addr"),
1007 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1010 let Inst{31-26} = 0b111101;
1011 let Inst{25} = 0; // 0 for immediate form
1012 let Inst{24} = data;
1013 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1014 let Inst{22} = read;
1015 let Inst{21-20} = 0b01;
1016 let Inst{19-16} = addr{16-13}; // Rn
1017 let Inst{15-12} = Rt;
1018 let Inst{11-0} = addr{11-0}; // imm12
1021 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1022 !strconcat(opc, "\t$shift"),
1023 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1026 let Inst{31-26} = 0b111101;
1027 let Inst{25} = 1; // 1 for register form
1028 let Inst{24} = data;
1029 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1030 let Inst{22} = read;
1031 let Inst{21-20} = 0b01;
1032 let Inst{19-16} = shift{16-13}; // Rn
1033 let Inst{11-0} = shift{11-0};
1037 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1038 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1039 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1041 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1043 [/* For disassembly only; pattern left blank */]>,
1046 let Inst{31-10} = 0b1111000100000001000000;
1051 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1052 [/* For disassembly only; pattern left blank */]>,
1053 Requires<[IsARM, HasV7]> {
1055 let Inst{27-4} = 0b001100100000111100001111;
1056 let Inst{3-0} = opt;
1059 // A5.4 Permanently UNDEFINED instructions.
1060 let isBarrier = 1, isTerminator = 1 in
1061 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1064 let Inst{27-25} = 0b011;
1065 let Inst{24-20} = 0b11111;
1066 let Inst{7-5} = 0b111;
1070 // Address computation and loads and stores in PIC mode.
1071 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1072 // classes (AXI1, et.al.) and so have encoding information and such,
1073 // which is suboptimal. Once the rest of the code emitter (including
1074 // JIT) is MC-ized we should look at refactoring these into true
1075 // pseudos. As is, the encoding information ends up being ignored,
1076 // as these instructions are lowered to individual MC-insts.
1077 let isNotDuplicable = 1 in {
1078 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1079 Pseudo, IIC_iALUr, "",
1080 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1082 let AddedComplexity = 10 in {
1083 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1084 Pseudo, IIC_iLoad_r, "",
1085 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1087 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1088 Pseudo, IIC_iLoad_bh_r, "",
1089 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1091 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1092 Pseudo, IIC_iLoad_bh_r, "",
1093 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1095 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1096 Pseudo, IIC_iLoad_bh_r, "",
1097 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1099 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1100 Pseudo, IIC_iLoad_bh_r, "",
1101 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1103 let AddedComplexity = 10 in {
1104 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1105 Pseudo, IIC_iStore_r, "",
1106 [(store GPR:$src, addrmodepc:$addr)]>;
1108 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1109 Pseudo, IIC_iStore_bh_r, "",
1110 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1112 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1113 Pseudo, IIC_iStore_bh_r, "",
1114 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1116 } // isNotDuplicable = 1
1119 // LEApcrel - Load a pc-relative address into a register without offending the
1121 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1122 // the ADR instruction. Is this the right way to handle that? They need
1123 // encoding information regardless.
1124 let neverHasSideEffects = 1 in {
1125 let isReMaterializable = 1 in
1126 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1128 "adr$p\t$dst, #$label", []>;
1130 } // neverHasSideEffects
1131 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1132 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1134 "adr$p\t$dst, #${label}_${id}", []> {
1138 //===----------------------------------------------------------------------===//
1139 // Control Flow Instructions.
1142 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1144 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1145 "bx", "\tlr", [(ARMretflag)]>,
1146 Requires<[IsARM, HasV4T]> {
1147 let Inst{27-0} = 0b0001001011111111111100011110;
1151 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1152 "mov", "\tpc, lr", [(ARMretflag)]>,
1153 Requires<[IsARM, NoV4T]> {
1154 let Inst{27-0} = 0b0001101000001111000000001110;
1158 // Indirect branches
1159 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1161 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1162 [(brind GPR:$dst)]>,
1163 Requires<[IsARM, HasV4T]> {
1165 let Inst{31-4} = 0b1110000100101111111111110001;
1166 let Inst{3-0} = dst;
1170 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1171 [(brind GPR:$dst)]>,
1172 Requires<[IsARM, NoV4T]> {
1174 let Inst{31-4} = 0b1110000110100000111100000000;
1175 let Inst{3-0} = dst;
1179 // FIXME: remove when we have a way to marking a MI with these properties.
1180 // FIXME: Should pc be an implicit operand like PICADD, etc?
1181 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1182 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1183 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$mode, pred:$p,
1184 reglist:$dsts, variable_ops),
1185 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1186 "ldm${mode}${p}\t$Rn!, $dsts",
1189 let Inst{31-28} = p;
1193 // On non-Darwin platforms R9 is callee-saved.
1195 Defs = [R0, R1, R2, R3, R12, LR,
1196 D0, D1, D2, D3, D4, D5, D6, D7,
1197 D16, D17, D18, D19, D20, D21, D22, D23,
1198 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1199 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1200 IIC_Br, "bl\t$func",
1201 [(ARMcall tglobaladdr:$func)]>,
1202 Requires<[IsARM, IsNotDarwin]> {
1203 let Inst{31-28} = 0b1110;
1204 // FIXME: Encoding info for $func. Needs fixups bits.
1207 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1208 IIC_Br, "bl", "\t$func",
1209 [(ARMcall_pred tglobaladdr:$func)]>,
1210 Requires<[IsARM, IsNotDarwin]>;
1213 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1214 IIC_Br, "blx\t$func",
1215 [(ARMcall GPR:$func)]>,
1216 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1218 let Inst{27-4} = 0b000100101111111111110011;
1219 let Inst{3-0} = func;
1223 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1224 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1225 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1226 [(ARMcall_nolink tGPR:$func)]>,
1227 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1229 let Inst{27-4} = 0b000100101111111111110001;
1230 let Inst{3-0} = func;
1234 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1235 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1236 [(ARMcall_nolink tGPR:$func)]>,
1237 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1239 let Inst{27-4} = 0b000110100000111100000000;
1240 let Inst{3-0} = func;
1244 // On Darwin R9 is call-clobbered.
1246 Defs = [R0, R1, R2, R3, R9, R12, LR,
1247 D0, D1, D2, D3, D4, D5, D6, D7,
1248 D16, D17, D18, D19, D20, D21, D22, D23,
1249 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1250 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1251 IIC_Br, "bl\t$func",
1252 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1253 let Inst{31-28} = 0b1110;
1254 // FIXME: Encoding info for $func. Needs fixups bits.
1257 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1258 IIC_Br, "bl", "\t$func",
1259 [(ARMcall_pred tglobaladdr:$func)]>,
1260 Requires<[IsARM, IsDarwin]>;
1263 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1264 IIC_Br, "blx\t$func",
1265 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1267 let Inst{27-4} = 0b000100101111111111110011;
1268 let Inst{3-0} = func;
1272 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1273 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1274 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1275 [(ARMcall_nolink tGPR:$func)]>,
1276 Requires<[IsARM, HasV4T, IsDarwin]> {
1278 let Inst{27-4} = 0b000100101111111111110001;
1279 let Inst{3-0} = func;
1283 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1284 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1285 [(ARMcall_nolink tGPR:$func)]>,
1286 Requires<[IsARM, NoV4T, IsDarwin]> {
1288 let Inst{27-4} = 0b000110100000111100000000;
1289 let Inst{3-0} = func;
1295 // FIXME: These should probably be xformed into the non-TC versions of the
1296 // instructions as part of MC lowering.
1297 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1299 let Defs = [R0, R1, R2, R3, R9, R12,
1300 D0, D1, D2, D3, D4, D5, D6, D7,
1301 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1302 D27, D28, D29, D30, D31, PC],
1304 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1306 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1308 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1310 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1312 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1313 IIC_Br, "b\t$dst @ TAILCALL",
1314 []>, Requires<[IsDarwin]>;
1316 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1317 IIC_Br, "b.w\t$dst @ TAILCALL",
1318 []>, Requires<[IsDarwin]>;
1320 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1321 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1322 []>, Requires<[IsDarwin]> {
1324 let Inst{31-4} = 0b1110000100101111111111110001;
1325 let Inst{3-0} = dst;
1329 // Non-Darwin versions (the difference is R9).
1330 let Defs = [R0, R1, R2, R3, R12,
1331 D0, D1, D2, D3, D4, D5, D6, D7,
1332 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1333 D27, D28, D29, D30, D31, PC],
1335 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1337 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1339 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1341 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1343 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1344 IIC_Br, "b\t$dst @ TAILCALL",
1345 []>, Requires<[IsARM, IsNotDarwin]>;
1347 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1348 IIC_Br, "b.w\t$dst @ TAILCALL",
1349 []>, Requires<[IsThumb, IsNotDarwin]>;
1351 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1352 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1353 []>, Requires<[IsNotDarwin]> {
1355 let Inst{31-4} = 0b1110000100101111111111110001;
1356 let Inst{3-0} = dst;
1361 let isBranch = 1, isTerminator = 1 in {
1362 // B is "predicable" since it can be xformed into a Bcc.
1363 let isBarrier = 1 in {
1364 let isPredicable = 1 in
1365 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1366 "b\t$target", [(br bb:$target)]>;
1368 let isNotDuplicable = 1, isIndirectBranch = 1,
1369 // FIXME: $imm field is not specified by asm string. Mark as cgonly.
1370 isCodeGenOnly = 1 in {
1371 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1372 IIC_Br, "mov\tpc, $target$jt",
1373 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1374 let Inst{11-4} = 0b00000000;
1375 let Inst{15-12} = 0b1111;
1376 let Inst{20} = 0; // S Bit
1377 let Inst{24-21} = 0b1101;
1378 let Inst{27-25} = 0b000;
1380 def BR_JTm : JTI<(outs),
1381 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1382 IIC_Br, "ldr\tpc, $target$jt",
1383 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1385 let Inst{15-12} = 0b1111;
1386 let Inst{20} = 1; // L bit
1387 let Inst{21} = 0; // W bit
1388 let Inst{22} = 0; // B bit
1389 let Inst{24} = 1; // P bit
1390 let Inst{27-25} = 0b011;
1392 def BR_JTadd : JTI<(outs),
1393 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1394 IIC_Br, "add\tpc, $target, $idx$jt",
1395 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1397 let Inst{15-12} = 0b1111;
1398 let Inst{20} = 0; // S bit
1399 let Inst{24-21} = 0b0100;
1400 let Inst{27-25} = 0b000;
1402 } // isNotDuplicable = 1, isIndirectBranch = 1
1405 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1406 // a two-value operand where a dag node expects two operands. :(
1407 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1408 IIC_Br, "b", "\t$target",
1409 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1412 // Branch and Exchange Jazelle -- for disassembly only
1413 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1414 [/* For disassembly only; pattern left blank */]> {
1415 let Inst{23-20} = 0b0010;
1416 //let Inst{19-8} = 0xfff;
1417 let Inst{7-4} = 0b0010;
1420 // Secure Monitor Call is a system instruction -- for disassembly only
1421 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1422 [/* For disassembly only; pattern left blank */]> {
1424 let Inst{23-4} = 0b01100000000000000111;
1425 let Inst{3-0} = opt;
1428 // Supervisor Call (Software Interrupt) -- for disassembly only
1430 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1431 [/* For disassembly only; pattern left blank */]> {
1433 let Inst{23-0} = svc;
1437 // Store Return State is a system instruction -- for disassembly only
1438 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1439 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1440 NoItinerary, "srs${amode}\tsp!, $mode",
1441 [/* For disassembly only; pattern left blank */]> {
1442 let Inst{31-28} = 0b1111;
1443 let Inst{22-20} = 0b110; // W = 1
1446 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1447 NoItinerary, "srs${amode}\tsp, $mode",
1448 [/* For disassembly only; pattern left blank */]> {
1449 let Inst{31-28} = 0b1111;
1450 let Inst{22-20} = 0b100; // W = 0
1453 // Return From Exception is a system instruction -- for disassembly only
1454 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1455 NoItinerary, "rfe${amode}\t$base!",
1456 [/* For disassembly only; pattern left blank */]> {
1457 let Inst{31-28} = 0b1111;
1458 let Inst{22-20} = 0b011; // W = 1
1461 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1462 NoItinerary, "rfe${amode}\t$base",
1463 [/* For disassembly only; pattern left blank */]> {
1464 let Inst{31-28} = 0b1111;
1465 let Inst{22-20} = 0b001; // W = 0
1467 } // isCodeGenOnly = 1
1469 //===----------------------------------------------------------------------===//
1470 // Load / store Instructions.
1476 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1477 UnOpFrag<(load node:$Src)>>;
1478 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1479 UnOpFrag<(zextloadi8 node:$Src)>>;
1480 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1481 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1482 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1483 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1485 // Special LDR for loads from non-pc-relative constpools.
1486 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1487 isReMaterializable = 1 in
1488 def LDRcp : AIldst1<0b010, 0, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1489 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> {
1492 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1493 let Inst{19-16} = 0b1111;
1494 let Inst{15-12} = Rt;
1495 let Inst{11-0} = addr{11-0}; // imm12
1498 // Loads with zero extension
1499 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1500 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1501 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1503 // Loads with sign extension
1504 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1505 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1506 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1508 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1509 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1510 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1512 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1513 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1515 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1516 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1517 []>, Requires<[IsARM, HasV5TE]>;
1520 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1521 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1522 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1524 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1525 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1526 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1528 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1529 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1530 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1532 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1533 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1534 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1536 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1537 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1538 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1540 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1541 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1542 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1544 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1545 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1546 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1548 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1549 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1550 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1552 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1553 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1554 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1556 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1557 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1558 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1560 // For disassembly only
1561 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1562 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1563 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1564 Requires<[IsARM, HasV5TE]>;
1566 // For disassembly only
1567 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1568 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1569 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1570 Requires<[IsARM, HasV5TE]>;
1572 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1574 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1576 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1577 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1578 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1579 let Inst{21} = 1; // overwrite
1582 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1583 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1584 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1585 let Inst{21} = 1; // overwrite
1588 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1589 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1590 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1591 let Inst{21} = 1; // overwrite
1594 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1595 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1596 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1597 let Inst{21} = 1; // overwrite
1600 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1601 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1602 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1603 let Inst{21} = 1; // overwrite
1608 // Stores with truncate
1609 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1610 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1611 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1614 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1615 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1616 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1617 StMiscFrm, IIC_iStore_d_r,
1618 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1621 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1622 (ins GPR:$src, GPR:$base, am2offset:$offset),
1623 StFrm, IIC_iStore_ru,
1624 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1626 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1628 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1629 (ins GPR:$src, GPR:$base,am2offset:$offset),
1630 StFrm, IIC_iStore_ru,
1631 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1633 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1635 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1636 (ins GPR:$src, GPR:$base,am3offset:$offset),
1637 StMiscFrm, IIC_iStore_ru,
1638 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1640 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1642 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1643 (ins GPR:$src, GPR:$base,am3offset:$offset),
1644 StMiscFrm, IIC_iStore_bh_ru,
1645 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1646 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1647 GPR:$base, am3offset:$offset))]>;
1649 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1650 (ins GPR:$src, GPR:$base,am2offset:$offset),
1651 StFrm, IIC_iStore_bh_ru,
1652 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1653 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1654 GPR:$base, am2offset:$offset))]>;
1656 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1657 (ins GPR:$src, GPR:$base,am2offset:$offset),
1658 StFrm, IIC_iStore_bh_ru,
1659 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1660 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1661 GPR:$base, am2offset:$offset))]>;
1663 // For disassembly only
1664 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1665 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1666 StMiscFrm, IIC_iStore_d_ru,
1667 "strd", "\t$src1, $src2, [$base, $offset]!",
1668 "$base = $base_wb", []>;
1670 // For disassembly only
1671 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1672 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1673 StMiscFrm, IIC_iStore_d_ru,
1674 "strd", "\t$src1, $src2, [$base], $offset",
1675 "$base = $base_wb", []>;
1677 // STRT, STRBT, and STRHT are for disassembly only.
1679 def STRT : AI2stwpo<(outs GPR:$base_wb),
1680 (ins GPR:$src, GPR:$base,am2offset:$offset),
1681 StFrm, IIC_iStore_ru,
1682 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1683 [/* For disassembly only; pattern left blank */]> {
1684 let Inst{21} = 1; // overwrite
1687 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1688 (ins GPR:$src, GPR:$base,am2offset:$offset),
1689 StFrm, IIC_iStore_bh_ru,
1690 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1691 [/* For disassembly only; pattern left blank */]> {
1692 let Inst{21} = 1; // overwrite
1695 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1696 (ins GPR:$src, GPR:$base,am3offset:$offset),
1697 StMiscFrm, IIC_iStore_bh_ru,
1698 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1699 [/* For disassembly only; pattern left blank */]> {
1700 let Inst{21} = 1; // overwrite
1703 //===----------------------------------------------------------------------===//
1704 // Load / store multiple Instructions.
1707 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1708 isCodeGenOnly = 1 in {
1709 def LDM : AXI4ld<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1710 reglist:$dsts, variable_ops),
1711 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1712 "ldm${amode}${p}\t$Rn, $dsts", "", []> {
1714 let Inst{31-28} = p;
1718 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1719 reglist:$dsts, variable_ops),
1720 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1721 "ldm${amode}${p}\t$Rn!, $dsts",
1724 let Inst{31-28} = p;
1727 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1729 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1730 isCodeGenOnly = 1 in {
1731 def STM : AXI4st<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1732 reglist:$srcs, variable_ops),
1733 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1734 "stm${amode}${p}\t$Rn, $srcs", "", []>;
1736 def STM_UPD : AXI4st<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
1737 reglist:$srcs, variable_ops),
1738 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1739 "stm${amode}${p}\t$Rn!, $srcs",
1741 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1743 //===----------------------------------------------------------------------===//
1744 // Move Instructions.
1747 let neverHasSideEffects = 1 in
1748 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1749 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1753 let Inst{11-4} = 0b00000000;
1756 let Inst{15-12} = Rd;
1759 // A version for the smaller set of tail call registers.
1760 let neverHasSideEffects = 1 in
1761 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1762 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1766 let Inst{11-4} = 0b00000000;
1769 let Inst{15-12} = Rd;
1772 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1773 DPSoRegFrm, IIC_iMOVsr,
1774 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1778 let Inst{15-12} = Rd;
1779 let Inst{11-0} = src;
1783 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1784 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1785 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1789 let Inst{15-12} = Rd;
1790 let Inst{19-16} = 0b0000;
1791 let Inst{11-0} = imm;
1794 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1795 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1797 "movw", "\t$Rd, $imm",
1798 [(set GPR:$Rd, imm0_65535:$imm)]>,
1799 Requires<[IsARM, HasV6T2]>, UnaryDP {
1802 let Inst{15-12} = Rd;
1803 let Inst{11-0} = imm{11-0};
1804 let Inst{19-16} = imm{15-12};
1809 let Constraints = "$src = $Rd" in
1810 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1812 "movt", "\t$Rd, $imm",
1814 (or (and GPR:$src, 0xffff),
1815 lo16AllZero:$imm))]>, UnaryDP,
1816 Requires<[IsARM, HasV6T2]> {
1819 let Inst{15-12} = Rd;
1820 let Inst{11-0} = imm{11-0};
1821 let Inst{19-16} = imm{15-12};
1826 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1827 Requires<[IsARM, HasV6T2]>;
1829 let Uses = [CPSR] in
1830 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1831 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1834 // These aren't really mov instructions, but we have to define them this way
1835 // due to flag operands.
1837 let Defs = [CPSR] in {
1838 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1839 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1841 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1842 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1846 //===----------------------------------------------------------------------===//
1847 // Extend Instructions.
1852 defm SXTB : AI_ext_rrot<0b01101010,
1853 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1854 defm SXTH : AI_ext_rrot<0b01101011,
1855 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1857 defm SXTAB : AI_exta_rrot<0b01101010,
1858 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1859 defm SXTAH : AI_exta_rrot<0b01101011,
1860 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1862 // For disassembly only
1863 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1865 // For disassembly only
1866 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1870 let AddedComplexity = 16 in {
1871 defm UXTB : AI_ext_rrot<0b01101110,
1872 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1873 defm UXTH : AI_ext_rrot<0b01101111,
1874 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1875 defm UXTB16 : AI_ext_rrot<0b01101100,
1876 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1878 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1879 // The transformation should probably be done as a combiner action
1880 // instead so we can include a check for masking back in the upper
1881 // eight bits of the source into the lower eight bits of the result.
1882 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1883 // (UXTB16r_rot GPR:$Src, 24)>;
1884 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1885 (UXTB16r_rot GPR:$Src, 8)>;
1887 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1888 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1889 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1890 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1893 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1894 // For disassembly only
1895 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1898 def SBFX : I<(outs GPR:$Rd),
1899 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1900 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1901 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1902 Requires<[IsARM, HasV6T2]> {
1907 let Inst{27-21} = 0b0111101;
1908 let Inst{6-4} = 0b101;
1909 let Inst{20-16} = width;
1910 let Inst{15-12} = Rd;
1911 let Inst{11-7} = lsb;
1915 def UBFX : I<(outs GPR:$Rd),
1916 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1917 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1918 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1919 Requires<[IsARM, HasV6T2]> {
1924 let Inst{27-21} = 0b0111111;
1925 let Inst{6-4} = 0b101;
1926 let Inst{20-16} = width;
1927 let Inst{15-12} = Rd;
1928 let Inst{11-7} = lsb;
1932 //===----------------------------------------------------------------------===//
1933 // Arithmetic Instructions.
1936 defm ADD : AsI1_bin_irs<0b0100, "add",
1937 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1938 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1939 defm SUB : AsI1_bin_irs<0b0010, "sub",
1940 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1941 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1943 // ADD and SUB with 's' bit set.
1944 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1945 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1946 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1947 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1948 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1949 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1951 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1952 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1953 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1954 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1955 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1956 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1957 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1958 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1960 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1961 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
1962 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
1967 let Inst{15-12} = Rd;
1968 let Inst{19-16} = Rn;
1969 let Inst{11-0} = imm;
1972 // The reg/reg form is only defined for the disassembler; for codegen it is
1973 // equivalent to SUBrr.
1974 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1975 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
1976 [/* For disassembly only; pattern left blank */]> {
1980 let Inst{11-4} = 0b00000000;
1983 let Inst{15-12} = Rd;
1984 let Inst{19-16} = Rn;
1987 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1988 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
1989 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
1994 let Inst{11-0} = shift;
1995 let Inst{15-12} = Rd;
1996 let Inst{19-16} = Rn;
1999 // RSB with 's' bit set.
2000 let Defs = [CPSR] in {
2001 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2002 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2003 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2009 let Inst{15-12} = Rd;
2010 let Inst{19-16} = Rn;
2011 let Inst{11-0} = imm;
2013 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2014 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2015 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2021 let Inst{11-0} = shift;
2022 let Inst{15-12} = Rd;
2023 let Inst{19-16} = Rn;
2027 let Uses = [CPSR] in {
2028 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2029 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2030 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2036 let Inst{15-12} = Rd;
2037 let Inst{19-16} = Rn;
2038 let Inst{11-0} = imm;
2040 // The reg/reg form is only defined for the disassembler; for codegen it is
2041 // equivalent to SUBrr.
2042 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2043 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2044 [/* For disassembly only; pattern left blank */]> {
2048 let Inst{11-4} = 0b00000000;
2051 let Inst{15-12} = Rd;
2052 let Inst{19-16} = Rn;
2054 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2055 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2056 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2062 let Inst{11-0} = shift;
2063 let Inst{15-12} = Rd;
2064 let Inst{19-16} = Rn;
2068 // FIXME: Allow these to be predicated.
2069 let Defs = [CPSR], Uses = [CPSR] in {
2070 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2071 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2072 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2079 let Inst{15-12} = Rd;
2080 let Inst{19-16} = Rn;
2081 let Inst{11-0} = imm;
2083 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2084 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2085 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2092 let Inst{11-0} = shift;
2093 let Inst{15-12} = Rd;
2094 let Inst{19-16} = Rn;
2098 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2099 // The assume-no-carry-in form uses the negation of the input since add/sub
2100 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2101 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2103 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2104 (SUBri GPR:$src, so_imm_neg:$imm)>;
2105 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2106 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2107 // The with-carry-in form matches bitwise not instead of the negation.
2108 // Effectively, the inverse interpretation of the carry flag already accounts
2109 // for part of the negation.
2110 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2111 (SBCri GPR:$src, so_imm_not:$imm)>;
2113 // Note: These are implemented in C++ code, because they have to generate
2114 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2116 // (mul X, 2^n+1) -> (add (X << n), X)
2117 // (mul X, 2^n-1) -> (rsb X, (X << n))
2119 // ARM Arithmetic Instruction -- for disassembly only
2120 // GPR:$dst = GPR:$a op GPR:$b
2121 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2122 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2123 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2124 opc, "\t$Rd, $Rn, $Rm", pattern> {
2128 let Inst{27-20} = op27_20;
2129 let Inst{11-4} = op11_4;
2130 let Inst{19-16} = Rn;
2131 let Inst{15-12} = Rd;
2135 // Saturating add/subtract -- for disassembly only
2137 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2138 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2139 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2140 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2141 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2142 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2144 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2145 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2146 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2147 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2148 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2149 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2150 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2151 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2152 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2153 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2154 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2155 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2157 // Signed/Unsigned add/subtract -- for disassembly only
2159 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2160 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2161 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2162 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2163 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2164 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2165 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2166 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2167 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2168 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2169 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2170 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2172 // Signed/Unsigned halving add/subtract -- for disassembly only
2174 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2175 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2176 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2177 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2178 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2179 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2180 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2181 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2182 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2183 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2184 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2185 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2187 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2189 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2190 MulFrm /* for convenience */, NoItinerary, "usad8",
2191 "\t$Rd, $Rn, $Rm", []>,
2192 Requires<[IsARM, HasV6]> {
2196 let Inst{27-20} = 0b01111000;
2197 let Inst{15-12} = 0b1111;
2198 let Inst{7-4} = 0b0001;
2199 let Inst{19-16} = Rd;
2200 let Inst{11-8} = Rm;
2203 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2204 MulFrm /* for convenience */, NoItinerary, "usada8",
2205 "\t$Rd, $Rn, $Rm, $Ra", []>,
2206 Requires<[IsARM, HasV6]> {
2211 let Inst{27-20} = 0b01111000;
2212 let Inst{7-4} = 0b0001;
2213 let Inst{19-16} = Rd;
2214 let Inst{15-12} = Ra;
2215 let Inst{11-8} = Rm;
2219 // Signed/Unsigned saturate -- for disassembly only
2221 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2222 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2223 [/* For disassembly only; pattern left blank */]> {
2228 let Inst{27-21} = 0b0110101;
2229 let Inst{5-4} = 0b01;
2230 let Inst{20-16} = sat_imm;
2231 let Inst{15-12} = Rd;
2232 let Inst{11-7} = sh{7-3};
2233 let Inst{6} = sh{0};
2237 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2238 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2239 [/* For disassembly only; pattern left blank */]> {
2243 let Inst{27-20} = 0b01101010;
2244 let Inst{11-4} = 0b11110011;
2245 let Inst{15-12} = Rd;
2246 let Inst{19-16} = sat_imm;
2250 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2251 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2252 [/* For disassembly only; pattern left blank */]> {
2257 let Inst{27-21} = 0b0110111;
2258 let Inst{5-4} = 0b01;
2259 let Inst{15-12} = Rd;
2260 let Inst{11-7} = sh{7-3};
2261 let Inst{6} = sh{0};
2262 let Inst{20-16} = sat_imm;
2266 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2267 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2268 [/* For disassembly only; pattern left blank */]> {
2272 let Inst{27-20} = 0b01101110;
2273 let Inst{11-4} = 0b11110011;
2274 let Inst{15-12} = Rd;
2275 let Inst{19-16} = sat_imm;
2279 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2280 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2282 //===----------------------------------------------------------------------===//
2283 // Bitwise Instructions.
2286 defm AND : AsI1_bin_irs<0b0000, "and",
2287 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2288 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2289 defm ORR : AsI1_bin_irs<0b1100, "orr",
2290 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2291 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2292 defm EOR : AsI1_bin_irs<0b0001, "eor",
2293 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2294 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2295 defm BIC : AsI1_bin_irs<0b1110, "bic",
2296 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2297 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2299 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2300 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2301 "bfc", "\t$Rd, $imm", "$src = $Rd",
2302 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2303 Requires<[IsARM, HasV6T2]> {
2306 let Inst{27-21} = 0b0111110;
2307 let Inst{6-0} = 0b0011111;
2308 let Inst{15-12} = Rd;
2309 let Inst{11-7} = imm{4-0}; // lsb
2310 let Inst{20-16} = imm{9-5}; // width
2313 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2314 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2315 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2316 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2317 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2318 bf_inv_mask_imm:$imm))]>,
2319 Requires<[IsARM, HasV6T2]> {
2323 let Inst{27-21} = 0b0111110;
2324 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2325 let Inst{15-12} = Rd;
2326 let Inst{11-7} = imm{4-0}; // lsb
2327 let Inst{20-16} = imm{9-5}; // width
2331 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2332 "mvn", "\t$Rd, $Rm",
2333 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2337 let Inst{19-16} = 0b0000;
2338 let Inst{11-4} = 0b00000000;
2339 let Inst{15-12} = Rd;
2342 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2343 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2344 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2349 let Inst{19-16} = 0b0000;
2350 let Inst{15-12} = Rd;
2351 let Inst{11-0} = shift;
2353 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2354 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2355 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2356 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2361 let Inst{19-16} = 0b0000;
2362 let Inst{15-12} = Rd;
2363 let Inst{11-0} = imm;
2366 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2367 (BICri GPR:$src, so_imm_not:$imm)>;
2369 //===----------------------------------------------------------------------===//
2370 // Multiply Instructions.
2372 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2373 string opc, string asm, list<dag> pattern>
2374 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2378 let Inst{19-16} = Rd;
2379 let Inst{11-8} = Rm;
2382 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2383 string opc, string asm, list<dag> pattern>
2384 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2389 let Inst{19-16} = RdHi;
2390 let Inst{15-12} = RdLo;
2391 let Inst{11-8} = Rm;
2395 let isCommutable = 1 in
2396 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2397 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2398 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2400 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2401 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2402 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2404 let Inst{15-12} = Ra;
2407 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2408 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2409 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2410 Requires<[IsARM, HasV6T2]> {
2414 let Inst{19-16} = Rd;
2415 let Inst{11-8} = Rm;
2419 // Extra precision multiplies with low / high results
2421 let neverHasSideEffects = 1 in {
2422 let isCommutable = 1 in {
2423 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2424 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2425 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2427 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2428 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2429 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2432 // Multiply + accumulate
2433 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2434 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2435 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2437 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2438 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2439 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2441 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2442 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2443 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2444 Requires<[IsARM, HasV6]> {
2449 let Inst{19-16} = RdLo;
2450 let Inst{15-12} = RdHi;
2451 let Inst{11-8} = Rm;
2454 } // neverHasSideEffects
2456 // Most significant word multiply
2457 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2458 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2459 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2460 Requires<[IsARM, HasV6]> {
2461 let Inst{15-12} = 0b1111;
2464 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2465 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2466 [/* For disassembly only; pattern left blank */]>,
2467 Requires<[IsARM, HasV6]> {
2468 let Inst{15-12} = 0b1111;
2471 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2472 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2473 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2474 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2475 Requires<[IsARM, HasV6]>;
2477 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2478 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2479 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2480 [/* For disassembly only; pattern left blank */]>,
2481 Requires<[IsARM, HasV6]>;
2483 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2484 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2485 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2486 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2487 Requires<[IsARM, HasV6]>;
2489 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2490 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2491 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2492 [/* For disassembly only; pattern left blank */]>,
2493 Requires<[IsARM, HasV6]>;
2495 multiclass AI_smul<string opc, PatFrag opnode> {
2496 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2497 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2498 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2499 (sext_inreg GPR:$Rm, i16)))]>,
2500 Requires<[IsARM, HasV5TE]>;
2502 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2503 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2504 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2505 (sra GPR:$Rm, (i32 16))))]>,
2506 Requires<[IsARM, HasV5TE]>;
2508 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2509 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2510 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2511 (sext_inreg GPR:$Rm, i16)))]>,
2512 Requires<[IsARM, HasV5TE]>;
2514 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2515 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2516 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2517 (sra GPR:$Rm, (i32 16))))]>,
2518 Requires<[IsARM, HasV5TE]>;
2520 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2521 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2522 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2523 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2524 Requires<[IsARM, HasV5TE]>;
2526 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2527 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2528 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2529 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2530 Requires<[IsARM, HasV5TE]>;
2534 multiclass AI_smla<string opc, PatFrag opnode> {
2535 def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$Rd),
2536 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2537 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2538 [(set GPR:$Rd, (add GPR:$Ra,
2539 (opnode (sext_inreg GPR:$Rn, i16),
2540 (sext_inreg GPR:$Rm, i16))))]>,
2541 Requires<[IsARM, HasV5TE]>;
2543 def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$Rd),
2544 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2545 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2546 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2547 (sra GPR:$Rm, (i32 16)))))]>,
2548 Requires<[IsARM, HasV5TE]>;
2550 def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$Rd),
2551 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2552 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2553 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2554 (sext_inreg GPR:$Rm, i16))))]>,
2555 Requires<[IsARM, HasV5TE]>;
2557 def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$Rd),
2558 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2559 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2560 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2561 (sra GPR:$Rm, (i32 16)))))]>,
2562 Requires<[IsARM, HasV5TE]>;
2564 def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$Rd),
2565 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2566 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2567 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2568 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2569 Requires<[IsARM, HasV5TE]>;
2571 def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$Rd),
2572 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2573 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2574 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2575 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2576 Requires<[IsARM, HasV5TE]>;
2579 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2580 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2582 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2583 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2584 (ins GPR:$Rn, GPR:$Rm),
2585 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2586 [/* For disassembly only; pattern left blank */]>,
2587 Requires<[IsARM, HasV5TE]>;
2589 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2590 (ins GPR:$Rn, GPR:$Rm),
2591 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2592 [/* For disassembly only; pattern left blank */]>,
2593 Requires<[IsARM, HasV5TE]>;
2595 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2596 (ins GPR:$Rn, GPR:$Rm),
2597 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2598 [/* For disassembly only; pattern left blank */]>,
2599 Requires<[IsARM, HasV5TE]>;
2601 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2602 (ins GPR:$Rn, GPR:$Rm),
2603 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2604 [/* For disassembly only; pattern left blank */]>,
2605 Requires<[IsARM, HasV5TE]>;
2607 // Helper class for AI_smld -- for disassembly only
2608 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2609 InstrItinClass itin, string opc, string asm>
2610 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2617 let Inst{21-20} = 0b00;
2618 let Inst{22} = long;
2619 let Inst{27-23} = 0b01110;
2620 let Inst{11-8} = Rm;
2623 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2624 InstrItinClass itin, string opc, string asm>
2625 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2627 let Inst{15-12} = 0b1111;
2628 let Inst{19-16} = Rd;
2630 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2631 InstrItinClass itin, string opc, string asm>
2632 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2634 let Inst{15-12} = Ra;
2636 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2637 InstrItinClass itin, string opc, string asm>
2638 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2641 let Inst{19-16} = RdHi;
2642 let Inst{15-12} = RdLo;
2645 multiclass AI_smld<bit sub, string opc> {
2647 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2648 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2650 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2651 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2653 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2654 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2655 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2657 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2658 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2659 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2663 defm SMLA : AI_smld<0, "smla">;
2664 defm SMLS : AI_smld<1, "smls">;
2666 multiclass AI_sdml<bit sub, string opc> {
2668 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2669 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2670 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2671 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2674 defm SMUA : AI_sdml<0, "smua">;
2675 defm SMUS : AI_sdml<1, "smus">;
2677 //===----------------------------------------------------------------------===//
2678 // Misc. Arithmetic Instructions.
2681 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2682 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2683 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2685 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2686 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2687 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2688 Requires<[IsARM, HasV6T2]>;
2690 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2691 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2692 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2694 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2695 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2697 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2698 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2699 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2700 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2701 Requires<[IsARM, HasV6]>;
2703 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2704 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2707 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2708 (shl GPR:$Rm, (i32 8))), i16))]>,
2709 Requires<[IsARM, HasV6]>;
2711 def lsl_shift_imm : SDNodeXForm<imm, [{
2712 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2713 return CurDAG->getTargetConstant(Sh, MVT::i32);
2716 def lsl_amt : PatLeaf<(i32 imm), [{
2717 return (N->getZExtValue() < 32);
2720 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2721 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2722 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2723 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2724 (and (shl GPR:$Rm, lsl_amt:$sh),
2726 Requires<[IsARM, HasV6]>;
2728 // Alternate cases for PKHBT where identities eliminate some nodes.
2729 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2730 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2731 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2732 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2734 def asr_shift_imm : SDNodeXForm<imm, [{
2735 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2736 return CurDAG->getTargetConstant(Sh, MVT::i32);
2739 def asr_amt : PatLeaf<(i32 imm), [{
2740 return (N->getZExtValue() <= 32);
2743 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2744 // will match the pattern below.
2745 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2746 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2747 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2748 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2749 (and (sra GPR:$Rm, asr_amt:$sh),
2751 Requires<[IsARM, HasV6]>;
2753 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2754 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2755 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2756 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2757 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2758 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2759 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2761 //===----------------------------------------------------------------------===//
2762 // Comparison Instructions...
2765 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2766 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2767 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2769 // FIXME: We have to be careful when using the CMN instruction and comparison
2770 // with 0. One would expect these two pieces of code should give identical
2786 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2787 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2788 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2789 // value of r0 and the carry bit (because the "carry bit" parameter to
2790 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2791 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2792 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2793 // parameter to AddWithCarry is defined as 0).
2795 // When x is 0 and unsigned:
2799 // ~x + 1 = 0x1 0000 0000
2800 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2802 // Therefore, we should disable CMN when comparing against zero, until we can
2803 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2804 // when it's a comparison which doesn't look at the 'carry' flag).
2806 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2808 // This is related to <rdar://problem/7569620>.
2810 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2811 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2813 // Note that TST/TEQ don't set all the same flags that CMP does!
2814 defm TST : AI1_cmp_irs<0b1000, "tst",
2815 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2816 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2817 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2818 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2819 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2821 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2822 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2823 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2824 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2825 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2826 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2828 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2829 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2831 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2832 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2834 // Pseudo i64 compares for some floating point compares.
2835 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2837 def BCCi64 : PseudoInst<(outs),
2838 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2840 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2842 def BCCZi64 : PseudoInst<(outs),
2843 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2844 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2845 } // usesCustomInserter
2848 // Conditional moves
2849 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2850 // a two-value operand where a dag node expects two operands. :(
2851 // FIXME: These should all be pseudo-instructions that get expanded to
2852 // the normal MOV instructions. That would fix the dependency on
2853 // special casing them in tblgen.
2854 let neverHasSideEffects = 1 in {
2855 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2856 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2857 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2858 RegConstraint<"$false = $Rd">, UnaryDP {
2863 let Inst{15-12} = Rd;
2864 let Inst{11-4} = 0b00000000;
2868 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
2869 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
2870 "mov", "\t$Rd, $shift",
2871 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
2872 RegConstraint<"$false = $Rd">, UnaryDP {
2878 let Inst{19-16} = Rn;
2879 let Inst{15-12} = Rd;
2880 let Inst{11-0} = shift;
2883 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
2885 "movw", "\t$Rd, $imm",
2887 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
2893 let Inst{19-16} = imm{15-12};
2894 let Inst{15-12} = Rd;
2895 let Inst{11-0} = imm{11-0};
2898 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
2899 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
2900 "mov", "\t$Rd, $imm",
2901 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2902 RegConstraint<"$false = $Rd">, UnaryDP {
2907 let Inst{19-16} = 0b0000;
2908 let Inst{15-12} = Rd;
2909 let Inst{11-0} = imm;
2911 } // neverHasSideEffects
2913 //===----------------------------------------------------------------------===//
2914 // Atomic operations intrinsics
2917 def memb_opt : Operand<i32> {
2918 let PrintMethod = "printMemBOption";
2921 // memory barriers protect the atomic sequences
2922 let hasSideEffects = 1 in {
2923 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2924 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2925 Requires<[IsARM, HasDB]> {
2927 let Inst{31-4} = 0xf57ff05;
2928 let Inst{3-0} = opt;
2931 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2932 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2933 [(ARMMemBarrierMCR GPR:$zero)]>,
2934 Requires<[IsARM, HasV6]> {
2935 // FIXME: add encoding
2939 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2941 [/* For disassembly only; pattern left blank */]>,
2942 Requires<[IsARM, HasDB]> {
2944 let Inst{31-4} = 0xf57ff04;
2945 let Inst{3-0} = opt;
2948 // ISB has only full system option -- for disassembly only
2949 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2950 Requires<[IsARM, HasDB]> {
2951 let Inst{31-4} = 0xf57ff06;
2952 let Inst{3-0} = 0b1111;
2955 let usesCustomInserter = 1 in {
2956 let Uses = [CPSR] in {
2957 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2958 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2959 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2960 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2961 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2962 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2963 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2964 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2965 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2966 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2967 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2968 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2969 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2970 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2971 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2972 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2973 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2974 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2975 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2976 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2977 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2978 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2979 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2980 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2981 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2982 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2983 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2984 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2985 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2986 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2987 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2988 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2989 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2990 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2991 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2992 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2993 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2994 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2995 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2996 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2997 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2998 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2999 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3000 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3001 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3002 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3003 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3004 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3005 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3006 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3007 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3008 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3009 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3010 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3012 def ATOMIC_SWAP_I8 : PseudoInst<
3013 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3014 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3015 def ATOMIC_SWAP_I16 : PseudoInst<
3016 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3017 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3018 def ATOMIC_SWAP_I32 : PseudoInst<
3019 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3020 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3022 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3023 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3024 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3025 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3026 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3027 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3028 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3029 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3030 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3034 let mayLoad = 1 in {
3035 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3036 "ldrexb", "\t$Rt, [$Rn]",
3038 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3039 "ldrexh", "\t$Rt, [$Rn]",
3041 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3042 "ldrex", "\t$Rt, [$Rn]",
3044 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3046 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3050 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3051 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3053 "strexb", "\t$Rd, $src, [$Rn]",
3055 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3057 "strexh", "\t$Rd, $Rt, [$Rn]",
3059 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3061 "strex", "\t$Rd, $Rt, [$Rn]",
3063 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3064 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3066 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3070 // Clear-Exclusive is for disassembly only.
3071 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3072 [/* For disassembly only; pattern left blank */]>,
3073 Requires<[IsARM, HasV7]> {
3074 let Inst{31-0} = 0b11110101011111111111000000011111;
3077 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3078 let mayLoad = 1 in {
3079 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3080 [/* For disassembly only; pattern left blank */]>;
3081 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3082 [/* For disassembly only; pattern left blank */]>;
3085 //===----------------------------------------------------------------------===//
3089 // __aeabi_read_tp preserves the registers r1-r3.
3090 // FIXME: This needs to be a pseudo of some sort so that we can get the
3091 // encoding right, complete with fixup for the aeabi_read_tp function.
3093 Defs = [R0, R12, LR, CPSR] in {
3094 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3095 "bl\t__aeabi_read_tp",
3096 [(set R0, ARMthread_pointer)]>;
3099 //===----------------------------------------------------------------------===//
3100 // SJLJ Exception handling intrinsics
3101 // eh_sjlj_setjmp() is an instruction sequence to store the return
3102 // address and save #0 in R0 for the non-longjmp case.
3103 // Since by its nature we may be coming from some other function to get
3104 // here, and we're using the stack frame for the containing function to
3105 // save/restore registers, we can't keep anything live in regs across
3106 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3107 // when we get here from a longjmp(). We force everthing out of registers
3108 // except for our own input by listing the relevant registers in Defs. By
3109 // doing so, we also cause the prologue/epilogue code to actively preserve
3110 // all of the callee-saved resgisters, which is exactly what we want.
3111 // A constant value is passed in $val, and we use the location as a scratch.
3113 // These are pseudo-instructions and are lowered to individual MC-insts, so
3114 // no encoding information is necessary.
3116 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3117 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3118 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3119 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3120 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3121 AddrModeNone, SizeSpecial, IndexModeNone,
3122 Pseudo, NoItinerary, "", "",
3123 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3124 Requires<[IsARM, HasVFP2]>;
3128 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3129 hasSideEffects = 1, isBarrier = 1 in {
3130 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3131 AddrModeNone, SizeSpecial, IndexModeNone,
3132 Pseudo, NoItinerary, "", "",
3133 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3134 Requires<[IsARM, NoVFP]>;
3137 // FIXME: Non-Darwin version(s)
3138 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3139 Defs = [ R7, LR, SP ] in {
3140 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3141 AddrModeNone, SizeSpecial, IndexModeNone,
3142 Pseudo, NoItinerary, "", "",
3143 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3144 Requires<[IsARM, IsDarwin]>;
3147 // eh.sjlj.dispatchsetup pseudo-instruction.
3148 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3149 // handled when the pseudo is expanded (which happens before any passes
3150 // that need the instruction size).
3151 let isBarrier = 1, hasSideEffects = 1 in
3152 def Int_eh_sjlj_dispatchsetup :
3153 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3154 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3155 Requires<[IsDarwin]>;
3157 //===----------------------------------------------------------------------===//
3158 // Non-Instruction Patterns
3161 // Large immediate handling.
3163 // Two piece so_imms.
3164 // FIXME: Remove this when we can do generalized remat.
3165 let isReMaterializable = 1 in
3166 def MOVi2pieces : PseudoInst<(outs GPR:$dst), (ins so_imm2part:$src),
3168 [(set GPR:$dst, (so_imm2part:$src))]>,
3169 Requires<[IsARM, NoV6T2]>;
3171 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3172 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3173 (so_imm2part_2 imm:$RHS))>;
3174 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3175 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3176 (so_imm2part_2 imm:$RHS))>;
3177 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3178 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3179 (so_imm2part_2 imm:$RHS))>;
3180 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3181 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3182 (so_neg_imm2part_2 imm:$RHS))>;
3184 // 32-bit immediate using movw + movt.
3185 // This is a single pseudo instruction, the benefit is that it can be remat'd
3186 // as a single unit instead of having to handle reg inputs.
3187 // FIXME: Remove this when we can do generalized remat.
3188 let isReMaterializable = 1 in
3189 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3190 [(set GPR:$dst, (i32 imm:$src))]>,
3191 Requires<[IsARM, HasV6T2]>;
3193 // ConstantPool, GlobalAddress, and JumpTable
3194 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3195 Requires<[IsARM, DontUseMovt]>;
3196 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3197 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3198 Requires<[IsARM, UseMovt]>;
3199 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3200 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3202 // TODO: add,sub,and, 3-instr forms?
3205 def : ARMPat<(ARMtcret tcGPR:$dst),
3206 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3208 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3209 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3211 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3212 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3214 def : ARMPat<(ARMtcret tcGPR:$dst),
3215 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3217 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3218 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3220 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3221 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3224 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3225 Requires<[IsARM, IsNotDarwin]>;
3226 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3227 Requires<[IsARM, IsDarwin]>;
3229 // zextload i1 -> zextload i8
3230 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3231 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3233 // extload -> zextload
3234 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3235 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3236 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3237 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3239 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3241 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3242 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3245 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3246 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3247 (SMULBB GPR:$a, GPR:$b)>;
3248 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3249 (SMULBB GPR:$a, GPR:$b)>;
3250 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3251 (sra GPR:$b, (i32 16))),
3252 (SMULBT GPR:$a, GPR:$b)>;
3253 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3254 (SMULBT GPR:$a, GPR:$b)>;
3255 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3256 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3257 (SMULTB GPR:$a, GPR:$b)>;
3258 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3259 (SMULTB GPR:$a, GPR:$b)>;
3260 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3262 (SMULWB GPR:$a, GPR:$b)>;
3263 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3264 (SMULWB GPR:$a, GPR:$b)>;
3266 def : ARMV5TEPat<(add GPR:$acc,
3267 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3268 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3269 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3270 def : ARMV5TEPat<(add GPR:$acc,
3271 (mul sext_16_node:$a, sext_16_node:$b)),
3272 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3273 def : ARMV5TEPat<(add GPR:$acc,
3274 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3275 (sra GPR:$b, (i32 16)))),
3276 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3277 def : ARMV5TEPat<(add GPR:$acc,
3278 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3279 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3280 def : ARMV5TEPat<(add GPR:$acc,
3281 (mul (sra GPR:$a, (i32 16)),
3282 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3283 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3284 def : ARMV5TEPat<(add GPR:$acc,
3285 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3286 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3287 def : ARMV5TEPat<(add GPR:$acc,
3288 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3290 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3291 def : ARMV5TEPat<(add GPR:$acc,
3292 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3293 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3295 //===----------------------------------------------------------------------===//
3299 include "ARMInstrThumb.td"
3301 //===----------------------------------------------------------------------===//
3305 include "ARMInstrThumb2.td"
3307 //===----------------------------------------------------------------------===//
3308 // Floating Point Support
3311 include "ARMInstrVFP.td"
3313 //===----------------------------------------------------------------------===//
3314 // Advanced SIMD (NEON) Support
3317 include "ARMInstrNEON.td"
3319 //===----------------------------------------------------------------------===//
3320 // Coprocessor Instructions. For disassembly only.
3323 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3324 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3325 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3326 [/* For disassembly only; pattern left blank */]> {
3330 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3331 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3332 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3333 [/* For disassembly only; pattern left blank */]> {
3334 let Inst{31-28} = 0b1111;
3338 class ACI<dag oops, dag iops, string opc, string asm>
3339 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3340 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3341 let Inst{27-25} = 0b110;
3344 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3346 def _OFFSET : ACI<(outs),
3347 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3348 opc, "\tp$cop, cr$CRd, $addr"> {
3349 let Inst{31-28} = op31_28;
3350 let Inst{24} = 1; // P = 1
3351 let Inst{21} = 0; // W = 0
3352 let Inst{22} = 0; // D = 0
3353 let Inst{20} = load;
3356 def _PRE : ACI<(outs),
3357 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3358 opc, "\tp$cop, cr$CRd, $addr!"> {
3359 let Inst{31-28} = op31_28;
3360 let Inst{24} = 1; // P = 1
3361 let Inst{21} = 1; // W = 1
3362 let Inst{22} = 0; // D = 0
3363 let Inst{20} = load;
3366 def _POST : ACI<(outs),
3367 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3368 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3369 let Inst{31-28} = op31_28;
3370 let Inst{24} = 0; // P = 0
3371 let Inst{21} = 1; // W = 1
3372 let Inst{22} = 0; // D = 0
3373 let Inst{20} = load;
3376 def _OPTION : ACI<(outs),
3377 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3378 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3379 let Inst{31-28} = op31_28;
3380 let Inst{24} = 0; // P = 0
3381 let Inst{23} = 1; // U = 1
3382 let Inst{21} = 0; // W = 0
3383 let Inst{22} = 0; // D = 0
3384 let Inst{20} = load;
3387 def L_OFFSET : ACI<(outs),
3388 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3389 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3390 let Inst{31-28} = op31_28;
3391 let Inst{24} = 1; // P = 1
3392 let Inst{21} = 0; // W = 0
3393 let Inst{22} = 1; // D = 1
3394 let Inst{20} = load;
3397 def L_PRE : ACI<(outs),
3398 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3399 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3400 let Inst{31-28} = op31_28;
3401 let Inst{24} = 1; // P = 1
3402 let Inst{21} = 1; // W = 1
3403 let Inst{22} = 1; // D = 1
3404 let Inst{20} = load;
3407 def L_POST : ACI<(outs),
3408 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3409 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3410 let Inst{31-28} = op31_28;
3411 let Inst{24} = 0; // P = 0
3412 let Inst{21} = 1; // W = 1
3413 let Inst{22} = 1; // D = 1
3414 let Inst{20} = load;
3417 def L_OPTION : ACI<(outs),
3418 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3419 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3420 let Inst{31-28} = op31_28;
3421 let Inst{24} = 0; // P = 0
3422 let Inst{23} = 1; // U = 1
3423 let Inst{21} = 0; // W = 0
3424 let Inst{22} = 1; // D = 1
3425 let Inst{20} = load;
3429 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3430 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3431 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3432 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3434 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3435 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3436 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3437 [/* For disassembly only; pattern left blank */]> {
3442 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3443 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3444 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3445 [/* For disassembly only; pattern left blank */]> {
3446 let Inst{31-28} = 0b1111;
3451 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3452 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3453 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3454 [/* For disassembly only; pattern left blank */]> {
3459 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3460 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3461 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3462 [/* For disassembly only; pattern left blank */]> {
3463 let Inst{31-28} = 0b1111;
3468 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3469 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3470 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3471 [/* For disassembly only; pattern left blank */]> {
3472 let Inst{23-20} = 0b0100;
3475 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3476 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3477 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3478 [/* For disassembly only; pattern left blank */]> {
3479 let Inst{31-28} = 0b1111;
3480 let Inst{23-20} = 0b0100;
3483 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3484 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3485 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3486 [/* For disassembly only; pattern left blank */]> {
3487 let Inst{23-20} = 0b0101;
3490 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3491 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3492 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3493 [/* For disassembly only; pattern left blank */]> {
3494 let Inst{31-28} = 0b1111;
3495 let Inst{23-20} = 0b0101;
3498 //===----------------------------------------------------------------------===//
3499 // Move between special register and ARM core register -- for disassembly only
3502 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3503 [/* For disassembly only; pattern left blank */]> {
3504 let Inst{23-20} = 0b0000;
3505 let Inst{7-4} = 0b0000;
3508 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3509 [/* For disassembly only; pattern left blank */]> {
3510 let Inst{23-20} = 0b0100;
3511 let Inst{7-4} = 0b0000;
3514 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3515 "msr", "\tcpsr$mask, $src",
3516 [/* For disassembly only; pattern left blank */]> {
3517 let Inst{23-20} = 0b0010;
3518 let Inst{7-4} = 0b0000;
3521 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3522 "msr", "\tcpsr$mask, $a",
3523 [/* For disassembly only; pattern left blank */]> {
3524 let Inst{23-20} = 0b0010;
3525 let Inst{7-4} = 0b0000;
3528 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3529 "msr", "\tspsr$mask, $src",
3530 [/* For disassembly only; pattern left blank */]> {
3531 let Inst{23-20} = 0b0110;
3532 let Inst{7-4} = 0b0000;
3535 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3536 "msr", "\tspsr$mask, $a",
3537 [/* For disassembly only; pattern left blank */]> {
3538 let Inst{23-20} = 0b0110;
3539 let Inst{7-4} = 0b0000;