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, [SDTCisInt<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]>;
66 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
67 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
68 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
69 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
71 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
72 [SDNPHasChain, SDNPOptInFlag]>;
74 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
76 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
79 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
80 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
82 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
84 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
87 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
90 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
91 [SDNPOutFlag,SDNPCommutative]>;
93 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
95 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
96 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
97 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
99 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
100 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
102 def ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
104 def ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7,
106 def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
108 def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
111 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
113 //===----------------------------------------------------------------------===//
114 // ARM Instruction Predicate Definitions.
116 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
117 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
118 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
119 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
120 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
121 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
122 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
123 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
124 def HasNEON : Predicate<"Subtarget->hasNEON()">;
125 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
126 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
127 def IsThumb : Predicate<"Subtarget->isThumb()">;
128 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
129 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
130 def IsARM : Predicate<"!Subtarget->isThumb()">;
131 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
132 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
134 // FIXME: Eventually this will be just "hasV6T2Ops".
135 def UseMovt : Predicate<"Subtarget->useMovt()">;
136 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
138 //===----------------------------------------------------------------------===//
139 // ARM Flag Definitions.
141 class RegConstraint<string C> {
142 string Constraints = C;
145 //===----------------------------------------------------------------------===//
146 // ARM specific transformation functions and pattern fragments.
149 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
150 // so_imm_neg def below.
151 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
152 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
155 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
156 // so_imm_not def below.
157 def so_imm_not_XFORM : SDNodeXForm<imm, [{
158 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
161 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
162 def rot_imm : PatLeaf<(i32 imm), [{
163 int32_t v = (int32_t)N->getZExtValue();
164 return v == 8 || v == 16 || v == 24;
167 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
168 def imm1_15 : PatLeaf<(i32 imm), [{
169 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
172 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
173 def imm16_31 : PatLeaf<(i32 imm), [{
174 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
179 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
180 }], so_imm_neg_XFORM>;
184 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
185 }], so_imm_not_XFORM>;
187 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
188 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
189 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
192 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
194 def bf_inv_mask_imm : Operand<i32>,
196 uint32_t v = (uint32_t)N->getZExtValue();
199 // there can be 1's on either or both "outsides", all the "inside"
201 unsigned int lsb = 0, msb = 31;
202 while (v & (1 << msb)) --msb;
203 while (v & (1 << lsb)) ++lsb;
204 for (unsigned int i = lsb; i <= msb; ++i) {
210 let PrintMethod = "printBitfieldInvMaskImmOperand";
213 /// Split a 32-bit immediate into two 16 bit parts.
214 def lo16 : SDNodeXForm<imm, [{
215 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
219 def hi16 : SDNodeXForm<imm, [{
220 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
223 def lo16AllZero : PatLeaf<(i32 imm), [{
224 // Returns true if all low 16-bits are 0.
225 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
228 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
230 def imm0_65535 : PatLeaf<(i32 imm), [{
231 return (uint32_t)N->getZExtValue() < 65536;
234 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
235 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
237 /// adde and sube predicates - True based on whether the carry flag output
238 /// will be needed or not.
239 def adde_dead_carry :
240 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
241 [{return !N->hasAnyUseOfValue(1);}]>;
242 def sube_dead_carry :
243 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
244 [{return !N->hasAnyUseOfValue(1);}]>;
245 def adde_live_carry :
246 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
247 [{return N->hasAnyUseOfValue(1);}]>;
248 def sube_live_carry :
249 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
250 [{return N->hasAnyUseOfValue(1);}]>;
252 //===----------------------------------------------------------------------===//
253 // Operand Definitions.
257 def brtarget : Operand<OtherVT>;
259 // A list of registers separated by comma. Used by load/store multiple.
260 def reglist : Operand<i32> {
261 let PrintMethod = "printRegisterList";
264 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
265 def cpinst_operand : Operand<i32> {
266 let PrintMethod = "printCPInstOperand";
269 def jtblock_operand : Operand<i32> {
270 let PrintMethod = "printJTBlockOperand";
272 def jt2block_operand : Operand<i32> {
273 let PrintMethod = "printJT2BlockOperand";
277 def pclabel : Operand<i32> {
278 let PrintMethod = "printPCLabel";
281 // shifter_operand operands: so_reg and so_imm.
282 def so_reg : Operand<i32>, // reg reg imm
283 ComplexPattern<i32, 3, "SelectShifterOperandReg",
284 [shl,srl,sra,rotr]> {
285 let PrintMethod = "printSORegOperand";
286 let MIOperandInfo = (ops GPR, GPR, i32imm);
289 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
290 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
291 // represented in the imm field in the same 12-bit form that they are encoded
292 // into so_imm instructions: the 8-bit immediate is the least significant bits
293 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
294 def so_imm : Operand<i32>,
296 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
298 let PrintMethod = "printSOImmOperand";
301 // Break so_imm's up into two pieces. This handles immediates with up to 16
302 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
303 // get the first/second pieces.
304 def so_imm2part : Operand<i32>,
306 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
308 let PrintMethod = "printSOImm2PartOperand";
311 def so_imm2part_1 : SDNodeXForm<imm, [{
312 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
313 return CurDAG->getTargetConstant(V, MVT::i32);
316 def so_imm2part_2 : SDNodeXForm<imm, [{
317 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
318 return CurDAG->getTargetConstant(V, MVT::i32);
321 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
322 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
324 let PrintMethod = "printSOImm2PartOperand";
327 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
328 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
329 return CurDAG->getTargetConstant(V, MVT::i32);
332 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
333 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
334 return CurDAG->getTargetConstant(V, MVT::i32);
337 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
338 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
339 return (int32_t)N->getZExtValue() < 32;
342 // Define ARM specific addressing modes.
344 // addrmode2 := reg +/- reg shop imm
345 // addrmode2 := reg +/- imm12
347 def addrmode2 : Operand<i32>,
348 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
349 let PrintMethod = "printAddrMode2Operand";
350 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
353 def am2offset : Operand<i32>,
354 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
355 let PrintMethod = "printAddrMode2OffsetOperand";
356 let MIOperandInfo = (ops GPR, i32imm);
359 // addrmode3 := reg +/- reg
360 // addrmode3 := reg +/- imm8
362 def addrmode3 : Operand<i32>,
363 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
364 let PrintMethod = "printAddrMode3Operand";
365 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
368 def am3offset : Operand<i32>,
369 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
370 let PrintMethod = "printAddrMode3OffsetOperand";
371 let MIOperandInfo = (ops GPR, i32imm);
374 // addrmode4 := reg, <mode|W>
376 def addrmode4 : Operand<i32>,
377 ComplexPattern<i32, 2, "SelectAddrMode4", []> {
378 let PrintMethod = "printAddrMode4Operand";
379 let MIOperandInfo = (ops GPR, i32imm);
382 // addrmode5 := reg +/- imm8*4
384 def addrmode5 : Operand<i32>,
385 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
386 let PrintMethod = "printAddrMode5Operand";
387 let MIOperandInfo = (ops GPR, i32imm);
390 // addrmode6 := reg with optional writeback
392 def addrmode6 : Operand<i32>,
393 ComplexPattern<i32, 4, "SelectAddrMode6", []> {
394 let PrintMethod = "printAddrMode6Operand";
395 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
398 // addrmodepc := pc + reg
400 def addrmodepc : Operand<i32>,
401 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
402 let PrintMethod = "printAddrModePCOperand";
403 let MIOperandInfo = (ops GPR, i32imm);
406 def nohash_imm : Operand<i32> {
407 let PrintMethod = "printNoHashImmediate";
410 //===----------------------------------------------------------------------===//
412 include "ARMInstrFormats.td"
414 //===----------------------------------------------------------------------===//
415 // Multiclass helpers...
418 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
419 /// binop that produces a value.
420 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
421 bit Commutable = 0> {
422 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
423 IIC_iALUi, opc, "\t$dst, $a, $b",
424 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
427 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
428 IIC_iALUr, opc, "\t$dst, $a, $b",
429 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
430 let Inst{11-4} = 0b00000000;
432 let isCommutable = Commutable;
434 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
435 IIC_iALUsr, opc, "\t$dst, $a, $b",
436 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
441 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
442 /// instruction modifies the CPSR register.
443 let Defs = [CPSR] in {
444 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
445 bit Commutable = 0> {
446 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
447 IIC_iALUi, opc, "\t$dst, $a, $b",
448 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
452 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
453 IIC_iALUr, opc, "\t$dst, $a, $b",
454 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
455 let isCommutable = Commutable;
456 let Inst{11-4} = 0b00000000;
460 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
461 IIC_iALUsr, opc, "\t$dst, $a, $b",
462 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
469 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
470 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
471 /// a explicit result, only implicitly set CPSR.
472 let Defs = [CPSR] in {
473 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
474 bit Commutable = 0> {
475 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi,
477 [(opnode GPR:$a, so_imm:$b)]> {
481 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr,
483 [(opnode GPR:$a, GPR:$b)]> {
484 let Inst{11-4} = 0b00000000;
487 let isCommutable = Commutable;
489 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr,
491 [(opnode GPR:$a, so_reg:$b)]> {
498 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
499 /// register and one whose operand is a register rotated by 8/16/24.
500 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
501 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
502 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
503 IIC_iUNAr, opc, "\t$dst, $src",
504 [(set GPR:$dst, (opnode GPR:$src))]>,
505 Requires<[IsARM, HasV6]> {
506 let Inst{11-10} = 0b00;
507 let Inst{19-16} = 0b1111;
509 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
510 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
511 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
512 Requires<[IsARM, HasV6]> {
513 let Inst{19-16} = 0b1111;
517 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
518 /// register and one whose operand is a register rotated by 8/16/24.
519 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
520 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
521 IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
522 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
523 Requires<[IsARM, HasV6]> {
524 let Inst{11-10} = 0b00;
526 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
527 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
528 [(set GPR:$dst, (opnode GPR:$LHS,
529 (rotr GPR:$RHS, rot_imm:$rot)))]>,
530 Requires<[IsARM, HasV6]>;
533 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
534 let Uses = [CPSR] in {
535 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
536 bit Commutable = 0> {
537 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
538 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
539 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
543 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
544 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
545 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
547 let isCommutable = Commutable;
548 let Inst{11-4} = 0b00000000;
551 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
552 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
553 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
558 // Carry setting variants
559 let Defs = [CPSR] in {
560 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
561 bit Commutable = 0> {
562 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
563 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
564 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
569 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
570 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
571 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
573 let Inst{11-4} = 0b00000000;
577 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
578 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
579 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
588 //===----------------------------------------------------------------------===//
590 //===----------------------------------------------------------------------===//
592 //===----------------------------------------------------------------------===//
593 // Miscellaneous Instructions.
596 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
597 /// the function. The first operand is the ID# for this instruction, the second
598 /// is the index into the MachineConstantPool that this is, the third is the
599 /// size in bytes of this constant pool entry.
600 let neverHasSideEffects = 1, isNotDuplicable = 1 in
601 def CONSTPOOL_ENTRY :
602 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
603 i32imm:$size), NoItinerary,
604 "${instid:label} ${cpidx:cpentry}", []>;
606 let Defs = [SP], Uses = [SP] in {
608 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
609 "@ ADJCALLSTACKUP $amt1",
610 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
612 def ADJCALLSTACKDOWN :
613 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
614 "@ ADJCALLSTACKDOWN $amt",
615 [(ARMcallseq_start timm:$amt)]>;
618 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
619 [/* For disassembly only; pattern left blank */]>,
620 Requires<[IsARM, HasV6T2]> {
621 let Inst{27-16} = 0b001100100000;
622 let Inst{7-0} = 0b00000000;
625 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
626 [/* For disassembly only; pattern left blank */]>,
627 Requires<[IsARM, HasV6T2]> {
628 let Inst{27-16} = 0b001100100000;
629 let Inst{7-0} = 0b00000001;
632 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
633 [/* For disassembly only; pattern left blank */]>,
634 Requires<[IsARM, HasV6T2]> {
635 let Inst{27-16} = 0b001100100000;
636 let Inst{7-0} = 0b00000010;
639 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
640 [/* For disassembly only; pattern left blank */]>,
641 Requires<[IsARM, HasV6T2]> {
642 let Inst{27-16} = 0b001100100000;
643 let Inst{7-0} = 0b00000011;
646 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
647 [/* For disassembly only; pattern left blank */]>,
648 Requires<[IsARM, HasV6T2]> {
649 let Inst{27-16} = 0b001100100000;
650 let Inst{7-0} = 0b00000100;
653 // The i32imm operand $val can be used by a debugger to store more information
654 // about the breakpoint.
655 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
656 [/* For disassembly only; pattern left blank */]>,
658 let Inst{27-20} = 0b00010010;
659 let Inst{7-4} = 0b0111;
662 // Change Processor State is a system instruction -- for disassembly only.
663 // The singleton $opt operand contains the following information:
664 // opt{4-0} = mode from Inst{4-0}
665 // opt{5} = changemode from Inst{17}
666 // opt{8-6} = AIF from Inst{8-6}
667 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
668 def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
669 [/* For disassembly only; pattern left blank */]>,
671 let Inst{31-28} = 0b1111;
672 let Inst{27-20} = 0b00010000;
677 def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
678 [/* For disassembly only; pattern left blank */]>,
680 let Inst{31-28} = 0b1111;
681 let Inst{27-20} = 0b00010000;
684 let Inst{7-4} = 0b0000;
687 def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
688 [/* For disassembly only; pattern left blank */]>,
690 let Inst{31-28} = 0b1111;
691 let Inst{27-20} = 0b00010000;
694 let Inst{7-4} = 0b0000;
697 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
698 [/* For disassembly only; pattern left blank */]>,
699 Requires<[IsARM, HasV7]> {
700 let Inst{27-16} = 0b001100100000;
701 let Inst{7-4} = 0b1111;
704 // A5.4 Permanently UNDEFINED instructions.
705 def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
706 [/* For disassembly only; pattern left blank */]>,
708 let Inst{27-25} = 0b011;
709 let Inst{24-20} = 0b11111;
710 let Inst{7-5} = 0b111;
714 // Address computation and loads and stores in PIC mode.
715 let isNotDuplicable = 1 in {
716 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
717 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
718 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
720 let AddedComplexity = 10 in {
721 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
722 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
723 [(set GPR:$dst, (load addrmodepc:$addr))]>;
725 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
726 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr",
727 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
729 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
730 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr",
731 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
733 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
734 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr",
735 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
737 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
738 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr",
739 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
741 let AddedComplexity = 10 in {
742 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
743 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
744 [(store GPR:$src, addrmodepc:$addr)]>;
746 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
747 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr",
748 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
750 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
751 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr",
752 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
754 } // isNotDuplicable = 1
757 // LEApcrel - Load a pc-relative address into a register without offending the
759 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
761 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
762 "${:private}PCRELL${:uid}+8))\n"),
763 !strconcat("${:private}PCRELL${:uid}:\n\t",
764 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
767 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
768 (ins i32imm:$label, nohash_imm:$id, pred:$p),
770 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
772 "${:private}PCRELL${:uid}+8))\n"),
773 !strconcat("${:private}PCRELL${:uid}:\n\t",
774 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
779 //===----------------------------------------------------------------------===//
780 // Control Flow Instructions.
783 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
784 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
785 "bx", "\tlr", [(ARMretflag)]> {
786 let Inst{3-0} = 0b1110;
787 let Inst{7-4} = 0b0001;
788 let Inst{19-8} = 0b111111111111;
789 let Inst{27-20} = 0b00010010;
793 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
794 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
795 [(brind GPR:$dst)]> {
796 let Inst{7-4} = 0b0001;
797 let Inst{19-8} = 0b111111111111;
798 let Inst{27-20} = 0b00010010;
799 let Inst{31-28} = 0b1110;
803 // FIXME: remove when we have a way to marking a MI with these properties.
804 // FIXME: Should pc be an implicit operand like PICADD, etc?
805 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
806 hasExtraDefRegAllocReq = 1 in
807 def LDM_RET : AXI4ld<(outs),
808 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
809 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
812 // On non-Darwin platforms R9 is callee-saved.
814 Defs = [R0, R1, R2, R3, R12, LR,
815 D0, D1, D2, D3, D4, D5, D6, D7,
816 D16, D17, D18, D19, D20, D21, D22, D23,
817 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
818 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
819 IIC_Br, "bl\t${func:call}",
820 [(ARMcall tglobaladdr:$func)]>,
821 Requires<[IsARM, IsNotDarwin]> {
822 let Inst{31-28} = 0b1110;
825 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
826 IIC_Br, "bl", "\t${func:call}",
827 [(ARMcall_pred tglobaladdr:$func)]>,
828 Requires<[IsARM, IsNotDarwin]>;
831 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
832 IIC_Br, "blx\t$func",
833 [(ARMcall GPR:$func)]>,
834 Requires<[IsARM, HasV5T, IsNotDarwin]> {
835 let Inst{7-4} = 0b0011;
836 let Inst{19-8} = 0b111111111111;
837 let Inst{27-20} = 0b00010010;
841 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
842 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
843 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
844 [(ARMcall_nolink tGPR:$func)]>,
845 Requires<[IsARM, IsNotDarwin]> {
846 let Inst{7-4} = 0b0001;
847 let Inst{19-8} = 0b111111111111;
848 let Inst{27-20} = 0b00010010;
852 // On Darwin R9 is call-clobbered.
854 Defs = [R0, R1, R2, R3, R9, R12, LR,
855 D0, D1, D2, D3, D4, D5, D6, D7,
856 D16, D17, D18, D19, D20, D21, D22, D23,
857 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
858 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
859 IIC_Br, "bl\t${func:call}",
860 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
861 let Inst{31-28} = 0b1110;
864 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
865 IIC_Br, "bl", "\t${func:call}",
866 [(ARMcall_pred tglobaladdr:$func)]>,
867 Requires<[IsARM, IsDarwin]>;
870 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
871 IIC_Br, "blx\t$func",
872 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
873 let Inst{7-4} = 0b0011;
874 let Inst{19-8} = 0b111111111111;
875 let Inst{27-20} = 0b00010010;
879 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
880 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
881 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
882 [(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
883 let Inst{7-4} = 0b0001;
884 let Inst{19-8} = 0b111111111111;
885 let Inst{27-20} = 0b00010010;
889 let isBranch = 1, isTerminator = 1 in {
890 // B is "predicable" since it can be xformed into a Bcc.
891 let isBarrier = 1 in {
892 let isPredicable = 1 in
893 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
894 "b\t$target", [(br bb:$target)]>;
896 let isNotDuplicable = 1, isIndirectBranch = 1 in {
897 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
898 IIC_Br, "mov\tpc, $target \n$jt",
899 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
900 let Inst{11-4} = 0b00000000;
901 let Inst{15-12} = 0b1111;
902 let Inst{20} = 0; // S Bit
903 let Inst{24-21} = 0b1101;
904 let Inst{27-25} = 0b000;
906 def BR_JTm : JTI<(outs),
907 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
908 IIC_Br, "ldr\tpc, $target \n$jt",
909 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
911 let Inst{15-12} = 0b1111;
912 let Inst{20} = 1; // L bit
913 let Inst{21} = 0; // W bit
914 let Inst{22} = 0; // B bit
915 let Inst{24} = 1; // P bit
916 let Inst{27-25} = 0b011;
918 def BR_JTadd : JTI<(outs),
919 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
920 IIC_Br, "add\tpc, $target, $idx \n$jt",
921 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
923 let Inst{15-12} = 0b1111;
924 let Inst{20} = 0; // S bit
925 let Inst{24-21} = 0b0100;
926 let Inst{27-25} = 0b000;
928 } // isNotDuplicable = 1, isIndirectBranch = 1
931 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
932 // a two-value operand where a dag node expects two operands. :(
933 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
934 IIC_Br, "b", "\t$target",
935 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
938 // Branch and Exchange Jazelle -- for disassembly only
939 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
940 [/* For disassembly only; pattern left blank */]> {
941 let Inst{23-20} = 0b0010;
942 //let Inst{19-8} = 0xfff;
943 let Inst{7-4} = 0b0010;
946 // Supervisor Call (Software Interrupt) -- for disassembly only
948 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
949 [/* For disassembly only; pattern left blank */]>;
952 // Store Return State -- for disassembly only
953 def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$opt),
954 NoItinerary, "srs${addr:submode}\tsp!, $opt",
955 [/* For disassembly only; pattern left blank */]> {
956 let Inst{31-28} = 0b1111;
957 let Inst{22-20} = 0b110; // W = 1
960 def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
961 NoItinerary, "srs${addr:submode}\tsp, $mode",
962 [/* For disassembly only; pattern left blank */]> {
963 let Inst{31-28} = 0b1111;
964 let Inst{22-20} = 0b100; // W = 0
967 //===----------------------------------------------------------------------===//
968 // Load / store Instructions.
972 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
973 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
974 "ldr", "\t$dst, $addr",
975 [(set GPR:$dst, (load addrmode2:$addr))]>;
977 // Special LDR for loads from non-pc-relative constpools.
978 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
979 mayHaveSideEffects = 1 in
980 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
981 "ldr", "\t$dst, $addr", []>;
983 // Loads with zero extension
984 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
985 IIC_iLoadr, "ldrh", "\t$dst, $addr",
986 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
988 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
989 IIC_iLoadr, "ldrb", "\t$dst, $addr",
990 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
992 // Loads with sign extension
993 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
994 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
995 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
997 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
998 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
999 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1001 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
1003 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1004 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
1005 []>, Requires<[IsARM, HasV5TE]>;
1008 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
1009 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1010 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1012 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1013 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1014 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1016 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
1017 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1018 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1020 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1021 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1022 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1024 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
1025 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
1026 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1028 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1029 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1030 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1032 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
1033 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1034 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1036 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1037 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1038 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1040 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
1041 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
1042 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
1044 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1045 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
1046 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
1049 // LDRT and LDRBT are for disassembly only.
1051 def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
1052 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
1053 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1054 let Inst{21} = 1; // overwrite
1057 def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
1058 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
1059 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1060 let Inst{21} = 1; // overwrite
1064 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1065 "str", "\t$src, $addr",
1066 [(store GPR:$src, addrmode2:$addr)]>;
1068 // Stores with truncate
1069 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
1070 "strh", "\t$src, $addr",
1071 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1073 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
1074 "strb", "\t$src, $addr",
1075 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
1078 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1079 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1080 StMiscFrm, IIC_iStorer,
1081 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1084 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
1085 (ins GPR:$src, GPR:$base, am2offset:$offset),
1086 StFrm, IIC_iStoreru,
1087 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
1089 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1091 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
1092 (ins GPR:$src, GPR:$base,am2offset:$offset),
1093 StFrm, IIC_iStoreru,
1094 "str", "\t$src, [$base], $offset", "$base = $base_wb",
1096 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
1098 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1099 (ins GPR:$src, GPR:$base,am3offset:$offset),
1100 StMiscFrm, IIC_iStoreru,
1101 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1103 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1105 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1106 (ins GPR:$src, GPR:$base,am3offset:$offset),
1107 StMiscFrm, IIC_iStoreru,
1108 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1109 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1110 GPR:$base, am3offset:$offset))]>;
1112 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
1113 (ins GPR:$src, GPR:$base,am2offset:$offset),
1114 StFrm, IIC_iStoreru,
1115 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
1116 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
1117 GPR:$base, am2offset:$offset))]>;
1119 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
1120 (ins GPR:$src, GPR:$base,am2offset:$offset),
1121 StFrm, IIC_iStoreru,
1122 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
1123 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
1124 GPR:$base, am2offset:$offset))]>;
1126 // STRT and STRBT are for disassembly only.
1128 def STRT : AI2stwpo<(outs GPR:$base_wb),
1129 (ins GPR:$src, GPR:$base,am2offset:$offset),
1130 StFrm, IIC_iStoreru,
1131 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1132 [/* For disassembly only; pattern left blank */]> {
1133 let Inst{21} = 1; // overwrite
1136 def STRBT : AI2stbpo<(outs GPR:$base_wb),
1137 (ins GPR:$src, GPR:$base,am2offset:$offset),
1138 StFrm, IIC_iStoreru,
1139 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1140 [/* For disassembly only; pattern left blank */]> {
1141 let Inst{21} = 1; // overwrite
1144 //===----------------------------------------------------------------------===//
1145 // Load / store multiple Instructions.
1148 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1149 def LDM : AXI4ld<(outs),
1150 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1151 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
1154 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1155 def STM : AXI4st<(outs),
1156 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1157 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
1160 //===----------------------------------------------------------------------===//
1161 // Move Instructions.
1164 let neverHasSideEffects = 1 in
1165 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1166 "mov", "\t$dst, $src", []>, UnaryDP {
1167 let Inst{11-4} = 0b00000000;
1171 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
1172 DPSoRegFrm, IIC_iMOVsr,
1173 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
1177 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1178 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
1179 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
1183 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1184 def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
1186 "movw", "\t$dst, $src",
1187 [(set GPR:$dst, imm0_65535:$src)]>,
1188 Requires<[IsARM, HasV6T2]>, UnaryDP {
1193 let Constraints = "$src = $dst" in
1194 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
1196 "movt", "\t$dst, $imm",
1198 (or (and GPR:$src, 0xffff),
1199 lo16AllZero:$imm))]>, UnaryDP,
1200 Requires<[IsARM, HasV6T2]> {
1205 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1206 Requires<[IsARM, HasV6T2]>;
1208 let Uses = [CPSR] in
1209 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
1210 "mov", "\t$dst, $src, rrx",
1211 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
1213 // These aren't really mov instructions, but we have to define them this way
1214 // due to flag operands.
1216 let Defs = [CPSR] in {
1217 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1218 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
1219 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
1220 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1221 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
1222 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
1225 //===----------------------------------------------------------------------===//
1226 // Extend Instructions.
1231 defm SXTB : AI_unary_rrot<0b01101010,
1232 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
1233 defm SXTH : AI_unary_rrot<0b01101011,
1234 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
1236 defm SXTAB : AI_bin_rrot<0b01101010,
1237 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1238 defm SXTAH : AI_bin_rrot<0b01101011,
1239 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1241 // TODO: SXT(A){B|H}16
1245 let AddedComplexity = 16 in {
1246 defm UXTB : AI_unary_rrot<0b01101110,
1247 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
1248 defm UXTH : AI_unary_rrot<0b01101111,
1249 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
1250 defm UXTB16 : AI_unary_rrot<0b01101100,
1251 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
1253 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
1254 (UXTB16r_rot GPR:$Src, 24)>;
1255 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
1256 (UXTB16r_rot GPR:$Src, 8)>;
1258 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
1259 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
1260 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
1261 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
1264 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
1265 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
1267 // TODO: UXT(A){B|H}16
1269 def SBFX : I<(outs GPR:$dst),
1270 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1271 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1272 "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
1273 Requires<[IsARM, HasV6T2]> {
1274 let Inst{27-21} = 0b0111101;
1275 let Inst{6-4} = 0b101;
1278 def UBFX : I<(outs GPR:$dst),
1279 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
1280 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
1281 "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
1282 Requires<[IsARM, HasV6T2]> {
1283 let Inst{27-21} = 0b0111111;
1284 let Inst{6-4} = 0b101;
1287 //===----------------------------------------------------------------------===//
1288 // Arithmetic Instructions.
1291 defm ADD : AsI1_bin_irs<0b0100, "add",
1292 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
1293 defm SUB : AsI1_bin_irs<0b0010, "sub",
1294 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
1296 // ADD and SUB with 's' bit set.
1297 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1298 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1299 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
1300 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
1302 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
1303 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
1304 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1305 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
1306 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1307 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
1308 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
1309 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
1311 // These don't define reg/reg forms, because they are handled above.
1312 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1313 IIC_iALUi, "rsb", "\t$dst, $a, $b",
1314 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
1318 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1319 IIC_iALUsr, "rsb", "\t$dst, $a, $b",
1320 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
1324 // RSB with 's' bit set.
1325 let Defs = [CPSR] in {
1326 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1327 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
1328 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
1332 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1333 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
1334 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
1340 let Uses = [CPSR] in {
1341 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1342 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
1343 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1347 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1348 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
1349 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1355 // FIXME: Allow these to be predicated.
1356 let Defs = [CPSR], Uses = [CPSR] in {
1357 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
1358 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
1359 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
1364 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
1365 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
1366 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
1373 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1374 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1375 (SUBri GPR:$src, so_imm_neg:$imm)>;
1377 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1378 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1379 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1380 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1382 // Note: These are implemented in C++ code, because they have to generate
1383 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1385 // (mul X, 2^n+1) -> (add (X << n), X)
1386 // (mul X, 2^n-1) -> (rsb X, (X << n))
1388 // Saturating adds/subtracts -- for disassembly only
1390 // GPR:$dst = GPR:$a op GPR:$b
1391 class AQI<bits<8> op27_20, bits<4> op7_4, string opc>
1392 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
1393 opc, "\t$dst, $a, $b",
1394 [/* For disassembly only; pattern left blank */]> {
1395 let Inst{27-20} = op27_20;
1396 let Inst{7-4} = op7_4;
1399 def QADD : AQI<0b00010000, 0b0101, "qadd">;
1400 def QADD16 : AQI<0b01100010, 0b0001, "qadd16">;
1401 def QADD8 : AQI<0b01100010, 0b1001, "qadd8">;
1402 def QASX : AQI<0b01100010, 0b0011, "qasx">;
1403 def QDADD : AQI<0b00010100, 0b0101, "qdadd">;
1404 def QDSUB : AQI<0b00010110, 0b0101, "qdsub">;
1405 def QSAX : AQI<0b01100010, 0b0101, "qsax">;
1406 def QSUB : AQI<0b00010010, 0b0101, "qsub">;
1407 def QSUB16 : AQI<0b01100010, 0b0111, "qsub16">;
1408 def QSUB8 : AQI<0b01100010, 0b1111, "qsub8">;
1409 def UQADD16 : AQI<0b01100110, 0b0001, "uqadd16">;
1410 def UQADD8 : AQI<0b01100110, 0b1001, "uqadd8">;
1411 def UQASX : AQI<0b01100110, 0b0011, "uqasx">;
1412 def UQSAX : AQI<0b01100110, 0b0101, "uqsax">;
1413 def UQSUB16 : AQI<0b01100110, 0b0111, "uqsub16">;
1414 def UQSUB8 : AQI<0b01100110, 0b1111, "uqsub8">;
1416 //===----------------------------------------------------------------------===//
1417 // Bitwise Instructions.
1420 defm AND : AsI1_bin_irs<0b0000, "and",
1421 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1422 defm ORR : AsI1_bin_irs<0b1100, "orr",
1423 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1424 defm EOR : AsI1_bin_irs<0b0001, "eor",
1425 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1426 defm BIC : AsI1_bin_irs<0b1110, "bic",
1427 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1429 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1430 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
1431 "bfc", "\t$dst, $imm", "$src = $dst",
1432 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1433 Requires<[IsARM, HasV6T2]> {
1434 let Inst{27-21} = 0b0111110;
1435 let Inst{6-0} = 0b0011111;
1438 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
1439 "mvn", "\t$dst, $src",
1440 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
1442 let Inst{11-4} = 0b00000000;
1444 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1445 IIC_iMOVsr, "mvn", "\t$dst, $src",
1446 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
1449 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1450 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1451 IIC_iMOVi, "mvn", "\t$dst, $imm",
1452 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
1456 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1457 (BICri GPR:$src, so_imm_not:$imm)>;
1459 //===----------------------------------------------------------------------===//
1460 // Multiply Instructions.
1463 let isCommutable = 1 in
1464 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1465 IIC_iMUL32, "mul", "\t$dst, $a, $b",
1466 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1468 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1469 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
1470 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1472 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1473 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
1474 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1475 Requires<[IsARM, HasV6T2]>;
1477 // Extra precision multiplies with low / high results
1478 let neverHasSideEffects = 1 in {
1479 let isCommutable = 1 in {
1480 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1481 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1482 "smull", "\t$ldst, $hdst, $a, $b", []>;
1484 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1485 (ins GPR:$a, GPR:$b), IIC_iMUL64,
1486 "umull", "\t$ldst, $hdst, $a, $b", []>;
1489 // Multiply + accumulate
1490 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1491 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1492 "smlal", "\t$ldst, $hdst, $a, $b", []>;
1494 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1495 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1496 "umlal", "\t$ldst, $hdst, $a, $b", []>;
1498 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1499 (ins GPR:$a, GPR:$b), IIC_iMAC64,
1500 "umaal", "\t$ldst, $hdst, $a, $b", []>,
1501 Requires<[IsARM, HasV6]>;
1502 } // neverHasSideEffects
1504 // Most significant word multiply
1505 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1506 IIC_iMUL32, "smmul", "\t$dst, $a, $b",
1507 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1508 Requires<[IsARM, HasV6]> {
1509 let Inst{7-4} = 0b0001;
1510 let Inst{15-12} = 0b1111;
1513 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1514 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
1515 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1516 Requires<[IsARM, HasV6]> {
1517 let Inst{7-4} = 0b0001;
1521 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1522 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
1523 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1524 Requires<[IsARM, HasV6]> {
1525 let Inst{7-4} = 0b1101;
1528 multiclass AI_smul<string opc, PatFrag opnode> {
1529 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1530 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
1531 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1532 (sext_inreg GPR:$b, i16)))]>,
1533 Requires<[IsARM, HasV5TE]> {
1538 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1539 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
1540 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1541 (sra GPR:$b, (i32 16))))]>,
1542 Requires<[IsARM, HasV5TE]> {
1547 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1548 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
1549 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1550 (sext_inreg GPR:$b, i16)))]>,
1551 Requires<[IsARM, HasV5TE]> {
1556 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1557 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
1558 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1559 (sra GPR:$b, (i32 16))))]>,
1560 Requires<[IsARM, HasV5TE]> {
1565 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1566 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
1567 [(set GPR:$dst, (sra (opnode GPR:$a,
1568 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1569 Requires<[IsARM, HasV5TE]> {
1574 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1575 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
1576 [(set GPR:$dst, (sra (opnode GPR:$a,
1577 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1578 Requires<[IsARM, HasV5TE]> {
1585 multiclass AI_smla<string opc, PatFrag opnode> {
1586 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1587 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
1588 [(set GPR:$dst, (add GPR:$acc,
1589 (opnode (sext_inreg GPR:$a, i16),
1590 (sext_inreg GPR:$b, i16))))]>,
1591 Requires<[IsARM, HasV5TE]> {
1596 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1597 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
1598 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1599 (sra GPR:$b, (i32 16)))))]>,
1600 Requires<[IsARM, HasV5TE]> {
1605 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1606 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
1607 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1608 (sext_inreg GPR:$b, i16))))]>,
1609 Requires<[IsARM, HasV5TE]> {
1614 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1615 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
1616 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1617 (sra GPR:$b, (i32 16)))))]>,
1618 Requires<[IsARM, HasV5TE]> {
1623 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1624 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
1625 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1626 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1627 Requires<[IsARM, HasV5TE]> {
1632 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1633 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
1634 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1635 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1636 Requires<[IsARM, HasV5TE]> {
1642 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1643 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1645 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
1646 def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1647 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
1648 [/* For disassembly only; pattern left blank */]>,
1649 Requires<[IsARM, HasV5TE]> {
1654 def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1655 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
1656 [/* For disassembly only; pattern left blank */]>,
1657 Requires<[IsARM, HasV5TE]> {
1662 def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1663 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
1664 [/* For disassembly only; pattern left blank */]>,
1665 Requires<[IsARM, HasV5TE]> {
1670 def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
1671 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
1672 [/* For disassembly only; pattern left blank */]>,
1673 Requires<[IsARM, HasV5TE]> {
1678 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1680 //===----------------------------------------------------------------------===//
1681 // Misc. Arithmetic Instructions.
1684 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1685 "clz", "\t$dst, $src",
1686 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1687 let Inst{7-4} = 0b0001;
1688 let Inst{11-8} = 0b1111;
1689 let Inst{19-16} = 0b1111;
1692 def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1693 "rbit", "\t$dst, $src",
1694 [(set GPR:$dst, (ARMrbit GPR:$src))]>,
1695 Requires<[IsARM, HasV6T2]> {
1696 let Inst{7-4} = 0b0011;
1697 let Inst{11-8} = 0b1111;
1698 let Inst{19-16} = 0b1111;
1701 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1702 "rev", "\t$dst, $src",
1703 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1704 let Inst{7-4} = 0b0011;
1705 let Inst{11-8} = 0b1111;
1706 let Inst{19-16} = 0b1111;
1709 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1710 "rev16", "\t$dst, $src",
1712 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1713 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1714 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1715 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1716 Requires<[IsARM, HasV6]> {
1717 let Inst{7-4} = 0b1011;
1718 let Inst{11-8} = 0b1111;
1719 let Inst{19-16} = 0b1111;
1722 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
1723 "revsh", "\t$dst, $src",
1726 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1727 (shl GPR:$src, (i32 8))), i16))]>,
1728 Requires<[IsARM, HasV6]> {
1729 let Inst{7-4} = 0b1011;
1730 let Inst{11-8} = 0b1111;
1731 let Inst{19-16} = 0b1111;
1734 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1735 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1736 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
1737 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1738 (and (shl GPR:$src2, (i32 imm:$shamt)),
1740 Requires<[IsARM, HasV6]> {
1741 let Inst{6-4} = 0b001;
1744 // Alternate cases for PKHBT where identities eliminate some nodes.
1745 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1746 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1747 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1748 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1751 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1752 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1753 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
1754 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1755 (and (sra GPR:$src2, imm16_31:$shamt),
1756 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1757 let Inst{6-4} = 0b101;
1760 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
1761 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1762 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1763 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1764 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1765 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1766 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1768 //===----------------------------------------------------------------------===//
1769 // Comparison Instructions...
1772 defm CMP : AI1_cmp_irs<0b1010, "cmp",
1773 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1774 //FIXME: Disable CMN, as CCodes are backwards from compare expectations
1775 // Compare-to-zero still works out, just not the relationals
1776 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
1777 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1779 // Note that TST/TEQ don't set all the same flags that CMP does!
1780 defm TST : AI1_cmp_irs<0b1000, "tst",
1781 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1782 defm TEQ : AI1_cmp_irs<0b1001, "teq",
1783 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1785 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1786 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1787 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1788 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1790 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1791 // (CMNri GPR:$src, so_imm_neg:$imm)>;
1793 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1794 (CMNzri GPR:$src, so_imm_neg:$imm)>;
1797 // Conditional moves
1798 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1799 // a two-value operand where a dag node expects two operands. :(
1800 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1801 IIC_iCMOVr, "mov", "\t$dst, $true",
1802 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1803 RegConstraint<"$false = $dst">, UnaryDP {
1804 let Inst{11-4} = 0b00000000;
1808 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1809 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
1810 "mov", "\t$dst, $true",
1811 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1812 RegConstraint<"$false = $dst">, UnaryDP {
1816 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1817 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
1818 "mov", "\t$dst, $true",
1819 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1820 RegConstraint<"$false = $dst">, UnaryDP {
1824 //===----------------------------------------------------------------------===//
1825 // Atomic operations intrinsics
1828 // memory barriers protect the atomic sequences
1829 let hasSideEffects = 1 in {
1830 def Int_MemBarrierV7 : AInoP<(outs), (ins),
1831 Pseudo, NoItinerary,
1833 [(ARMMemBarrierV7)]>,
1834 Requires<[IsARM, HasV7]> {
1835 let Inst{31-4} = 0xf57ff05;
1836 // FIXME: add support for options other than a full system DMB
1837 let Inst{3-0} = 0b1111;
1840 def Int_SyncBarrierV7 : AInoP<(outs), (ins),
1841 Pseudo, NoItinerary,
1843 [(ARMSyncBarrierV7)]>,
1844 Requires<[IsARM, HasV7]> {
1845 let Inst{31-4} = 0xf57ff04;
1846 // FIXME: add support for options other than a full system DSB
1847 let Inst{3-0} = 0b1111;
1850 def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1851 Pseudo, NoItinerary,
1852 "mcr", "\tp15, 0, $zero, c7, c10, 5",
1853 [(ARMMemBarrierV6 GPR:$zero)]>,
1854 Requires<[IsARM, HasV6]> {
1855 // FIXME: add support for options other than a full system DMB
1856 // FIXME: add encoding
1859 def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
1860 Pseudo, NoItinerary,
1861 "mcr", "\tp15, 0, $zero, c7, c10, 4",
1862 [(ARMSyncBarrierV6 GPR:$zero)]>,
1863 Requires<[IsARM, HasV6]> {
1864 // FIXME: add support for options other than a full system DSB
1865 // FIXME: add encoding
1869 let usesCustomInserter = 1 in {
1870 let Uses = [CPSR] in {
1871 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
1872 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1873 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
1874 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
1875 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
1876 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1877 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
1878 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
1879 def ATOMIC_LOAD_AND_I8 : PseudoInst<
1880 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1881 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
1882 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
1883 def ATOMIC_LOAD_OR_I8 : PseudoInst<
1884 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1885 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
1886 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
1887 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
1888 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1889 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
1890 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
1891 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
1892 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1893 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
1894 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
1895 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
1896 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1897 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
1898 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
1899 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
1900 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1901 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
1902 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
1903 def ATOMIC_LOAD_AND_I16 : PseudoInst<
1904 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1905 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
1906 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
1907 def ATOMIC_LOAD_OR_I16 : PseudoInst<
1908 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1909 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
1910 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
1911 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
1912 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1913 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
1914 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
1915 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
1916 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1917 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
1918 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
1919 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
1920 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1921 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
1922 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
1923 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
1924 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1925 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
1926 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
1927 def ATOMIC_LOAD_AND_I32 : PseudoInst<
1928 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1929 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
1930 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
1931 def ATOMIC_LOAD_OR_I32 : PseudoInst<
1932 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1933 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
1934 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
1935 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
1936 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1937 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
1938 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
1939 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
1940 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
1941 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
1942 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
1944 def ATOMIC_SWAP_I8 : PseudoInst<
1945 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1946 "${:comment} ATOMIC_SWAP_I8 PSEUDO!",
1947 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
1948 def ATOMIC_SWAP_I16 : PseudoInst<
1949 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1950 "${:comment} ATOMIC_SWAP_I16 PSEUDO!",
1951 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
1952 def ATOMIC_SWAP_I32 : PseudoInst<
1953 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
1954 "${:comment} ATOMIC_SWAP_I32 PSEUDO!",
1955 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
1957 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
1958 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1959 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
1960 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
1961 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
1962 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1963 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
1964 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
1965 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
1966 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
1967 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
1968 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
1972 let mayLoad = 1 in {
1973 def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1974 "ldrexb", "\t$dest, [$ptr]",
1976 def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1977 "ldrexh", "\t$dest, [$ptr]",
1979 def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
1980 "ldrex", "\t$dest, [$ptr]",
1982 def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1984 "ldrexd", "\t$dest, $dest2, [$ptr]",
1988 let mayStore = 1, Constraints = "@earlyclobber $success" in {
1989 def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1991 "strexb", "\t$success, $src, [$ptr]",
1993 def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1995 "strexh", "\t$success, $src, [$ptr]",
1997 def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1999 "strex", "\t$success, $src, [$ptr]",
2001 def STREXD : AIstrex<0b01, (outs GPR:$success),
2002 (ins GPR:$src, GPR:$src2, GPR:$ptr),
2004 "strexd", "\t$success, $src, $src2, [$ptr]",
2008 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
2009 let mayLoad = 1 in {
2010 def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2011 "swp", "\t$dst, $src, [$ptr]",
2012 [/* For disassembly only; pattern left blank */]> {
2013 let Inst{27-23} = 0b00010;
2014 let Inst{22} = 0; // B = 0
2015 let Inst{21-20} = 0b00;
2016 let Inst{7-4} = 0b1001;
2019 def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
2020 "swpb", "\t$dst, $src, [$ptr]",
2021 [/* For disassembly only; pattern left blank */]> {
2022 let Inst{27-23} = 0b00010;
2023 let Inst{22} = 1; // B = 1
2024 let Inst{21-20} = 0b00;
2025 let Inst{7-4} = 0b1001;
2029 //===----------------------------------------------------------------------===//
2033 // __aeabi_read_tp preserves the registers r1-r3.
2035 Defs = [R0, R12, LR, CPSR] in {
2036 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
2037 "bl\t__aeabi_read_tp",
2038 [(set R0, ARMthread_pointer)]>;
2041 //===----------------------------------------------------------------------===//
2042 // SJLJ Exception handling intrinsics
2043 // eh_sjlj_setjmp() is an instruction sequence to store the return
2044 // address and save #0 in R0 for the non-longjmp case.
2045 // Since by its nature we may be coming from some other function to get
2046 // here, and we're using the stack frame for the containing function to
2047 // save/restore registers, we can't keep anything live in regs across
2048 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
2049 // when we get here from a longjmp(). We force everthing out of registers
2050 // except for our own input by listing the relevant registers in Defs. By
2051 // doing so, we also cause the prologue/epilogue code to actively preserve
2052 // all of the callee-saved resgisters, which is exactly what we want.
2053 // A constant value is passed in $val, and we use the location as a scratch.
2055 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
2056 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
2057 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
2059 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
2060 AddrModeNone, SizeSpecial, IndexModeNone,
2061 Pseudo, NoItinerary,
2062 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
2063 "add\t$val, pc, #8\n\t"
2064 "str\t$val, [$src, #+4]\n\t"
2066 "add\tpc, pc, #0\n\t"
2067 "mov\tr0, #1 @ eh_setjmp end", "",
2068 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
2071 //===----------------------------------------------------------------------===//
2072 // Non-Instruction Patterns
2075 // Large immediate handling.
2077 // Two piece so_imms.
2078 let isReMaterializable = 1 in
2079 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
2081 "mov", "\t$dst, $src",
2082 [(set GPR:$dst, so_imm2part:$src)]>,
2083 Requires<[IsARM, NoV6T2]>;
2085 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
2086 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2087 (so_imm2part_2 imm:$RHS))>;
2088 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
2089 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2090 (so_imm2part_2 imm:$RHS))>;
2091 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
2092 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
2093 (so_imm2part_2 imm:$RHS))>;
2094 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
2095 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
2096 (so_neg_imm2part_2 imm:$RHS))>;
2098 // 32-bit immediate using movw + movt.
2099 // This is a single pseudo instruction, the benefit is that it can be remat'd
2100 // as a single unit instead of having to handle reg inputs.
2101 // FIXME: Remove this when we can do generalized remat.
2102 let isReMaterializable = 1 in
2103 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
2104 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
2105 [(set GPR:$dst, (i32 imm:$src))]>,
2106 Requires<[IsARM, HasV6T2]>;
2108 // ConstantPool, GlobalAddress, and JumpTable
2109 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
2110 Requires<[IsARM, DontUseMovt]>;
2111 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
2112 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
2113 Requires<[IsARM, UseMovt]>;
2114 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
2115 (LEApcrelJT tjumptable:$dst, imm:$id)>;
2117 // TODO: add,sub,and, 3-instr forms?
2121 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
2122 Requires<[IsARM, IsNotDarwin]>;
2123 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
2124 Requires<[IsARM, IsDarwin]>;
2126 // zextload i1 -> zextload i8
2127 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2129 // extload -> zextload
2130 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2131 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
2132 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
2134 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
2135 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
2138 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2139 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2140 (SMULBB GPR:$a, GPR:$b)>;
2141 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
2142 (SMULBB GPR:$a, GPR:$b)>;
2143 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2144 (sra GPR:$b, (i32 16))),
2145 (SMULBT GPR:$a, GPR:$b)>;
2146 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
2147 (SMULBT GPR:$a, GPR:$b)>;
2148 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
2149 (sra (shl GPR:$b, (i32 16)), (i32 16))),
2150 (SMULTB GPR:$a, GPR:$b)>;
2151 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
2152 (SMULTB GPR:$a, GPR:$b)>;
2153 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2155 (SMULWB GPR:$a, GPR:$b)>;
2156 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
2157 (SMULWB GPR:$a, GPR:$b)>;
2159 def : ARMV5TEPat<(add GPR:$acc,
2160 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2161 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2162 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2163 def : ARMV5TEPat<(add GPR:$acc,
2164 (mul sext_16_node:$a, sext_16_node:$b)),
2165 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
2166 def : ARMV5TEPat<(add GPR:$acc,
2167 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
2168 (sra GPR:$b, (i32 16)))),
2169 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2170 def : ARMV5TEPat<(add GPR:$acc,
2171 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
2172 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
2173 def : ARMV5TEPat<(add GPR:$acc,
2174 (mul (sra GPR:$a, (i32 16)),
2175 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
2176 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2177 def : ARMV5TEPat<(add GPR:$acc,
2178 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
2179 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
2180 def : ARMV5TEPat<(add GPR:$acc,
2181 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
2183 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2184 def : ARMV5TEPat<(add GPR:$acc,
2185 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
2186 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
2188 //===----------------------------------------------------------------------===//
2192 include "ARMInstrThumb.td"
2194 //===----------------------------------------------------------------------===//
2198 include "ARMInstrThumb2.td"
2200 //===----------------------------------------------------------------------===//
2201 // Floating Point Support
2204 include "ARMInstrVFP.td"
2206 //===----------------------------------------------------------------------===//
2207 // Advanced SIMD (NEON) Support
2210 include "ARMInstrNEON.td"
2212 //===----------------------------------------------------------------------===//
2213 // Coprocessor Instructions. For disassembly only.
2216 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2217 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2218 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2219 [/* For disassembly only; pattern left blank */]> {
2223 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2224 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2225 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
2226 [/* For disassembly only; pattern left blank */]> {
2227 let Inst{31-28} = 0b1111;
2231 class ACI<dag oops, dag iops, string opc, string asm>
2232 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
2233 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
2234 let Inst{27-25} = 0b110;
2237 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
2239 def _OFFSET : ACI<(outs),
2240 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2241 opc, "\tp$cop, cr$CRd, $addr"> {
2242 let Inst{31-28} = op31_28;
2243 let Inst{24} = 1; // P = 1
2244 let Inst{21} = 0; // W = 0
2245 let Inst{22} = 0; // D = 0
2246 let Inst{20} = load;
2249 def _PRE : ACI<(outs),
2250 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2251 opc, "\tp$cop, cr$CRd, $addr!"> {
2252 let Inst{31-28} = op31_28;
2253 let Inst{24} = 1; // P = 1
2254 let Inst{21} = 1; // W = 1
2255 let Inst{22} = 0; // D = 0
2256 let Inst{20} = load;
2259 def _POST : ACI<(outs),
2260 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2261 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
2262 let Inst{31-28} = op31_28;
2263 let Inst{24} = 0; // P = 0
2264 let Inst{21} = 1; // W = 1
2265 let Inst{22} = 0; // D = 0
2266 let Inst{20} = load;
2269 def _OPTION : ACI<(outs),
2270 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
2271 opc, "\tp$cop, cr$CRd, [$base], $option"> {
2272 let Inst{31-28} = op31_28;
2273 let Inst{24} = 0; // P = 0
2274 let Inst{23} = 1; // U = 1
2275 let Inst{21} = 0; // W = 0
2276 let Inst{22} = 0; // D = 0
2277 let Inst{20} = load;
2280 def L_OFFSET : ACI<(outs),
2281 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2282 opc, "l\tp$cop, cr$CRd, $addr"> {
2283 let Inst{31-28} = op31_28;
2284 let Inst{24} = 1; // P = 1
2285 let Inst{21} = 0; // W = 0
2286 let Inst{22} = 1; // D = 1
2287 let Inst{20} = load;
2290 def L_PRE : ACI<(outs),
2291 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
2292 opc, "l\tp$cop, cr$CRd, $addr!"> {
2293 let Inst{31-28} = op31_28;
2294 let Inst{24} = 1; // P = 1
2295 let Inst{21} = 1; // W = 1
2296 let Inst{22} = 1; // D = 1
2297 let Inst{20} = load;
2300 def L_POST : ACI<(outs),
2301 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
2302 opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
2303 let Inst{31-28} = op31_28;
2304 let Inst{24} = 0; // P = 0
2305 let Inst{21} = 1; // W = 1
2306 let Inst{22} = 1; // D = 1
2307 let Inst{20} = load;
2310 def L_OPTION : ACI<(outs),
2311 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
2312 opc, "l\tp$cop, cr$CRd, [$base], $option"> {
2313 let Inst{31-28} = op31_28;
2314 let Inst{24} = 0; // P = 0
2315 let Inst{23} = 1; // U = 1
2316 let Inst{21} = 0; // W = 0
2317 let Inst{22} = 1; // D = 1
2318 let Inst{20} = load;
2322 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
2323 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
2324 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
2325 defm STC2 : LdStCop<0b1111, 0, "stc2">;
2327 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2328 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2329 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2330 [/* For disassembly only; pattern left blank */]> {
2335 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2336 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2337 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2338 [/* For disassembly only; pattern left blank */]> {
2339 let Inst{31-28} = 0b1111;
2344 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2345 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2346 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2347 [/* For disassembly only; pattern left blank */]> {
2352 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
2353 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
2354 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
2355 [/* For disassembly only; pattern left blank */]> {
2356 let Inst{31-28} = 0b1111;
2361 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2362 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2363 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2364 [/* For disassembly only; pattern left blank */]> {
2365 let Inst{23-20} = 0b0100;
2368 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2369 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2370 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2371 [/* For disassembly only; pattern left blank */]> {
2372 let Inst{31-28} = 0b1111;
2373 let Inst{23-20} = 0b0100;
2376 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2377 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2378 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2379 [/* For disassembly only; pattern left blank */]> {
2380 let Inst{23-20} = 0b0101;
2383 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
2384 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
2385 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
2386 [/* For disassembly only; pattern left blank */]> {
2387 let Inst{31-28} = 0b1111;
2388 let Inst{23-20} = 0b0101;
2391 //===----------------------------------------------------------------------===//
2392 // Move between special register and ARM core register -- for disassembly only
2395 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
2396 [/* For disassembly only; pattern left blank */]> {
2397 let Inst{23-20} = 0b0000;
2398 let Inst{7-4} = 0b0000;
2401 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
2402 [/* For disassembly only; pattern left blank */]> {
2403 let Inst{23-20} = 0b0100;
2404 let Inst{7-4} = 0b0000;
2407 // FIXME: mask is ignored for the time being.
2408 def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
2409 [/* For disassembly only; pattern left blank */]> {
2410 let Inst{23-20} = 0b0010;
2411 let Inst{7-4} = 0b0000;
2414 // FIXME: mask is ignored for the time being.
2415 def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
2416 [/* For disassembly only; pattern left blank */]> {
2417 let Inst{23-20} = 0b0010;
2418 let Inst{7-4} = 0b0000;
2421 // FIXME: mask is ignored for the time being.
2422 def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
2423 [/* For disassembly only; pattern left blank */]> {
2424 let Inst{23-20} = 0b0110;
2425 let Inst{7-4} = 0b0000;
2428 // FIXME: mask is ignored for the time being.
2429 def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
2430 [/* For disassembly only; pattern left blank */]> {
2431 let Inst{23-20} = 0b0110;
2432 let Inst{7-4} = 0b0000;