1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
74 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
75 [SDNPHasChain, SDNPOutFlag]>;
76 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
77 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
79 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
80 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
82 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
85 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
89 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
90 [SDNPHasChain, SDNPOptInFlag]>;
92 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
94 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
97 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
98 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
100 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
102 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
105 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
108 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
111 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
112 [SDNPOutFlag, SDNPCommutative]>;
114 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
117 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
118 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
120 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
121 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
122 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
123 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
124 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
126 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
129 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
131 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
134 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
136 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
137 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
140 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
142 //===----------------------------------------------------------------------===//
143 // ARM Instruction Predicate Definitions.
145 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
146 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
147 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
148 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
149 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
150 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
151 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
152 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
153 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
154 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
155 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
156 def HasNEON : Predicate<"Subtarget->hasNEON()">;
157 def HasDivide : Predicate<"Subtarget->hasDivide()">;
158 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
159 def HasDB : Predicate<"Subtarget->hasDataBarrier()">;
160 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
161 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
162 def IsThumb : Predicate<"Subtarget->isThumb()">;
163 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
164 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
165 def IsARM : Predicate<"!Subtarget->isThumb()">;
166 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
167 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
169 // FIXME: Eventually this will be just "hasV6T2Ops".
170 def UseMovt : Predicate<"Subtarget->useMovt()">;
171 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
172 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
174 //===----------------------------------------------------------------------===//
175 // ARM Flag Definitions.
177 class RegConstraint<string C> {
178 string Constraints = C;
181 //===----------------------------------------------------------------------===//
182 // ARM specific transformation functions and pattern fragments.
185 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
186 // so_imm_neg def below.
187 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
188 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
191 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
192 // so_imm_not def below.
193 def so_imm_not_XFORM : SDNodeXForm<imm, [{
194 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
197 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
198 def imm1_15 : PatLeaf<(i32 imm), [{
199 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
202 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
203 def imm16_31 : PatLeaf<(i32 imm), [{
204 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
209 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
210 }], so_imm_neg_XFORM>;
214 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
215 }], so_imm_not_XFORM>;
217 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
218 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
219 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
222 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
224 def bf_inv_mask_imm : Operand<i32>,
226 return ARM::isBitFieldInvertedMask(N->getZExtValue());
228 string EncoderMethod = "getBitfieldInvertedMaskOpValue";
229 let PrintMethod = "printBitfieldInvMaskImmOperand";
232 /// Split a 32-bit immediate into two 16 bit parts.
233 def hi16 : SDNodeXForm<imm, [{
234 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
237 def lo16AllZero : PatLeaf<(i32 imm), [{
238 // Returns true if all low 16-bits are 0.
239 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
242 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
244 def imm0_65535 : PatLeaf<(i32 imm), [{
245 return (uint32_t)N->getZExtValue() < 65536;
248 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
249 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
251 /// adde and sube predicates - True based on whether the carry flag output
252 /// will be needed or not.
253 def adde_dead_carry :
254 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
255 [{return !N->hasAnyUseOfValue(1);}]>;
256 def sube_dead_carry :
257 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
258 [{return !N->hasAnyUseOfValue(1);}]>;
259 def adde_live_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return N->hasAnyUseOfValue(1);}]>;
262 def sube_live_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return N->hasAnyUseOfValue(1);}]>;
266 //===----------------------------------------------------------------------===//
267 // Operand Definitions.
271 def brtarget : Operand<OtherVT>;
273 // A list of registers separated by comma. Used by load/store multiple.
274 def reglist : Operand<i32> {
275 string EncoderMethod = "getRegisterListOpValue";
276 let PrintMethod = "printRegisterList";
279 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
280 def cpinst_operand : Operand<i32> {
281 let PrintMethod = "printCPInstOperand";
284 def jtblock_operand : Operand<i32> {
285 let PrintMethod = "printJTBlockOperand";
287 def jt2block_operand : Operand<i32> {
288 let PrintMethod = "printJT2BlockOperand";
292 def pclabel : Operand<i32> {
293 let PrintMethod = "printPCLabel";
296 def neon_vcvt_imm32 : Operand<i32> {
297 string EncoderMethod = "getNEONVcvtImm32OpValue";
300 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
301 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
302 int32_t v = (int32_t)N->getZExtValue();
303 return v == 8 || v == 16 || v == 24; }]> {
304 string EncoderMethod = "getRotImmOpValue";
307 // shift_imm: An integer that encodes a shift amount and the type of shift
308 // (currently either asr or lsl) using the same encoding used for the
309 // immediates in so_reg operands.
310 def shift_imm : Operand<i32> {
311 let PrintMethod = "printShiftImmOperand";
314 // shifter_operand operands: so_reg and so_imm.
315 def so_reg : Operand<i32>, // reg reg imm
316 ComplexPattern<i32, 3, "SelectShifterOperandReg",
317 [shl,srl,sra,rotr]> {
318 string EncoderMethod = "getSORegOpValue";
319 let PrintMethod = "printSORegOperand";
320 let MIOperandInfo = (ops GPR, GPR, i32imm);
322 def shift_so_reg : Operand<i32>, // reg reg imm
323 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
324 [shl,srl,sra,rotr]> {
325 string EncoderMethod = "getSORegOpValue";
326 let PrintMethod = "printSORegOperand";
327 let MIOperandInfo = (ops GPR, GPR, i32imm);
330 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
331 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
332 // represented in the imm field in the same 12-bit form that they are encoded
333 // into so_imm instructions: the 8-bit immediate is the least significant bits
334 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
335 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
336 string EncoderMethod = "getSOImmOpValue";
337 let PrintMethod = "printSOImmOperand";
340 // Break so_imm's up into two pieces. This handles immediates with up to 16
341 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
342 // get the first/second pieces.
343 def so_imm2part : Operand<i32>,
345 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
347 let PrintMethod = "printSOImm2PartOperand";
350 def so_imm2part_1 : SDNodeXForm<imm, [{
351 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
352 return CurDAG->getTargetConstant(V, MVT::i32);
355 def so_imm2part_2 : SDNodeXForm<imm, [{
356 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
357 return CurDAG->getTargetConstant(V, MVT::i32);
360 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
361 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
363 let PrintMethod = "printSOImm2PartOperand";
366 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
367 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
368 return CurDAG->getTargetConstant(V, MVT::i32);
371 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
372 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
373 return CurDAG->getTargetConstant(V, MVT::i32);
376 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
377 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
378 return (int32_t)N->getZExtValue() < 32;
381 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
382 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
383 return (int32_t)N->getZExtValue() < 32;
385 string EncoderMethod = "getImmMinusOneOpValue";
388 // Define ARM specific addressing modes.
391 // addrmode_imm12 := reg +/- imm12
393 def addrmode_imm12 : Operand<i32>,
394 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
395 // 12-bit immediate operand. Note that instructions using this encode
396 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
397 // immediate values are as normal.
399 string EncoderMethod = "getAddrModeImm12OpValue";
400 let PrintMethod = "printAddrModeImm12Operand";
401 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
403 // ldst_so_reg := reg +/- reg shop imm
405 def ldst_so_reg : Operand<i32>,
406 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
407 // FIXME: Simplify the printer
408 // FIXME: Add EncoderMethod for this addressing mode
409 let PrintMethod = "printAddrMode2Operand";
410 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
413 // addrmode2 := reg +/- imm12
414 // := reg +/- reg shop imm
416 def addrmode2 : Operand<i32>,
417 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
418 let PrintMethod = "printAddrMode2Operand";
419 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
422 def am2offset : Operand<i32>,
423 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
424 [], [SDNPWantRoot]> {
425 let PrintMethod = "printAddrMode2OffsetOperand";
426 let MIOperandInfo = (ops GPR, i32imm);
429 // addrmode3 := reg +/- reg
430 // addrmode3 := reg +/- imm8
432 def addrmode3 : Operand<i32>,
433 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
434 let PrintMethod = "printAddrMode3Operand";
435 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
438 def am3offset : Operand<i32>,
439 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
440 [], [SDNPWantRoot]> {
441 let PrintMethod = "printAddrMode3OffsetOperand";
442 let MIOperandInfo = (ops GPR, i32imm);
445 // addrmode4 := reg, <mode|W>
447 def addrmode4 : Operand<i32>,
448 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
449 let PrintMethod = "printAddrMode4Operand";
450 let MIOperandInfo = (ops GPR:$addr, i32imm);
453 def ARMMemMode5AsmOperand : AsmOperandClass {
454 let Name = "MemMode5";
455 let SuperClasses = [];
458 // addrmode5 := reg +/- imm8*4
460 def addrmode5 : Operand<i32>,
461 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
462 let PrintMethod = "printAddrMode5Operand";
463 let MIOperandInfo = (ops GPR:$base, i32imm);
464 let ParserMatchClass = ARMMemMode5AsmOperand;
467 // addrmode6 := reg with optional writeback
469 def addrmode6 : Operand<i32>,
470 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
471 let PrintMethod = "printAddrMode6Operand";
472 let MIOperandInfo = (ops GPR:$addr, i32imm);
475 def am6offset : Operand<i32> {
476 let PrintMethod = "printAddrMode6OffsetOperand";
477 let MIOperandInfo = (ops GPR);
480 // addrmodepc := pc + reg
482 def addrmodepc : Operand<i32>,
483 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
484 let PrintMethod = "printAddrModePCOperand";
485 let MIOperandInfo = (ops GPR, i32imm);
488 def nohash_imm : Operand<i32> {
489 let PrintMethod = "printNoHashImmediate";
492 //===----------------------------------------------------------------------===//
494 include "ARMInstrFormats.td"
496 //===----------------------------------------------------------------------===//
497 // Multiclass helpers...
500 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
501 /// binop that produces a value.
502 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
503 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
504 PatFrag opnode, bit Commutable = 0> {
505 // The register-immediate version is re-materializable. This is useful
506 // in particular for taking the address of a local.
507 let isReMaterializable = 1 in {
508 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
509 iii, opc, "\t$Rd, $Rn, $imm",
510 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
515 let Inst{15-12} = Rd;
516 let Inst{19-16} = Rn;
517 let Inst{11-0} = imm;
520 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
521 iir, opc, "\t$Rd, $Rn, $Rm",
522 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
526 let Inst{11-4} = 0b00000000;
528 let isCommutable = Commutable;
530 let Inst{15-12} = Rd;
531 let Inst{19-16} = Rn;
533 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
534 iis, opc, "\t$Rd, $Rn, $shift",
535 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
540 let Inst{11-0} = shift;
541 let Inst{15-12} = Rd;
542 let Inst{19-16} = Rn;
546 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
547 /// instruction modifies the CPSR register.
548 let Defs = [CPSR] in {
549 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
550 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
551 PatFrag opnode, bit Commutable = 0> {
552 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
553 iii, opc, "\t$Rd, $Rn, $imm",
554 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
559 let Inst{15-12} = Rd;
560 let Inst{19-16} = Rn;
561 let Inst{11-0} = imm;
564 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
565 iir, opc, "\t$Rd, $Rn, $Rm",
566 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
570 let Inst{11-4} = 0b00000000;
572 let isCommutable = Commutable;
574 let Inst{15-12} = Rd;
575 let Inst{19-16} = Rn;
578 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
579 iis, opc, "\t$Rd, $Rn, $shift",
580 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
585 let Inst{11-0} = shift;
586 let Inst{15-12} = Rd;
587 let Inst{19-16} = Rn;
593 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
594 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
595 /// a explicit result, only implicitly set CPSR.
596 let isCompare = 1, Defs = [CPSR] in {
597 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
598 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
599 PatFrag opnode, bit Commutable = 0> {
600 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
602 [(opnode GPR:$Rn, so_imm:$imm)]> {
606 let Inst{15-12} = 0b0000;
607 let Inst{19-16} = Rn;
608 let Inst{11-0} = imm;
612 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
614 [(opnode GPR:$Rn, GPR:$Rm)]> {
617 let Inst{11-4} = 0b00000000;
619 let isCommutable = Commutable;
621 let Inst{15-12} = 0b0000;
622 let Inst{19-16} = Rn;
625 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
626 opc, "\t$Rn, $shift",
627 [(opnode GPR:$Rn, so_reg:$shift)]> {
631 let Inst{11-0} = shift;
632 let Inst{15-12} = 0b0000;
633 let Inst{19-16} = Rn;
639 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
640 /// register and one whose operand is a register rotated by 8/16/24.
641 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
642 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
643 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
644 IIC_iEXTr, opc, "\t$Rd, $Rm",
645 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
646 Requires<[IsARM, HasV6]> {
649 let Inst{15-12} = Rd;
651 let Inst{11-10} = 0b00;
652 let Inst{19-16} = 0b1111;
654 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
655 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
656 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
657 Requires<[IsARM, HasV6]> {
661 let Inst{15-12} = Rd;
662 let Inst{11-10} = rot;
664 let Inst{19-16} = 0b1111;
668 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
669 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
670 IIC_iEXTr, opc, "\t$Rd, $Rm",
671 [/* For disassembly only; pattern left blank */]>,
672 Requires<[IsARM, HasV6]> {
673 let Inst{11-10} = 0b00;
674 let Inst{19-16} = 0b1111;
676 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
677 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
678 [/* For disassembly only; pattern left blank */]>,
679 Requires<[IsARM, HasV6]> {
681 let Inst{11-10} = rot;
682 let Inst{19-16} = 0b1111;
686 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
687 /// register and one whose operand is a register rotated by 8/16/24.
688 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
689 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
690 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
691 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
692 Requires<[IsARM, HasV6]> {
693 let Inst{11-10} = 0b00;
695 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
697 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
698 [(set GPR:$Rd, (opnode GPR:$Rn,
699 (rotr GPR:$Rm, rot_imm:$rot)))]>,
700 Requires<[IsARM, HasV6]> {
703 let Inst{19-16} = Rn;
704 let Inst{11-10} = rot;
708 // For disassembly only.
709 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
710 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
711 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
712 [/* For disassembly only; pattern left blank */]>,
713 Requires<[IsARM, HasV6]> {
714 let Inst{11-10} = 0b00;
716 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
718 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
719 [/* For disassembly only; pattern left blank */]>,
720 Requires<[IsARM, HasV6]> {
723 let Inst{19-16} = Rn;
724 let Inst{11-10} = rot;
728 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
729 let Uses = [CPSR] in {
730 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
731 bit Commutable = 0> {
732 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
733 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
734 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
740 let Inst{15-12} = Rd;
741 let Inst{19-16} = Rn;
742 let Inst{11-0} = imm;
744 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
745 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
746 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
751 let Inst{11-4} = 0b00000000;
753 let isCommutable = Commutable;
755 let Inst{15-12} = Rd;
756 let Inst{19-16} = Rn;
758 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
759 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
760 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
766 let Inst{11-0} = shift;
767 let Inst{15-12} = Rd;
768 let Inst{19-16} = Rn;
771 // Carry setting variants
772 let Defs = [CPSR] in {
773 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
774 bit Commutable = 0> {
775 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
776 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
777 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
782 let Inst{15-12} = Rd;
783 let Inst{19-16} = Rn;
784 let Inst{11-0} = imm;
788 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
789 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
790 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
795 let Inst{11-4} = 0b00000000;
796 let isCommutable = Commutable;
798 let Inst{15-12} = Rd;
799 let Inst{19-16} = Rn;
803 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
804 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
805 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
810 let Inst{11-0} = shift;
811 let Inst{15-12} = Rd;
812 let Inst{19-16} = Rn;
820 let canFoldAsLoad = 1, isReMaterializable = 1 in {
821 multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
822 InstrItinClass iir, PatFrag opnode> {
823 // Note: We use the complex addrmode_imm12 rather than just an input
824 // GPR and a constrained immediate so that we can use this to match
825 // frame index references and avoid matching constant pool references.
826 def i12 : AIldst1<0b010, opc22, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
827 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
828 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
831 let Inst{23} = addr{12}; // U (add = ('U' == 1))
832 let Inst{19-16} = addr{16-13}; // Rn
833 let Inst{15-12} = Rt;
834 let Inst{11-0} = addr{11-0}; // imm12
836 def rs : AIldst1<0b011, opc22, 1, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
837 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
838 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
841 let Inst{23} = shift{12}; // U (add = ('U' == 1))
842 let Inst{19-16} = shift{16-13}; // Rn
843 let Inst{11-0} = shift{11-0};
848 multiclass AI_str1<bit opc22, string opc, InstrItinClass iii,
849 InstrItinClass iir, PatFrag opnode> {
850 // Note: We use the complex addrmode_imm12 rather than just an input
851 // GPR and a constrained immediate so that we can use this to match
852 // frame index references and avoid matching constant pool references.
853 def i12 : AIldst1<0b010, opc22, 0, (outs),
854 (ins GPR:$Rt, addrmode_imm12:$addr),
855 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
856 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
859 let Inst{23} = addr{12}; // U (add = ('U' == 1))
860 let Inst{19-16} = addr{16-13}; // Rn
861 let Inst{15-12} = Rt;
862 let Inst{11-0} = addr{11-0}; // imm12
864 def rs : AIldst1<0b011, opc22, 0, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
865 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
866 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
869 let Inst{23} = shift{12}; // U (add = ('U' == 1))
870 let Inst{19-16} = shift{16-13}; // Rn
871 let Inst{11-0} = shift{11-0};
874 //===----------------------------------------------------------------------===//
876 //===----------------------------------------------------------------------===//
878 //===----------------------------------------------------------------------===//
879 // Miscellaneous Instructions.
882 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
883 /// the function. The first operand is the ID# for this instruction, the second
884 /// is the index into the MachineConstantPool that this is, the third is the
885 /// size in bytes of this constant pool entry.
886 let neverHasSideEffects = 1, isNotDuplicable = 1 in
887 def CONSTPOOL_ENTRY :
888 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
889 i32imm:$size), NoItinerary, "", []>;
891 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
892 // from removing one half of the matched pairs. That breaks PEI, which assumes
893 // these will always be in pairs, and asserts if it finds otherwise. Better way?
894 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
896 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
897 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
899 def ADJCALLSTACKDOWN :
900 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
901 [(ARMcallseq_start timm:$amt)]>;
904 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
905 [/* For disassembly only; pattern left blank */]>,
906 Requires<[IsARM, HasV6T2]> {
907 let Inst{27-16} = 0b001100100000;
908 let Inst{15-8} = 0b11110000;
909 let Inst{7-0} = 0b00000000;
912 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
913 [/* For disassembly only; pattern left blank */]>,
914 Requires<[IsARM, HasV6T2]> {
915 let Inst{27-16} = 0b001100100000;
916 let Inst{15-8} = 0b11110000;
917 let Inst{7-0} = 0b00000001;
920 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
921 [/* For disassembly only; pattern left blank */]>,
922 Requires<[IsARM, HasV6T2]> {
923 let Inst{27-16} = 0b001100100000;
924 let Inst{15-8} = 0b11110000;
925 let Inst{7-0} = 0b00000010;
928 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
929 [/* For disassembly only; pattern left blank */]>,
930 Requires<[IsARM, HasV6T2]> {
931 let Inst{27-16} = 0b001100100000;
932 let Inst{15-8} = 0b11110000;
933 let Inst{7-0} = 0b00000011;
936 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
938 [/* For disassembly only; pattern left blank */]>,
939 Requires<[IsARM, HasV6]> {
944 let Inst{15-12} = Rd;
945 let Inst{19-16} = Rn;
946 let Inst{27-20} = 0b01101000;
947 let Inst{7-4} = 0b1011;
948 let Inst{11-8} = 0b1111;
951 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
952 [/* For disassembly only; pattern left blank */]>,
953 Requires<[IsARM, HasV6T2]> {
954 let Inst{27-16} = 0b001100100000;
955 let Inst{15-8} = 0b11110000;
956 let Inst{7-0} = 0b00000100;
959 // The i32imm operand $val can be used by a debugger to store more information
960 // about the breakpoint.
961 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
962 [/* For disassembly only; pattern left blank */]>,
965 let Inst{3-0} = val{3-0};
966 let Inst{19-8} = val{15-4};
967 let Inst{27-20} = 0b00010010;
968 let Inst{7-4} = 0b0111;
971 // Change Processor State is a system instruction -- for disassembly only.
972 // The singleton $opt operand contains the following information:
973 // opt{4-0} = mode from Inst{4-0}
974 // opt{5} = changemode from Inst{17}
975 // opt{8-6} = AIF from Inst{8-6}
976 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
977 // FIXME: Integrated assembler will need these split out.
978 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
979 [/* For disassembly only; pattern left blank */]>,
981 let Inst{31-28} = 0b1111;
982 let Inst{27-20} = 0b00010000;
987 // Preload signals the memory system of possible future data/instruction access.
988 // These are for disassembly only.
990 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
991 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
992 multiclass APreLoad<bit data, bit read, string opc> {
994 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, NoItinerary,
995 !strconcat(opc, "\t$addr"), []> {
998 let Inst{31-26} = 0b111101;
999 let Inst{25} = 0; // 0 for immediate form
1000 let Inst{24} = data;
1001 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1002 let Inst{22} = read;
1003 let Inst{21-20} = 0b01;
1004 let Inst{19-16} = addr{16-13}; // Rn
1005 let Inst{15-12} = Rt;
1006 let Inst{11-0} = addr{11-0}; // imm12
1009 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, NoItinerary,
1010 !strconcat(opc, "\t$shift"), []> {
1013 let Inst{31-26} = 0b111101;
1014 let Inst{25} = 1; // 1 for register form
1015 let Inst{24} = data;
1016 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1017 let Inst{22} = read;
1018 let Inst{21-20} = 0b01;
1019 let Inst{19-16} = shift{16-13}; // Rn
1020 let Inst{11-0} = shift{11-0};
1024 defm PLD : APreLoad<1, 1, "pld">;
1025 defm PLDW : APreLoad<1, 0, "pldw">;
1026 defm PLI : APreLoad<0, 1, "pli">;
1028 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1030 [/* For disassembly only; pattern left blank */]>,
1033 let Inst{31-10} = 0b1111000100000001000000;
1038 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1039 [/* For disassembly only; pattern left blank */]>,
1040 Requires<[IsARM, HasV7]> {
1042 let Inst{27-4} = 0b001100100000111100001111;
1043 let Inst{3-0} = opt;
1046 // A5.4 Permanently UNDEFINED instructions.
1047 let isBarrier = 1, isTerminator = 1 in
1048 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1051 let Inst{27-25} = 0b011;
1052 let Inst{24-20} = 0b11111;
1053 let Inst{7-5} = 0b111;
1057 // Address computation and loads and stores in PIC mode.
1058 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1059 // classes (AXI1, et.al.) and so have encoding information and such,
1060 // which is suboptimal. Once the rest of the code emitter (including
1061 // JIT) is MC-ized we should look at refactoring these into true
1062 // pseudos. As is, the encoding information ends up being ignored,
1063 // as these instructions are lowered to individual MC-insts.
1064 let isNotDuplicable = 1 in {
1065 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1066 Pseudo, IIC_iALUr, "",
1067 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1069 let AddedComplexity = 10 in {
1070 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1071 Pseudo, IIC_iLoad_r, "",
1072 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1074 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1075 Pseudo, IIC_iLoad_bh_r, "",
1076 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1078 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1079 Pseudo, IIC_iLoad_bh_r, "",
1080 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1082 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1083 Pseudo, IIC_iLoad_bh_r, "",
1084 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1086 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1087 Pseudo, IIC_iLoad_bh_r, "",
1088 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1090 let AddedComplexity = 10 in {
1091 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1092 Pseudo, IIC_iStore_r, "",
1093 [(store GPR:$src, addrmodepc:$addr)]>;
1095 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1096 Pseudo, IIC_iStore_bh_r, "",
1097 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1099 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1100 Pseudo, IIC_iStore_bh_r, "",
1101 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1103 } // isNotDuplicable = 1
1106 // LEApcrel - Load a pc-relative address into a register without offending the
1108 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1109 // the ADR instruction. Is this the right way to handle that? They need
1110 // encoding information regardless.
1111 let neverHasSideEffects = 1 in {
1112 let isReMaterializable = 1 in
1113 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1115 "adr$p\t$dst, #$label", []>;
1117 } // neverHasSideEffects
1118 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1119 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1121 "adr$p\t$dst, #${label}_${id}", []> {
1125 //===----------------------------------------------------------------------===//
1126 // Control Flow Instructions.
1129 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1131 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1132 "bx", "\tlr", [(ARMretflag)]>,
1133 Requires<[IsARM, HasV4T]> {
1134 let Inst{27-0} = 0b0001001011111111111100011110;
1138 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1139 "mov", "\tpc, lr", [(ARMretflag)]>,
1140 Requires<[IsARM, NoV4T]> {
1141 let Inst{27-0} = 0b0001101000001111000000001110;
1145 // Indirect branches
1146 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1148 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1149 [(brind GPR:$dst)]>,
1150 Requires<[IsARM, HasV4T]> {
1152 let Inst{31-4} = 0b1110000100101111111111110001;
1153 let Inst{3-0} = dst;
1157 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1158 [(brind GPR:$dst)]>,
1159 Requires<[IsARM, NoV4T]> {
1161 let Inst{31-4} = 0b1110000110100000111100000000;
1162 let Inst{3-0} = dst;
1166 // FIXME: remove when we have a way to marking a MI with these properties.
1167 // FIXME: Should pc be an implicit operand like PICADD, etc?
1168 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1169 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1170 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1171 reglist:$dsts, variable_ops),
1172 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1173 "ldm${addr:submode}${p}\t$addr!, $dsts",
1174 "$addr.addr = $wb", []>;
1176 // On non-Darwin platforms R9 is callee-saved.
1178 Defs = [R0, R1, R2, R3, R12, LR,
1179 D0, D1, D2, D3, D4, D5, D6, D7,
1180 D16, D17, D18, D19, D20, D21, D22, D23,
1181 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1182 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1183 IIC_Br, "bl\t$func",
1184 [(ARMcall tglobaladdr:$func)]>,
1185 Requires<[IsARM, IsNotDarwin]> {
1186 let Inst{31-28} = 0b1110;
1187 // FIXME: Encoding info for $func. Needs fixups bits.
1190 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1191 IIC_Br, "bl", "\t$func",
1192 [(ARMcall_pred tglobaladdr:$func)]>,
1193 Requires<[IsARM, IsNotDarwin]>;
1196 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1197 IIC_Br, "blx\t$func",
1198 [(ARMcall GPR:$func)]>,
1199 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1201 let Inst{27-4} = 0b000100101111111111110011;
1202 let Inst{3-0} = func;
1206 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1207 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1208 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1209 [(ARMcall_nolink tGPR:$func)]>,
1210 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1212 let Inst{27-4} = 0b000100101111111111110001;
1213 let Inst{3-0} = func;
1217 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1218 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1219 [(ARMcall_nolink tGPR:$func)]>,
1220 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1222 let Inst{27-4} = 0b000110100000111100000000;
1223 let Inst{3-0} = func;
1227 // On Darwin R9 is call-clobbered.
1229 Defs = [R0, R1, R2, R3, R9, R12, LR,
1230 D0, D1, D2, D3, D4, D5, D6, D7,
1231 D16, D17, D18, D19, D20, D21, D22, D23,
1232 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1233 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1234 IIC_Br, "bl\t$func",
1235 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1236 let Inst{31-28} = 0b1110;
1237 // FIXME: Encoding info for $func. Needs fixups bits.
1240 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
1241 IIC_Br, "bl", "\t$func",
1242 [(ARMcall_pred tglobaladdr:$func)]>,
1243 Requires<[IsARM, IsDarwin]>;
1246 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1247 IIC_Br, "blx\t$func",
1248 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1250 let Inst{27-4} = 0b000100101111111111110011;
1251 let Inst{3-0} = func;
1255 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1256 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1257 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1258 [(ARMcall_nolink tGPR:$func)]>,
1259 Requires<[IsARM, HasV4T, IsDarwin]> {
1261 let Inst{27-4} = 0b000100101111111111110001;
1262 let Inst{3-0} = func;
1266 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1267 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1268 [(ARMcall_nolink tGPR:$func)]>,
1269 Requires<[IsARM, NoV4T, IsDarwin]> {
1271 let Inst{27-4} = 0b000110100000111100000000;
1272 let Inst{3-0} = func;
1278 // FIXME: These should probably be xformed into the non-TC versions of the
1279 // instructions as part of MC lowering.
1280 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1282 let Defs = [R0, R1, R2, R3, R9, R12,
1283 D0, D1, D2, D3, D4, D5, D6, D7,
1284 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1285 D27, D28, D29, D30, D31, PC],
1287 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1289 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1291 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1293 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1295 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1296 IIC_Br, "b\t$dst @ TAILCALL",
1297 []>, Requires<[IsDarwin]>;
1299 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1300 IIC_Br, "b.w\t$dst @ TAILCALL",
1301 []>, Requires<[IsDarwin]>;
1303 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1304 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1305 []>, Requires<[IsDarwin]> {
1307 let Inst{31-4} = 0b1110000100101111111111110001;
1308 let Inst{3-0} = dst;
1312 // Non-Darwin versions (the difference is R9).
1313 let Defs = [R0, R1, R2, R3, R12,
1314 D0, D1, D2, D3, D4, D5, D6, D7,
1315 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1316 D27, D28, D29, D30, D31, PC],
1318 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1320 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1322 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1324 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1326 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1327 IIC_Br, "b\t$dst @ TAILCALL",
1328 []>, Requires<[IsARM, IsNotDarwin]>;
1330 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1331 IIC_Br, "b.w\t$dst @ TAILCALL",
1332 []>, Requires<[IsThumb, IsNotDarwin]>;
1334 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1335 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1336 []>, Requires<[IsNotDarwin]> {
1338 let Inst{31-4} = 0b1110000100101111111111110001;
1339 let Inst{3-0} = dst;
1344 let isBranch = 1, isTerminator = 1 in {
1345 // B is "predicable" since it can be xformed into a Bcc.
1346 let isBarrier = 1 in {
1347 let isPredicable = 1 in
1348 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1349 "b\t$target", [(br bb:$target)]>;
1351 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1352 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1353 IIC_Br, "mov\tpc, $target$jt",
1354 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1355 let Inst{11-4} = 0b00000000;
1356 let Inst{15-12} = 0b1111;
1357 let Inst{20} = 0; // S Bit
1358 let Inst{24-21} = 0b1101;
1359 let Inst{27-25} = 0b000;
1361 def BR_JTm : JTI<(outs),
1362 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1363 IIC_Br, "ldr\tpc, $target$jt",
1364 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1366 let Inst{15-12} = 0b1111;
1367 let Inst{20} = 1; // L bit
1368 let Inst{21} = 0; // W bit
1369 let Inst{22} = 0; // B bit
1370 let Inst{24} = 1; // P bit
1371 let Inst{27-25} = 0b011;
1373 def BR_JTadd : JTI<(outs),
1374 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1375 IIC_Br, "add\tpc, $target, $idx$jt",
1376 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1378 let Inst{15-12} = 0b1111;
1379 let Inst{20} = 0; // S bit
1380 let Inst{24-21} = 0b0100;
1381 let Inst{27-25} = 0b000;
1383 } // isNotDuplicable = 1, isIndirectBranch = 1
1386 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1387 // a two-value operand where a dag node expects two operands. :(
1388 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1389 IIC_Br, "b", "\t$target",
1390 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1393 // Branch and Exchange Jazelle -- for disassembly only
1394 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1395 [/* For disassembly only; pattern left blank */]> {
1396 let Inst{23-20} = 0b0010;
1397 //let Inst{19-8} = 0xfff;
1398 let Inst{7-4} = 0b0010;
1401 // Secure Monitor Call is a system instruction -- for disassembly only
1402 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1403 [/* For disassembly only; pattern left blank */]> {
1405 let Inst{23-4} = 0b01100000000000000111;
1406 let Inst{3-0} = opt;
1409 // Supervisor Call (Software Interrupt) -- for disassembly only
1411 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1412 [/* For disassembly only; pattern left blank */]> {
1414 let Inst{23-0} = svc;
1418 // Store Return State is a system instruction -- for disassembly only
1419 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1420 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1421 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1422 [/* For disassembly only; pattern left blank */]> {
1423 let Inst{31-28} = 0b1111;
1424 let Inst{22-20} = 0b110; // W = 1
1427 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1428 NoItinerary, "srs${addr:submode}\tsp, $mode",
1429 [/* For disassembly only; pattern left blank */]> {
1430 let Inst{31-28} = 0b1111;
1431 let Inst{22-20} = 0b100; // W = 0
1434 // Return From Exception is a system instruction -- for disassembly only
1435 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1436 NoItinerary, "rfe${addr:submode}\t$base!",
1437 [/* For disassembly only; pattern left blank */]> {
1438 let Inst{31-28} = 0b1111;
1439 let Inst{22-20} = 0b011; // W = 1
1442 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1443 NoItinerary, "rfe${addr:submode}\t$base",
1444 [/* For disassembly only; pattern left blank */]> {
1445 let Inst{31-28} = 0b1111;
1446 let Inst{22-20} = 0b001; // W = 0
1448 } // isCodeGenOnly = 1
1450 //===----------------------------------------------------------------------===//
1451 // Load / store Instructions.
1457 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1458 UnOpFrag<(load node:$Src)>>;
1459 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1460 UnOpFrag<(zextloadi8 node:$Src)>>;
1461 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1462 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1463 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1464 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1466 // Special LDR for loads from non-pc-relative constpools.
1467 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1468 isReMaterializable = 1 in
1469 def LDRcp : AIldst1<0b010, 0, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1470 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> {
1473 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1474 let Inst{19-16} = 0b1111;
1475 let Inst{15-12} = Rt;
1476 let Inst{11-0} = addr{11-0}; // imm12
1479 // Loads with zero extension
1480 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1481 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1482 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1484 // Loads with sign extension
1485 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1486 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1487 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1489 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1490 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1491 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1493 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1495 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1496 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1497 []>, Requires<[IsARM, HasV5TE]>;
1500 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1501 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru,
1502 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1504 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1505 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1506 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1508 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1509 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1510 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1512 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1513 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1514 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1516 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1517 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru,
1518 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1520 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1521 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1522 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1524 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1525 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1526 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1528 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1529 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1530 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1532 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1533 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1534 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1536 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1537 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1538 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1540 // For disassembly only
1541 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1542 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1543 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1544 Requires<[IsARM, HasV5TE]>;
1546 // For disassembly only
1547 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1548 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1549 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1550 Requires<[IsARM, HasV5TE]>;
1552 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1554 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1556 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1557 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru,
1558 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1559 let Inst{21} = 1; // overwrite
1562 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1563 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru,
1564 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1565 let Inst{21} = 1; // overwrite
1568 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1569 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1570 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1571 let Inst{21} = 1; // overwrite
1574 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1575 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1576 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1577 let Inst{21} = 1; // overwrite
1580 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1581 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1582 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1583 let Inst{21} = 1; // overwrite
1588 // Stores with truncate
1589 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1590 IIC_iStore_bh_r, "strh", "\t$src, $addr",
1591 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1594 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1595 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1596 StMiscFrm, IIC_iStore_d_r,
1597 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1600 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1601 (ins GPR:$src, GPR:$base, am2offset:$offset),
1602 StFrm, IIC_iStore_ru,
1603 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1605 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1607 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1608 (ins GPR:$src, GPR:$base,am2offset:$offset),
1609 StFrm, IIC_iStore_ru,
1610 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1612 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1614 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1615 (ins GPR:$src, GPR:$base,am3offset:$offset),
1616 StMiscFrm, IIC_iStore_ru,
1617 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1619 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1621 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1622 (ins GPR:$src, GPR:$base,am3offset:$offset),
1623 StMiscFrm, IIC_iStore_bh_ru,
1624 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1625 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1626 GPR:$base, am3offset:$offset))]>;
1628 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1629 (ins GPR:$src, GPR:$base,am2offset:$offset),
1630 StFrm, IIC_iStore_bh_ru,
1631 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1632 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1633 GPR:$base, am2offset:$offset))]>;
1635 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1636 (ins GPR:$src, GPR:$base,am2offset:$offset),
1637 StFrm, IIC_iStore_bh_ru,
1638 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1639 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1640 GPR:$base, am2offset:$offset))]>;
1642 // For disassembly only
1643 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1644 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1645 StMiscFrm, IIC_iStore_d_ru,
1646 "strd", "\t$src1, $src2, [$base, $offset]!",
1647 "$base = $base_wb", []>;
1649 // For disassembly only
1650 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1651 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1652 StMiscFrm, IIC_iStore_d_ru,
1653 "strd", "\t$src1, $src2, [$base], $offset",
1654 "$base = $base_wb", []>;
1656 // STRT, STRBT, and STRHT are for disassembly only.
1658 def STRT : AI2stwpo<(outs GPR:$base_wb),
1659 (ins GPR:$src, GPR:$base,am2offset:$offset),
1660 StFrm, IIC_iStore_ru,
1661 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1662 [/* For disassembly only; pattern left blank */]> {
1663 let Inst{21} = 1; // overwrite
1666 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1667 (ins GPR:$src, GPR:$base,am2offset:$offset),
1668 StFrm, IIC_iStore_bh_ru,
1669 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1670 [/* For disassembly only; pattern left blank */]> {
1671 let Inst{21} = 1; // overwrite
1674 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1675 (ins GPR:$src, GPR:$base,am3offset:$offset),
1676 StMiscFrm, IIC_iStore_bh_ru,
1677 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1678 [/* For disassembly only; pattern left blank */]> {
1679 let Inst{21} = 1; // overwrite
1682 //===----------------------------------------------------------------------===//
1683 // Load / store multiple Instructions.
1686 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1687 isCodeGenOnly = 1 in {
1688 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1689 reglist:$dsts, variable_ops),
1690 IndexModeNone, LdStMulFrm, IIC_iLoad_m,
1691 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1693 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1694 reglist:$dsts, variable_ops),
1695 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
1696 "ldm${addr:submode}${p}\t$addr!, $dsts",
1697 "$addr.addr = $wb", []>;
1698 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1700 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1701 isCodeGenOnly = 1 in {
1702 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1703 reglist:$srcs, variable_ops),
1704 IndexModeNone, LdStMulFrm, IIC_iStore_m,
1705 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1707 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1708 reglist:$srcs, variable_ops),
1709 IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
1710 "stm${addr:submode}${p}\t$addr!, $srcs",
1711 "$addr.addr = $wb", []>;
1712 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1714 //===----------------------------------------------------------------------===//
1715 // Move Instructions.
1718 let neverHasSideEffects = 1 in
1719 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1720 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1724 let Inst{11-4} = 0b00000000;
1727 let Inst{15-12} = Rd;
1730 // A version for the smaller set of tail call registers.
1731 let neverHasSideEffects = 1 in
1732 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1733 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1737 let Inst{11-4} = 0b00000000;
1740 let Inst{15-12} = Rd;
1743 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1744 DPSoRegFrm, IIC_iMOVsr,
1745 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1749 let Inst{15-12} = Rd;
1750 let Inst{11-0} = src;
1754 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1755 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1756 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1760 let Inst{15-12} = Rd;
1761 let Inst{19-16} = 0b0000;
1762 let Inst{11-0} = imm;
1765 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1766 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1768 "movw", "\t$Rd, $imm",
1769 [(set GPR:$Rd, imm0_65535:$imm)]>,
1770 Requires<[IsARM, HasV6T2]>, UnaryDP {
1773 let Inst{15-12} = Rd;
1774 let Inst{11-0} = imm{11-0};
1775 let Inst{19-16} = imm{15-12};
1780 let Constraints = "$src = $Rd" in
1781 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1783 "movt", "\t$Rd, $imm",
1785 (or (and GPR:$src, 0xffff),
1786 lo16AllZero:$imm))]>, UnaryDP,
1787 Requires<[IsARM, HasV6T2]> {
1790 let Inst{15-12} = Rd;
1791 let Inst{11-0} = imm{11-0};
1792 let Inst{19-16} = imm{15-12};
1797 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1798 Requires<[IsARM, HasV6T2]>;
1800 let Uses = [CPSR] in
1801 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1802 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1805 // These aren't really mov instructions, but we have to define them this way
1806 // due to flag operands.
1808 let Defs = [CPSR] in {
1809 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1810 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
1812 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
1813 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
1817 //===----------------------------------------------------------------------===//
1818 // Extend Instructions.
1823 defm SXTB : AI_ext_rrot<0b01101010,
1824 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1825 defm SXTH : AI_ext_rrot<0b01101011,
1826 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1828 defm SXTAB : AI_exta_rrot<0b01101010,
1829 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1830 defm SXTAH : AI_exta_rrot<0b01101011,
1831 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1833 // For disassembly only
1834 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
1836 // For disassembly only
1837 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
1841 let AddedComplexity = 16 in {
1842 defm UXTB : AI_ext_rrot<0b01101110,
1843 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1844 defm UXTH : AI_ext_rrot<0b01101111,
1845 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1846 defm UXTB16 : AI_ext_rrot<0b01101100,
1847 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1849 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
1850 // The transformation should probably be done as a combiner action
1851 // instead so we can include a check for masking back in the upper
1852 // eight bits of the source into the lower eight bits of the result.
1853 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1854 // (UXTB16r_rot GPR:$Src, 24)>;
1855 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1856 (UXTB16r_rot GPR:$Src, 8)>;
1858 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
1859 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1860 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
1861 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1864 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1865 // For disassembly only
1866 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
1869 def SBFX : I<(outs GPR:$Rd),
1870 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1871 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1872 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1873 Requires<[IsARM, HasV6T2]> {
1878 let Inst{27-21} = 0b0111101;
1879 let Inst{6-4} = 0b101;
1880 let Inst{20-16} = width;
1881 let Inst{15-12} = Rd;
1882 let Inst{11-7} = lsb;
1886 def UBFX : I<(outs GPR:$Rd),
1887 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
1888 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1889 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
1890 Requires<[IsARM, HasV6T2]> {
1895 let Inst{27-21} = 0b0111111;
1896 let Inst{6-4} = 0b101;
1897 let Inst{20-16} = width;
1898 let Inst{15-12} = Rd;
1899 let Inst{11-7} = lsb;
1903 //===----------------------------------------------------------------------===//
1904 // Arithmetic Instructions.
1907 defm ADD : AsI1_bin_irs<0b0100, "add",
1908 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1909 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1910 defm SUB : AsI1_bin_irs<0b0010, "sub",
1911 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1912 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1914 // ADD and SUB with 's' bit set.
1915 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1916 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1917 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1918 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1919 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
1920 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1922 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1923 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1924 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1925 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1926 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1927 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1928 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1929 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1931 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1932 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
1933 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
1938 let Inst{15-12} = Rd;
1939 let Inst{19-16} = Rn;
1940 let Inst{11-0} = imm;
1943 // The reg/reg form is only defined for the disassembler; for codegen it is
1944 // equivalent to SUBrr.
1945 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
1946 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
1947 [/* For disassembly only; pattern left blank */]> {
1951 let Inst{11-4} = 0b00000000;
1954 let Inst{15-12} = Rd;
1955 let Inst{19-16} = Rn;
1958 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1959 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
1960 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
1965 let Inst{11-0} = shift;
1966 let Inst{15-12} = Rd;
1967 let Inst{19-16} = Rn;
1970 // RSB with 's' bit set.
1971 let Defs = [CPSR] in {
1972 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
1973 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
1974 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
1980 let Inst{15-12} = Rd;
1981 let Inst{19-16} = Rn;
1982 let Inst{11-0} = imm;
1984 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
1985 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
1986 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
1992 let Inst{11-0} = shift;
1993 let Inst{15-12} = Rd;
1994 let Inst{19-16} = Rn;
1998 let Uses = [CPSR] in {
1999 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2000 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2001 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2007 let Inst{15-12} = Rd;
2008 let Inst{19-16} = Rn;
2009 let Inst{11-0} = imm;
2011 // The reg/reg form is only defined for the disassembler; for codegen it is
2012 // equivalent to SUBrr.
2013 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2014 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2015 [/* For disassembly only; pattern left blank */]> {
2019 let Inst{11-4} = 0b00000000;
2022 let Inst{15-12} = Rd;
2023 let Inst{19-16} = Rn;
2025 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2026 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2027 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2033 let Inst{11-0} = shift;
2034 let Inst{15-12} = Rd;
2035 let Inst{19-16} = Rn;
2039 // FIXME: Allow these to be predicated.
2040 let Defs = [CPSR], Uses = [CPSR] in {
2041 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2042 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2043 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2050 let Inst{15-12} = Rd;
2051 let Inst{19-16} = Rn;
2052 let Inst{11-0} = imm;
2054 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2055 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2056 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2063 let Inst{11-0} = shift;
2064 let Inst{15-12} = Rd;
2065 let Inst{19-16} = Rn;
2069 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2070 // The assume-no-carry-in form uses the negation of the input since add/sub
2071 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2072 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2074 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2075 (SUBri GPR:$src, so_imm_neg:$imm)>;
2076 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2077 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2078 // The with-carry-in form matches bitwise not instead of the negation.
2079 // Effectively, the inverse interpretation of the carry flag already accounts
2080 // for part of the negation.
2081 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2082 (SBCri GPR:$src, so_imm_not:$imm)>;
2084 // Note: These are implemented in C++ code, because they have to generate
2085 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2087 // (mul X, 2^n+1) -> (add (X << n), X)
2088 // (mul X, 2^n-1) -> (rsb X, (X << n))
2090 // ARM Arithmetic Instruction -- for disassembly only
2091 // GPR:$dst = GPR:$a op GPR:$b
2092 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2093 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2094 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2095 opc, "\t$Rd, $Rn, $Rm", pattern> {
2099 let Inst{27-20} = op27_20;
2100 let Inst{11-4} = op11_4;
2101 let Inst{19-16} = Rn;
2102 let Inst{15-12} = Rd;
2106 // Saturating add/subtract -- for disassembly only
2108 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2109 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2110 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2111 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2112 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2113 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2115 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2116 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2117 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2118 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2119 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2120 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2121 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2122 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2123 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2124 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2125 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2126 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2128 // Signed/Unsigned add/subtract -- for disassembly only
2130 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2131 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2132 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2133 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2134 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2135 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2136 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2137 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2138 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2139 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2140 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2141 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2143 // Signed/Unsigned halving add/subtract -- for disassembly only
2145 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2146 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2147 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2148 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2149 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2150 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2151 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2152 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2153 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2154 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2155 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2156 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2158 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2160 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2161 MulFrm /* for convenience */, NoItinerary, "usad8",
2162 "\t$Rd, $Rn, $Rm", []>,
2163 Requires<[IsARM, HasV6]> {
2167 let Inst{27-20} = 0b01111000;
2168 let Inst{15-12} = 0b1111;
2169 let Inst{7-4} = 0b0001;
2170 let Inst{19-16} = Rd;
2171 let Inst{11-8} = Rm;
2174 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2175 MulFrm /* for convenience */, NoItinerary, "usada8",
2176 "\t$Rd, $Rn, $Rm, $Ra", []>,
2177 Requires<[IsARM, HasV6]> {
2182 let Inst{27-20} = 0b01111000;
2183 let Inst{7-4} = 0b0001;
2184 let Inst{19-16} = Rd;
2185 let Inst{15-12} = Ra;
2186 let Inst{11-8} = Rm;
2190 // Signed/Unsigned saturate -- for disassembly only
2192 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2193 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2194 [/* For disassembly only; pattern left blank */]> {
2199 let Inst{27-21} = 0b0110101;
2200 let Inst{5-4} = 0b01;
2201 let Inst{20-16} = sat_imm;
2202 let Inst{15-12} = Rd;
2203 let Inst{11-7} = sh{7-3};
2204 let Inst{6} = sh{0};
2208 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2209 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2210 [/* For disassembly only; pattern left blank */]> {
2214 let Inst{27-20} = 0b01101010;
2215 let Inst{11-4} = 0b11110011;
2216 let Inst{15-12} = Rd;
2217 let Inst{19-16} = sat_imm;
2221 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2222 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2223 [/* For disassembly only; pattern left blank */]> {
2228 let Inst{27-21} = 0b0110111;
2229 let Inst{5-4} = 0b01;
2230 let Inst{15-12} = Rd;
2231 let Inst{11-7} = sh{7-3};
2232 let Inst{6} = sh{0};
2233 let Inst{20-16} = sat_imm;
2237 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2238 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2239 [/* For disassembly only; pattern left blank */]> {
2243 let Inst{27-20} = 0b01101110;
2244 let Inst{11-4} = 0b11110011;
2245 let Inst{15-12} = Rd;
2246 let Inst{19-16} = sat_imm;
2250 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2251 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2253 //===----------------------------------------------------------------------===//
2254 // Bitwise Instructions.
2257 defm AND : AsI1_bin_irs<0b0000, "and",
2258 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2259 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2260 defm ORR : AsI1_bin_irs<0b1100, "orr",
2261 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2262 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2263 defm EOR : AsI1_bin_irs<0b0001, "eor",
2264 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2265 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2266 defm BIC : AsI1_bin_irs<0b1110, "bic",
2267 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2268 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2270 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2271 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2272 "bfc", "\t$Rd, $imm", "$src = $Rd",
2273 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2274 Requires<[IsARM, HasV6T2]> {
2277 let Inst{27-21} = 0b0111110;
2278 let Inst{6-0} = 0b0011111;
2279 let Inst{15-12} = Rd;
2280 let Inst{11-7} = imm{4-0}; // lsb
2281 let Inst{20-16} = imm{9-5}; // width
2284 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2285 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2286 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2287 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2288 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2289 bf_inv_mask_imm:$imm))]>,
2290 Requires<[IsARM, HasV6T2]> {
2294 let Inst{27-21} = 0b0111110;
2295 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2296 let Inst{15-12} = Rd;
2297 let Inst{11-7} = imm{4-0}; // lsb
2298 let Inst{20-16} = imm{9-5}; // width
2302 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2303 "mvn", "\t$Rd, $Rm",
2304 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2308 let Inst{19-16} = 0b0000;
2309 let Inst{11-4} = 0b00000000;
2310 let Inst{15-12} = Rd;
2313 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2314 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2315 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2320 let Inst{19-16} = 0b0000;
2321 let Inst{15-12} = Rd;
2322 let Inst{11-0} = shift;
2324 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2325 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2326 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2327 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2332 let Inst{19-16} = 0b0000;
2333 let Inst{15-12} = Rd;
2334 let Inst{11-0} = imm;
2337 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2338 (BICri GPR:$src, so_imm_not:$imm)>;
2340 //===----------------------------------------------------------------------===//
2341 // Multiply Instructions.
2343 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2344 string opc, string asm, list<dag> pattern>
2345 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2349 let Inst{19-16} = Rd;
2350 let Inst{11-8} = Rm;
2353 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2354 string opc, string asm, list<dag> pattern>
2355 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2360 let Inst{19-16} = RdHi;
2361 let Inst{15-12} = RdLo;
2362 let Inst{11-8} = Rm;
2366 let isCommutable = 1 in
2367 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2368 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2369 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2371 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2372 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2373 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2375 let Inst{15-12} = Ra;
2378 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2379 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2380 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2381 Requires<[IsARM, HasV6T2]> {
2385 let Inst{19-16} = Rd;
2386 let Inst{11-8} = Rm;
2390 // Extra precision multiplies with low / high results
2392 let neverHasSideEffects = 1 in {
2393 let isCommutable = 1 in {
2394 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2395 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2396 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2398 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2399 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2400 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2403 // Multiply + accumulate
2404 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2405 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2406 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2408 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2409 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2410 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2412 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2413 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2414 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2415 Requires<[IsARM, HasV6]> {
2420 let Inst{19-16} = RdLo;
2421 let Inst{15-12} = RdHi;
2422 let Inst{11-8} = Rm;
2425 } // neverHasSideEffects
2427 // Most significant word multiply
2428 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2429 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2430 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2431 Requires<[IsARM, HasV6]> {
2432 let Inst{15-12} = 0b1111;
2435 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2436 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2437 [/* For disassembly only; pattern left blank */]>,
2438 Requires<[IsARM, HasV6]> {
2439 let Inst{15-12} = 0b1111;
2442 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2443 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2444 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2445 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2446 Requires<[IsARM, HasV6]>;
2448 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2449 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2450 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2451 [/* For disassembly only; pattern left blank */]>,
2452 Requires<[IsARM, HasV6]>;
2454 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2455 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2456 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2457 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2458 Requires<[IsARM, HasV6]>;
2460 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2461 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2462 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2463 [/* For disassembly only; pattern left blank */]>,
2464 Requires<[IsARM, HasV6]>;
2466 multiclass AI_smul<string opc, PatFrag opnode> {
2467 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2468 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2469 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2470 (sext_inreg GPR:$Rm, i16)))]>,
2471 Requires<[IsARM, HasV5TE]>;
2473 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2474 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2475 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2476 (sra GPR:$Rm, (i32 16))))]>,
2477 Requires<[IsARM, HasV5TE]>;
2479 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2480 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2481 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2482 (sext_inreg GPR:$Rm, i16)))]>,
2483 Requires<[IsARM, HasV5TE]>;
2485 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2486 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2487 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2488 (sra GPR:$Rm, (i32 16))))]>,
2489 Requires<[IsARM, HasV5TE]>;
2491 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2492 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2493 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2494 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2495 Requires<[IsARM, HasV5TE]>;
2497 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2498 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2499 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2500 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2501 Requires<[IsARM, HasV5TE]>;
2505 multiclass AI_smla<string opc, PatFrag opnode> {
2506 def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$Rd),
2507 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2508 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2509 [(set GPR:$Rd, (add GPR:$Ra,
2510 (opnode (sext_inreg GPR:$Rn, i16),
2511 (sext_inreg GPR:$Rm, i16))))]>,
2512 Requires<[IsARM, HasV5TE]>;
2514 def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$Rd),
2515 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2516 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2517 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2518 (sra GPR:$Rm, (i32 16)))))]>,
2519 Requires<[IsARM, HasV5TE]>;
2521 def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$Rd),
2522 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2523 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2524 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2525 (sext_inreg GPR:$Rm, i16))))]>,
2526 Requires<[IsARM, HasV5TE]>;
2528 def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$Rd),
2529 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2530 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2531 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2532 (sra GPR:$Rm, (i32 16)))))]>,
2533 Requires<[IsARM, HasV5TE]>;
2535 def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$Rd),
2536 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2537 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2538 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2539 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2540 Requires<[IsARM, HasV5TE]>;
2542 def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$Rd),
2543 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2544 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2545 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2546 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2547 Requires<[IsARM, HasV5TE]>;
2550 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2551 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2553 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2554 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2555 (ins GPR:$Rn, GPR:$Rm),
2556 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2557 [/* For disassembly only; pattern left blank */]>,
2558 Requires<[IsARM, HasV5TE]>;
2560 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2561 (ins GPR:$Rn, GPR:$Rm),
2562 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2563 [/* For disassembly only; pattern left blank */]>,
2564 Requires<[IsARM, HasV5TE]>;
2566 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2567 (ins GPR:$Rn, GPR:$Rm),
2568 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2569 [/* For disassembly only; pattern left blank */]>,
2570 Requires<[IsARM, HasV5TE]>;
2572 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2573 (ins GPR:$Rn, GPR:$Rm),
2574 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2575 [/* For disassembly only; pattern left blank */]>,
2576 Requires<[IsARM, HasV5TE]>;
2578 // Helper class for AI_smld -- for disassembly only
2579 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2580 InstrItinClass itin, string opc, string asm>
2581 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2588 let Inst{21-20} = 0b00;
2589 let Inst{22} = long;
2590 let Inst{27-23} = 0b01110;
2591 let Inst{11-8} = Rm;
2594 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2595 InstrItinClass itin, string opc, string asm>
2596 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2598 let Inst{15-12} = 0b1111;
2599 let Inst{19-16} = Rd;
2601 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2602 InstrItinClass itin, string opc, string asm>
2603 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2605 let Inst{15-12} = Ra;
2607 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2608 InstrItinClass itin, string opc, string asm>
2609 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2612 let Inst{19-16} = RdHi;
2613 let Inst{15-12} = RdLo;
2616 multiclass AI_smld<bit sub, string opc> {
2618 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2619 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2621 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2622 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2624 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2625 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2626 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2628 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2629 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2630 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2634 defm SMLA : AI_smld<0, "smla">;
2635 defm SMLS : AI_smld<1, "smls">;
2637 multiclass AI_sdml<bit sub, string opc> {
2639 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2640 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2641 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2642 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2645 defm SMUA : AI_sdml<0, "smua">;
2646 defm SMUS : AI_sdml<1, "smus">;
2648 //===----------------------------------------------------------------------===//
2649 // Misc. Arithmetic Instructions.
2652 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2653 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2654 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2656 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2657 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2658 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2659 Requires<[IsARM, HasV6T2]>;
2661 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2662 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2663 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2665 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2666 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2668 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2669 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2670 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2671 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2672 Requires<[IsARM, HasV6]>;
2674 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2675 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2678 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2679 (shl GPR:$Rm, (i32 8))), i16))]>,
2680 Requires<[IsARM, HasV6]>;
2682 def lsl_shift_imm : SDNodeXForm<imm, [{
2683 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2684 return CurDAG->getTargetConstant(Sh, MVT::i32);
2687 def lsl_amt : PatLeaf<(i32 imm), [{
2688 return (N->getZExtValue() < 32);
2691 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2692 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2693 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2694 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2695 (and (shl GPR:$Rm, lsl_amt:$sh),
2697 Requires<[IsARM, HasV6]>;
2699 // Alternate cases for PKHBT where identities eliminate some nodes.
2700 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2701 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2702 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2703 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2705 def asr_shift_imm : SDNodeXForm<imm, [{
2706 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2707 return CurDAG->getTargetConstant(Sh, MVT::i32);
2710 def asr_amt : PatLeaf<(i32 imm), [{
2711 return (N->getZExtValue() <= 32);
2714 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2715 // will match the pattern below.
2716 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2717 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2718 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2719 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2720 (and (sra GPR:$Rm, asr_amt:$sh),
2722 Requires<[IsARM, HasV6]>;
2724 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2725 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2726 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2727 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2728 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2729 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2730 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2732 //===----------------------------------------------------------------------===//
2733 // Comparison Instructions...
2736 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2737 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2738 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2740 // FIXME: We have to be careful when using the CMN instruction and comparison
2741 // with 0. One would expect these two pieces of code should give identical
2757 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2758 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2759 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2760 // value of r0 and the carry bit (because the "carry bit" parameter to
2761 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2762 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2763 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2764 // parameter to AddWithCarry is defined as 0).
2766 // When x is 0 and unsigned:
2770 // ~x + 1 = 0x1 0000 0000
2771 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2773 // Therefore, we should disable CMN when comparing against zero, until we can
2774 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2775 // when it's a comparison which doesn't look at the 'carry' flag).
2777 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2779 // This is related to <rdar://problem/7569620>.
2781 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2782 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2784 // Note that TST/TEQ don't set all the same flags that CMP does!
2785 defm TST : AI1_cmp_irs<0b1000, "tst",
2786 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2787 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2788 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2789 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2790 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2792 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2793 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2794 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2795 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2796 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2797 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2799 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2800 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2802 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2803 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2805 // Pseudo i64 compares for some floating point compares.
2806 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2808 def BCCi64 : PseudoInst<(outs),
2809 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2811 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
2813 def BCCZi64 : PseudoInst<(outs),
2814 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
2815 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
2816 } // usesCustomInserter
2819 // Conditional moves
2820 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2821 // a two-value operand where a dag node expects two operands. :(
2822 // FIXME: These should all be pseudo-instructions that get expanded to
2823 // the normal MOV instructions. That would fix the dependency on
2824 // special casing them in tblgen.
2825 let neverHasSideEffects = 1 in {
2826 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
2827 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
2828 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
2829 RegConstraint<"$false = $Rd">, UnaryDP {
2834 let Inst{15-12} = Rd;
2835 let Inst{11-4} = 0b00000000;
2839 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
2840 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
2841 "mov", "\t$Rd, $shift",
2842 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
2843 RegConstraint<"$false = $Rd">, UnaryDP {
2849 let Inst{19-16} = Rn;
2850 let Inst{15-12} = Rd;
2851 let Inst{11-0} = shift;
2854 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
2856 "movw", "\t$Rd, $imm",
2858 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
2864 let Inst{19-16} = imm{15-12};
2865 let Inst{15-12} = Rd;
2866 let Inst{11-0} = imm{11-0};
2869 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
2870 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
2871 "mov", "\t$Rd, $imm",
2872 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
2873 RegConstraint<"$false = $Rd">, UnaryDP {
2878 let Inst{19-16} = 0b0000;
2879 let Inst{15-12} = Rd;
2880 let Inst{11-0} = imm;
2882 } // neverHasSideEffects
2884 //===----------------------------------------------------------------------===//
2885 // Atomic operations intrinsics
2888 def memb_opt : Operand<i32> {
2889 let PrintMethod = "printMemBOption";
2892 // memory barriers protect the atomic sequences
2893 let hasSideEffects = 1 in {
2894 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2895 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
2896 Requires<[IsARM, HasDB]> {
2898 let Inst{31-4} = 0xf57ff05;
2899 let Inst{3-0} = opt;
2902 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
2903 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2904 [(ARMMemBarrierMCR GPR:$zero)]>,
2905 Requires<[IsARM, HasV6]> {
2906 // FIXME: add encoding
2910 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
2912 [/* For disassembly only; pattern left blank */]>,
2913 Requires<[IsARM, HasDB]> {
2915 let Inst{31-4} = 0xf57ff04;
2916 let Inst{3-0} = opt;
2919 // ISB has only full system option -- for disassembly only
2920 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
2921 Requires<[IsARM, HasDB]> {
2922 let Inst{31-4} = 0xf57ff06;
2923 let Inst{3-0} = 0b1111;
2926 let usesCustomInserter = 1 in {
2927 let Uses = [CPSR] in {
2928 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2929 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2930 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2931 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2932 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2933 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2934 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2935 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2936 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2937 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2938 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2939 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2940 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2941 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2942 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2943 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2944 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2945 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2946 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2947 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2948 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2949 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2950 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2951 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2952 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2953 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2954 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2955 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2956 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2957 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2958 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2959 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2960 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2961 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2962 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2963 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2964 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2965 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2966 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2967 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2968 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2969 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2970 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2971 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2972 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2973 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2974 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2975 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2976 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2977 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2978 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2979 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2980 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
2981 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2983 def ATOMIC_SWAP_I8 : PseudoInst<
2984 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2985 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2986 def ATOMIC_SWAP_I16 : PseudoInst<
2987 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2988 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2989 def ATOMIC_SWAP_I32 : PseudoInst<
2990 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
2991 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2993 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2994 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2995 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2996 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2997 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
2998 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2999 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3000 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3001 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3005 let mayLoad = 1 in {
3006 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3007 "ldrexb", "\t$Rt, [$Rn]",
3009 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3010 "ldrexh", "\t$Rt, [$Rn]",
3012 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3013 "ldrex", "\t$Rt, [$Rn]",
3015 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3017 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3021 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3022 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3024 "strexb", "\t$Rd, $src, [$Rn]",
3026 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3028 "strexh", "\t$Rd, $Rt, [$Rn]",
3030 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3032 "strex", "\t$Rd, $Rt, [$Rn]",
3034 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3035 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3037 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3041 // Clear-Exclusive is for disassembly only.
3042 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3043 [/* For disassembly only; pattern left blank */]>,
3044 Requires<[IsARM, HasV7]> {
3045 let Inst{31-0} = 0b11110101011111111111000000011111;
3048 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3049 let mayLoad = 1 in {
3050 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3051 [/* For disassembly only; pattern left blank */]>;
3052 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3053 [/* For disassembly only; pattern left blank */]>;
3056 //===----------------------------------------------------------------------===//
3060 // __aeabi_read_tp preserves the registers r1-r3.
3061 // FIXME: This needs to be a pseudo of some sort so that we can get the
3062 // encoding right, complete with fixup for the aeabi_read_tp function.
3064 Defs = [R0, R12, LR, CPSR] in {
3065 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3066 "bl\t__aeabi_read_tp",
3067 [(set R0, ARMthread_pointer)]>;
3070 //===----------------------------------------------------------------------===//
3071 // SJLJ Exception handling intrinsics
3072 // eh_sjlj_setjmp() is an instruction sequence to store the return
3073 // address and save #0 in R0 for the non-longjmp case.
3074 // Since by its nature we may be coming from some other function to get
3075 // here, and we're using the stack frame for the containing function to
3076 // save/restore registers, we can't keep anything live in regs across
3077 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3078 // when we get here from a longjmp(). We force everthing out of registers
3079 // except for our own input by listing the relevant registers in Defs. By
3080 // doing so, we also cause the prologue/epilogue code to actively preserve
3081 // all of the callee-saved resgisters, which is exactly what we want.
3082 // A constant value is passed in $val, and we use the location as a scratch.
3084 // These are pseudo-instructions and are lowered to individual MC-insts, so
3085 // no encoding information is necessary.
3087 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3088 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3089 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3090 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3091 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3092 AddrModeNone, SizeSpecial, IndexModeNone,
3093 Pseudo, NoItinerary, "", "",
3094 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3095 Requires<[IsARM, HasVFP2]>;
3099 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3100 hasSideEffects = 1, isBarrier = 1 in {
3101 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3102 AddrModeNone, SizeSpecial, IndexModeNone,
3103 Pseudo, NoItinerary, "", "",
3104 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3105 Requires<[IsARM, NoVFP]>;
3108 // FIXME: Non-Darwin version(s)
3109 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3110 Defs = [ R7, LR, SP ] in {
3111 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3112 AddrModeNone, SizeSpecial, IndexModeNone,
3113 Pseudo, NoItinerary, "", "",
3114 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3115 Requires<[IsARM, IsDarwin]>;
3118 // eh.sjlj.dispatchsetup pseudo-instruction.
3119 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3120 // handled when the pseudo is expanded (which happens before any passes
3121 // that need the instruction size).
3122 let isBarrier = 1, hasSideEffects = 1 in
3123 def Int_eh_sjlj_dispatchsetup :
3124 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3125 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3126 Requires<[IsDarwin]>;
3128 //===----------------------------------------------------------------------===//
3129 // Non-Instruction Patterns
3132 // Large immediate handling.
3134 // Two piece so_imms.
3135 // FIXME: Remove this when we can do generalized remat.
3136 let isReMaterializable = 1 in
3137 def MOVi2pieces : PseudoInst<(outs GPR:$dst), (ins so_imm2part:$src),
3139 [(set GPR:$dst, (so_imm2part:$src))]>,
3140 Requires<[IsARM, NoV6T2]>;
3142 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3143 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3144 (so_imm2part_2 imm:$RHS))>;
3145 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3146 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3147 (so_imm2part_2 imm:$RHS))>;
3148 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3149 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3150 (so_imm2part_2 imm:$RHS))>;
3151 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3152 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3153 (so_neg_imm2part_2 imm:$RHS))>;
3155 // 32-bit immediate using movw + movt.
3156 // This is a single pseudo instruction, the benefit is that it can be remat'd
3157 // as a single unit instead of having to handle reg inputs.
3158 // FIXME: Remove this when we can do generalized remat.
3159 let isReMaterializable = 1 in
3160 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3161 [(set GPR:$dst, (i32 imm:$src))]>,
3162 Requires<[IsARM, HasV6T2]>;
3164 // ConstantPool, GlobalAddress, and JumpTable
3165 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3166 Requires<[IsARM, DontUseMovt]>;
3167 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3168 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3169 Requires<[IsARM, UseMovt]>;
3170 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3171 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3173 // TODO: add,sub,and, 3-instr forms?
3176 def : ARMPat<(ARMtcret tcGPR:$dst),
3177 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3179 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3180 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3182 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3183 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3185 def : ARMPat<(ARMtcret tcGPR:$dst),
3186 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3188 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3189 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3191 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3192 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3195 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3196 Requires<[IsARM, IsNotDarwin]>;
3197 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3198 Requires<[IsARM, IsDarwin]>;
3200 // zextload i1 -> zextload i8
3201 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3202 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3204 // extload -> zextload
3205 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3206 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3207 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3208 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3210 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3212 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3213 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3216 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3217 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3218 (SMULBB GPR:$a, GPR:$b)>;
3219 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3220 (SMULBB GPR:$a, GPR:$b)>;
3221 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3222 (sra GPR:$b, (i32 16))),
3223 (SMULBT GPR:$a, GPR:$b)>;
3224 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3225 (SMULBT GPR:$a, GPR:$b)>;
3226 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3227 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3228 (SMULTB GPR:$a, GPR:$b)>;
3229 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3230 (SMULTB GPR:$a, GPR:$b)>;
3231 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3233 (SMULWB GPR:$a, GPR:$b)>;
3234 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3235 (SMULWB GPR:$a, GPR:$b)>;
3237 def : ARMV5TEPat<(add GPR:$acc,
3238 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3239 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3240 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3241 def : ARMV5TEPat<(add GPR:$acc,
3242 (mul sext_16_node:$a, sext_16_node:$b)),
3243 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3244 def : ARMV5TEPat<(add GPR:$acc,
3245 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3246 (sra GPR:$b, (i32 16)))),
3247 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3248 def : ARMV5TEPat<(add GPR:$acc,
3249 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3250 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3251 def : ARMV5TEPat<(add GPR:$acc,
3252 (mul (sra GPR:$a, (i32 16)),
3253 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3254 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3255 def : ARMV5TEPat<(add GPR:$acc,
3256 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3257 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3258 def : ARMV5TEPat<(add GPR:$acc,
3259 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3261 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3262 def : ARMV5TEPat<(add GPR:$acc,
3263 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3264 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3266 //===----------------------------------------------------------------------===//
3270 include "ARMInstrThumb.td"
3272 //===----------------------------------------------------------------------===//
3276 include "ARMInstrThumb2.td"
3278 //===----------------------------------------------------------------------===//
3279 // Floating Point Support
3282 include "ARMInstrVFP.td"
3284 //===----------------------------------------------------------------------===//
3285 // Advanced SIMD (NEON) Support
3288 include "ARMInstrNEON.td"
3290 //===----------------------------------------------------------------------===//
3291 // Coprocessor Instructions. For disassembly only.
3294 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3295 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3296 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3297 [/* For disassembly only; pattern left blank */]> {
3301 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3302 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3303 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3304 [/* For disassembly only; pattern left blank */]> {
3305 let Inst{31-28} = 0b1111;
3309 class ACI<dag oops, dag iops, string opc, string asm>
3310 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3311 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3312 let Inst{27-25} = 0b110;
3315 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3317 def _OFFSET : ACI<(outs),
3318 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3319 opc, "\tp$cop, cr$CRd, $addr"> {
3320 let Inst{31-28} = op31_28;
3321 let Inst{24} = 1; // P = 1
3322 let Inst{21} = 0; // W = 0
3323 let Inst{22} = 0; // D = 0
3324 let Inst{20} = load;
3327 def _PRE : ACI<(outs),
3328 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3329 opc, "\tp$cop, cr$CRd, $addr!"> {
3330 let Inst{31-28} = op31_28;
3331 let Inst{24} = 1; // P = 1
3332 let Inst{21} = 1; // W = 1
3333 let Inst{22} = 0; // D = 0
3334 let Inst{20} = load;
3337 def _POST : ACI<(outs),
3338 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3339 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3340 let Inst{31-28} = op31_28;
3341 let Inst{24} = 0; // P = 0
3342 let Inst{21} = 1; // W = 1
3343 let Inst{22} = 0; // D = 0
3344 let Inst{20} = load;
3347 def _OPTION : ACI<(outs),
3348 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3349 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3350 let Inst{31-28} = op31_28;
3351 let Inst{24} = 0; // P = 0
3352 let Inst{23} = 1; // U = 1
3353 let Inst{21} = 0; // W = 0
3354 let Inst{22} = 0; // D = 0
3355 let Inst{20} = load;
3358 def L_OFFSET : ACI<(outs),
3359 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3360 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3361 let Inst{31-28} = op31_28;
3362 let Inst{24} = 1; // P = 1
3363 let Inst{21} = 0; // W = 0
3364 let Inst{22} = 1; // D = 1
3365 let Inst{20} = load;
3368 def L_PRE : ACI<(outs),
3369 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3370 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3371 let Inst{31-28} = op31_28;
3372 let Inst{24} = 1; // P = 1
3373 let Inst{21} = 1; // W = 1
3374 let Inst{22} = 1; // D = 1
3375 let Inst{20} = load;
3378 def L_POST : ACI<(outs),
3379 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3380 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3381 let Inst{31-28} = op31_28;
3382 let Inst{24} = 0; // P = 0
3383 let Inst{21} = 1; // W = 1
3384 let Inst{22} = 1; // D = 1
3385 let Inst{20} = load;
3388 def L_OPTION : ACI<(outs),
3389 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3390 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3391 let Inst{31-28} = op31_28;
3392 let Inst{24} = 0; // P = 0
3393 let Inst{23} = 1; // U = 1
3394 let Inst{21} = 0; // W = 0
3395 let Inst{22} = 1; // D = 1
3396 let Inst{20} = load;
3400 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3401 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3402 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3403 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3405 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3406 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3407 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3408 [/* For disassembly only; pattern left blank */]> {
3413 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3414 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3415 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3416 [/* For disassembly only; pattern left blank */]> {
3417 let Inst{31-28} = 0b1111;
3422 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3423 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3424 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3425 [/* For disassembly only; pattern left blank */]> {
3430 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3431 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3432 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3433 [/* For disassembly only; pattern left blank */]> {
3434 let Inst{31-28} = 0b1111;
3439 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3440 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3441 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3442 [/* For disassembly only; pattern left blank */]> {
3443 let Inst{23-20} = 0b0100;
3446 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3447 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3448 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3449 [/* For disassembly only; pattern left blank */]> {
3450 let Inst{31-28} = 0b1111;
3451 let Inst{23-20} = 0b0100;
3454 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3455 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3456 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3457 [/* For disassembly only; pattern left blank */]> {
3458 let Inst{23-20} = 0b0101;
3461 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3462 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3463 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3464 [/* For disassembly only; pattern left blank */]> {
3465 let Inst{31-28} = 0b1111;
3466 let Inst{23-20} = 0b0101;
3469 //===----------------------------------------------------------------------===//
3470 // Move between special register and ARM core register -- for disassembly only
3473 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3474 [/* For disassembly only; pattern left blank */]> {
3475 let Inst{23-20} = 0b0000;
3476 let Inst{7-4} = 0b0000;
3479 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3480 [/* For disassembly only; pattern left blank */]> {
3481 let Inst{23-20} = 0b0100;
3482 let Inst{7-4} = 0b0000;
3485 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3486 "msr", "\tcpsr$mask, $src",
3487 [/* For disassembly only; pattern left blank */]> {
3488 let Inst{23-20} = 0b0010;
3489 let Inst{7-4} = 0b0000;
3492 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3493 "msr", "\tcpsr$mask, $a",
3494 [/* For disassembly only; pattern left blank */]> {
3495 let Inst{23-20} = 0b0010;
3496 let Inst{7-4} = 0b0000;
3499 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3500 "msr", "\tspsr$mask, $src",
3501 [/* For disassembly only; pattern left blank */]> {
3502 let Inst{23-20} = 0b0110;
3503 let Inst{7-4} = 0b0000;
3506 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3507 "msr", "\tspsr$mask, $a",
3508 [/* For disassembly only; pattern left blank */]> {
3509 let Inst{23-20} = 0b0110;
3510 let Inst{7-4} = 0b0000;