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_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
43 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
44 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
46 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
47 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
50 def SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>;
51 def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
52 def SDT_ARMMEMBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
53 def SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
56 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
57 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
59 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
60 [SDNPHasChain, SDNPOutFlag]>;
61 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
62 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
64 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
65 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
67 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
68 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
70 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
71 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
74 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
75 [SDNPHasChain, SDNPOptInFlag]>;
77 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
79 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
82 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
83 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
85 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
87 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
90 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
93 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
94 [SDNPOutFlag,SDNPCommutative]>;
96 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
98 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
99 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
100 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
102 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
103 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
105 def ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
107 def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
109 def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
111 def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
114 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
116 //===----------------------------------------------------------------------===//
117 // ARM Instruction Predicate Definitions.
119 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
120 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
121 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
122 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
123 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
124 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
125 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
126 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
127 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
128 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
129 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
130 def HasNEON : Predicate<"Subtarget->hasNEON()">;
131 def HasDivide : Predicate<"Subtarget->hasDivide()">;
132 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
133 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
134 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
135 def IsThumb : Predicate<"Subtarget->isThumb()">;
136 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
137 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
138 def IsARM : Predicate<"!Subtarget->isThumb()">;
139 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
140 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
142 // FIXME: Eventually this will be just "hasV6T2Ops".
143 def UseMovt : Predicate<"Subtarget->useMovt()">;
144 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
146 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
148 //===----------------------------------------------------------------------===//
149 // ARM Flag Definitions.
151 class RegConstraint<string C> {
152 string Constraints = C;
155 //===----------------------------------------------------------------------===//
156 // ARM specific transformation functions and pattern fragments.
159 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
160 // so_imm_neg def below.
161 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
162 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
165 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
166 // so_imm_not def below.
167 def so_imm_not_XFORM : SDNodeXForm<imm, [{
168 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
171 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
172 def rot_imm : PatLeaf<(i32 imm), [{
173 int32_t v = (int32_t)N->getZExtValue();
174 return v == 8 || v == 16 || v == 24;
177 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
178 def imm1_15 : PatLeaf<(i32 imm), [{
179 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
182 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
183 def imm16_31 : PatLeaf<(i32 imm), [{
184 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
189 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
190 }], so_imm_neg_XFORM>;
194 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
195 }], so_imm_not_XFORM>;
197 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
198 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
199 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
202 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
204 def bf_inv_mask_imm : Operand<i32>,
206 uint32_t v = (uint32_t)N->getZExtValue();
209 // there can be 1's on either or both "outsides", all the "inside"
211 unsigned int lsb = 0, msb = 31;
212 while (v & (1 << msb)) --msb;
213 while (v & (1 << lsb)) ++lsb;
214 for (unsigned int i = lsb; i <= msb; ++i) {
220 let PrintMethod = "printBitfieldInvMaskImmOperand";
223 /// Split a 32-bit immediate into two 16 bit parts.
224 def lo16 : SDNodeXForm<imm, [{
225 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
229 def hi16 : SDNodeXForm<imm, [{
230 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
233 def lo16AllZero : PatLeaf<(i32 imm), [{
234 // Returns true if all low 16-bits are 0.
235 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
238 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
240 def imm0_65535 : PatLeaf<(i32 imm), [{
241 return (uint32_t)N->getZExtValue() < 65536;
244 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
245 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
247 /// adde and sube predicates - True based on whether the carry flag output
248 /// will be needed or not.
249 def adde_dead_carry :
250 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
251 [{return !N->hasAnyUseOfValue(1);}]>;
252 def sube_dead_carry :
253 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
254 [{return !N->hasAnyUseOfValue(1);}]>;
255 def adde_live_carry :
256 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
257 [{return N->hasAnyUseOfValue(1);}]>;
258 def sube_live_carry :
259 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
260 [{return N->hasAnyUseOfValue(1);}]>;
262 //===----------------------------------------------------------------------===//
263 // Operand Definitions.
267 def brtarget : Operand<OtherVT>;
269 // A list of registers separated by comma. Used by load/store multiple.
270 def reglist : Operand<i32> {
271 let PrintMethod = "printRegisterList";
274 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
275 def cpinst_operand : Operand<i32> {
276 let PrintMethod = "printCPInstOperand";
279 def jtblock_operand : Operand<i32> {
280 let PrintMethod = "printJTBlockOperand";
282 def jt2block_operand : Operand<i32> {
283 let PrintMethod = "printJT2BlockOperand";
287 def pclabel : Operand<i32> {
288 let PrintMethod = "printPCLabel";
291 // shifter_operand operands: so_reg and so_imm.
292 def so_reg : Operand<i32>, // reg reg imm
293 ComplexPattern<i32, 3, "SelectShifterOperandReg",
294 [shl,srl,sra,rotr]> {
295 let PrintMethod = "printSORegOperand";
296 let MIOperandInfo = (ops GPR, GPR, i32imm);
299 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
300 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
301 // represented in the imm field in the same 12-bit form that they are encoded
302 // into so_imm instructions: the 8-bit immediate is the least significant bits
303 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
304 def so_imm : Operand<i32>,
306 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
308 let PrintMethod = "printSOImmOperand";
311 // Break so_imm's up into two pieces. This handles immediates with up to 16
312 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
313 // get the first/second pieces.
314 def so_imm2part : Operand<i32>,
316 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
318 let PrintMethod = "printSOImm2PartOperand";
321 def so_imm2part_1 : SDNodeXForm<imm, [{
322 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
323 return CurDAG->getTargetConstant(V, MVT::i32);
326 def so_imm2part_2 : SDNodeXForm<imm, [{
327 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
328 return CurDAG->getTargetConstant(V, MVT::i32);
331 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
332 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
334 let PrintMethod = "printSOImm2PartOperand";
337 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
338 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
339 return CurDAG->getTargetConstant(V, MVT::i32);
342 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
343 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
344 return CurDAG->getTargetConstant(V, MVT::i32);
347 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
348 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
349 return (int32_t)N->getZExtValue() < 32;
352 // Define ARM specific addressing modes.
354 // addrmode2 := reg +/- reg shop imm
355 // addrmode2 := reg +/- imm12
357 def addrmode2 : Operand<i32>,
358 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
359 let PrintMethod = "printAddrMode2Operand";
360 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
363 def am2offset : Operand<i32>,
364 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
365 let PrintMethod = "printAddrMode2OffsetOperand";
366 let MIOperandInfo = (ops GPR, i32imm);
369 // addrmode3 := reg +/- reg
370 // addrmode3 := reg +/- imm8
372 def addrmode3 : Operand<i32>,
373 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
374 let PrintMethod = "printAddrMode3Operand";
375 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
378 def am3offset : Operand<i32>,
379 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
380 let PrintMethod = "printAddrMode3OffsetOperand";
381 let MIOperandInfo = (ops GPR, i32imm);
384 // addrmode4 := reg, <mode|W>
386 def addrmode4 : Operand<i32>,
387 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
388 let PrintMethod = "printAddrMode4Operand";
389 let MIOperandInfo = (ops GPR:$addr, i32imm);
392 // addrmode5 := reg +/- imm8*4
394 def addrmode5 : Operand<i32>,
395 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
396 let PrintMethod = "printAddrMode5Operand";
397 let MIOperandInfo = (ops GPR:$base, i32imm);
400 // addrmode6 := reg with optional writeback
402 def addrmode6 : Operand<i32>,
403 ComplexPattern<i32, 2, "SelectAddrMode6", []> {
404 let PrintMethod = "printAddrMode6Operand";
405 let MIOperandInfo = (ops GPR:$addr, i32imm);
408 def am6offset : Operand<i32> {
409 let PrintMethod = "printAddrMode6OffsetOperand";
410 let MIOperandInfo = (ops GPR);
413 // addrmodepc := pc + reg
415 def addrmodepc : Operand<i32>,
416 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
417 let PrintMethod = "printAddrModePCOperand";
418 let MIOperandInfo = (ops GPR, i32imm);
421 def nohash_imm : Operand<i32> {
422 let PrintMethod = "printNoHashImmediate";
425 //===----------------------------------------------------------------------===//
427 include "ARMInstrFormats.td"
429 //===----------------------------------------------------------------------===//
430 // Multiclass helpers...
433 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
434 /// binop that produces a value.
435 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
436 bit Commutable = 0> {
437 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
438 IIC_iALUi, opc, "\t$dst, $a, $b",
439 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
442 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
443 IIC_iALUr, opc, "\t$dst, $a, $b",
444 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
445 let Inst{11-4} = 0b00000000;
447 let isCommutable = Commutable;
449 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
450 IIC_iALUsr, opc, "\t$dst, $a, $b",
451 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
456 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
457 /// instruction modifies the CPSR register.
458 let Defs = [CPSR] in {
459 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
460 bit Commutable = 0> {
461 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
462 IIC_iALUi, opc, "\t$dst, $a, $b",
463 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
467 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
468 IIC_iALUr, opc, "\t$dst, $a, $b",
469 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
470 let isCommutable = Commutable;
471 let Inst{11-4} = 0b00000000;
475 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
476 IIC_iALUsr, opc, "\t$dst, $a, $b",
477 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
484 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
485 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
486 /// a explicit result, only implicitly set CPSR.
487 let Defs = [CPSR] in {
488 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
489 bit Commutable = 0> {
490 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
492 [(opnode GPR:$a, so_imm:$b)]> {
496 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
498 [(opnode GPR:$a, GPR:$b)]> {
499 let Inst{11-4} = 0b00000000;
502 let isCommutable = Commutable;
504 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
506 [(opnode GPR:$a, so_reg:$b)]> {
513 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
514 /// register and one whose operand is a register rotated by 8/16/24.
515 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
516 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
517 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
518 IIC_iUNAr, opc, "\t$dst, $src",
519 [(set GPR:$dst, (opnode GPR:$src))]>,
520 Requires<[IsARM, HasV6]> {
521 let Inst{11-10} = 0b00;
522 let Inst{19-16} = 0b1111;
524 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
525 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
526 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
527 Requires<[IsARM, HasV6]> {
528 let Inst{19-16} = 0b1111;
532 multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
533 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
534 IIC_iUNAr, opc, "\t$dst, $src",
535 [/* For disassembly only; pattern left blank */]>,
536 Requires<[IsARM, HasV6]> {
537 let Inst{11-10} = 0b00;
538 let Inst{19-16} = 0b1111;
540 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
541 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
542 [/* For disassembly only; pattern left blank */]>,
543 Requires<[IsARM, HasV6]> {
544 let Inst{19-16} = 0b1111;
548 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
549 /// register and one whose operand is a register rotated by 8/16/24.
550 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
551 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
552 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
553 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
554 Requires<[IsARM, HasV6]> {
555 let Inst{11-10} = 0b00;
557 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
559 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
560 [(set GPR:$dst, (opnode GPR:$LHS,
561 (rotr GPR:$RHS, rot_imm:$rot)))]>,
562 Requires<[IsARM, HasV6]>;
565 // For disassembly only.
566 multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
567 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
568 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
569 [/* For disassembly only; pattern left blank */]>,
570 Requires<[IsARM, HasV6]> {
571 let Inst{11-10} = 0b00;
573 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
575 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
576 [/* For disassembly only; pattern left blank */]>,
577 Requires<[IsARM, HasV6]>;
580 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
581 let Uses = [CPSR] in {
582 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
583 bit Commutable = 0> {
584 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
585 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
586 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
590 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
591 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
592 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
594 let isCommutable = Commutable;
595 let Inst{11-4} = 0b00000000;
598 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
599 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
600 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
605 // Carry setting variants
606 let Defs = [CPSR] in {
607 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
608 bit Commutable = 0> {
609 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
610 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
611 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
616 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
617 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
618 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
620 let Inst{11-4} = 0b00000000;
624 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
625 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
626 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
635 //===----------------------------------------------------------------------===//
637 //===----------------------------------------------------------------------===//
639 //===----------------------------------------------------------------------===//
640 // Miscellaneous Instructions.
643 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
644 /// the function. The first operand is the ID# for this instruction, the second
645 /// is the index into the MachineConstantPool that this is, the third is the
646 /// size in bytes of this constant pool entry.
647 let neverHasSideEffects = 1, isNotDuplicable = 1 in
648 def CONSTPOOL_ENTRY :
649 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
650 i32imm:$size), NoItinerary,
651 "${instid:label} ${cpidx:cpentry}", []>;
653 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
654 // from removing one half of the matched pairs. That breaks PEI, which assumes
655 // these will always be in pairs, and asserts if it finds otherwise. Better way?
656 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
658 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
659 "${:comment} ADJCALLSTACKUP $amt1",
660 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
662 def ADJCALLSTACKDOWN :
663 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
664 "${:comment} ADJCALLSTACKDOWN $amt",
665 [(ARMcallseq_start timm:$amt)]>;
668 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
669 [/* For disassembly only; pattern left blank */]>,
670 Requires<[IsARM, HasV6T2]> {
671 let Inst{27-16} = 0b001100100000;
672 let Inst{7-0} = 0b00000000;
675 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
676 [/* For disassembly only; pattern left blank */]>,
677 Requires<[IsARM, HasV6T2]> {
678 let Inst{27-16} = 0b001100100000;
679 let Inst{7-0} = 0b00000001;
682 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
683 [/* For disassembly only; pattern left blank */]>,
684 Requires<[IsARM, HasV6T2]> {
685 let Inst{27-16} = 0b001100100000;
686 let Inst{7-0} = 0b00000010;
689 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
690 [/* For disassembly only; pattern left blank */]>,
691 Requires<[IsARM, HasV6T2]> {
692 let Inst{27-16} = 0b001100100000;
693 let Inst{7-0} = 0b00000011;
696 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
698 [/* For disassembly only; pattern left blank */]>,
699 Requires<[IsARM, HasV6]> {
700 let Inst{27-20} = 0b01101000;
701 let Inst{7-4} = 0b1011;
704 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
705 [/* For disassembly only; pattern left blank */]>,
706 Requires<[IsARM, HasV6T2]> {
707 let Inst{27-16} = 0b001100100000;
708 let Inst{7-0} = 0b00000100;
711 // The i32imm operand $val can be used by a debugger to store more information
712 // about the breakpoint.
713 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
714 [/* For disassembly only; pattern left blank */]>,
716 let Inst{27-20} = 0b00010010;
717 let Inst{7-4} = 0b0111;
720 // Change Processor State is a system instruction -- for disassembly only.
721 // The singleton $opt operand contains the following information:
722 // opt{4-0} = mode from Inst{4-0}
723 // opt{5} = changemode from Inst{17}
724 // opt{8-6} = AIF from Inst{8-6}
725 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
726 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
727 [/* For disassembly only; pattern left blank */]>,
729 let Inst{31-28} = 0b1111;
730 let Inst{27-20} = 0b00010000;
735 // Preload signals the memory system of possible future data/instruction access.
736 // These are for disassembly only.
738 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
739 // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
740 multiclass APreLoad<bit data, bit read, string opc> {
742 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
743 !strconcat(opc, "\t[$base, $imm]"), []> {
744 let Inst{31-26} = 0b111101;
745 let Inst{25} = 0; // 0 for immediate form
748 let Inst{21-20} = 0b01;
751 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
752 !strconcat(opc, "\t$addr"), []> {
753 let Inst{31-26} = 0b111101;
754 let Inst{25} = 1; // 1 for register form
757 let Inst{21-20} = 0b01;
762 defm PLD : APreLoad<1, 1, "pld">;
763 defm PLDW : APreLoad<1, 0, "pldw">;
764 defm PLI : APreLoad<0, 1, "pli">;
766 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
767 [/* For disassembly only; pattern left blank */]>,
769 let Inst{31-28} = 0b1111;
770 let Inst{27-20} = 0b00010000;
773 let Inst{7-4} = 0b0000;
776 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
777 [/* For disassembly only; pattern left blank */]>,
779 let Inst{31-28} = 0b1111;
780 let Inst{27-20} = 0b00010000;
783 let Inst{7-4} = 0b0000;
786 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
787 [/* For disassembly only; pattern left blank */]>,
788 Requires<[IsARM, HasV7]> {
789 let Inst{27-16} = 0b001100100000;
790 let Inst{7-4} = 0b1111;
793 // A5.4 Permanently UNDEFINED instructions.
794 // FIXME: Temporary emitted as raw bytes until this pseudo-op will be added to
796 let isBarrier = 1, isTerminator = 1 in
797 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
798 ".long 0xe7ffdefe ${:comment} trap", [(trap)]>,
800 let Inst{27-25} = 0b011;
801 let Inst{24-20} = 0b11111;
802 let Inst{7-5} = 0b111;
806 // Address computation and loads and stores in PIC mode.
807 let isNotDuplicable = 1 in {
808 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
809 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
810 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
812 let AddedComplexity = 10 in {
813 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
814 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
815 [(set GPR:$dst, (load addrmodepc:$addr))]>;
817 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
818 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
819 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
821 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
822 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
823 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
825 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
826 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
827 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
829 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
830 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
831 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
833 let AddedComplexity = 10 in {
834 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
835 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
836 [(store GPR:$src, addrmodepc:$addr)]>;
838 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
839 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
840 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
842 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
843 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
844 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
846 } // isNotDuplicable = 1
849 // LEApcrel - Load a pc-relative address into a register without offending the
851 let neverHasSideEffects = 1 in {
852 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
854 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
855 "${:private}PCRELL${:uid}+8))\n"),
856 !strconcat("${:private}PCRELL${:uid}:\n\t",
857 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
860 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
861 (ins i32imm:$label, nohash_imm:$id, pred:$p),
863 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
865 "${:private}PCRELL${:uid}+8))\n"),
866 !strconcat("${:private}PCRELL${:uid}:\n\t",
867 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
871 } // neverHasSideEffects
873 //===----------------------------------------------------------------------===//
874 // Control Flow Instructions.
877 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
879 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
880 "bx", "\tlr", [(ARMretflag)]>,
881 Requires<[IsARM, HasV4T]> {
882 let Inst{3-0} = 0b1110;
883 let Inst{7-4} = 0b0001;
884 let Inst{19-8} = 0b111111111111;
885 let Inst{27-20} = 0b00010010;
889 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
890 "mov", "\tpc, lr", [(ARMretflag)]>,
891 Requires<[IsARM, NoV4T]> {
892 let Inst{11-0} = 0b000000001110;
893 let Inst{15-12} = 0b1111;
894 let Inst{19-16} = 0b0000;
895 let Inst{27-20} = 0b00011010;
900 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
902 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
904 Requires<[IsARM, HasV4T]> {
905 let Inst{7-4} = 0b0001;
906 let Inst{19-8} = 0b111111111111;
907 let Inst{27-20} = 0b00010010;
908 let Inst{31-28} = 0b1110;
912 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
914 Requires<[IsARM, NoV4T]> {
915 let Inst{11-4} = 0b00000000;
916 let Inst{15-12} = 0b1111;
917 let Inst{19-16} = 0b0000;
918 let Inst{27-20} = 0b00011010;
919 let Inst{31-28} = 0b1110;
923 // FIXME: remove when we have a way to marking a MI with these properties.
924 // FIXME: Should pc be an implicit operand like PICADD, etc?
925 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
926 hasExtraDefRegAllocReq = 1 in
927 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
928 reglist:$dsts, variable_ops),
929 IndexModeUpd, LdStMulFrm, IIC_Br,
930 "ldm${addr:submode}${p}\t$addr!, $dsts",
931 "$addr.addr = $wb", []>;
933 // On non-Darwin platforms R9 is callee-saved.
935 Defs = [R0, R1, R2, R3, R12, LR,
936 D0, D1, D2, D3, D4, D5, D6, D7,
937 D16, D17, D18, D19, D20, D21, D22, D23,
938 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
939 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
940 IIC_Br, "bl\t${func:call}",
941 [(ARMcall tglobaladdr:$func)]>,
942 Requires<[IsARM, IsNotDarwin]> {
943 let Inst{31-28} = 0b1110;
946 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
947 IIC_Br, "bl", "\t${func:call}",
948 [(ARMcall_pred tglobaladdr:$func)]>,
949 Requires<[IsARM, IsNotDarwin]>;
952 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
953 IIC_Br, "blx\t$func",
954 [(ARMcall GPR:$func)]>,
955 Requires<[IsARM, HasV5T, IsNotDarwin]> {
956 let Inst{7-4} = 0b0011;
957 let Inst{19-8} = 0b111111111111;
958 let Inst{27-20} = 0b00010010;
962 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
963 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
964 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
965 [(ARMcall_nolink tGPR:$func)]>,
966 Requires<[IsARM, HasV4T, IsNotDarwin]> {
967 let Inst{7-4} = 0b0001;
968 let Inst{19-8} = 0b111111111111;
969 let Inst{27-20} = 0b00010010;
973 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
974 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
975 [(ARMcall_nolink tGPR:$func)]>,
976 Requires<[IsARM, NoV4T, IsNotDarwin]> {
977 let Inst{11-4} = 0b00000000;
978 let Inst{15-12} = 0b1111;
979 let Inst{19-16} = 0b0000;
980 let Inst{27-20} = 0b00011010;
984 // On Darwin R9 is call-clobbered.
986 Defs = [R0, R1, R2, R3, R9, R12, LR,
987 D0, D1, D2, D3, D4, D5, D6, D7,
988 D16, D17, D18, D19, D20, D21, D22, D23,
989 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
990 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
991 IIC_Br, "bl\t${func:call}",
992 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
993 let Inst{31-28} = 0b1110;
996 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
997 IIC_Br, "bl", "\t${func:call}",
998 [(ARMcall_pred tglobaladdr:$func)]>,
999 Requires<[IsARM, IsDarwin]>;
1002 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1003 IIC_Br, "blx\t$func",
1004 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1005 let Inst{7-4} = 0b0011;
1006 let Inst{19-8} = 0b111111111111;
1007 let Inst{27-20} = 0b00010010;
1011 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1012 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1013 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1014 [(ARMcall_nolink tGPR:$func)]>,
1015 Requires<[IsARM, HasV4T, IsDarwin]> {
1016 let Inst{7-4} = 0b0001;
1017 let Inst{19-8} = 0b111111111111;
1018 let Inst{27-20} = 0b00010010;
1022 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1023 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1024 [(ARMcall_nolink tGPR:$func)]>,
1025 Requires<[IsARM, NoV4T, IsDarwin]> {
1026 let Inst{11-4} = 0b00000000;
1027 let Inst{15-12} = 0b1111;
1028 let Inst{19-16} = 0b0000;
1029 let Inst{27-20} = 0b00011010;
1033 let isBranch = 1, isTerminator = 1 in {
1034 // B is "predicable" since it can be xformed into a Bcc.
1035 let isBarrier = 1 in {
1036 let isPredicable = 1 in
1037 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1038 "b\t$target", [(br bb:$target)]>;
1040 let isNotDuplicable = 1, isIndirectBranch = 1 in {
1041 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1042 IIC_Br, "mov\tpc, $target \n$jt",
1043 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1044 let Inst{11-4} = 0b00000000;
1045 let Inst{15-12} = 0b1111;
1046 let Inst{20} = 0; // S Bit
1047 let Inst{24-21} = 0b1101;
1048 let Inst{27-25} = 0b000;
1050 def BR_JTm : JTI<(outs),
1051 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1052 IIC_Br, "ldr\tpc, $target \n$jt",
1053 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1055 let Inst{15-12} = 0b1111;
1056 let Inst{20} = 1; // L bit
1057 let Inst{21} = 0; // W bit
1058 let Inst{22} = 0; // B bit
1059 let Inst{24} = 1; // P bit
1060 let Inst{27-25} = 0b011;
1062 def BR_JTadd : JTI<(outs),
1063 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1064 IIC_Br, "add\tpc, $target, $idx \n$jt",
1065 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1067 let Inst{15-12} = 0b1111;
1068 let Inst{20} = 0; // S bit
1069 let Inst{24-21} = 0b0100;
1070 let Inst{27-25} = 0b000;
1072 } // isNotDuplicable = 1, isIndirectBranch = 1
1075 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1076 // a two-value operand where a dag node expects two operands. :(
1077 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1078 IIC_Br, "b", "\t$target",
1079 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
1082 // Branch and Exchange Jazelle -- for disassembly only
1083 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1084 [/* For disassembly only; pattern left blank */]> {
1085 let Inst{23-20} = 0b0010;
1086 //let Inst{19-8} = 0xfff;
1087 let Inst{7-4} = 0b0010;
1090 // Secure Monitor Call is a system instruction -- for disassembly only
1091 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1092 [/* For disassembly only; pattern left blank */]> {
1093 let Inst{23-20} = 0b0110;
1094 let Inst{7-4} = 0b0111;
1097 // Supervisor Call (Software Interrupt) -- for disassembly only
1099 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1100 [/* For disassembly only; pattern left blank */]>;
1103 // Store Return State is a system instruction -- for disassembly only
1104 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1105 NoItinerary, "srs${addr:submode}\tsp!, $mode",
1106 [/* For disassembly only; pattern left blank */]> {
1107 let Inst{31-28} = 0b1111;
1108 let Inst{22-20} = 0b110; // W = 1
1111 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
1112 NoItinerary, "srs${addr:submode}\tsp, $mode",
1113 [/* For disassembly only; pattern left blank */]> {
1114 let Inst{31-28} = 0b1111;
1115 let Inst{22-20} = 0b100; // W = 0
1118 // Return From Exception is a system instruction -- for disassembly only
1119 def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1120 NoItinerary, "rfe${addr:submode}\t$base!",
1121 [/* For disassembly only; pattern left blank */]> {
1122 let Inst{31-28} = 0b1111;
1123 let Inst{22-20} = 0b011; // W = 1
1126 def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
1127 NoItinerary, "rfe${addr:submode}\t$base",
1128 [/* For disassembly only; pattern left blank */]> {
1129 let Inst{31-28} = 0b1111;
1130 let Inst{22-20} = 0b001; // W = 0
1133 //===----------------------------------------------------------------------===//
1134 // Load / store Instructions.
1138 let canFoldAsLoad = 1, isReMaterializable = 1 in
1139 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1140 "ldr", "\t$dst, $addr",
1141 [(set GPR:$dst, (load addrmode2:$addr))]>;
1143 // Special LDR for loads from non-pc-relative constpools.
1144 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1145 isReMaterializable = 1 in
1146 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
1147 "ldr", "\t$dst, $addr", []>;
1149 // Loads with zero extension
1150 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1151 IIC_iLoadr, "ldrh", "\t$dst, $addr",
1152 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1154 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
1155 IIC_iLoadr, "ldrb", "\t$dst, $addr",
1156 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
1158 // Loads with sign extension
1159 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1160 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
1161 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1163 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1164 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
1165 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1167 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1169 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1170 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1171 []>, Requires<[IsARM, HasV5TE]>;
1174 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1175 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1176 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1178 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1179 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1180 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1182 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1183 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1184 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1186 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1187 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1188 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1190 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1191 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1192 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1194 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1195 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1196 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1198 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1199 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1200 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1202 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1203 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1204 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1206 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1207 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1208 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1210 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1211 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1212 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1214 // For disassembly only
1215 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1216 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
1217 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1218 Requires<[IsARM, HasV5TE]>;
1220 // For disassembly only
1221 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1222 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
1223 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1224 Requires<[IsARM, HasV5TE]>;
1226 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1228 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1230 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1231 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1232 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1233 let Inst{21} = 1; // overwrite
1236 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1237 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1238 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1239 let Inst{21} = 1; // overwrite
1242 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1243 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1244 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1245 let Inst{21} = 1; // overwrite
1248 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1249 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1250 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1251 let Inst{21} = 1; // overwrite
1254 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1255 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1256 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1257 let Inst{21} = 1; // overwrite
1261 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1262 "str", "\t$src, $addr",
1263 [(store GPR:$src, addrmode2:$addr)]>;
1265 // Stores with truncate
1266 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
1267 IIC_iStorer, "strh", "\t$src, $addr",
1268 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1270 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1271 "strb", "\t$src, $addr",
1272 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1275 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
1276 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1277 StMiscFrm, IIC_iStorer,
1278 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1281 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1282 (ins GPR:$src, GPR:$base, am2offset:$offset),
1283 StFrm, IIC_iStoreru,
1284 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1286 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1288 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1289 (ins GPR:$src, GPR:$base,am2offset:$offset),
1290 StFrm, IIC_iStoreru,
1291 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1293 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1295 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1296 (ins GPR:$src, GPR:$base,am3offset:$offset),
1297 StMiscFrm, IIC_iStoreru,
1298 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1300 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1302 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1303 (ins GPR:$src, GPR:$base,am3offset:$offset),
1304 StMiscFrm, IIC_iStoreru,
1305 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1306 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1307 GPR:$base, am3offset:$offset))]>;
1309 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1310 (ins GPR:$src, GPR:$base,am2offset:$offset),
1311 StFrm, IIC_iStoreru,
1312 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1313 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1314 GPR:$base, am2offset:$offset))]>;
1316 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1317 (ins GPR:$src, GPR:$base,am2offset:$offset),
1318 StFrm, IIC_iStoreru,
1319 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1320 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1321 GPR:$base, am2offset:$offset))]>;
1323 // For disassembly only
1324 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1325 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1326 StMiscFrm, IIC_iStoreru,
1327 "strd", "\t$src1, $src2, [$base, $offset]!",
1328 "$base = $base_wb", []>;
1330 // For disassembly only
1331 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1332 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1333 StMiscFrm, IIC_iStoreru,
1334 "strd", "\t$src1, $src2, [$base], $offset",
1335 "$base = $base_wb", []>;
1337 // STRT, STRBT, and STRHT are for disassembly only.
1339 def STRT : AI2stwpo<(outs GPR:$base_wb),
1340 (ins GPR:$src, GPR:$base,am2offset:$offset),
1341 StFrm, IIC_iStoreru,
1342 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1343 [/* For disassembly only; pattern left blank */]> {
1344 let Inst{21} = 1; // overwrite
1347 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1348 (ins GPR:$src, GPR:$base,am2offset:$offset),
1349 StFrm, IIC_iStoreru,
1350 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1351 [/* For disassembly only; pattern left blank */]> {
1352 let Inst{21} = 1; // overwrite
1355 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1356 (ins GPR:$src, GPR:$base,am3offset:$offset),
1357 StMiscFrm, IIC_iStoreru,
1358 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1359 [/* For disassembly only; pattern left blank */]> {
1360 let Inst{21} = 1; // overwrite
1363 //===----------------------------------------------------------------------===//
1364 // Load / store multiple Instructions.
1367 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
1368 def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
1369 reglist:$dsts, variable_ops),
1370 IndexModeNone, LdStMulFrm, IIC_iLoadm,
1371 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
1373 def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1374 reglist:$dsts, variable_ops),
1375 IndexModeUpd, LdStMulFrm, IIC_iLoadm,
1376 "ldm${addr:submode}${p}\t$addr!, $dsts",
1377 "$addr.addr = $wb", []>;
1378 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
1380 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
1381 def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
1382 reglist:$srcs, variable_ops),
1383 IndexModeNone, LdStMulFrm, IIC_iStorem,
1384 "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
1386 def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
1387 reglist:$srcs, variable_ops),
1388 IndexModeUpd, LdStMulFrm, IIC_iStorem,
1389 "stm${addr:submode}${p}\t$addr!, $srcs",
1390 "$addr.addr = $wb", []>;
1391 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
1393 //===----------------------------------------------------------------------===//
1394 // Move Instructions.
1397 let neverHasSideEffects = 1 in
1398 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1399 "mov", "\t$dst, $src", []>, UnaryDP {
1400 let Inst{11-4} = 0b00000000;
1404 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1405 DPSoRegFrm, IIC_iMOVsr,
1406 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1410 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1411 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1412 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1416 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1417 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1419 "movw", "\t$dst, $src",
1420 [(set GPR:$dst, imm0_65535:$src)]>,
1421 Requires<[IsARM, HasV6T2]>, UnaryDP {
1426 let Constraints = "$src = $dst" in
1427 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1429 "movt", "\t$dst, $imm",
1431 (or (and GPR:$src, 0xffff),
1432 lo16AllZero:$imm))]>, UnaryDP,
1433 Requires<[IsARM, HasV6T2]> {
1438 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1439 Requires<[IsARM, HasV6T2]>;
1441 let Uses = [CPSR] in
1442 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1443 "mov", "\t$dst, $src, rrx",
1444 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1446 // These aren't really mov instructions, but we have to define them this way
1447 // due to flag operands.
1449 let Defs = [CPSR] in {
1450 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1451 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1452 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1453 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1454 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1455 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1458 //===----------------------------------------------------------------------===//
1459 // Extend Instructions.
1464 defm SXTB : AI_unary_rrot<0b01101010,
1465 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1466 defm SXTH : AI_unary_rrot<0b01101011,
1467 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1469 defm SXTAB : AI_bin_rrot<0b01101010,
1470 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1471 defm SXTAH : AI_bin_rrot<0b01101011,
1472 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1474 // For disassembly only
1475 defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
1477 // For disassembly only
1478 defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
1482 let AddedComplexity = 16 in {
1483 defm UXTB : AI_unary_rrot<0b01101110,
1484 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1485 defm UXTH : AI_unary_rrot<0b01101111,
1486 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1487 defm UXTB16 : AI_unary_rrot<0b01101100,
1488 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1490 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1491 (UXTB16r_rot GPR:$Src, 24)>;
1492 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1493 (UXTB16r_rot GPR:$Src, 8)>;
1495 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1496 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1497 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1498 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1501 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1502 // For disassembly only
1503 defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
1506 def SBFX : I<(outs GPR:$dst),
1507 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1508 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1509 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1510 Requires<[IsARM, HasV6T2]> {
1511 let Inst{27-21} = 0b0111101;
1512 let Inst{6-4} = 0b101;
1515 def UBFX : I<(outs GPR:$dst),
1516 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1517 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1518 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1519 Requires<[IsARM, HasV6T2]> {
1520 let Inst{27-21} = 0b0111111;
1521 let Inst{6-4} = 0b101;
1524 //===----------------------------------------------------------------------===//
1525 // Arithmetic Instructions.
1528 defm ADD : AsI1_bin_irs<0b0100, "add",
1529 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1530 defm SUB : AsI1_bin_irs<0b0010, "sub",
1531 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1533 // ADD and SUB with 's' bit set.
1534 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1535 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1536 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1537 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1539 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1540 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1541 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1542 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1543 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1544 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1545 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1546 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1548 // These don't define reg/reg forms, because they are handled above.
1549 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1550 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1551 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1555 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1556 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1557 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1561 // RSB with 's' bit set.
1562 let Defs = [CPSR] in {
1563 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1564 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1565 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1569 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1570 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1571 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1577 let Uses = [CPSR] in {
1578 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1579 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1580 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1584 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1585 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1586 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1592 // FIXME: Allow these to be predicated.
1593 let Defs = [CPSR], Uses = [CPSR] in {
1594 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1595 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1596 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1601 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1602 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1603 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1610 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1611 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1612 (SUBri GPR:$src, so_imm_neg:$imm)>;
1614 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1615 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1616 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1617 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1619 // Note: These are implemented in C++ code, because they have to generate
1620 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1622 // (mul X, 2^n+1) -> (add (X << n), X)
1623 // (mul X, 2^n-1) -> (rsb X, (X << n))
1625 // ARM Arithmetic Instruction -- for disassembly only
1626 // GPR:$dst = GPR:$a op GPR:$b
1627 class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
1628 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1629 opc, "\t$dst, $a, $b",
1630 [/* For disassembly only; pattern left blank */]> {
1631 let Inst{27-20} = op27_20;
1632 let Inst{7-4} = op7_4;
1635 // Saturating add/subtract -- for disassembly only
1637 def QADD : AAI<0b00010000, 0b0101, "qadd">;
1638 def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
1639 def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
1640 def QASX : AAI<0b01100010, 0b0011, "qasx">;
1641 def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
1642 def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
1643 def QSAX : AAI<0b01100010, 0b0101, "qsax">;
1644 def QSUB : AAI<0b00010010, 0b0101, "qsub">;
1645 def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
1646 def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
1647 def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
1648 def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
1649 def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
1650 def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
1651 def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
1652 def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
1654 // Signed/Unsigned add/subtract -- for disassembly only
1656 def SASX : AAI<0b01100001, 0b0011, "sasx">;
1657 def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
1658 def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
1659 def SSAX : AAI<0b01100001, 0b0101, "ssax">;
1660 def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
1661 def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
1662 def UASX : AAI<0b01100101, 0b0011, "uasx">;
1663 def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
1664 def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
1665 def USAX : AAI<0b01100101, 0b0101, "usax">;
1666 def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
1667 def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
1669 // Signed/Unsigned halving add/subtract -- for disassembly only
1671 def SHASX : AAI<0b01100011, 0b0011, "shasx">;
1672 def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
1673 def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
1674 def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
1675 def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
1676 def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
1677 def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
1678 def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
1679 def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
1680 def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
1681 def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
1682 def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
1684 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
1686 def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
1687 MulFrm /* for convenience */, NoItinerary, "usad8",
1688 "\t$dst, $a, $b", []>,
1689 Requires<[IsARM, HasV6]> {
1690 let Inst{27-20} = 0b01111000;
1691 let Inst{15-12} = 0b1111;
1692 let Inst{7-4} = 0b0001;
1694 def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1695 MulFrm /* for convenience */, NoItinerary, "usada8",
1696 "\t$dst, $a, $b, $acc", []>,
1697 Requires<[IsARM, HasV6]> {
1698 let Inst{27-20} = 0b01111000;
1699 let Inst{7-4} = 0b0001;
1702 // Signed/Unsigned saturate -- for disassembly only
1704 def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1705 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1706 [/* For disassembly only; pattern left blank */]> {
1707 let Inst{27-21} = 0b0110101;
1708 let Inst{6-4} = 0b001;
1711 def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1712 DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1713 [/* For disassembly only; pattern left blank */]> {
1714 let Inst{27-21} = 0b0110101;
1715 let Inst{6-4} = 0b101;
1718 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1719 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
1720 [/* For disassembly only; pattern left blank */]> {
1721 let Inst{27-20} = 0b01101010;
1722 let Inst{7-4} = 0b0011;
1725 def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1726 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1727 [/* For disassembly only; pattern left blank */]> {
1728 let Inst{27-21} = 0b0110111;
1729 let Inst{6-4} = 0b001;
1732 def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1733 DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1734 [/* For disassembly only; pattern left blank */]> {
1735 let Inst{27-21} = 0b0110111;
1736 let Inst{6-4} = 0b101;
1739 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
1740 NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
1741 [/* For disassembly only; pattern left blank */]> {
1742 let Inst{27-20} = 0b01101110;
1743 let Inst{7-4} = 0b0011;
1746 //===----------------------------------------------------------------------===//
1747 // Bitwise Instructions.
1750 defm AND : AsI1_bin_irs<0b0000, "and",
1751 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1752 defm ORR : AsI1_bin_irs<0b1100, "orr",
1753 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1754 defm EOR : AsI1_bin_irs<0b0001, "eor",
1755 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1756 defm BIC : AsI1_bin_irs<0b1110, "bic",
1757 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1759 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1760 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1761 "bfc", "\t$dst, $imm", "$src = $dst",
1762 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1763 Requires<[IsARM, HasV6T2]> {
1764 let Inst{27-21} = 0b0111110;
1765 let Inst{6-0} = 0b0011111;
1768 // A8.6.18 BFI - Bitfield insert (Encoding A1)
1769 // Added for disassembler with the pattern field purposely left blank.
1770 def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1771 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1772 "bfi", "\t$dst, $src, $imm", "",
1773 [/* For disassembly only; pattern left blank */]>,
1774 Requires<[IsARM, HasV6T2]> {
1775 let Inst{27-21} = 0b0111110;
1776 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
1779 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1780 "mvn", "\t$dst, $src",
1781 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1783 let Inst{11-4} = 0b00000000;
1785 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1786 IIC_iMOVsr, "mvn", "\t$dst, $src",
1787 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1790 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1791 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1792 IIC_iMOVi, "mvn", "\t$dst, $imm",
1793 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1797 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1798 (BICri GPR:$src, so_imm_not:$imm)>;
1800 //===----------------------------------------------------------------------===//
1801 // Multiply Instructions.
1804 let isCommutable = 1 in
1805 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1806 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1807 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1809 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1810 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1811 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1813 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1814 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1815 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1816 Requires<[IsARM, HasV6T2]>;
1818 // Extra precision multiplies with low / high results
1819 let neverHasSideEffects = 1 in {
1820 let isCommutable = 1 in {
1821 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1822 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1823 "smull", "\t$ldst, $hdst, $a, $b", []>;
1825 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1826 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1827 "umull", "\t$ldst, $hdst, $a, $b", []>;
1830 // Multiply + accumulate
1831 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1832 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1833 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1835 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1836 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1837 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1839 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1840 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1841 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1842 Requires<[IsARM, HasV6]>;
1843 } // neverHasSideEffects
1845 // Most significant word multiply
1846 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1847 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1848 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1849 Requires<[IsARM, HasV6]> {
1850 let Inst{7-4} = 0b0001;
1851 let Inst{15-12} = 0b1111;
1854 def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1855 IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
1856 [/* For disassembly only; pattern left blank */]>,
1857 Requires<[IsARM, HasV6]> {
1858 let Inst{7-4} = 0b0011; // R = 1
1859 let Inst{15-12} = 0b1111;
1862 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1863 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1864 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1865 Requires<[IsARM, HasV6]> {
1866 let Inst{7-4} = 0b0001;
1869 def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1870 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
1871 [/* For disassembly only; pattern left blank */]>,
1872 Requires<[IsARM, HasV6]> {
1873 let Inst{7-4} = 0b0011; // R = 1
1876 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1877 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1878 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1879 Requires<[IsARM, HasV6]> {
1880 let Inst{7-4} = 0b1101;
1883 def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1884 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
1885 [/* For disassembly only; pattern left blank */]>,
1886 Requires<[IsARM, HasV6]> {
1887 let Inst{7-4} = 0b1111; // R = 1
1890 multiclass AI_smul<string opc, PatFrag opnode> {
1891 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1892 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1893 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1894 (sext_inreg GPR:$b, i16)))]>,
1895 Requires<[IsARM, HasV5TE]> {
1900 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1901 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1902 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1903 (sra GPR:$b, (i32 16))))]>,
1904 Requires<[IsARM, HasV5TE]> {
1909 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1910 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1911 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1912 (sext_inreg GPR:$b, i16)))]>,
1913 Requires<[IsARM, HasV5TE]> {
1918 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1919 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1920 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1921 (sra GPR:$b, (i32 16))))]>,
1922 Requires<[IsARM, HasV5TE]> {
1927 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1928 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1929 [(set GPR:$dst, (sra (opnode GPR:$a,
1930 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1931 Requires<[IsARM, HasV5TE]> {
1936 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1937 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1938 [(set GPR:$dst, (sra (opnode GPR:$a,
1939 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1940 Requires<[IsARM, HasV5TE]> {
1947 multiclass AI_smla<string opc, PatFrag opnode> {
1948 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1949 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1950 [(set GPR:$dst, (add GPR:$acc,
1951 (opnode (sext_inreg GPR:$a, i16),
1952 (sext_inreg GPR:$b, i16))))]>,
1953 Requires<[IsARM, HasV5TE]> {
1958 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1959 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1960 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1961 (sra GPR:$b, (i32 16)))))]>,
1962 Requires<[IsARM, HasV5TE]> {
1967 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1968 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1969 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1970 (sext_inreg GPR:$b, i16))))]>,
1971 Requires<[IsARM, HasV5TE]> {
1976 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1977 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1978 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1979 (sra GPR:$b, (i32 16)))))]>,
1980 Requires<[IsARM, HasV5TE]> {
1985 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1986 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1987 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1988 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1989 Requires<[IsARM, HasV5TE]> {
1994 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1995 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1996 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1997 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1998 Requires<[IsARM, HasV5TE]> {
2004 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2005 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2007 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2008 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2009 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
2010 [/* For disassembly only; pattern left blank */]>,
2011 Requires<[IsARM, HasV5TE]> {
2016 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2017 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
2018 [/* For disassembly only; pattern left blank */]>,
2019 Requires<[IsARM, HasV5TE]> {
2024 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2025 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
2026 [/* For disassembly only; pattern left blank */]>,
2027 Requires<[IsARM, HasV5TE]> {
2032 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2033 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
2034 [/* For disassembly only; pattern left blank */]>,
2035 Requires<[IsARM, HasV5TE]> {
2040 // Helper class for AI_smld -- for disassembly only
2041 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2042 InstrItinClass itin, string opc, string asm>
2043 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2048 let Inst{21-20} = 0b00;
2049 let Inst{22} = long;
2050 let Inst{27-23} = 0b01110;
2053 multiclass AI_smld<bit sub, string opc> {
2055 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2056 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
2058 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
2059 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
2061 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
2062 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
2064 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
2065 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
2069 defm SMLA : AI_smld<0, "smla">;
2070 defm SMLS : AI_smld<1, "smls">;
2072 multiclass AI_sdml<bit sub, string opc> {
2074 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2075 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
2076 let Inst{15-12} = 0b1111;
2079 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
2080 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
2081 let Inst{15-12} = 0b1111;
2086 defm SMUA : AI_sdml<0, "smua">;
2087 defm SMUS : AI_sdml<1, "smus">;
2089 //===----------------------------------------------------------------------===//
2090 // Misc. Arithmetic Instructions.
2093 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2094 "clz", "\t$dst, $src",
2095 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
2096 let Inst{7-4} = 0b0001;
2097 let Inst{11-8} = 0b1111;
2098 let Inst{19-16} = 0b1111;
2101 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2102 "rbit", "\t$dst, $src",
2103 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
2104 Requires<[IsARM, HasV6T2]> {
2105 let Inst{7-4} = 0b0011;
2106 let Inst{11-8} = 0b1111;
2107 let Inst{19-16} = 0b1111;
2110 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2111 "rev", "\t$dst, $src",
2112 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
2113 let Inst{7-4} = 0b0011;
2114 let Inst{11-8} = 0b1111;
2115 let Inst{19-16} = 0b1111;
2118 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2119 "rev16", "\t$dst, $src",
2121 (or (and (srl GPR:$src, (i32 8)), 0xFF),
2122 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
2123 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
2124 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
2125 Requires<[IsARM, HasV6]> {
2126 let Inst{7-4} = 0b1011;
2127 let Inst{11-8} = 0b1111;
2128 let Inst{19-16} = 0b1111;
2131 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
2132 "revsh", "\t$dst, $src",
2135 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
2136 (shl GPR:$src, (i32 8))), i16))]>,
2137 Requires<[IsARM, HasV6]> {
2138 let Inst{7-4} = 0b1011;
2139 let Inst{11-8} = 0b1111;
2140 let Inst{19-16} = 0b1111;
2143 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
2144 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2145 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
2146 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
2147 (and (shl GPR:$src2, (i32 imm:$shamt)),
2149 Requires<[IsARM, HasV6]> {
2150 let Inst{6-4} = 0b001;
2153 // Alternate cases for PKHBT where identities eliminate some nodes.
2154 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
2155 (PKHBT GPR:$src1, GPR:$src2, 0)>;
2156 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
2157 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
2160 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
2161 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
2162 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
2163 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
2164 (and (sra GPR:$src2, imm16_31:$shamt),
2165 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
2166 let Inst{6-4} = 0b101;
2169 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2170 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2171 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
2172 (PKHTB GPR:$src1, GPR:$src2, 16)>;
2173 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2174 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
2175 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
2177 //===----------------------------------------------------------------------===//
2178 // Comparison Instructions...
2181 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2182 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2183 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
2184 // Compare-to-zero still works out, just not the relationals
2185 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2186 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2188 // Note that TST/TEQ don't set all the same flags that CMP does!
2189 defm TST : AI1_cmp_irs<0b1000, "tst",
2190 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2191 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2192 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2194 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2195 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2196 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2197 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2199 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2200 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2202 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2203 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2206 // Conditional moves
2207 // FIXME: should be able to write a pattern for ARMcmov, but can't use
2208 // a two-value operand where a dag node expects two operands. :(
2209 let neverHasSideEffects = 1 in {
2210 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
2211 IIC_iCMOVr, "mov", "\t$dst, $true",
2212 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
2213 RegConstraint<"$false = $dst">, UnaryDP {
2214 let Inst{11-4} = 0b00000000;
2218 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
2219 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
2220 "mov", "\t$dst, $true",
2221 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
2222 RegConstraint<"$false = $dst">, UnaryDP {
2226 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
2227 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2228 "mov", "\t$dst, $true",
2229 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
2230 RegConstraint<"$false = $dst">, UnaryDP {
2233 } // neverHasSideEffects
2235 //===----------------------------------------------------------------------===//
2236 // Atomic operations intrinsics
2239 // memory barriers protect the atomic sequences
2240 let hasSideEffects = 1 in {
2241 def Int_MemBarrierV7 : AInoP<(outs), (ins),
2242 Pseudo, NoItinerary,
2244 [(ARMMemBarrierV7)]>,
2245 Requires<[IsARM, HasV7]> {
2246 let Inst{31-4} = 0xf57ff05;
2247 // FIXME: add support for options other than a full system DMB
2248 // See DMB disassembly-only variants below.
2249 let Inst{3-0} = 0b1111;
2252 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
2253 Pseudo, NoItinerary,
2255 [(ARMSyncBarrierV7)]>,
2256 Requires<[IsARM, HasV7]> {
2257 let Inst{31-4} = 0xf57ff04;
2258 // FIXME: add support for options other than a full system DSB
2259 // See DSB disassembly-only variants below.
2260 let Inst{3-0} = 0b1111;
2263 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2264 Pseudo, NoItinerary,
2265 "mcr", "\tp15, 0, $zero, c7, c10, 5",
2266 [(ARMMemBarrierV6 GPR:$zero)]>,
2267 Requires<[IsARM, HasV6]> {
2268 // FIXME: add support for options other than a full system DMB
2269 // FIXME: add encoding
2272 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
2273 Pseudo, NoItinerary,
2274 "mcr", "\tp15, 0, $zero, c7, c10, 4",
2275 [(ARMSyncBarrierV6 GPR:$zero)]>,
2276 Requires<[IsARM, HasV6]> {
2277 // FIXME: add support for options other than a full system DSB
2278 // FIXME: add encoding
2282 // Helper class for multiclass MemB -- for disassembly only
2283 class AMBI<string opc, string asm>
2284 : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
2285 [/* For disassembly only; pattern left blank */]>,
2286 Requires<[IsARM, HasV7]> {
2287 let Inst{31-20} = 0xf57;
2290 multiclass MemB<bits<4> op7_4, string opc> {
2292 def st : AMBI<opc, "\tst"> {
2293 let Inst{7-4} = op7_4;
2294 let Inst{3-0} = 0b1110;
2297 def ish : AMBI<opc, "\tish"> {
2298 let Inst{7-4} = op7_4;
2299 let Inst{3-0} = 0b1011;
2302 def ishst : AMBI<opc, "\tishst"> {
2303 let Inst{7-4} = op7_4;
2304 let Inst{3-0} = 0b1010;
2307 def nsh : AMBI<opc, "\tnsh"> {
2308 let Inst{7-4} = op7_4;
2309 let Inst{3-0} = 0b0111;
2312 def nshst : AMBI<opc, "\tnshst"> {
2313 let Inst{7-4} = op7_4;
2314 let Inst{3-0} = 0b0110;
2317 def osh : AMBI<opc, "\tosh"> {
2318 let Inst{7-4} = op7_4;
2319 let Inst{3-0} = 0b0011;
2322 def oshst : AMBI<opc, "\toshst"> {
2323 let Inst{7-4} = op7_4;
2324 let Inst{3-0} = 0b0010;
2328 // These DMB variants are for disassembly only.
2329 defm DMB : MemB<0b0101, "dmb">;
2331 // These DSB variants are for disassembly only.
2332 defm DSB : MemB<0b0100, "dsb">;
2334 // ISB has only full system option -- for disassembly only
2335 def ISBsy : AMBI<"isb", ""> {
2336 let Inst{7-4} = 0b0110;
2337 let Inst{3-0} = 0b1111;
2340 let usesCustomInserter = 1 in {
2341 let Uses = [CPSR] in {
2342 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
2343 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2344 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
2345 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
2346 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
2347 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2348 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
2349 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
2350 def ATOMIC_LOAD_AND_I8 : PseudoInst<
2351 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2352 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
2353 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
2354 def ATOMIC_LOAD_OR_I8 : PseudoInst<
2355 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2356 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
2357 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
2358 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
2359 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2360 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
2361 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
2362 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
2363 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2364 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
2365 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
2366 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
2367 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2368 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
2369 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
2370 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
2371 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2372 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
2373 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
2374 def ATOMIC_LOAD_AND_I16 : PseudoInst<
2375 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2376 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
2377 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
2378 def ATOMIC_LOAD_OR_I16 : PseudoInst<
2379 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2380 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
2381 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
2382 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
2383 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2384 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
2385 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
2386 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
2387 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2388 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
2389 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
2390 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
2391 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2392 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
2393 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
2394 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
2395 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2396 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
2397 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
2398 def ATOMIC_LOAD_AND_I32 : PseudoInst<
2399 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2400 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
2401 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
2402 def ATOMIC_LOAD_OR_I32 : PseudoInst<
2403 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2404 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
2405 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
2406 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
2407 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2408 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
2409 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
2410 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
2411 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
2412 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
2413 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
2415 def ATOMIC_SWAP_I8 : PseudoInst<
2416 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2417 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
2418 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
2419 def ATOMIC_SWAP_I16 : PseudoInst<
2420 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2421 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
2422 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
2423 def ATOMIC_SWAP_I32 : PseudoInst<
2424 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
2425 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
2426 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
2428 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
2429 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2430 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
2431 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
2432 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
2433 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2434 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
2435 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
2436 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
2437 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
2438 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
2439 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
2443 let mayLoad = 1 in {
2444 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2445 "ldrexb", "\t$dest, [$ptr]",
2447 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2448 "ldrexh", "\t$dest, [$ptr]",
2450 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
2451 "ldrex", "\t$dest, [$ptr]",
2453 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
2455 "ldrexd", "\t$dest, $dest2, [$ptr]",
2459 let mayStore = 1, Constraints = "@earlyclobber $success" in {
2460 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2462 "strexb", "\t$success, $src, [$ptr]",
2464 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2466 "strexh", "\t$success, $src, [$ptr]",
2468 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
2470 "strex", "\t$success, $src, [$ptr]",
2472 def STREXD : AIstrex<0b01, (outs GPR:$success),
2473 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2475 "strexd", "\t$success, $src, $src2, [$ptr]",
2479 // Clear-Exclusive is for disassembly only.
2480 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
2481 [/* For disassembly only; pattern left blank */]>,
2482 Requires<[IsARM, HasV7]> {
2483 let Inst{31-20} = 0xf57;
2484 let Inst{7-4} = 0b0001;
2487 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2488 let mayLoad = 1 in {
2489 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2490 "swp", "\t$dst, $src, [$ptr]",
2491 [/* For disassembly only; pattern left blank */]> {
2492 let Inst{27-23} = 0b00010;
2493 let Inst{22} = 0; // B = 0
2494 let Inst{21-20} = 0b00;
2495 let Inst{7-4} = 0b1001;
2498 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2499 "swpb", "\t$dst, $src, [$ptr]",
2500 [/* For disassembly only; pattern left blank */]> {
2501 let Inst{27-23} = 0b00010;
2502 let Inst{22} = 1; // B = 1
2503 let Inst{21-20} = 0b00;
2504 let Inst{7-4} = 0b1001;
2508 //===----------------------------------------------------------------------===//
2512 // __aeabi_read_tp preserves the registers r1-r3.
2514 Defs = [R0, R12, LR, CPSR] in {
2515 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2516 "bl\t__aeabi_read_tp",
2517 [(set R0, ARMthread_pointer)]>;
2520 //===----------------------------------------------------------------------===//
2521 // SJLJ Exception handling intrinsics
2522 // eh_sjlj_setjmp() is an instruction sequence to store the return
2523 // address and save #0 in R0 for the non-longjmp case.
2524 // Since by its nature we may be coming from some other function to get
2525 // here, and we're using the stack frame for the containing function to
2526 // save/restore registers, we can't keep anything live in regs across
2527 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2528 // when we get here from a longjmp(). We force everthing out of registers
2529 // except for our own input by listing the relevant registers in Defs. By
2530 // doing so, we also cause the prologue/epilogue code to actively preserve
2531 // all of the callee-saved resgisters, which is exactly what we want.
2532 // A constant value is passed in $val, and we use the location as a scratch.
2534 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2535 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2536 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2538 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2539 AddrModeNone, SizeSpecial, IndexModeNone,
2540 Pseudo, NoItinerary,
2541 "str\tsp, [$src, #+8] ${:comment} eh_setjmp begin\n\t"
2542 "add\t$val, pc, #8\n\t"
2543 "str\t$val, [$src, #+4]\n\t"
2545 "add\tpc, pc, #0\n\t"
2546 "mov\tr0, #1 ${:comment} eh_setjmp end", "",
2547 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2548 Requires<[IsARM, HasVFP2]>;
2552 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ] in {
2553 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
2554 AddrModeNone, SizeSpecial, IndexModeNone,
2555 Pseudo, NoItinerary,
2556 "str\tsp, [$src, #+8] ${:comment} eh_setjmp begin\n\t"
2557 "add\t$val, pc, #8\n\t"
2558 "str\t$val, [$src, #+4]\n\t"
2560 "add\tpc, pc, #0\n\t"
2561 "mov\tr0, #1 ${:comment} eh_setjmp end", "",
2562 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
2563 Requires<[IsARM, NoVFP]>;
2566 //===----------------------------------------------------------------------===//
2567 // Non-Instruction Patterns
2570 // Large immediate handling.
2572 // Two piece so_imms.
2573 let isReMaterializable = 1 in
2574 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2576 "mov", "\t$dst, $src",
2577 [(set GPR:$dst, so_imm2part:$src)]>,
2578 Requires<[IsARM, NoV6T2]>;
2580 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2581 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2582 (so_imm2part_2 imm:$RHS))>;
2583 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2584 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2585 (so_imm2part_2 imm:$RHS))>;
2586 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2587 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2588 (so_imm2part_2 imm:$RHS))>;
2589 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2590 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2591 (so_neg_imm2part_2 imm:$RHS))>;
2593 // 32-bit immediate using movw + movt.
2594 // This is a single pseudo instruction, the benefit is that it can be remat'd
2595 // as a single unit instead of having to handle reg inputs.
2596 // FIXME: Remove this when we can do generalized remat.
2597 let isReMaterializable = 1 in
2598 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2599 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2600 [(set GPR:$dst, (i32 imm:$src))]>,
2601 Requires<[IsARM, HasV6T2]>;
2603 // ConstantPool, GlobalAddress, and JumpTable
2604 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2605 Requires<[IsARM, DontUseMovt]>;
2606 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2607 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2608 Requires<[IsARM, UseMovt]>;
2609 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2610 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2612 // TODO: add,sub,and, 3-instr forms?
2616 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2617 Requires<[IsARM, IsNotDarwin]>;
2618 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2619 Requires<[IsARM, IsDarwin]>;
2621 // zextload i1 -> zextload i8
2622 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2624 // extload -> zextload
2625 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2626 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2627 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2629 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2630 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2633 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2634 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2635 (SMULBB GPR:$a, GPR:$b)>;
2636 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2637 (SMULBB GPR:$a, GPR:$b)>;
2638 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2639 (sra GPR:$b, (i32 16))),
2640 (SMULBT GPR:$a, GPR:$b)>;
2641 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2642 (SMULBT GPR:$a, GPR:$b)>;
2643 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2644 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2645 (SMULTB GPR:$a, GPR:$b)>;
2646 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2647 (SMULTB GPR:$a, GPR:$b)>;
2648 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2650 (SMULWB GPR:$a, GPR:$b)>;
2651 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2652 (SMULWB GPR:$a, GPR:$b)>;
2654 def : ARMV5TEPat<(add GPR:$acc,
2655 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2656 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2657 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2658 def : ARMV5TEPat<(add GPR:$acc,
2659 (mul sext_16_node:$a, sext_16_node:$b)),
2660 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2661 def : ARMV5TEPat<(add GPR:$acc,
2662 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2663 (sra GPR:$b, (i32 16)))),
2664 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2665 def : ARMV5TEPat<(add GPR:$acc,
2666 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2667 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2668 def : ARMV5TEPat<(add GPR:$acc,
2669 (mul (sra GPR:$a, (i32 16)),
2670 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2671 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2672 def : ARMV5TEPat<(add GPR:$acc,
2673 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2674 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2675 def : ARMV5TEPat<(add GPR:$acc,
2676 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2678 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2679 def : ARMV5TEPat<(add GPR:$acc,
2680 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2681 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2683 //===----------------------------------------------------------------------===//
2687 include "ARMInstrThumb.td"
2689 //===----------------------------------------------------------------------===//
2693 include "ARMInstrThumb2.td"
2695 //===----------------------------------------------------------------------===//
2696 // Floating Point Support
2699 include "ARMInstrVFP.td"
2701 //===----------------------------------------------------------------------===//
2702 // Advanced SIMD (NEON) Support
2705 include "ARMInstrNEON.td"
2707 //===----------------------------------------------------------------------===//
2708 // Coprocessor Instructions. For disassembly only.
2711 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2712 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2713 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2714 [/* For disassembly only; pattern left blank */]> {
2718 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2719 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2720 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2721 [/* For disassembly only; pattern left blank */]> {
2722 let Inst{31-28} = 0b1111;
2726 class ACI<dag oops, dag iops, string opc, string asm>
2727 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2728 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2729 let Inst{27-25} = 0b110;
2732 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2734 def _OFFSET : ACI<(outs),
2735 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2736 opc, "\tp$cop, cr$CRd, $addr"> {
2737 let Inst{31-28} = op31_28;
2738 let Inst{24} = 1; // P = 1
2739 let Inst{21} = 0; // W = 0
2740 let Inst{22} = 0; // D = 0
2741 let Inst{20} = load;
2744 def _PRE : ACI<(outs),
2745 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2746 opc, "\tp$cop, cr$CRd, $addr!"> {
2747 let Inst{31-28} = op31_28;
2748 let Inst{24} = 1; // P = 1
2749 let Inst{21} = 1; // W = 1
2750 let Inst{22} = 0; // D = 0
2751 let Inst{20} = load;
2754 def _POST : ACI<(outs),
2755 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2756 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2757 let Inst{31-28} = op31_28;
2758 let Inst{24} = 0; // P = 0
2759 let Inst{21} = 1; // W = 1
2760 let Inst{22} = 0; // D = 0
2761 let Inst{20} = load;
2764 def _OPTION : ACI<(outs),
2765 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2766 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2767 let Inst{31-28} = op31_28;
2768 let Inst{24} = 0; // P = 0
2769 let Inst{23} = 1; // U = 1
2770 let Inst{21} = 0; // W = 0
2771 let Inst{22} = 0; // D = 0
2772 let Inst{20} = load;
2775 def L_OFFSET : ACI<(outs),
2776 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2777 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
2778 let Inst{31-28} = op31_28;
2779 let Inst{24} = 1; // P = 1
2780 let Inst{21} = 0; // W = 0
2781 let Inst{22} = 1; // D = 1
2782 let Inst{20} = load;
2785 def L_PRE : ACI<(outs),
2786 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2787 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
2788 let Inst{31-28} = op31_28;
2789 let Inst{24} = 1; // P = 1
2790 let Inst{21} = 1; // W = 1
2791 let Inst{22} = 1; // D = 1
2792 let Inst{20} = load;
2795 def L_POST : ACI<(outs),
2796 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2797 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
2798 let Inst{31-28} = op31_28;
2799 let Inst{24} = 0; // P = 0
2800 let Inst{21} = 1; // W = 1
2801 let Inst{22} = 1; // D = 1
2802 let Inst{20} = load;
2805 def L_OPTION : ACI<(outs),
2806 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2807 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
2808 let Inst{31-28} = op31_28;
2809 let Inst{24} = 0; // P = 0
2810 let Inst{23} = 1; // U = 1
2811 let Inst{21} = 0; // W = 0
2812 let Inst{22} = 1; // D = 1
2813 let Inst{20} = load;
2817 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2818 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2819 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2820 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2822 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2823 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2824 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2825 [/* For disassembly only; pattern left blank */]> {
2830 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2831 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2832 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2833 [/* For disassembly only; pattern left blank */]> {
2834 let Inst{31-28} = 0b1111;
2839 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2840 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2841 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2842 [/* For disassembly only; pattern left blank */]> {
2847 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2848 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2849 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2850 [/* For disassembly only; pattern left blank */]> {
2851 let Inst{31-28} = 0b1111;
2856 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2857 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2858 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2859 [/* For disassembly only; pattern left blank */]> {
2860 let Inst{23-20} = 0b0100;
2863 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2864 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2865 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2866 [/* For disassembly only; pattern left blank */]> {
2867 let Inst{31-28} = 0b1111;
2868 let Inst{23-20} = 0b0100;
2871 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2872 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2873 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2874 [/* For disassembly only; pattern left blank */]> {
2875 let Inst{23-20} = 0b0101;
2878 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2879 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2880 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2881 [/* For disassembly only; pattern left blank */]> {
2882 let Inst{31-28} = 0b1111;
2883 let Inst{23-20} = 0b0101;
2886 //===----------------------------------------------------------------------===//
2887 // Move between special register and ARM core register -- for disassembly only
2890 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2891 [/* For disassembly only; pattern left blank */]> {
2892 let Inst{23-20} = 0b0000;
2893 let Inst{7-4} = 0b0000;
2896 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2897 [/* For disassembly only; pattern left blank */]> {
2898 let Inst{23-20} = 0b0100;
2899 let Inst{7-4} = 0b0000;
2902 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
2903 "msr", "\tcpsr$mask, $src",
2904 [/* For disassembly only; pattern left blank */]> {
2905 let Inst{23-20} = 0b0010;
2906 let Inst{7-4} = 0b0000;
2909 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
2910 "msr", "\tcpsr$mask, $a",
2911 [/* For disassembly only; pattern left blank */]> {
2912 let Inst{23-20} = 0b0010;
2913 let Inst{7-4} = 0b0000;
2916 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
2917 "msr", "\tspsr$mask, $src",
2918 [/* For disassembly only; pattern left blank */]> {
2919 let Inst{23-20} = 0b0110;
2920 let Inst{7-4} = 0b0000;
2923 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
2924 "msr", "\tspsr$mask, $a",
2925 [/* For disassembly only; pattern left blank */]> {
2926 let Inst{23-20} = 0b0110;
2927 let Inst{7-4} = 0b0000;