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, 0, []>;
64 def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
65 def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
66 def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
68 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
70 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
71 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
74 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
75 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
77 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
78 [SDNPHasChain, SDNPOutFlag]>;
79 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
80 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
82 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
85 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
88 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
89 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
92 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
93 [SDNPHasChain, SDNPOptInFlag]>;
95 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
97 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
100 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
101 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
103 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
105 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
108 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
111 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
114 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
115 [SDNPOutFlag, SDNPCommutative]>;
117 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
119 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
120 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
121 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
123 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
124 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
125 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
126 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
127 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
128 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
129 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
132 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
134 def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
136 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR,
138 def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR,
141 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
143 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
144 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
147 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
149 //===----------------------------------------------------------------------===//
150 // ARM Instruction Predicate Definitions.
152 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
153 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
154 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
155 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
156 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
157 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
158 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
159 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
160 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
161 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
162 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
163 def HasNEON : Predicate<"Subtarget->hasNEON()">;
164 def HasDivide : Predicate<"Subtarget->hasDivide()">;
165 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
166 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
167 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
168 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
169 def IsThumb : Predicate<"Subtarget->isThumb()">;
170 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
171 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
172 def IsARM : Predicate<"!Subtarget->isThumb()">;
173 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
174 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
176 // FIXME: Eventually this will be just "hasV6T2Ops".
177 def UseMovt : Predicate<"Subtarget->useMovt()">;
178 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
179 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
181 //===----------------------------------------------------------------------===//
182 // ARM Flag Definitions.
184 class RegConstraint<string C> {
185 string Constraints = C;
188 //===----------------------------------------------------------------------===//
189 // ARM specific transformation functions and pattern fragments.
192 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
193 // so_imm_neg def below.
194 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
195 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
198 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
199 // so_imm_not def below.
200 def so_imm_not_XFORM : SDNodeXForm<imm, [{
201 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
204 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
205 def imm1_15 : PatLeaf<(i32 imm), [{
206 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
209 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
210 def imm16_31 : PatLeaf<(i32 imm), [{
211 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
216 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
217 }], so_imm_neg_XFORM>;
221 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
222 }], so_imm_not_XFORM>;
224 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
225 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
226 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
229 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
231 def bf_inv_mask_imm : Operand<i32>,
233 return ARM::isBitFieldInvertedMask(N->getZExtValue());
235 string EncoderMethod = "getBitfieldInvertedMaskOpValue";
236 let PrintMethod = "printBitfieldInvMaskImmOperand";
239 /// Split a 32-bit immediate into two 16 bit parts.
240 def hi16 : SDNodeXForm<imm, [{
241 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
244 def lo16AllZero : PatLeaf<(i32 imm), [{
245 // Returns true if all low 16-bits are 0.
246 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
249 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
251 def imm0_65535 : PatLeaf<(i32 imm), [{
252 return (uint32_t)N->getZExtValue() < 65536;
255 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
256 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
258 /// adde and sube predicates - True based on whether the carry flag output
259 /// will be needed or not.
260 def adde_dead_carry :
261 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
262 [{return !N->hasAnyUseOfValue(1);}]>;
263 def sube_dead_carry :
264 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
265 [{return !N->hasAnyUseOfValue(1);}]>;
266 def adde_live_carry :
267 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
268 [{return N->hasAnyUseOfValue(1);}]>;
269 def sube_live_carry :
270 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
271 [{return N->hasAnyUseOfValue(1);}]>;
273 //===----------------------------------------------------------------------===//
274 // Operand Definitions.
278 def brtarget : Operand<OtherVT>;
280 // A list of registers separated by comma. Used by load/store multiple.
281 def reglist : Operand<i32> {
282 let PrintMethod = "printRegisterList";
285 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
286 def cpinst_operand : Operand<i32> {
287 let PrintMethod = "printCPInstOperand";
290 def jtblock_operand : Operand<i32> {
291 let PrintMethod = "printJTBlockOperand";
293 def jt2block_operand : Operand<i32> {
294 let PrintMethod = "printJT2BlockOperand";
298 def pclabel : Operand<i32> {
299 let PrintMethod = "printPCLabel";
302 def neon_vcvt_imm32 : Operand<i32> {
303 string EncoderMethod = "getNEONVcvtImm32";
306 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
307 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
308 int32_t v = (int32_t)N->getZExtValue();
309 return v == 8 || v == 16 || v == 24; }]> {
310 string EncoderMethod = "getRotImmOpValue";
313 // shift_imm: An integer that encodes a shift amount and the type of shift
314 // (currently either asr or lsl) using the same encoding used for the
315 // immediates in so_reg operands.
316 def shift_imm : Operand<i32> {
317 let PrintMethod = "printShiftImmOperand";
320 // shifter_operand operands: so_reg and so_imm.
321 def so_reg : Operand<i32>, // reg reg imm
322 ComplexPattern<i32, 3, "SelectShifterOperandReg",
323 [shl,srl,sra,rotr]> {
324 string EncoderMethod = "getSORegOpValue";
325 let PrintMethod = "printSORegOperand";
326 let MIOperandInfo = (ops GPR, GPR, i32imm);
328 def shift_so_reg : Operand<i32>, // reg reg imm
329 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
330 [shl,srl,sra,rotr]> {
331 string EncoderMethod = "getSORegOpValue";
332 let PrintMethod = "printSORegOperand";
333 let MIOperandInfo = (ops GPR, GPR, i32imm);
336 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
337 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
338 // represented in the imm field in the same 12-bit form that they are encoded
339 // into so_imm instructions: the 8-bit immediate is the least significant bits
340 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
341 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
342 string EncoderMethod = "getSOImmOpValue";
343 let PrintMethod = "printSOImmOperand";
346 // Break so_imm's up into two pieces. This handles immediates with up to 16
347 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
348 // get the first/second pieces.
349 def so_imm2part : Operand<i32>,
351 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
353 let PrintMethod = "printSOImm2PartOperand";
356 def so_imm2part_1 : SDNodeXForm<imm, [{
357 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
358 return CurDAG->getTargetConstant(V, MVT::i32);
361 def so_imm2part_2 : SDNodeXForm<imm, [{
362 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
363 return CurDAG->getTargetConstant(V, MVT::i32);
366 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
367 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
369 let PrintMethod = "printSOImm2PartOperand";
372 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
373 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
374 return CurDAG->getTargetConstant(V, MVT::i32);
377 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
378 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
379 return CurDAG->getTargetConstant(V, MVT::i32);
382 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
383 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
384 return (int32_t)N->getZExtValue() < 32;
387 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
388 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
389 return (int32_t)N->getZExtValue() < 32;
391 string EncoderMethod = "getImmMinusOneOpValue";
394 // Define ARM specific addressing modes.
397 // addrmode_imm12 := reg +/- imm12
399 def addrmode_imm12 : Operand<i32>,
400 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
402 string EncoderMethod = "getAddrModeImm12OpValue";
403 let PrintMethod = "printAddrModeImm12Operand";
404 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
406 // ldst_so_reg := reg +/- reg shop imm
408 def ldst_so_reg : Operand<i32>,
409 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
410 // FIXME: Simplify the printer
411 // FIXME: Add EncoderMethod for this addressing mode
412 let PrintMethod = "printAddrMode2Operand";
413 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
416 // addrmode2 := reg +/- imm12
417 // := reg +/- reg shop imm
419 def addrmode2 : Operand<i32>,
420 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
421 let PrintMethod = "printAddrMode2Operand";
422 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
425 def am2offset : Operand<i32>,
426 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
427 [], [SDNPWantRoot]> {
428 let PrintMethod = "printAddrMode2OffsetOperand";
429 let MIOperandInfo = (ops GPR, i32imm);
432 // addrmode3 := reg +/- reg
433 // addrmode3 := reg +/- imm8
435 def addrmode3 : Operand<i32>,
436 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
437 let PrintMethod = "printAddrMode3Operand";
438 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
441 def am3offset : Operand<i32>,
442 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
443 [], [SDNPWantRoot]> {
444 let PrintMethod = "printAddrMode3OffsetOperand";
445 let MIOperandInfo = (ops GPR, i32imm);
448 // addrmode4 := reg, <mode|W>
450 def addrmode4 : Operand<i32>,
451 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
452 let PrintMethod = "printAddrMode4Operand";
453 let MIOperandInfo = (ops GPR:$addr, i32imm);
456 // addrmode5 := reg +/- imm8*4
458 def addrmode5 : Operand<i32>,
459 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
460 let PrintMethod = "printAddrMode5Operand";
461 let MIOperandInfo = (ops GPR:$base, i32imm);
464 // addrmode6 := reg with optional writeback
466 def addrmode6 : Operand<i32>,
467 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
468 let PrintMethod = "printAddrMode6Operand";
469 let MIOperandInfo = (ops GPR:$addr, i32imm);
472 def am6offset : Operand<i32> {
473 let PrintMethod = "printAddrMode6OffsetOperand";
474 let MIOperandInfo = (ops GPR);
477 // addrmodepc := pc + reg
479 def addrmodepc : Operand<i32>,
480 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
481 let PrintMethod = "printAddrModePCOperand";
482 let MIOperandInfo = (ops GPR, i32imm);
485 def nohash_imm : Operand<i32> {
486 let PrintMethod = "printNoHashImmediate";
489 //===----------------------------------------------------------------------===//
491 include "ARMInstrFormats.td"
493 //===----------------------------------------------------------------------===//
494 // Multiclass helpers...
497 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
498 /// binop that produces a value.
499 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
500 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
501 PatFrag opnode, bit Commutable = 0> {
502 // The register-immediate version is re-materializable. This is useful
503 // in particular for taking the address of a local.
504 let isReMaterializable = 1 in {
505 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
506 iii, opc, "\t$Rd, $Rn, $imm",
507 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
512 let Inst{15-12} = Rd;
513 let Inst{19-16} = Rn;
514 let Inst{11-0} = imm;
517 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
518 iir, opc, "\t$Rd, $Rn, $Rm",
519 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
523 let Inst{11-4} = 0b00000000;
525 let isCommutable = Commutable;
527 let Inst{15-12} = Rd;
528 let Inst{19-16} = Rn;
530 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
531 iis, opc, "\t$Rd, $Rn, $shift",
532 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
537 let Inst{11-0} = shift;
538 let Inst{15-12} = Rd;
539 let Inst{19-16} = Rn;
543 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
544 /// instruction modifies the CPSR register.
545 let Defs = [CPSR] in {
546 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
547 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
548 PatFrag opnode, bit Commutable = 0> {
549 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
550 iii, opc, "\t$Rd, $Rn, $imm",
551 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
556 let Inst{15-12} = Rd;
557 let Inst{19-16} = Rn;
558 let Inst{11-0} = imm;
561 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
562 iir, opc, "\t$Rd, $Rn, $Rm",
563 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
567 let Inst{11-4} = 0b00000000;
569 let isCommutable = Commutable;
571 let Inst{15-12} = Rd;
572 let Inst{19-16} = Rn;
575 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
576 iis, opc, "\t$Rd, $Rn, $shift",
577 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
582 let Inst{11-0} = shift;
583 let Inst{15-12} = Rd;
584 let Inst{19-16} = Rn;
590 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
591 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
592 /// a explicit result, only implicitly set CPSR.
593 let isCompare = 1, Defs = [CPSR] in {
594 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
595 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
596 PatFrag opnode, bit Commutable = 0> {
597 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
599 [(opnode GPR:$Rn, so_imm:$imm)]> {
603 let Inst{15-12} = 0b0000;
604 let Inst{19-16} = Rn;
605 let Inst{11-0} = imm;
609 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
611 [(opnode GPR:$Rn, GPR:$Rm)]> {
614 let Inst{11-4} = 0b00000000;
616 let isCommutable = Commutable;
618 let Inst{15-12} = 0b0000;
619 let Inst{19-16} = Rn;
622 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
623 opc, "\t$Rn, $shift",
624 [(opnode GPR:$Rn, so_reg:$shift)]> {
628 let Inst{11-0} = shift;
629 let Inst{15-12} = 0b0000;
630 let Inst{19-16} = Rn;
636 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
637 /// register and one whose operand is a register rotated by 8/16/24.
638 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
639 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
640 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
641 IIC_iEXTr, opc, "\t$Rd, $Rm",
642 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
643 Requires<[IsARM, HasV6]> {
646 let Inst{15-12} = Rd;
648 let Inst{11-10} = 0b00;
649 let Inst{19-16} = 0b1111;
651 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
652 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
653 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
654 Requires<[IsARM, HasV6]> {
658 let Inst{15-12} = Rd;
659 let Inst{11-10} = rot;
661 let Inst{19-16} = 0b1111;
665 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
666 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
667 IIC_iEXTr, opc, "\t$Rd, $Rm",
668 [/* For disassembly only; pattern left blank */]>,
669 Requires<[IsARM, HasV6]> {
670 let Inst{11-10} = 0b00;
671 let Inst{19-16} = 0b1111;
673 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
674 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
675 [/* For disassembly only; pattern left blank */]>,
676 Requires<[IsARM, HasV6]> {
678 let Inst{11-10} = rot;
679 let Inst{19-16} = 0b1111;
683 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
684 /// register and one whose operand is a register rotated by 8/16/24.
685 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
686 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
687 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
688 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
689 Requires<[IsARM, HasV6]> {
690 let Inst{11-10} = 0b00;
692 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
694 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
695 [(set GPR:$Rd, (opnode GPR:$Rn,
696 (rotr GPR:$Rm, rot_imm:$rot)))]>,
697 Requires<[IsARM, HasV6]> {
700 let Inst{19-16} = Rn;
701 let Inst{11-10} = rot;
705 // For disassembly only.
706 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
707 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
708 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
709 [/* For disassembly only; pattern left blank */]>,
710 Requires<[IsARM, HasV6]> {
711 let Inst{11-10} = 0b00;
713 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
715 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
716 [/* For disassembly only; pattern left blank */]>,
717 Requires<[IsARM, HasV6]> {
720 let Inst{19-16} = Rn;
721 let Inst{11-10} = rot;
725 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
726 let Uses = [CPSR] in {
727 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
728 bit Commutable = 0> {
729 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
730 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
731 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
737 let Inst{15-12} = Rd;
738 let Inst{19-16} = Rn;
739 let Inst{11-0} = imm;
741 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
742 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
743 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
748 let Inst{11-4} = 0b00000000;
750 let isCommutable = Commutable;
752 let Inst{15-12} = Rd;
753 let Inst{19-16} = Rn;
755 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
756 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
757 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
763 let Inst{11-0} = shift;
764 let Inst{15-12} = Rd;
765 let Inst{19-16} = Rn;
768 // Carry setting variants
769 let Defs = [CPSR] in {
770 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
771 bit Commutable = 0> {
772 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
773 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
774 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
779 let Inst{15-12} = Rd;
780 let Inst{19-16} = Rn;
781 let Inst{11-0} = imm;
785 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
786 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
787 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
792 let Inst{11-4} = 0b00000000;
793 let isCommutable = Commutable;
795 let Inst{15-12} = Rd;
796 let Inst{19-16} = Rn;
800 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
801 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
802 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
807 let Inst{11-0} = shift;
808 let Inst{15-12} = Rd;
809 let Inst{19-16} = Rn;
817 let canFoldAsLoad = 1, isReMaterializable = 1 in {
818 multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
819 InstrItinClass iir, PatFrag opnode> {
820 // Note: We use the complex addrmode_imm12 rather than just an input
821 // GPR and a constrained immediate so that we can use this to match
822 // frame index references and avoid matching constant pool references.
823 def i12 : AIldst1<0b010, opc22, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
824 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
825 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
828 let Inst{23} = addr{12}; // U (add = ('U' == 1))
829 let Inst{19-16} = addr{16-13}; // Rn
830 let Inst{15-12} = Rt;
831 let Inst{11-0} = addr{11-0}; // imm12
833 def rs : AIldst1<0b011, opc22, 1, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
834 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
835 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
838 let Inst{23} = shift{12}; // U (add = ('U' == 1))
839 let Inst{19-16} = shift{16-13}; // Rn
840 let Inst{11-0} = shift{11-0};
845 multiclass AI_str1<bit opc22, string opc, InstrItinClass iii,
846 InstrItinClass iir, PatFrag opnode> {
847 // Note: We use the complex addrmode_imm12 rather than just an input
848 // GPR and a constrained immediate so that we can use this to match
849 // frame index references and avoid matching constant pool references.
850 def i12 : AIldst1<0b010, opc22, 0, (outs),
851 (ins GPR:$Rt, addrmode_imm12:$addr),
852 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
853 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
856 let Inst{23} = addr{12}; // U (add = ('U' == 1))
857 let Inst{19-16} = addr{16-13}; // Rn
858 let Inst{15-12} = Rt;
859 let Inst{11-0} = addr{11-0}; // imm12
861 def rs : AIldst1<0b011, opc22, 0, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
862 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
863 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
866 let Inst{23} = shift{12}; // U (add = ('U' == 1))
867 let Inst{19-16} = shift{16-13}; // Rn
868 let Inst{11-0} = shift{11-0};
871 //===----------------------------------------------------------------------===//
873 //===----------------------------------------------------------------------===//
875 //===----------------------------------------------------------------------===//
876 // Miscellaneous Instructions.
879 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
880 /// the function. The first operand is the ID# for this instruction, the second
881 /// is the index into the MachineConstantPool that this is, the third is the
882 /// size in bytes of this constant pool entry.
883 let neverHasSideEffects = 1, isNotDuplicable = 1 in
884 def CONSTPOOL_ENTRY :
885 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
886 i32imm:$size), NoItinerary, "", []>;
888 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
889 // from removing one half of the matched pairs. That breaks PEI, which assumes
890 // these will always be in pairs, and asserts if it finds otherwise. Better way?
891 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
893 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
894 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
896 def ADJCALLSTACKDOWN :
897 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
898 [(ARMcallseq_start timm:$amt)]>;
901 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
902 [/* For disassembly only; pattern left blank */]>,
903 Requires<[IsARM, HasV6T2]> {
904 let Inst{27-16} = 0b001100100000;
905 let Inst{15-8} = 0b11110000;
906 let Inst{7-0} = 0b00000000;
909 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
910 [/* For disassembly only; pattern left blank */]>,
911 Requires<[IsARM, HasV6T2]> {
912 let Inst{27-16} = 0b001100100000;
913 let Inst{15-8} = 0b11110000;
914 let Inst{7-0} = 0b00000001;
917 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
918 [/* For disassembly only; pattern left blank */]>,
919 Requires<[IsARM, HasV6T2]> {
920 let Inst{27-16} = 0b001100100000;
921 let Inst{15-8} = 0b11110000;
922 let Inst{7-0} = 0b00000010;
925 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
926 [/* For disassembly only; pattern left blank */]>,
927 Requires<[IsARM, HasV6T2]> {
928 let Inst{27-16} = 0b001100100000;
929 let Inst{15-8} = 0b11110000;
930 let Inst{7-0} = 0b00000011;
933 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
935 [/* For disassembly only; pattern left blank */]>,
936 Requires<[IsARM, HasV6]> {
941 let Inst{15-12} = Rd;
942 let Inst{19-16} = Rn;
943 let Inst{27-20} = 0b01101000;
944 let Inst{7-4} = 0b1011;
945 let Inst{11-8} = 0b1111;
948 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
949 [/* For disassembly only; pattern left blank */]>,
950 Requires<[IsARM, HasV6T2]> {
951 let Inst{27-16} = 0b001100100000;
952 let Inst{15-8} = 0b11110000;
953 let Inst{7-0} = 0b00000100;
956 // The i32imm operand $val can be used by a debugger to store more information
957 // about the breakpoint.
958 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
959 [/* For disassembly only; pattern left blank */]>,
962 let Inst{3-0} = val{3-0};
963 let Inst{19-8} = val{15-4};
964 let Inst{27-20} = 0b00010010;
965 let Inst{7-4} = 0b0111;
968 // Change Processor State is a system instruction -- for disassembly only.
969 // The singleton $opt operand contains the following information:
970 // opt{4-0} = mode from Inst{4-0}
971 // opt{5} = changemode from Inst{17}
972 // opt{8-6} = AIF from Inst{8-6}
973 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
974 // FIXME: Integrated assembler will need these split out.
975 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
976 [/* For disassembly only; pattern left blank */]>,
978 let Inst{31-28} = 0b1111;
979 let Inst{27-20} = 0b00010000;
984 // Preload signals the memory system of possible future data/instruction access.
985 // These are for disassembly only.
987 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
988 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
989 multiclass APreLoad<bit data, bit read, string opc> {
991 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
992 !strconcat(opc, "\t[$base, $imm]"), []> {
993 let Inst{31-26} = 0b111101;
994 let Inst{25} = 0; // 0 for immediate form
997 let Inst{21-20} = 0b01;
1000 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
1001 !strconcat(opc, "\t$addr"), []> {
1002 let Inst{31-26} = 0b111101;
1003 let Inst{25} = 1; // 1 for register form
1004 let Inst{24} = data;
1005 let Inst{22} = read;
1006 let Inst{21-20} = 0b01;
1011 defm PLD : APreLoad<1, 1, "pld">;
1012 defm PLDW : APreLoad<1, 0, "pldw">;
1013 defm PLI : APreLoad<0, 1, "pli">;
1015 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1017 [/* For disassembly only; pattern left blank */]>,
1020 let Inst{31-10} = 0b1111000100000001000000;
1025 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1026 [/* For disassembly only; pattern left blank */]>,
1027 Requires<[IsARM, HasV7]> {
1029 let Inst{27-4} = 0b001100100000111100001111;
1030 let Inst{3-0} = opt;
1033 // A5.4 Permanently UNDEFINED instructions.
1034 let isBarrier = 1, isTerminator = 1 in
1035 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1038 let Inst{27-25} = 0b011;
1039 let Inst{24-20} = 0b11111;
1040 let Inst{7-5} = 0b111;
1044 // Address computation and loads and stores in PIC mode.
1045 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1046 // classes (AXI1, et.al.) and so have encoding information and such,
1047 // which is suboptimal. Once the rest of the code emitter (including
1048 // JIT) is MC-ized we should look at refactoring these into true
1050 let isNotDuplicable = 1 in {
1051 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1052 Pseudo, IIC_iALUr, "",
1053 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1055 let AddedComplexity = 10 in {
1056 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1057 Pseudo, IIC_iLoad_r, "",
1058 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1060 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1061 Pseudo, IIC_iLoad_bh_r, "",
1062 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1064 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1065 Pseudo, IIC_iLoad_bh_r, "",
1066 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1068 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1069 Pseudo, IIC_iLoad_bh_r, "",
1070 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1072 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1073 Pseudo, IIC_iLoad_bh_r, "",
1074 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1076 let AddedComplexity = 10 in {
1077 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1078 Pseudo, IIC_iStore_r, "",
1079 [(store GPR:$src, addrmodepc:$addr)]>;
1081 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1082 Pseudo, IIC_iStore_bh_r, "",
1083 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1085 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1086 Pseudo, IIC_iStore_bh_r, "",
1087 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1089 } // isNotDuplicable = 1
1092 // LEApcrel - Load a pc-relative address into a register without offending the
1094 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1095 // the ADR instruction. Is this the right way to handle that? They need
1096 // encoding information regardless.
1097 let neverHasSideEffects = 1 in {
1098 let isReMaterializable = 1 in
1099 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1101 "adr$p\t$dst, #$label", []>;
1103 } // neverHasSideEffects
1104 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1105 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1107 "adr$p\t$dst, #${label}_${id}", []> {
1111 //===----------------------------------------------------------------------===//
1112 // Control Flow Instructions.
1115 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1117 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1118 "bx", "\tlr", [(ARMretflag)]>,
1119 Requires<[IsARM, HasV4T]> {
1120 let Inst{27-0} = 0b0001001011111111111100011110;
1124 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1125 "mov", "\tpc, lr", [(ARMretflag)]>,
1126 Requires<[IsARM, NoV4T]> {
1127 let Inst{27-0} = 0b0001101000001111000000001110;
1131 // Indirect branches
1132 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1134 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1135 [(brind GPR:$dst)]>,
1136 Requires<[IsARM, HasV4T]> {
1138 let Inst{31-4} = 0b1110000100101111111111110001;
1139 let Inst{3-0} = dst;
1143 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1144 [(brind GPR:$dst)]>,
1145 Requires<[IsARM, NoV4T]> {
1147 let Inst{31-4} = 0b1110000110100000111100000000;
1148 let Inst{3-0} = dst;
1152 // FIXME: remove when we have a way to marking a MI with these properties.
1153 // FIXME: Should pc be an implicit operand like PICADD, etc?
1154 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1155 hasExtraDefRegAllocReq = 1 in
1156 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1157 reglist:$dsts, variable_ops),
1158 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1159 "ldm${addr:submode}${p}\t$addr!, $dsts",
1160 "$addr.addr = $wb", []>;
1162 // On non-Darwin platforms R9 is callee-saved.
1164 Defs = [R0, R1, R2, R3, R12, LR,
1165 D0, D1, D2, D3, D4, D5, D6, D7,
1166 D16, D17, D18, D19, D20, D21, D22, D23,
1167 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1168 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1169 IIC_Br, "bl\t$func",
1170 [(ARMcall tglobaladdr:$func)]>,
1171 Requires<[IsARM, IsNotDarwin]> {
1172 let Inst{31-28} = 0b1110;
1173 // FIXME: Encoding info for $func. Needs fixups bits.
1176 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1177 IIC_Br, "bl", "\t$func",
1178 [(ARMcall_pred tglobaladdr:$func)]>,
1179 Requires<[IsARM, IsNotDarwin]>;
1182 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1183 IIC_Br, "blx\t$func",
1184 [(ARMcall GPR:$func)]>,
1185 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1187 let Inst{27-4} = 0b000100101111111111110011;
1188 let Inst{3-0} = func;
1192 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1193 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1194 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1195 [(ARMcall_nolink tGPR:$func)]>,
1196 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1198 let Inst{27-4} = 0b000100101111111111110001;
1199 let Inst{3-0} = func;
1203 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1204 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1205 [(ARMcall_nolink tGPR:$func)]>,
1206 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1208 let Inst{27-4} = 0b000110100000111100000000;
1209 let Inst{3-0} = func;
1213 // On Darwin R9 is call-clobbered.
1215 Defs = [R0, R1, R2, R3, R9, R12, LR,
1216 D0, D1, D2, D3, D4, D5, D6, D7,
1217 D16, D17, D18, D19, D20, D21, D22, D23,
1218 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1219 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1220 IIC_Br, "bl\t$func",
1221 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1222 let Inst{31-28} = 0b1110;
1223 // FIXME: Encoding info for $func. Needs fixups bits.
1226 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1227 IIC_Br, "bl", "\t$func",
1228 [(ARMcall_pred tglobaladdr:$func)]>,
1229 Requires<[IsARM, IsDarwin]>;
1232 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1233 IIC_Br, "blx\t$func",
1234 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1236 let Inst{27-4} = 0b000100101111111111110011;
1237 let Inst{3-0} = func;
1241 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1242 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1243 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1244 [(ARMcall_nolink tGPR:$func)]>,
1245 Requires<[IsARM, HasV4T, IsDarwin]> {
1247 let Inst{27-4} = 0b000100101111111111110001;
1248 let Inst{3-0} = func;
1252 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1253 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1254 [(ARMcall_nolink tGPR:$func)]>,
1255 Requires<[IsARM, NoV4T, IsDarwin]> {
1257 let Inst{27-4} = 0b000110100000111100000000;
1258 let Inst{3-0} = func;
1264 // FIXME: These should probably be xformed into the non-TC versions of the
1265 // instructions as part of MC lowering.
1266 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1268 let Defs = [R0, R1, R2, R3, R9, R12,
1269 D0, D1, D2, D3, D4, D5, D6, D7,
1270 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1271 D27, D28, D29, D30, D31, PC],
1273 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1275 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1277 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1279 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1281 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1282 IIC_Br, "b\t$dst @ TAILCALL",
1283 []>, Requires<[IsDarwin]>;
1285 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1286 IIC_Br, "b.w\t$dst @ TAILCALL",
1287 []>, Requires<[IsDarwin]>;
1289 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1290 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1291 []>, Requires<[IsDarwin]> {
1293 let Inst{31-4} = 0b1110000100101111111111110001;
1294 let Inst{3-0} = dst;
1298 // Non-Darwin versions (the difference is R9).
1299 let Defs = [R0, R1, R2, R3, 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 TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1306 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1308 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1310 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1312 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1313 IIC_Br, "b\t$dst @ TAILCALL",
1314 []>, Requires<[IsARM, IsNotDarwin]>;
1316 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1317 IIC_Br, "b.w\t$dst @ TAILCALL",
1318 []>, Requires<[IsThumb, IsNotDarwin]>;
1320 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1321 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1322 []>, Requires<[IsNotDarwin]> {
1324 let Inst{31-4} = 0b1110000100101111111111110001;
1325 let Inst{3-0} = dst;
1330 let isBranch = 1, isTerminator = 1 in {
1331 // B is "predicable" since it can be xformed into a Bcc.
1332 let isBarrier = 1 in {
1333 let isPredicable = 1 in
1334 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1335 "b\t$target", [(br bb:$target)]>;
1337 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1338 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1339 IIC_Br, "mov\tpc, $target$jt",
1340 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1341 let Inst{11-4} = 0b00000000;
1342 let Inst{15-12} = 0b1111;
1343 let Inst{20} = 0; // S Bit
1344 let Inst{24-21} = 0b1101;
1345 let Inst{27-25} = 0b000;
1347 def BR_JTm : JTI<(outs),
1348 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1349 IIC_Br, "ldr\tpc, $target$jt",
1350 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1352 let Inst{15-12} = 0b1111;
1353 let Inst{20} = 1; // L bit
1354 let Inst{21} = 0; // W bit
1355 let Inst{22} = 0; // B bit
1356 let Inst{24} = 1; // P bit
1357 let Inst{27-25} = 0b011;
1359 def BR_JTadd : JTI<(outs),
1360 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1361 IIC_Br, "add\tpc, $target, $idx$jt",
1362 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1364 let Inst{15-12} = 0b1111;
1365 let Inst{20} = 0; // S bit
1366 let Inst{24-21} = 0b0100;
1367 let Inst{27-25} = 0b000;
1369 } // isNotDuplicable = 1, isIndirectBranch = 1
1372 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1373 // a two-value operand where a dag node expects two operands. :(
1374 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1375 IIC_Br, "b", "\t$target",
1376 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1379 // Branch and Exchange Jazelle -- for disassembly only
1380 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1381 [/* For disassembly only; pattern left blank */]> {
1382 let Inst{23-20} = 0b0010;
1383 //let Inst{19-8} = 0xfff;
1384 let Inst{7-4} = 0b0010;
1387 // Secure Monitor Call is a system instruction -- for disassembly only
1388 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1389 [/* For disassembly only; pattern left blank */]> {
1391 let Inst{23-4} = 0b01100000000000000111;
1392 let Inst{3-0} = opt;
1395 // Supervisor Call (Software Interrupt) -- for disassembly only
1397 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1398 [/* For disassembly only; pattern left blank */]> {
1400 let Inst{23-0} = svc;
1404 // Store Return State is a system instruction -- for disassembly only
1405 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1406 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1407 [/* For disassembly only; pattern left blank */]> {
1408 let Inst{31-28} = 0b1111;
1409 let Inst{22-20} = 0b110; // W = 1
1412 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1413 NoItinerary, "srs${addr:submode}\tsp, $mode",
1414 [/* For disassembly only; pattern left blank */]> {
1415 let Inst{31-28} = 0b1111;
1416 let Inst{22-20} = 0b100; // W = 0
1419 // Return From Exception is a system instruction -- for disassembly only
1420 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1421 NoItinerary, "rfe${addr:submode}\t$base!",
1422 [/* For disassembly only; pattern left blank */]> {
1423 let Inst{31-28} = 0b1111;
1424 let Inst{22-20} = 0b011; // W = 1
1427 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1428 NoItinerary, "rfe${addr:submode}\t$base",
1429 [/* For disassembly only; pattern left blank */]> {
1430 let Inst{31-28} = 0b1111;
1431 let Inst{22-20} = 0b001; // W = 0
1434 //===----------------------------------------------------------------------===//
1435 // Load / store Instructions.
1441 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1442 UnOpFrag<(load node:$Src)>>;
1443 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1444 UnOpFrag<(zextloadi8 node:$Src)>>;
1445 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1446 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1447 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1448 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1450 // Special LDR for loads from non-pc-relative constpools.
1451 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1452 isReMaterializable = 1 in
1453 def LDRcp : AIldst1<0b010, 0, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1454 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> {
1457 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1458 let Inst{19-16} = 0b1111;
1459 let Inst{15-12} = Rt;
1460 let Inst{11-0} = addr{11-0}; // imm12
1463 // Loads with zero extension
1464 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1465 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1466 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1468 // Loads with sign extension
1469 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1470 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1471 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1473 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1474 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1475 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1477 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1479 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1480 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1481 []>, Requires<[IsARM, HasV5TE]>;
1484 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1485 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1486 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1488 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1489 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1490 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1492 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1493 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1494 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1496 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1497 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1498 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1500 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1501 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1502 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1504 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1505 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1506 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1508 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1509 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1510 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1512 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1513 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1514 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1516 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1517 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1518 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1520 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1521 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1522 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1524 // For disassembly only
1525 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1526 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1527 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1528 Requires<[IsARM, HasV5TE]>;
1530 // For disassembly only
1531 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1532 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1533 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1534 Requires<[IsARM, HasV5TE]>;
1536 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1538 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1540 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1541 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1542 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1543 let Inst{21} = 1; // overwrite
1546 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1547 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1548 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1549 let Inst{21} = 1; // overwrite
1552 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1553 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1554 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1555 let Inst{21} = 1; // overwrite
1558 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1559 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1560 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1561 let Inst{21} = 1; // overwrite
1564 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1565 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1566 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1567 let Inst{21} = 1; // overwrite
1572 // Stores with truncate
1573 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1574 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1575 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1578 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1579 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1580 StMiscFrm, IIC_iStore_d_r,
1581 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1584 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1585 (ins GPR:$src, GPR:$base, am2offset:$offset),
1586 StFrm, IIC_iStore_ru,
1587 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1589 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1591 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1592 (ins GPR:$src, GPR:$base,am2offset:$offset),
1593 StFrm, IIC_iStore_ru,
1594 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1596 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1598 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1599 (ins GPR:$src, GPR:$base,am3offset:$offset),
1600 StMiscFrm, IIC_iStore_ru,
1601 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1603 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1605 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1606 (ins GPR:$src, GPR:$base,am3offset:$offset),
1607 StMiscFrm, IIC_iStore_bh_ru,
1608 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1609 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1610 GPR:$base, am3offset:$offset))]>;
1612 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1613 (ins GPR:$src, GPR:$base,am2offset:$offset),
1614 StFrm, IIC_iStore_bh_ru,
1615 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1616 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1617 GPR:$base, am2offset:$offset))]>;
1619 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1620 (ins GPR:$src, GPR:$base,am2offset:$offset),
1621 StFrm, IIC_iStore_bh_ru,
1622 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1623 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1624 GPR:$base, am2offset:$offset))]>;
1626 // For disassembly only
1627 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1628 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1629 StMiscFrm, IIC_iStore_d_ru,
1630 "strd", "\t$src1, $src2, [$base, $offset]!",
1631 "$base = $base_wb", []>;
1633 // For disassembly only
1634 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1635 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1636 StMiscFrm, IIC_iStore_d_ru,
1637 "strd", "\t$src1, $src2, [$base], $offset",
1638 "$base = $base_wb", []>;
1640 // STRT, STRBT, and STRHT are for disassembly only.
1642 def STRT : AI2stwpo<(outs GPR:$base_wb),
1643 (ins GPR:$src, GPR:$base,am2offset:$offset),
1644 StFrm, IIC_iStore_ru,
1645 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1646 [/* For disassembly only; pattern left blank */]> {
1647 let Inst{21} = 1; // overwrite
1650 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1651 (ins GPR:$src, GPR:$base,am2offset:$offset),
1652 StFrm, IIC_iStore_bh_ru,
1653 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1654 [/* For disassembly only; pattern left blank */]> {
1655 let Inst{21} = 1; // overwrite
1658 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1659 (ins GPR:$src, GPR:$base,am3offset:$offset),
1660 StMiscFrm, IIC_iStore_bh_ru,
1661 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1662 [/* For disassembly only; pattern left blank */]> {
1663 let Inst{21} = 1; // overwrite
1666 //===----------------------------------------------------------------------===//
1667 // Load / store multiple Instructions.
1670 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1671 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1672 reglist:$dsts, variable_ops),
1673 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1674 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1676 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1677 reglist:$dsts, variable_ops),
1678 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1679 "ldm${addr:submode}${p}\t$addr!, $dsts",
1680 "$addr.addr = $wb", []>;
1681 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1683 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1684 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1685 reglist:$srcs, variable_ops),
1686 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1687 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1689 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1690 reglist:$srcs, variable_ops),
1691 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1692 "stm${addr:submode}${p}\t$addr!, $srcs",
1693 "$addr.addr = $wb", []>;
1694 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1696 //===----------------------------------------------------------------------===//
1697 // Move Instructions.
1700 let neverHasSideEffects = 1 in
1701 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1702 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1706 let Inst{11-4} = 0b00000000;
1709 let Inst{15-12} = Rd;
1712 // A version for the smaller set of tail call registers.
1713 let neverHasSideEffects = 1 in
1714 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1715 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1719 let Inst{11-4} = 0b00000000;
1722 let Inst{15-12} = Rd;
1725 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1726 DPSoRegFrm, IIC_iMOVsr,
1727 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1731 let Inst{15-12} = Rd;
1732 let Inst{11-0} = src;
1736 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1737 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1738 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1742 let Inst{15-12} = Rd;
1743 let Inst{19-16} = 0b0000;
1744 let Inst{11-0} = imm;
1747 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1748 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1750 "movw", "\t$Rd, $imm",
1751 [(set GPR:$Rd, imm0_65535:$imm)]>,
1752 Requires<[IsARM, HasV6T2]>, UnaryDP {
1755 let Inst{15-12} = Rd;
1756 let Inst{11-0} = imm{11-0};
1757 let Inst{19-16} = imm{15-12};
1762 let Constraints = "$src = $Rd" in
1763 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1765 "movt", "\t$Rd, $imm",
1767 (or (and GPR:$src, 0xffff),
1768 lo16AllZero:$imm))]>, UnaryDP,
1769 Requires<[IsARM, HasV6T2]> {
1772 let Inst{15-12} = Rd;
1773 let Inst{11-0} = imm{11-0};
1774 let Inst{19-16} = imm{15-12};
1779 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1780 Requires<[IsARM, HasV6T2]>;
1782 let Uses = [CPSR] in
1783 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1784 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1787 // These aren't really mov instructions, but we have to define them this way
1788 // due to flag operands.
1790 let Defs = [CPSR] in {
1791 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1792 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1794 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1795 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1799 //===----------------------------------------------------------------------===//
1800 // Extend Instructions.
1805 defm SXTB : AI_ext_rrot<0b01101010,
1806 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1807 defm SXTH : AI_ext_rrot<0b01101011,
1808 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1810 defm SXTAB : AI_exta_rrot<0b01101010,
1811 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1812 defm SXTAH : AI_exta_rrot<0b01101011,
1813 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1815 // For disassembly only
1816 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1818 // For disassembly only
1819 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1823 let AddedComplexity = 16 in {
1824 defm UXTB : AI_ext_rrot<0b01101110,
1825 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1826 defm UXTH : AI_ext_rrot<0b01101111,
1827 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1828 defm UXTB16 : AI_ext_rrot<0b01101100,
1829 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1831 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1832 // The transformation should probably be done as a combiner action
1833 // instead so we can include a check for masking back in the upper
1834 // eight bits of the source into the lower eight bits of the result.
1835 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1836 // (UXTB16r_rot GPR:$Src, 24)>;
1837 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1838 (UXTB16r_rot GPR:$Src, 8)>;
1840 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1841 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1842 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1843 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1846 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1847 // For disassembly only
1848 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1851 def SBFX : I<(outs GPR:$Rd),
1852 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1853 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1854 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1855 Requires<[IsARM, HasV6T2]> {
1860 let Inst{27-21} = 0b0111101;
1861 let Inst{6-4} = 0b101;
1862 let Inst{20-16} = width;
1863 let Inst{15-12} = Rd;
1864 let Inst{11-7} = lsb;
1868 def UBFX : I<(outs GPR:$Rd),
1869 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1870 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1871 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1872 Requires<[IsARM, HasV6T2]> {
1877 let Inst{27-21} = 0b0111111;
1878 let Inst{6-4} = 0b101;
1879 let Inst{20-16} = width;
1880 let Inst{15-12} = Rd;
1881 let Inst{11-7} = lsb;
1885 //===----------------------------------------------------------------------===//
1886 // Arithmetic Instructions.
1889 defm ADD : AsI1_bin_irs<0b0100, "add",
1890 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1891 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1892 defm SUB : AsI1_bin_irs<0b0010, "sub",
1893 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1894 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1896 // ADD and SUB with 's' bit set.
1897 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1898 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1899 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1900 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1901 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1902 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1904 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1905 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1906 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1907 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1908 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1909 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1910 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1911 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1913 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1914 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
1915 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
1920 let Inst{15-12} = Rd;
1921 let Inst{19-16} = Rn;
1922 let Inst{11-0} = imm;
1925 // The reg/reg form is only defined for the disassembler; for codegen it is
1926 // equivalent to SUBrr.
1927 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1928 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
1929 [/* For disassembly only; pattern left blank */]> {
1933 let Inst{11-4} = 0b00000000;
1936 let Inst{15-12} = Rd;
1937 let Inst{19-16} = Rn;
1940 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1941 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
1942 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
1947 let Inst{11-0} = shift;
1948 let Inst{15-12} = Rd;
1949 let Inst{19-16} = Rn;
1952 // RSB with 's' bit set.
1953 let Defs = [CPSR] in {
1954 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1955 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
1956 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
1962 let Inst{15-12} = Rd;
1963 let Inst{19-16} = Rn;
1964 let Inst{11-0} = imm;
1966 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1967 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
1968 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
1974 let Inst{11-0} = shift;
1975 let Inst{15-12} = Rd;
1976 let Inst{19-16} = Rn;
1980 let Uses = [CPSR] in {
1981 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
1982 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
1983 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
1989 let Inst{15-12} = Rd;
1990 let Inst{19-16} = Rn;
1991 let Inst{11-0} = imm;
1993 // The reg/reg form is only defined for the disassembler; for codegen it is
1994 // equivalent to SUBrr.
1995 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1996 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
1997 [/* For disassembly only; pattern left blank */]> {
2001 let Inst{11-4} = 0b00000000;
2004 let Inst{15-12} = Rd;
2005 let Inst{19-16} = Rn;
2007 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2008 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2009 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2015 let Inst{11-0} = shift;
2016 let Inst{15-12} = Rd;
2017 let Inst{19-16} = Rn;
2021 // FIXME: Allow these to be predicated.
2022 let Defs = [CPSR], Uses = [CPSR] in {
2023 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2024 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2025 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2032 let Inst{15-12} = Rd;
2033 let Inst{19-16} = Rn;
2034 let Inst{11-0} = imm;
2036 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2037 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2038 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2045 let Inst{11-0} = shift;
2046 let Inst{15-12} = Rd;
2047 let Inst{19-16} = Rn;
2051 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2052 // The assume-no-carry-in form uses the negation of the input since add/sub
2053 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2054 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2056 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2057 (SUBri GPR:$src, so_imm_neg:$imm)>;
2058 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2059 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2060 // The with-carry-in form matches bitwise not instead of the negation.
2061 // Effectively, the inverse interpretation of the carry flag already accounts
2062 // for part of the negation.
2063 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2064 (SBCri GPR:$src, so_imm_not:$imm)>;
2066 // Note: These are implemented in C++ code, because they have to generate
2067 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2069 // (mul X, 2^n+1) -> (add (X << n), X)
2070 // (mul X, 2^n-1) -> (rsb X, (X << n))
2072 // ARM Arithmetic Instruction -- for disassembly only
2073 // GPR:$dst = GPR:$a op GPR:$b
2074 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2075 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2076 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2077 opc, "\t$Rd, $Rn, $Rm", pattern> {
2081 let Inst{27-20} = op27_20;
2082 let Inst{11-4} = op11_4;
2083 let Inst{19-16} = Rn;
2084 let Inst{15-12} = Rd;
2088 // Saturating add/subtract -- for disassembly only
2090 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2091 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2092 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2093 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2094 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2095 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2097 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2098 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2099 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2100 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2101 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2102 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2103 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2104 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2105 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2106 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2107 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2108 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2110 // Signed/Unsigned add/subtract -- for disassembly only
2112 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2113 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2114 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2115 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2116 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2117 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2118 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2119 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2120 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2121 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2122 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2123 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2125 // Signed/Unsigned halving add/subtract -- for disassembly only
2127 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2128 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2129 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2130 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2131 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2132 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2133 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2134 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2135 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2136 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2137 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2138 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2140 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2142 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2143 MulFrm /* for convenience */, NoItinerary, "usad8",
2144 "\t$Rd, $Rn, $Rm", []>,
2145 Requires<[IsARM, HasV6]> {
2149 let Inst{27-20} = 0b01111000;
2150 let Inst{15-12} = 0b1111;
2151 let Inst{7-4} = 0b0001;
2152 let Inst{19-16} = Rd;
2153 let Inst{11-8} = Rm;
2156 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2157 MulFrm /* for convenience */, NoItinerary, "usada8",
2158 "\t$Rd, $Rn, $Rm, $Ra", []>,
2159 Requires<[IsARM, HasV6]> {
2164 let Inst{27-20} = 0b01111000;
2165 let Inst{7-4} = 0b0001;
2166 let Inst{19-16} = Rd;
2167 let Inst{15-12} = Ra;
2168 let Inst{11-8} = Rm;
2172 // Signed/Unsigned saturate -- for disassembly only
2174 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2175 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2176 [/* For disassembly only; pattern left blank */]> {
2181 let Inst{27-21} = 0b0110101;
2182 let Inst{5-4} = 0b01;
2183 let Inst{20-16} = sat_imm;
2184 let Inst{15-12} = Rd;
2185 let Inst{11-7} = sh{7-3};
2186 let Inst{6} = sh{0};
2190 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2191 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2192 [/* For disassembly only; pattern left blank */]> {
2196 let Inst{27-20} = 0b01101010;
2197 let Inst{11-4} = 0b11110011;
2198 let Inst{15-12} = Rd;
2199 let Inst{19-16} = sat_imm;
2203 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2204 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2205 [/* For disassembly only; pattern left blank */]> {
2210 let Inst{27-21} = 0b0110111;
2211 let Inst{5-4} = 0b01;
2212 let Inst{15-12} = Rd;
2213 let Inst{11-7} = sh{7-3};
2214 let Inst{6} = sh{0};
2215 let Inst{20-16} = sat_imm;
2219 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2220 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2221 [/* For disassembly only; pattern left blank */]> {
2225 let Inst{27-20} = 0b01101110;
2226 let Inst{11-4} = 0b11110011;
2227 let Inst{15-12} = Rd;
2228 let Inst{19-16} = sat_imm;
2232 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2233 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2235 //===----------------------------------------------------------------------===//
2236 // Bitwise Instructions.
2239 defm AND : AsI1_bin_irs<0b0000, "and",
2240 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2241 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2242 defm ORR : AsI1_bin_irs<0b1100, "orr",
2243 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2244 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2245 defm EOR : AsI1_bin_irs<0b0001, "eor",
2246 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2247 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2248 defm BIC : AsI1_bin_irs<0b1110, "bic",
2249 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2250 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2252 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2253 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2254 "bfc", "\t$Rd, $imm", "$src = $Rd",
2255 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2256 Requires<[IsARM, HasV6T2]> {
2259 let Inst{27-21} = 0b0111110;
2260 let Inst{6-0} = 0b0011111;
2261 let Inst{15-12} = Rd;
2262 let Inst{11-7} = imm{4-0}; // lsb
2263 let Inst{20-16} = imm{9-5}; // width
2266 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2267 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2268 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2269 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2270 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2271 bf_inv_mask_imm:$imm))]>,
2272 Requires<[IsARM, HasV6T2]> {
2276 let Inst{27-21} = 0b0111110;
2277 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2278 let Inst{15-12} = Rd;
2279 let Inst{11-7} = imm{4-0}; // lsb
2280 let Inst{20-16} = imm{9-5}; // width
2284 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2285 "mvn", "\t$Rd, $Rm",
2286 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2290 let Inst{19-16} = 0b0000;
2291 let Inst{11-4} = 0b00000000;
2292 let Inst{15-12} = Rd;
2295 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2296 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2297 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2302 let Inst{19-16} = 0b0000;
2303 let Inst{15-12} = Rd;
2304 let Inst{11-0} = shift;
2306 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2307 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2308 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2309 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2314 let Inst{19-16} = 0b0000;
2315 let Inst{15-12} = Rd;
2316 let Inst{11-0} = imm;
2319 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2320 (BICri GPR:$src, so_imm_not:$imm)>;
2322 //===----------------------------------------------------------------------===//
2323 // Multiply Instructions.
2325 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2326 string opc, string asm, list<dag> pattern>
2327 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2331 let Inst{19-16} = Rd;
2332 let Inst{11-8} = Rm;
2335 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2336 string opc, string asm, list<dag> pattern>
2337 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2342 let Inst{19-16} = RdHi;
2343 let Inst{15-12} = RdLo;
2344 let Inst{11-8} = Rm;
2348 let isCommutable = 1 in
2349 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2350 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2351 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2353 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2354 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2355 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2357 let Inst{15-12} = Ra;
2360 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2361 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2362 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2363 Requires<[IsARM, HasV6T2]> {
2367 let Inst{19-16} = Rd;
2368 let Inst{11-8} = Rm;
2372 // Extra precision multiplies with low / high results
2374 let neverHasSideEffects = 1 in {
2375 let isCommutable = 1 in {
2376 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2377 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2378 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2380 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2381 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2382 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2385 // Multiply + accumulate
2386 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2387 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2388 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2390 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2391 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2392 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2394 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2395 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2396 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2397 Requires<[IsARM, HasV6]> {
2402 let Inst{19-16} = RdLo;
2403 let Inst{15-12} = RdHi;
2404 let Inst{11-8} = Rm;
2407 } // neverHasSideEffects
2409 // Most significant word multiply
2410 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2411 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2412 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2413 Requires<[IsARM, HasV6]> {
2414 let Inst{15-12} = 0b1111;
2417 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2418 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2419 [/* For disassembly only; pattern left blank */]>,
2420 Requires<[IsARM, HasV6]> {
2421 let Inst{15-12} = 0b1111;
2424 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2425 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2426 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2427 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2428 Requires<[IsARM, HasV6]>;
2430 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2431 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2432 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2433 [/* For disassembly only; pattern left blank */]>,
2434 Requires<[IsARM, HasV6]>;
2436 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2437 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2438 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2439 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2440 Requires<[IsARM, HasV6]>;
2442 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2443 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2444 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2445 [/* For disassembly only; pattern left blank */]>,
2446 Requires<[IsARM, HasV6]>;
2448 multiclass AI_smul<string opc, PatFrag opnode> {
2449 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2450 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2451 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2452 (sext_inreg GPR:$Rm, i16)))]>,
2453 Requires<[IsARM, HasV5TE]>;
2455 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2456 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2457 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2458 (sra GPR:$Rm, (i32 16))))]>,
2459 Requires<[IsARM, HasV5TE]>;
2461 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2462 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2463 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2464 (sext_inreg GPR:$Rm, i16)))]>,
2465 Requires<[IsARM, HasV5TE]>;
2467 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2468 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2469 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2470 (sra GPR:$Rm, (i32 16))))]>,
2471 Requires<[IsARM, HasV5TE]>;
2473 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2474 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2475 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2476 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2477 Requires<[IsARM, HasV5TE]>;
2479 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2480 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2481 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2482 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2483 Requires<[IsARM, HasV5TE]>;
2487 multiclass AI_smla<string opc, PatFrag opnode> {
2488 def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$Rd),
2489 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2490 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2491 [(set GPR:$Rd, (add GPR:$Ra,
2492 (opnode (sext_inreg GPR:$Rn, i16),
2493 (sext_inreg GPR:$Rm, i16))))]>,
2494 Requires<[IsARM, HasV5TE]>;
2496 def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$Rd),
2497 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2498 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2499 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2500 (sra GPR:$Rm, (i32 16)))))]>,
2501 Requires<[IsARM, HasV5TE]>;
2503 def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$Rd),
2504 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2505 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2506 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2507 (sext_inreg GPR:$Rm, i16))))]>,
2508 Requires<[IsARM, HasV5TE]>;
2510 def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$Rd),
2511 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2512 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2513 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2514 (sra GPR:$Rm, (i32 16)))))]>,
2515 Requires<[IsARM, HasV5TE]>;
2517 def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$Rd),
2518 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2519 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2520 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2521 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2522 Requires<[IsARM, HasV5TE]>;
2524 def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$Rd),
2525 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2526 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2527 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2528 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2529 Requires<[IsARM, HasV5TE]>;
2532 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2533 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2535 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2536 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2537 (ins GPR:$Rn, GPR:$Rm),
2538 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2539 [/* For disassembly only; pattern left blank */]>,
2540 Requires<[IsARM, HasV5TE]>;
2542 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2543 (ins GPR:$Rn, GPR:$Rm),
2544 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2545 [/* For disassembly only; pattern left blank */]>,
2546 Requires<[IsARM, HasV5TE]>;
2548 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2549 (ins GPR:$Rn, GPR:$Rm),
2550 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2551 [/* For disassembly only; pattern left blank */]>,
2552 Requires<[IsARM, HasV5TE]>;
2554 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2555 (ins GPR:$Rn, GPR:$Rm),
2556 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2557 [/* For disassembly only; pattern left blank */]>,
2558 Requires<[IsARM, HasV5TE]>;
2560 // Helper class for AI_smld -- for disassembly only
2561 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2562 InstrItinClass itin, string opc, string asm>
2563 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2570 let Inst{21-20} = 0b00;
2571 let Inst{22} = long;
2572 let Inst{27-23} = 0b01110;
2573 let Inst{11-8} = Rm;
2576 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2577 InstrItinClass itin, string opc, string asm>
2578 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2580 let Inst{15-12} = 0b1111;
2581 let Inst{19-16} = Rd;
2583 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2584 InstrItinClass itin, string opc, string asm>
2585 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2587 let Inst{15-12} = Ra;
2589 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2590 InstrItinClass itin, string opc, string asm>
2591 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2594 let Inst{19-16} = RdHi;
2595 let Inst{15-12} = RdLo;
2598 multiclass AI_smld<bit sub, string opc> {
2600 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2601 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2603 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2604 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2606 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2607 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2608 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2610 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2611 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2612 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2616 defm SMLA : AI_smld<0, "smla">;
2617 defm SMLS : AI_smld<1, "smls">;
2619 multiclass AI_sdml<bit sub, string opc> {
2621 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2622 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2623 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2624 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2627 defm SMUA : AI_sdml<0, "smua">;
2628 defm SMUS : AI_sdml<1, "smus">;
2630 //===----------------------------------------------------------------------===//
2631 // Misc. Arithmetic Instructions.
2634 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2635 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2636 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2638 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2639 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2640 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2641 Requires<[IsARM, HasV6T2]>;
2643 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2644 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2645 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2647 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2648 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2650 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2651 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2652 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2653 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2654 Requires<[IsARM, HasV6]>;
2656 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2657 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2660 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2661 (shl GPR:$Rm, (i32 8))), i16))]>,
2662 Requires<[IsARM, HasV6]>;
2664 def lsl_shift_imm : SDNodeXForm<imm, [{
2665 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2666 return CurDAG->getTargetConstant(Sh, MVT::i32);
2669 def lsl_amt : PatLeaf<(i32 imm), [{
2670 return (N->getZExtValue() < 32);
2673 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2674 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2675 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2676 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2677 (and (shl GPR:$Rm, lsl_amt:$sh),
2679 Requires<[IsARM, HasV6]>;
2681 // Alternate cases for PKHBT where identities eliminate some nodes.
2682 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2683 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2684 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2685 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2687 def asr_shift_imm : SDNodeXForm<imm, [{
2688 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2689 return CurDAG->getTargetConstant(Sh, MVT::i32);
2692 def asr_amt : PatLeaf<(i32 imm), [{
2693 return (N->getZExtValue() <= 32);
2696 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2697 // will match the pattern below.
2698 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2699 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2700 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2701 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2702 (and (sra GPR:$Rm, asr_amt:$sh),
2704 Requires<[IsARM, HasV6]>;
2706 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2707 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2708 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2709 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2710 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2711 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2712 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2714 //===----------------------------------------------------------------------===//
2715 // Comparison Instructions...
2718 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2719 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2720 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2722 // FIXME: We have to be careful when using the CMN instruction and comparison
2723 // with 0. One would expect these two pieces of code should give identical
2739 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2740 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2741 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2742 // value of r0 and the carry bit (because the "carry bit" parameter to
2743 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2744 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2745 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2746 // parameter to AddWithCarry is defined as 0).
2748 // When x is 0 and unsigned:
2752 // ~x + 1 = 0x1 0000 0000
2753 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2755 // Therefore, we should disable CMN when comparing against zero, until we can
2756 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2757 // when it's a comparison which doesn't look at the 'carry' flag).
2759 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2761 // This is related to <rdar://problem/7569620>.
2763 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2764 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2766 // Note that TST/TEQ don't set all the same flags that CMP does!
2767 defm TST : AI1_cmp_irs<0b1000, "tst",
2768 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2769 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2770 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2771 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2772 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2774 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2775 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2776 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2777 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2778 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2779 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2781 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2782 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2784 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2785 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2787 // Pseudo i64 compares for some floating point compares.
2788 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2790 def BCCi64 : PseudoInst<(outs),
2791 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2793 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2795 def BCCZi64 : PseudoInst<(outs),
2796 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2797 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2798 } // usesCustomInserter
2801 // Conditional moves
2802 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2803 // a two-value operand where a dag node expects two operands. :(
2804 // FIXME: These should all be pseudo-instructions that get expanded to
2805 // the normal MOV instructions. That would fix the dependency on
2806 // special casing them in tblgen.
2807 let neverHasSideEffects = 1 in {
2808 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2809 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2810 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2811 RegConstraint<"$false = $Rd">, UnaryDP {
2815 let Inst{11-4} = 0b00000000;
2818 let Inst{15-12} = Rd;
2819 let Inst{11-4} = 0b00000000;
2823 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2824 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2825 "mov", "\t$dst, $true",
2826 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2827 RegConstraint<"$false = $dst">, UnaryDP {
2831 def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src),
2833 "movw", "\t$dst, $src",
2835 RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>,
2841 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2842 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2843 "mov", "\t$dst, $true",
2844 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2845 RegConstraint<"$false = $dst">, UnaryDP {
2848 } // neverHasSideEffects
2850 //===----------------------------------------------------------------------===//
2851 // Atomic operations intrinsics
2854 // memory barriers protect the atomic sequences
2855 let hasSideEffects = 1 in {
2856 def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
2857 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
2858 let Inst{31-4} = 0xf57ff05;
2859 // FIXME: add support for options other than a full system DMB
2860 // See DMB disassembly-only variants below.
2861 let Inst{3-0} = 0b1111;
2864 def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
2865 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
2866 let Inst{31-4} = 0xf57ff04;
2867 // FIXME: add support for options other than a full system DSB
2868 // See DSB disassembly-only variants below.
2869 let Inst{3-0} = 0b1111;
2872 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2873 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2874 [(ARMMemBarrierMCR GPR:$zero)]>,
2875 Requires<[IsARM, HasV6]> {
2876 // FIXME: add support for options other than a full system DMB
2877 // FIXME: add encoding
2880 def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2881 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2882 [(ARMSyncBarrierMCR GPR:$zero)]>,
2883 Requires<[IsARM, HasV6]> {
2884 // FIXME: add support for options other than a full system DSB
2885 // FIXME: add encoding
2889 // Memory Barrier Operations Variants -- for disassembly only
2891 def memb_opt : Operand<i32> {
2892 let PrintMethod = "printMemBOption";
2895 class AMBI<bits<4> op7_4, string opc>
2896 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
2897 [/* For disassembly only; pattern left blank */]>,
2898 Requires<[IsARM, HasDB]> {
2899 let Inst{31-8} = 0xf57ff0;
2900 let Inst{7-4} = op7_4;
2903 // These DMB variants are for disassembly only.
2904 def DMBvar : AMBI<0b0101, "dmb">;
2906 // These DSB variants are for disassembly only.
2907 def DSBvar : AMBI<0b0100, "dsb">;
2909 // ISB has only full system option -- for disassembly only
2910 def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2911 Requires<[IsARM, HasDB]> {
2912 let Inst{31-4} = 0xf57ff06;
2913 let Inst{3-0} = 0b1111;
2916 let usesCustomInserter = 1 in {
2917 let Uses = [CPSR] in {
2918 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2919 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2920 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2921 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2922 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2923 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2924 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2925 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2926 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2927 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2928 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2929 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2930 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2931 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2932 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2933 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2934 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2935 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2936 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2937 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2938 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2939 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2940 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2941 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2942 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2943 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2944 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2945 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2946 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2947 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2948 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2949 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2950 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2951 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2952 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2953 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2954 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2955 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2956 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2957 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2958 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2959 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2960 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2961 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2962 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2963 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2964 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2965 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2966 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2967 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2968 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2969 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2970 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2971 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2973 def ATOMIC_SWAP_I8 : PseudoInst<
2974 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2975 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2976 def ATOMIC_SWAP_I16 : PseudoInst<
2977 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2978 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2979 def ATOMIC_SWAP_I32 : PseudoInst<
2980 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2981 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2983 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2984 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2985 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2986 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2987 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2988 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2989 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2990 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2991 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2995 let mayLoad = 1 in {
2996 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2997 "ldrexb", "\t$dest, [$ptr]",
2999 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
3000 "ldrexh", "\t$dest, [$ptr]",
3002 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
3003 "ldrex", "\t$dest, [$ptr]",
3005 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
3007 "ldrexd", "\t$dest, $dest2, [$ptr]",
3011 let mayStore = 1, Constraints = "@earlyclobber $success" in {
3012 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
3014 "strexb", "\t$success, $src, [$ptr]",
3016 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
3018 "strexh", "\t$success, $src, [$ptr]",
3020 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
3022 "strex", "\t$success, $src, [$ptr]",
3024 def STREXD : AIstrex<0b01, (outs GPR:$success),
3025 (ins GPR:$src, GPR:$src2, GPR:$ptr),
3027 "strexd", "\t$success, $src, $src2, [$ptr]",
3031 // Clear-Exclusive is for disassembly only.
3032 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3033 [/* For disassembly only; pattern left blank */]>,
3034 Requires<[IsARM, HasV7]> {
3035 let Inst{31-20} = 0xf57;
3036 let Inst{7-4} = 0b0001;
3039 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3040 let mayLoad = 1 in {
3041 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
3042 "swp", "\t$dst, $src, [$ptr]",
3043 [/* For disassembly only; pattern left blank */]> {
3044 let Inst{27-23} = 0b00010;
3045 let Inst{22} = 0; // B = 0
3046 let Inst{21-20} = 0b00;
3047 let Inst{7-4} = 0b1001;
3050 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
3051 "swpb", "\t$dst, $src, [$ptr]",
3052 [/* For disassembly only; pattern left blank */]> {
3053 let Inst{27-23} = 0b00010;
3054 let Inst{22} = 1; // B = 1
3055 let Inst{21-20} = 0b00;
3056 let Inst{7-4} = 0b1001;
3060 //===----------------------------------------------------------------------===//
3064 // __aeabi_read_tp preserves the registers r1-r3.
3066 Defs = [R0, R12, LR, CPSR] in {
3067 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3068 "bl\t__aeabi_read_tp",
3069 [(set R0, ARMthread_pointer)]>;
3072 //===----------------------------------------------------------------------===//
3073 // SJLJ Exception handling intrinsics
3074 // eh_sjlj_setjmp() is an instruction sequence to store the return
3075 // address and save #0 in R0 for the non-longjmp case.
3076 // Since by its nature we may be coming from some other function to get
3077 // here, and we're using the stack frame for the containing function to
3078 // save/restore registers, we can't keep anything live in regs across
3079 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3080 // when we get here from a longjmp(). We force everthing out of registers
3081 // except for our own input by listing the relevant registers in Defs. By
3082 // doing so, we also cause the prologue/epilogue code to actively preserve
3083 // all of the callee-saved resgisters, which is exactly what we want.
3084 // A constant value is passed in $val, and we use the location as a scratch.
3086 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3087 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3088 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3089 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3090 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3091 AddrModeNone, SizeSpecial, IndexModeNone,
3092 Pseudo, NoItinerary, "", "",
3093 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3094 Requires<[IsARM, HasVFP2]>;
3098 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3099 hasSideEffects = 1, isBarrier = 1 in {
3100 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3101 AddrModeNone, SizeSpecial, IndexModeNone,
3102 Pseudo, NoItinerary, "", "",
3103 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3104 Requires<[IsARM, NoVFP]>;
3107 // FIXME: Non-Darwin version(s)
3108 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3109 Defs = [ R7, LR, SP ] in {
3110 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3111 AddrModeNone, SizeSpecial, IndexModeNone,
3112 Pseudo, NoItinerary, "", "",
3113 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3114 Requires<[IsARM, IsDarwin]>;
3117 // eh.sjlj.dispatchsetup pseudo-instruction.
3118 // This pseudo is usef for ARM, Thumb1 and Thumb2. Any differences are
3119 // handled when the pseudo is expanded (which happens before any passes
3120 // that need the instruction size).
3121 let isBarrier = 1, hasSideEffects = 1 in
3122 def Int_eh_sjlj_dispatchsetup :
3123 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3124 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3125 Requires<[IsDarwin]>;
3127 //===----------------------------------------------------------------------===//
3128 // Non-Instruction Patterns
3131 // Large immediate handling.
3133 // Two piece so_imms.
3134 // FIXME: Expand this in ARMExpandPseudoInsts.
3135 // FIXME: Remove this when we can do generalized remat.
3136 let isReMaterializable = 1 in
3137 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
3138 Pseudo, IIC_iMOVix2,
3139 "mov", "\t$dst, $src",
3140 [(set GPR:$dst, so_imm2part:$src)]>,
3141 Requires<[IsARM, NoV6T2]>;
3143 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3144 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3145 (so_imm2part_2 imm:$RHS))>;
3146 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3147 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3148 (so_imm2part_2 imm:$RHS))>;
3149 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3150 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3151 (so_imm2part_2 imm:$RHS))>;
3152 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3153 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3154 (so_neg_imm2part_2 imm:$RHS))>;
3156 // 32-bit immediate using movw + movt.
3157 // This is a single pseudo instruction, the benefit is that it can be remat'd
3158 // as a single unit instead of having to handle reg inputs.
3159 // FIXME: Remove this when we can do generalized remat.
3160 let isReMaterializable = 1 in
3161 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3162 [(set GPR:$dst, (i32 imm:$src))]>,
3163 Requires<[IsARM, HasV6T2]>;
3165 // ConstantPool, GlobalAddress, and JumpTable
3166 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3167 Requires<[IsARM, DontUseMovt]>;
3168 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3169 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3170 Requires<[IsARM, UseMovt]>;
3171 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3172 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3174 // TODO: add,sub,and, 3-instr forms?
3177 def : ARMPat<(ARMtcret tcGPR:$dst),
3178 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3180 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3181 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3183 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3184 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3186 def : ARMPat<(ARMtcret tcGPR:$dst),
3187 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3189 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3190 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3192 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3193 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3196 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3197 Requires<[IsARM, IsNotDarwin]>;
3198 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3199 Requires<[IsARM, IsDarwin]>;
3201 // zextload i1 -> zextload i8
3202 //def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
3203 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3204 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3206 // extload -> zextload
3207 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3208 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3209 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3210 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3212 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3214 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3215 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3218 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3219 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3220 (SMULBB GPR:$a, GPR:$b)>;
3221 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3222 (SMULBB GPR:$a, GPR:$b)>;
3223 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3224 (sra GPR:$b, (i32 16))),
3225 (SMULBT GPR:$a, GPR:$b)>;
3226 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3227 (SMULBT GPR:$a, GPR:$b)>;
3228 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3229 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3230 (SMULTB GPR:$a, GPR:$b)>;
3231 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3232 (SMULTB GPR:$a, GPR:$b)>;
3233 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3235 (SMULWB GPR:$a, GPR:$b)>;
3236 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3237 (SMULWB GPR:$a, GPR:$b)>;
3239 def : ARMV5TEPat<(add GPR:$acc,
3240 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3241 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3242 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3243 def : ARMV5TEPat<(add GPR:$acc,
3244 (mul sext_16_node:$a, sext_16_node:$b)),
3245 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3246 def : ARMV5TEPat<(add GPR:$acc,
3247 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3248 (sra GPR:$b, (i32 16)))),
3249 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3250 def : ARMV5TEPat<(add GPR:$acc,
3251 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3252 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3253 def : ARMV5TEPat<(add GPR:$acc,
3254 (mul (sra GPR:$a, (i32 16)),
3255 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3256 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3257 def : ARMV5TEPat<(add GPR:$acc,
3258 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3259 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3260 def : ARMV5TEPat<(add GPR:$acc,
3261 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3263 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3264 def : ARMV5TEPat<(add GPR:$acc,
3265 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3266 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3268 //===----------------------------------------------------------------------===//
3272 include "ARMInstrThumb.td"
3274 //===----------------------------------------------------------------------===//
3278 include "ARMInstrThumb2.td"
3280 //===----------------------------------------------------------------------===//
3281 // Floating Point Support
3284 include "ARMInstrVFP.td"
3286 //===----------------------------------------------------------------------===//
3287 // Advanced SIMD (NEON) Support
3290 include "ARMInstrNEON.td"
3292 //===----------------------------------------------------------------------===//
3293 // Coprocessor Instructions. For disassembly only.
3296 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3297 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3298 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3299 [/* For disassembly only; pattern left blank */]> {
3303 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3304 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3305 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3306 [/* For disassembly only; pattern left blank */]> {
3307 let Inst{31-28} = 0b1111;
3311 class ACI<dag oops, dag iops, string opc, string asm>
3312 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3313 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3314 let Inst{27-25} = 0b110;
3317 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3319 def _OFFSET : ACI<(outs),
3320 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3321 opc, "\tp$cop, cr$CRd, $addr"> {
3322 let Inst{31-28} = op31_28;
3323 let Inst{24} = 1; // P = 1
3324 let Inst{21} = 0; // W = 0
3325 let Inst{22} = 0; // D = 0
3326 let Inst{20} = load;
3329 def _PRE : ACI<(outs),
3330 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3331 opc, "\tp$cop, cr$CRd, $addr!"> {
3332 let Inst{31-28} = op31_28;
3333 let Inst{24} = 1; // P = 1
3334 let Inst{21} = 1; // W = 1
3335 let Inst{22} = 0; // D = 0
3336 let Inst{20} = load;
3339 def _POST : ACI<(outs),
3340 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3341 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3342 let Inst{31-28} = op31_28;
3343 let Inst{24} = 0; // P = 0
3344 let Inst{21} = 1; // W = 1
3345 let Inst{22} = 0; // D = 0
3346 let Inst{20} = load;
3349 def _OPTION : ACI<(outs),
3350 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3351 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3352 let Inst{31-28} = op31_28;
3353 let Inst{24} = 0; // P = 0
3354 let Inst{23} = 1; // U = 1
3355 let Inst{21} = 0; // W = 0
3356 let Inst{22} = 0; // D = 0
3357 let Inst{20} = load;
3360 def L_OFFSET : ACI<(outs),
3361 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3362 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3363 let Inst{31-28} = op31_28;
3364 let Inst{24} = 1; // P = 1
3365 let Inst{21} = 0; // W = 0
3366 let Inst{22} = 1; // D = 1
3367 let Inst{20} = load;
3370 def L_PRE : ACI<(outs),
3371 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3372 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3373 let Inst{31-28} = op31_28;
3374 let Inst{24} = 1; // P = 1
3375 let Inst{21} = 1; // W = 1
3376 let Inst{22} = 1; // D = 1
3377 let Inst{20} = load;
3380 def L_POST : ACI<(outs),
3381 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3382 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3383 let Inst{31-28} = op31_28;
3384 let Inst{24} = 0; // P = 0
3385 let Inst{21} = 1; // W = 1
3386 let Inst{22} = 1; // D = 1
3387 let Inst{20} = load;
3390 def L_OPTION : ACI<(outs),
3391 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3392 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3393 let Inst{31-28} = op31_28;
3394 let Inst{24} = 0; // P = 0
3395 let Inst{23} = 1; // U = 1
3396 let Inst{21} = 0; // W = 0
3397 let Inst{22} = 1; // D = 1
3398 let Inst{20} = load;
3402 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3403 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3404 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3405 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3407 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3408 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3409 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3410 [/* For disassembly only; pattern left blank */]> {
3415 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3416 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3417 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3418 [/* For disassembly only; pattern left blank */]> {
3419 let Inst{31-28} = 0b1111;
3424 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3425 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3426 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3427 [/* For disassembly only; pattern left blank */]> {
3432 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3433 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3434 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3435 [/* For disassembly only; pattern left blank */]> {
3436 let Inst{31-28} = 0b1111;
3441 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3442 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3443 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3444 [/* For disassembly only; pattern left blank */]> {
3445 let Inst{23-20} = 0b0100;
3448 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3449 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3450 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3451 [/* For disassembly only; pattern left blank */]> {
3452 let Inst{31-28} = 0b1111;
3453 let Inst{23-20} = 0b0100;
3456 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3457 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3458 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3459 [/* For disassembly only; pattern left blank */]> {
3460 let Inst{23-20} = 0b0101;
3463 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3464 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3465 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3466 [/* For disassembly only; pattern left blank */]> {
3467 let Inst{31-28} = 0b1111;
3468 let Inst{23-20} = 0b0101;
3471 //===----------------------------------------------------------------------===//
3472 // Move between special register and ARM core register -- for disassembly only
3475 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3476 [/* For disassembly only; pattern left blank */]> {
3477 let Inst{23-20} = 0b0000;
3478 let Inst{7-4} = 0b0000;
3481 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3482 [/* For disassembly only; pattern left blank */]> {
3483 let Inst{23-20} = 0b0100;
3484 let Inst{7-4} = 0b0000;
3487 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3488 "msr", "\tcpsr$mask, $src",
3489 [/* For disassembly only; pattern left blank */]> {
3490 let Inst{23-20} = 0b0010;
3491 let Inst{7-4} = 0b0000;
3494 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3495 "msr", "\tcpsr$mask, $a",
3496 [/* For disassembly only; pattern left blank */]> {
3497 let Inst{23-20} = 0b0010;
3498 let Inst{7-4} = 0b0000;
3501 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3502 "msr", "\tspsr$mask, $src",
3503 [/* For disassembly only; pattern left blank */]> {
3504 let Inst{23-20} = 0b0110;
3505 let Inst{7-4} = 0b0000;
3508 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3509 "msr", "\tspsr$mask, $a",
3510 [/* For disassembly only; pattern left blank */]> {
3511 let Inst{23-20} = 0b0110;
3512 let Inst{7-4} = 0b0000;