1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMBr2JT : SDTypeProfile<0, 4,
38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
41 def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
43 SDTCisVT<1, i32>, SDTCisVT<2, i32>,
44 SDTCisVT<3, i32>, SDTCisVT<4, i32>,
45 SDTCisVT<5, OtherVT>]>;
47 def SDT_ARMAnd : SDTypeProfile<1, 2,
48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
51 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
53 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
56 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
57 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
59 def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
61 def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
63 def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
65 def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
67 def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
71 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
72 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
74 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
75 [SDNPHasChain, SDNPOutFlag]>;
76 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
77 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
79 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
80 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
82 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
83 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
85 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
86 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
89 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
90 [SDNPHasChain, SDNPOptInFlag]>;
92 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
94 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
97 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
98 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
100 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
102 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
105 def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
108 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
111 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
112 [SDNPOutFlag, SDNPCommutative]>;
114 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
116 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
117 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
118 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
120 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
121 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
122 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>;
123 def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
124 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
125 def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP",
126 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>;
129 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
131 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
133 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
134 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
136 def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
138 def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
139 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
142 def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
144 //===----------------------------------------------------------------------===//
145 // ARM Instruction Predicate Definitions.
147 def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate;
148 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
149 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
150 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
151 def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
152 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
153 def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
154 def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
155 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
156 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate;
157 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate;
158 def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate;
159 def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate;
160 def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
162 def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
164 def HasMP : Predicate<"Subtarget->hasMPExtension()">,
166 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
167 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
168 def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate;
169 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
170 def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate;
171 def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate;
172 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
173 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
175 // FIXME: Eventually this will be just "hasV6T2Ops".
176 def UseMovt : Predicate<"Subtarget->useMovt()">;
177 def DontUseMovt : Predicate<"!Subtarget->useMovt()">;
178 def UseVMLx : Predicate<"Subtarget->useVMLx()">;
180 //===----------------------------------------------------------------------===//
181 // ARM Flag Definitions.
183 class RegConstraint<string C> {
184 string Constraints = C;
187 //===----------------------------------------------------------------------===//
188 // ARM specific transformation functions and pattern fragments.
191 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
192 // so_imm_neg def below.
193 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
194 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
197 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
198 // so_imm_not def below.
199 def so_imm_not_XFORM : SDNodeXForm<imm, [{
200 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
203 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
204 def imm1_15 : PatLeaf<(i32 imm), [{
205 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
208 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
209 def imm16_31 : PatLeaf<(i32 imm), [{
210 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
215 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
216 }], so_imm_neg_XFORM>;
220 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
221 }], so_imm_not_XFORM>;
223 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
224 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
225 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
228 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
230 def bf_inv_mask_imm : Operand<i32>,
232 return ARM::isBitFieldInvertedMask(N->getZExtValue());
234 let EncoderMethod = "getBitfieldInvertedMaskOpValue";
235 let PrintMethod = "printBitfieldInvMaskImmOperand";
238 /// Split a 32-bit immediate into two 16 bit parts.
239 def hi16 : SDNodeXForm<imm, [{
240 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
243 def lo16AllZero : PatLeaf<(i32 imm), [{
244 // Returns true if all low 16-bits are 0.
245 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
248 /// imm0_65535 predicate - True if the 32-bit immediate is in the range
250 def imm0_65535 : PatLeaf<(i32 imm), [{
251 return (uint32_t)N->getZExtValue() < 65536;
254 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
255 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
257 /// adde and sube predicates - True based on whether the carry flag output
258 /// will be needed or not.
259 def adde_dead_carry :
260 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
261 [{return !N->hasAnyUseOfValue(1);}]>;
262 def sube_dead_carry :
263 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
264 [{return !N->hasAnyUseOfValue(1);}]>;
265 def adde_live_carry :
266 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
267 [{return N->hasAnyUseOfValue(1);}]>;
268 def sube_live_carry :
269 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
270 [{return N->hasAnyUseOfValue(1);}]>;
272 //===----------------------------------------------------------------------===//
273 // Operand Definitions.
277 def brtarget : Operand<OtherVT> {
278 let EncoderMethod = "getBranchTargetOpValue";
282 def bltarget : Operand<i32> {
283 // Encoded the same as branch targets.
284 let EncoderMethod = "getBranchTargetOpValue";
287 // A list of registers separated by comma. Used by load/store multiple.
288 def RegListAsmOperand : AsmOperandClass {
289 let Name = "RegList";
290 let SuperClasses = [];
293 def DPRRegListAsmOperand : AsmOperandClass {
294 let Name = "DPRRegList";
295 let SuperClasses = [];
298 def SPRRegListAsmOperand : AsmOperandClass {
299 let Name = "SPRRegList";
300 let SuperClasses = [];
303 def reglist : Operand<i32> {
304 let EncoderMethod = "getRegisterListOpValue";
305 let ParserMatchClass = RegListAsmOperand;
306 let PrintMethod = "printRegisterList";
309 def dpr_reglist : Operand<i32> {
310 let EncoderMethod = "getRegisterListOpValue";
311 let ParserMatchClass = DPRRegListAsmOperand;
312 let PrintMethod = "printRegisterList";
315 def spr_reglist : Operand<i32> {
316 let EncoderMethod = "getRegisterListOpValue";
317 let ParserMatchClass = SPRRegListAsmOperand;
318 let PrintMethod = "printRegisterList";
321 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
322 def cpinst_operand : Operand<i32> {
323 let PrintMethod = "printCPInstOperand";
326 def jtblock_operand : Operand<i32> {
327 let PrintMethod = "printJTBlockOperand";
329 def jt2block_operand : Operand<i32> {
330 let PrintMethod = "printJT2BlockOperand";
334 def pclabel : Operand<i32> {
335 let PrintMethod = "printPCLabel";
338 def neon_vcvt_imm32 : Operand<i32> {
339 let EncoderMethod = "getNEONVcvtImm32OpValue";
342 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
343 def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
344 int32_t v = (int32_t)N->getZExtValue();
345 return v == 8 || v == 16 || v == 24; }]> {
346 let EncoderMethod = "getRotImmOpValue";
349 // shift_imm: An integer that encodes a shift amount and the type of shift
350 // (currently either asr or lsl) using the same encoding used for the
351 // immediates in so_reg operands.
352 def shift_imm : Operand<i32> {
353 let PrintMethod = "printShiftImmOperand";
356 // shifter_operand operands: so_reg and so_imm.
357 def so_reg : Operand<i32>, // reg reg imm
358 ComplexPattern<i32, 3, "SelectShifterOperandReg",
359 [shl,srl,sra,rotr]> {
360 let EncoderMethod = "getSORegOpValue";
361 let PrintMethod = "printSORegOperand";
362 let MIOperandInfo = (ops GPR, GPR, i32imm);
364 def shift_so_reg : Operand<i32>, // reg reg imm
365 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
366 [shl,srl,sra,rotr]> {
367 let EncoderMethod = "getSORegOpValue";
368 let PrintMethod = "printSORegOperand";
369 let MIOperandInfo = (ops GPR, GPR, i32imm);
372 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
373 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
374 // represented in the imm field in the same 12-bit form that they are encoded
375 // into so_imm instructions: the 8-bit immediate is the least significant bits
376 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
377 def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> {
378 let EncoderMethod = "getSOImmOpValue";
379 let PrintMethod = "printSOImmOperand";
382 // Break so_imm's up into two pieces. This handles immediates with up to 16
383 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
384 // get the first/second pieces.
385 def so_imm2part : PatLeaf<(imm), [{
386 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
389 /// arm_i32imm - True for +V6T2, or true only if so_imm2part is true.
391 def arm_i32imm : PatLeaf<(imm), [{
392 if (Subtarget->hasV6T2Ops())
394 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
397 def so_imm2part_1 : SDNodeXForm<imm, [{
398 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
399 return CurDAG->getTargetConstant(V, MVT::i32);
402 def so_imm2part_2 : SDNodeXForm<imm, [{
403 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
404 return CurDAG->getTargetConstant(V, MVT::i32);
407 def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
408 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue());
410 let PrintMethod = "printSOImm2PartOperand";
413 def so_neg_imm2part_1 : SDNodeXForm<imm, [{
414 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue());
415 return CurDAG->getTargetConstant(V, MVT::i32);
418 def so_neg_imm2part_2 : SDNodeXForm<imm, [{
419 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue());
420 return CurDAG->getTargetConstant(V, MVT::i32);
423 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
424 def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
425 return (int32_t)N->getZExtValue() < 32;
428 /// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
429 def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
430 return (int32_t)N->getZExtValue() < 32;
432 let EncoderMethod = "getImmMinusOneOpValue";
435 // Define ARM specific addressing modes.
438 // addrmode_imm12 := reg +/- imm12
440 def addrmode_imm12 : Operand<i32>,
441 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
442 // 12-bit immediate operand. Note that instructions using this encode
443 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
444 // immediate values are as normal.
446 let EncoderMethod = "getAddrModeImm12OpValue";
447 let PrintMethod = "printAddrModeImm12Operand";
448 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
450 // ldst_so_reg := reg +/- reg shop imm
452 def ldst_so_reg : Operand<i32>,
453 ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
454 let EncoderMethod = "getLdStSORegOpValue";
455 // FIXME: Simplify the printer
456 let PrintMethod = "printAddrMode2Operand";
457 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
460 // addrmode2 := reg +/- imm12
461 // := reg +/- reg shop imm
463 def addrmode2 : Operand<i32>,
464 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
465 string EncoderMethod = "getAddrMode2OpValue";
466 let PrintMethod = "printAddrMode2Operand";
467 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
470 def am2offset : Operand<i32>,
471 ComplexPattern<i32, 2, "SelectAddrMode2Offset",
472 [], [SDNPWantRoot]> {
473 string EncoderMethod = "getAddrMode2OffsetOpValue";
474 let PrintMethod = "printAddrMode2OffsetOperand";
475 let MIOperandInfo = (ops GPR, i32imm);
478 // addrmode3 := reg +/- reg
479 // addrmode3 := reg +/- imm8
481 def addrmode3 : Operand<i32>,
482 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
483 let EncoderMethod = "getAddrMode3OpValue";
484 let PrintMethod = "printAddrMode3Operand";
485 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
488 def am3offset : Operand<i32>,
489 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
490 [], [SDNPWantRoot]> {
491 let EncoderMethod = "getAddrMode3OffsetOpValue";
492 let PrintMethod = "printAddrMode3OffsetOperand";
493 let MIOperandInfo = (ops GPR, i32imm);
496 // ldstm_mode := {ia, ib, da, db}
498 def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
499 let EncoderMethod = "getLdStmModeOpValue";
500 let PrintMethod = "printLdStmModeOperand";
503 def MemMode5AsmOperand : AsmOperandClass {
504 let Name = "MemMode5";
505 let SuperClasses = [];
508 // addrmode5 := reg +/- imm8*4
510 def addrmode5 : Operand<i32>,
511 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
512 let PrintMethod = "printAddrMode5Operand";
513 let MIOperandInfo = (ops GPR:$base, i32imm);
514 let ParserMatchClass = MemMode5AsmOperand;
515 let EncoderMethod = "getAddrMode5OpValue";
518 // addrmode6 := reg with optional writeback
520 def addrmode6 : Operand<i32>,
521 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
522 let PrintMethod = "printAddrMode6Operand";
523 let MIOperandInfo = (ops GPR:$addr, i32imm);
524 let EncoderMethod = "getAddrMode6AddressOpValue";
527 def am6offset : Operand<i32> {
528 let PrintMethod = "printAddrMode6OffsetOperand";
529 let MIOperandInfo = (ops GPR);
530 let EncoderMethod = "getAddrMode6OffsetOpValue";
533 // addrmodepc := pc + reg
535 def addrmodepc : Operand<i32>,
536 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
537 let PrintMethod = "printAddrModePCOperand";
538 let MIOperandInfo = (ops GPR, i32imm);
541 def nohash_imm : Operand<i32> {
542 let PrintMethod = "printNoHashImmediate";
545 //===----------------------------------------------------------------------===//
547 include "ARMInstrFormats.td"
549 //===----------------------------------------------------------------------===//
550 // Multiclass helpers...
553 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
554 /// binop that produces a value.
555 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
556 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
557 PatFrag opnode, bit Commutable = 0> {
558 // The register-immediate version is re-materializable. This is useful
559 // in particular for taking the address of a local.
560 let isReMaterializable = 1 in {
561 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
562 iii, opc, "\t$Rd, $Rn, $imm",
563 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
568 let Inst{19-16} = Rn;
569 let Inst{15-12} = Rd;
570 let Inst{11-0} = imm;
573 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
574 iir, opc, "\t$Rd, $Rn, $Rm",
575 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
580 let isCommutable = Commutable;
581 let Inst{19-16} = Rn;
582 let Inst{15-12} = Rd;
583 let Inst{11-4} = 0b00000000;
586 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
587 iis, opc, "\t$Rd, $Rn, $shift",
588 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
593 let Inst{19-16} = Rn;
594 let Inst{15-12} = Rd;
595 let Inst{11-0} = shift;
599 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
600 /// instruction modifies the CPSR register.
601 let Defs = [CPSR] in {
602 multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
603 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
604 PatFrag opnode, bit Commutable = 0> {
605 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
606 iii, opc, "\t$Rd, $Rn, $imm",
607 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
613 let Inst{19-16} = Rn;
614 let Inst{15-12} = Rd;
615 let Inst{11-0} = imm;
617 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
618 iir, opc, "\t$Rd, $Rn, $Rm",
619 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
623 let isCommutable = Commutable;
626 let Inst{19-16} = Rn;
627 let Inst{15-12} = Rd;
628 let Inst{11-4} = 0b00000000;
631 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
632 iis, opc, "\t$Rd, $Rn, $shift",
633 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
639 let Inst{19-16} = Rn;
640 let Inst{15-12} = Rd;
641 let Inst{11-0} = shift;
646 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
647 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
648 /// a explicit result, only implicitly set CPSR.
649 let isCompare = 1, Defs = [CPSR] in {
650 multiclass AI1_cmp_irs<bits<4> opcod, string opc,
651 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
652 PatFrag opnode, bit Commutable = 0> {
653 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii,
655 [(opnode GPR:$Rn, so_imm:$imm)]> {
660 let Inst{19-16} = Rn;
661 let Inst{15-12} = 0b0000;
662 let Inst{11-0} = imm;
664 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
666 [(opnode GPR:$Rn, GPR:$Rm)]> {
669 let isCommutable = Commutable;
672 let Inst{19-16} = Rn;
673 let Inst{15-12} = 0b0000;
674 let Inst{11-4} = 0b00000000;
677 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
678 opc, "\t$Rn, $shift",
679 [(opnode GPR:$Rn, so_reg:$shift)]> {
684 let Inst{19-16} = Rn;
685 let Inst{15-12} = 0b0000;
686 let Inst{11-0} = shift;
691 /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
692 /// register and one whose operand is a register rotated by 8/16/24.
693 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
694 multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
695 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
696 IIC_iEXTr, opc, "\t$Rd, $Rm",
697 [(set GPR:$Rd, (opnode GPR:$Rm))]>,
698 Requires<[IsARM, HasV6]> {
701 let Inst{19-16} = 0b1111;
702 let Inst{15-12} = Rd;
703 let Inst{11-10} = 0b00;
706 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
707 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
708 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
709 Requires<[IsARM, HasV6]> {
713 let Inst{19-16} = 0b1111;
714 let Inst{15-12} = Rd;
715 let Inst{11-10} = rot;
720 multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
721 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
722 IIC_iEXTr, opc, "\t$Rd, $Rm",
723 [/* For disassembly only; pattern left blank */]>,
724 Requires<[IsARM, HasV6]> {
725 let Inst{19-16} = 0b1111;
726 let Inst{11-10} = 0b00;
728 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
729 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
730 [/* For disassembly only; pattern left blank */]>,
731 Requires<[IsARM, HasV6]> {
733 let Inst{19-16} = 0b1111;
734 let Inst{11-10} = rot;
738 /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
739 /// register and one whose operand is a register rotated by 8/16/24.
740 multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
741 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
742 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
743 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
744 Requires<[IsARM, HasV6]> {
745 let Inst{11-10} = 0b00;
747 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
749 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
750 [(set GPR:$Rd, (opnode GPR:$Rn,
751 (rotr GPR:$Rm, rot_imm:$rot)))]>,
752 Requires<[IsARM, HasV6]> {
755 let Inst{19-16} = Rn;
756 let Inst{11-10} = rot;
760 // For disassembly only.
761 multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
762 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
763 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
764 [/* For disassembly only; pattern left blank */]>,
765 Requires<[IsARM, HasV6]> {
766 let Inst{11-10} = 0b00;
768 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
770 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
771 [/* For disassembly only; pattern left blank */]>,
772 Requires<[IsARM, HasV6]> {
775 let Inst{19-16} = Rn;
776 let Inst{11-10} = rot;
780 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
781 let Uses = [CPSR] in {
782 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
783 bit Commutable = 0> {
784 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
785 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
786 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
792 let Inst{15-12} = Rd;
793 let Inst{19-16} = Rn;
794 let Inst{11-0} = imm;
796 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
797 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
798 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
803 let Inst{11-4} = 0b00000000;
805 let isCommutable = Commutable;
807 let Inst{15-12} = Rd;
808 let Inst{19-16} = Rn;
810 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
811 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
812 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
818 let Inst{11-0} = shift;
819 let Inst{15-12} = Rd;
820 let Inst{19-16} = Rn;
823 // Carry setting variants
824 let Defs = [CPSR] in {
825 multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
826 bit Commutable = 0> {
827 def Sri : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
828 DPFrm, IIC_iALUi, !strconcat(opc, "\t$Rd, $Rn, $imm"),
829 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
834 let Inst{15-12} = Rd;
835 let Inst{19-16} = Rn;
836 let Inst{11-0} = imm;
840 def Srr : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
841 DPFrm, IIC_iALUr, !strconcat(opc, "\t$Rd, $Rn, $Rm"),
842 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
847 let Inst{11-4} = 0b00000000;
848 let isCommutable = Commutable;
850 let Inst{15-12} = Rd;
851 let Inst{19-16} = Rn;
855 def Srs : AXI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
856 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$Rd, $Rn, $shift"),
857 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
862 let Inst{11-0} = shift;
863 let Inst{15-12} = Rd;
864 let Inst{19-16} = Rn;
872 let canFoldAsLoad = 1, isReMaterializable = 1 in {
873 multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
874 InstrItinClass iir, PatFrag opnode> {
875 // Note: We use the complex addrmode_imm12 rather than just an input
876 // GPR and a constrained immediate so that we can use this to match
877 // frame index references and avoid matching constant pool references.
878 def i12: AIldst1<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
879 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
880 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
883 let Inst{23} = addr{12}; // U (add = ('U' == 1))
884 let Inst{19-16} = addr{16-13}; // Rn
885 let Inst{15-12} = Rt;
886 let Inst{11-0} = addr{11-0}; // imm12
888 def rs : AIldst1<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
889 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
890 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
893 let Inst{23} = shift{12}; // U (add = ('U' == 1))
894 let Inst{19-16} = shift{16-13}; // Rn
895 let Inst{15-12} = Rt;
896 let Inst{11-0} = shift{11-0};
901 multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
902 InstrItinClass iir, PatFrag opnode> {
903 // Note: We use the complex addrmode_imm12 rather than just an input
904 // GPR and a constrained immediate so that we can use this to match
905 // frame index references and avoid matching constant pool references.
906 def i12 : AIldst1<0b010, 0, isByte, (outs),
907 (ins GPR:$Rt, addrmode_imm12:$addr),
908 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
909 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
912 let Inst{23} = addr{12}; // U (add = ('U' == 1))
913 let Inst{19-16} = addr{16-13}; // Rn
914 let Inst{15-12} = Rt;
915 let Inst{11-0} = addr{11-0}; // imm12
917 def rs : AIldst1<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
918 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
919 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
922 let Inst{23} = shift{12}; // U (add = ('U' == 1))
923 let Inst{19-16} = shift{16-13}; // Rn
924 let Inst{15-12} = Rt;
925 let Inst{11-0} = shift{11-0};
928 //===----------------------------------------------------------------------===//
930 //===----------------------------------------------------------------------===//
932 //===----------------------------------------------------------------------===//
933 // Miscellaneous Instructions.
936 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
937 /// the function. The first operand is the ID# for this instruction, the second
938 /// is the index into the MachineConstantPool that this is, the third is the
939 /// size in bytes of this constant pool entry.
940 let neverHasSideEffects = 1, isNotDuplicable = 1 in
941 def CONSTPOOL_ENTRY :
942 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
943 i32imm:$size), NoItinerary, "", []>;
945 // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
946 // from removing one half of the matched pairs. That breaks PEI, which assumes
947 // these will always be in pairs, and asserts if it finds otherwise. Better way?
948 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
950 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "",
951 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
953 def ADJCALLSTACKDOWN :
954 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "",
955 [(ARMcallseq_start timm:$amt)]>;
958 def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
959 [/* For disassembly only; pattern left blank */]>,
960 Requires<[IsARM, HasV6T2]> {
961 let Inst{27-16} = 0b001100100000;
962 let Inst{15-8} = 0b11110000;
963 let Inst{7-0} = 0b00000000;
966 def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
967 [/* For disassembly only; pattern left blank */]>,
968 Requires<[IsARM, HasV6T2]> {
969 let Inst{27-16} = 0b001100100000;
970 let Inst{15-8} = 0b11110000;
971 let Inst{7-0} = 0b00000001;
974 def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
975 [/* For disassembly only; pattern left blank */]>,
976 Requires<[IsARM, HasV6T2]> {
977 let Inst{27-16} = 0b001100100000;
978 let Inst{15-8} = 0b11110000;
979 let Inst{7-0} = 0b00000010;
982 def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
983 [/* For disassembly only; pattern left blank */]>,
984 Requires<[IsARM, HasV6T2]> {
985 let Inst{27-16} = 0b001100100000;
986 let Inst{15-8} = 0b11110000;
987 let Inst{7-0} = 0b00000011;
990 def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
992 [/* For disassembly only; pattern left blank */]>,
993 Requires<[IsARM, HasV6]> {
998 let Inst{15-12} = Rd;
999 let Inst{19-16} = Rn;
1000 let Inst{27-20} = 0b01101000;
1001 let Inst{7-4} = 0b1011;
1002 let Inst{11-8} = 0b1111;
1005 def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
1006 [/* For disassembly only; pattern left blank */]>,
1007 Requires<[IsARM, HasV6T2]> {
1008 let Inst{27-16} = 0b001100100000;
1009 let Inst{15-8} = 0b11110000;
1010 let Inst{7-0} = 0b00000100;
1013 // The i32imm operand $val can be used by a debugger to store more information
1014 // about the breakpoint.
1015 def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
1016 [/* For disassembly only; pattern left blank */]>,
1019 let Inst{3-0} = val{3-0};
1020 let Inst{19-8} = val{15-4};
1021 let Inst{27-20} = 0b00010010;
1022 let Inst{7-4} = 0b0111;
1025 // Change Processor State is a system instruction -- for disassembly only.
1026 // The singleton $opt operand contains the following information:
1027 // opt{4-0} = mode from Inst{4-0}
1028 // opt{5} = changemode from Inst{17}
1029 // opt{8-6} = AIF from Inst{8-6}
1030 // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
1031 // FIXME: Integrated assembler will need these split out.
1032 def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
1033 [/* For disassembly only; pattern left blank */]>,
1035 let Inst{31-28} = 0b1111;
1036 let Inst{27-20} = 0b00010000;
1041 // Preload signals the memory system of possible future data/instruction access.
1042 // These are for disassembly only.
1043 multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
1045 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
1046 !strconcat(opc, "\t$addr"),
1047 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
1050 let Inst{31-26} = 0b111101;
1051 let Inst{25} = 0; // 0 for immediate form
1052 let Inst{24} = data;
1053 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1054 let Inst{22} = read;
1055 let Inst{21-20} = 0b01;
1056 let Inst{19-16} = addr{16-13}; // Rn
1057 let Inst{15-12} = Rt;
1058 let Inst{11-0} = addr{11-0}; // imm12
1061 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
1062 !strconcat(opc, "\t$shift"),
1063 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
1066 let Inst{31-26} = 0b111101;
1067 let Inst{25} = 1; // 1 for register form
1068 let Inst{24} = data;
1069 let Inst{23} = shift{12}; // U (add = ('U' == 1))
1070 let Inst{22} = read;
1071 let Inst{21-20} = 0b01;
1072 let Inst{19-16} = shift{16-13}; // Rn
1073 let Inst{11-0} = shift{11-0};
1077 defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
1078 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
1079 defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
1081 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
1083 [/* For disassembly only; pattern left blank */]>,
1086 let Inst{31-10} = 0b1111000100000001000000;
1091 def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
1092 [/* For disassembly only; pattern left blank */]>,
1093 Requires<[IsARM, HasV7]> {
1095 let Inst{27-4} = 0b001100100000111100001111;
1096 let Inst{3-0} = opt;
1099 // A5.4 Permanently UNDEFINED instructions.
1100 let isBarrier = 1, isTerminator = 1 in
1101 def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
1104 let Inst{27-25} = 0b011;
1105 let Inst{24-20} = 0b11111;
1106 let Inst{7-5} = 0b111;
1110 // Address computation and loads and stores in PIC mode.
1111 // FIXME: These PIC insn patterns are pseudos, but derive from the normal insn
1112 // classes (AXI1, et.al.) and so have encoding information and such,
1113 // which is suboptimal. Once the rest of the code emitter (including
1114 // JIT) is MC-ized we should look at refactoring these into true
1115 // pseudos. As is, the encoding information ends up being ignored,
1116 // as these instructions are lowered to individual MC-insts.
1117 let isNotDuplicable = 1 in {
1118 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
1119 Pseudo, IIC_iALUr, "",
1120 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
1122 let AddedComplexity = 10 in {
1123 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1124 Pseudo, IIC_iLoad_r, "",
1125 [(set GPR:$dst, (load addrmodepc:$addr))]>;
1127 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1128 Pseudo, IIC_iLoad_bh_r, "",
1129 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
1131 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1132 Pseudo, IIC_iLoad_bh_r, "",
1133 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
1135 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1136 Pseudo, IIC_iLoad_bh_r, "",
1137 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
1139 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
1140 Pseudo, IIC_iLoad_bh_r, "",
1141 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
1143 let AddedComplexity = 10 in {
1144 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1145 Pseudo, IIC_iStore_r, "",
1146 [(store GPR:$src, addrmodepc:$addr)]>;
1148 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1149 Pseudo, IIC_iStore_bh_r, "",
1150 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
1152 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
1153 Pseudo, IIC_iStore_bh_r, "",
1154 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
1156 } // isNotDuplicable = 1
1159 // LEApcrel - Load a pc-relative address into a register without offending the
1161 // FIXME: These are marked as pseudos, but they're really not(?). They're just
1162 // the ADR instruction. Is this the right way to handle that? They need
1163 // encoding information regardless.
1164 let neverHasSideEffects = 1 in {
1165 let isReMaterializable = 1 in
1166 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
1168 "adr$p\t$dst, #$label", []>;
1170 } // neverHasSideEffects
1171 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
1172 (ins i32imm:$label, nohash_imm:$id, pred:$p),
1174 "adr$p\t$dst, #${label}_${id}", []> {
1178 //===----------------------------------------------------------------------===//
1179 // Control Flow Instructions.
1182 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
1184 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1185 "bx", "\tlr", [(ARMretflag)]>,
1186 Requires<[IsARM, HasV4T]> {
1187 let Inst{27-0} = 0b0001001011111111111100011110;
1191 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
1192 "mov", "\tpc, lr", [(ARMretflag)]>,
1193 Requires<[IsARM, NoV4T]> {
1194 let Inst{27-0} = 0b0001101000001111000000001110;
1198 // Indirect branches
1199 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1201 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
1202 [(brind GPR:$dst)]>,
1203 Requires<[IsARM, HasV4T]> {
1205 let Inst{31-4} = 0b1110000100101111111111110001;
1206 let Inst{3-0} = dst;
1210 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
1211 [(brind GPR:$dst)]>,
1212 Requires<[IsARM, NoV4T]> {
1214 let Inst{31-4} = 0b1110000110100000111100000000;
1215 let Inst{3-0} = dst;
1219 // On non-Darwin platforms R9 is callee-saved.
1221 Defs = [R0, R1, R2, R3, R12, LR,
1222 D0, D1, D2, D3, D4, D5, D6, D7,
1223 D16, D17, D18, D19, D20, D21, D22, D23,
1224 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1225 def BL : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1226 IIC_Br, "bl\t$func",
1227 [(ARMcall tglobaladdr:$func)]>,
1228 Requires<[IsARM, IsNotDarwin]> {
1229 let Inst{31-28} = 0b1110;
1231 let Inst{23-0} = func;
1234 def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1235 IIC_Br, "bl", "\t$func",
1236 [(ARMcall_pred tglobaladdr:$func)]>,
1237 Requires<[IsARM, IsNotDarwin]> {
1239 let Inst{23-0} = func;
1243 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1244 IIC_Br, "blx\t$func",
1245 [(ARMcall GPR:$func)]>,
1246 Requires<[IsARM, HasV5T, IsNotDarwin]> {
1248 let Inst{27-4} = 0b000100101111111111110011;
1249 let Inst{3-0} = func;
1253 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1254 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1255 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1256 [(ARMcall_nolink tGPR:$func)]>,
1257 Requires<[IsARM, HasV4T, IsNotDarwin]> {
1259 let Inst{27-4} = 0b000100101111111111110001;
1260 let Inst{3-0} = func;
1264 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1265 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1266 [(ARMcall_nolink tGPR:$func)]>,
1267 Requires<[IsARM, NoV4T, IsNotDarwin]> {
1269 let Inst{27-4} = 0b000110100000111100000000;
1270 let Inst{3-0} = func;
1274 // On Darwin R9 is call-clobbered.
1276 Defs = [R0, R1, R2, R3, R9, R12, LR,
1277 D0, D1, D2, D3, D4, D5, D6, D7,
1278 D16, D17, D18, D19, D20, D21, D22, D23,
1279 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
1280 def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1281 IIC_Br, "bl\t$func",
1282 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
1283 let Inst{31-28} = 0b1110;
1285 let Inst{23-0} = func;
1288 def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
1289 IIC_Br, "bl", "\t$func",
1290 [(ARMcall_pred tglobaladdr:$func)]>,
1291 Requires<[IsARM, IsDarwin]> {
1293 let Inst{23-0} = func;
1297 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
1298 IIC_Br, "blx\t$func",
1299 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
1301 let Inst{27-4} = 0b000100101111111111110011;
1302 let Inst{3-0} = func;
1306 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
1307 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1308 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
1309 [(ARMcall_nolink tGPR:$func)]>,
1310 Requires<[IsARM, HasV4T, IsDarwin]> {
1312 let Inst{27-4} = 0b000100101111111111110001;
1313 let Inst{3-0} = func;
1317 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1318 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1319 [(ARMcall_nolink tGPR:$func)]>,
1320 Requires<[IsARM, NoV4T, IsDarwin]> {
1322 let Inst{27-4} = 0b000110100000111100000000;
1323 let Inst{3-0} = func;
1329 // FIXME: These should probably be xformed into the non-TC versions of the
1330 // instructions as part of MC lowering.
1331 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1333 let Defs = [R0, R1, R2, R3, R9, R12,
1334 D0, D1, D2, D3, D4, D5, D6, D7,
1335 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1336 D27, D28, D29, D30, D31, PC],
1338 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1340 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1342 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1344 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
1346 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1347 IIC_Br, "b\t$dst @ TAILCALL",
1348 []>, Requires<[IsDarwin]>;
1350 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1351 IIC_Br, "b.w\t$dst @ TAILCALL",
1352 []>, Requires<[IsDarwin]>;
1354 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1355 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1356 []>, Requires<[IsDarwin]> {
1358 let Inst{31-4} = 0b1110000100101111111111110001;
1359 let Inst{3-0} = dst;
1363 // Non-Darwin versions (the difference is R9).
1364 let Defs = [R0, R1, R2, R3, R12,
1365 D0, D1, D2, D3, D4, D5, D6, D7,
1366 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26,
1367 D27, D28, D29, D30, D31, PC],
1369 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops),
1371 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1373 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops),
1375 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>;
1377 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1378 IIC_Br, "b\t$dst @ TAILCALL",
1379 []>, Requires<[IsARM, IsNotDarwin]>;
1381 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
1382 IIC_Br, "b.w\t$dst @ TAILCALL",
1383 []>, Requires<[IsThumb, IsNotDarwin]>;
1385 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
1386 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
1387 []>, Requires<[IsNotDarwin]> {
1389 let Inst{31-4} = 0b1110000100101111111111110001;
1390 let Inst{3-0} = dst;
1395 let isBranch = 1, isTerminator = 1 in {
1396 // B is "predicable" since it can be xformed into a Bcc.
1397 let isBarrier = 1 in {
1398 let isPredicable = 1 in
1399 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
1400 "b\t$target", [(br bb:$target)]> {
1402 let Inst{31-28} = 0b1110;
1403 let Inst{23-0} = target;
1406 let isNotDuplicable = 1, isIndirectBranch = 1,
1407 // FIXME: $imm field is not specified by asm string. Mark as cgonly.
1408 isCodeGenOnly = 1 in {
1409 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
1410 IIC_Br, "mov\tpc, $target$jt",
1411 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
1412 let Inst{11-4} = 0b00000000;
1413 let Inst{15-12} = 0b1111;
1414 let Inst{20} = 0; // S Bit
1415 let Inst{24-21} = 0b1101;
1416 let Inst{27-25} = 0b000;
1418 def BR_JTm : JTI<(outs),
1419 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
1420 IIC_Br, "ldr\tpc, $target$jt",
1421 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
1423 let Inst{15-12} = 0b1111;
1424 let Inst{20} = 1; // L bit
1425 let Inst{21} = 0; // W bit
1426 let Inst{22} = 0; // B bit
1427 let Inst{24} = 1; // P bit
1428 let Inst{27-25} = 0b011;
1430 def BR_JTadd : JTI<(outs),
1431 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
1432 IIC_Br, "add\tpc, $target, $idx$jt",
1433 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
1435 let Inst{15-12} = 0b1111;
1436 let Inst{20} = 0; // S bit
1437 let Inst{24-21} = 0b0100;
1438 let Inst{27-25} = 0b000;
1440 } // isNotDuplicable = 1, isIndirectBranch = 1
1443 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1444 // a two-value operand where a dag node expects two operands. :(
1445 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
1446 IIC_Br, "b", "\t$target",
1447 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1449 let Inst{23-0} = target;
1453 // Branch and Exchange Jazelle -- for disassembly only
1454 def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
1455 [/* For disassembly only; pattern left blank */]> {
1456 let Inst{23-20} = 0b0010;
1457 //let Inst{19-8} = 0xfff;
1458 let Inst{7-4} = 0b0010;
1461 // Secure Monitor Call is a system instruction -- for disassembly only
1462 def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
1463 [/* For disassembly only; pattern left blank */]> {
1465 let Inst{23-4} = 0b01100000000000000111;
1466 let Inst{3-0} = opt;
1469 // Supervisor Call (Software Interrupt) -- for disassembly only
1471 def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
1472 [/* For disassembly only; pattern left blank */]> {
1474 let Inst{23-0} = svc;
1478 // Store Return State is a system instruction -- for disassembly only
1479 let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
1480 def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1481 NoItinerary, "srs${amode}\tsp!, $mode",
1482 [/* For disassembly only; pattern left blank */]> {
1483 let Inst{31-28} = 0b1111;
1484 let Inst{22-20} = 0b110; // W = 1
1487 def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
1488 NoItinerary, "srs${amode}\tsp, $mode",
1489 [/* For disassembly only; pattern left blank */]> {
1490 let Inst{31-28} = 0b1111;
1491 let Inst{22-20} = 0b100; // W = 0
1494 // Return From Exception is a system instruction -- for disassembly only
1495 def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1496 NoItinerary, "rfe${amode}\t$base!",
1497 [/* For disassembly only; pattern left blank */]> {
1498 let Inst{31-28} = 0b1111;
1499 let Inst{22-20} = 0b011; // W = 1
1502 def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
1503 NoItinerary, "rfe${amode}\t$base",
1504 [/* For disassembly only; pattern left blank */]> {
1505 let Inst{31-28} = 0b1111;
1506 let Inst{22-20} = 0b001; // W = 0
1508 } // isCodeGenOnly = 1
1510 //===----------------------------------------------------------------------===//
1511 // Load / store Instructions.
1517 defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si,
1518 UnOpFrag<(load node:$Src)>>;
1519 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
1520 UnOpFrag<(zextloadi8 node:$Src)>>;
1521 defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si,
1522 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1523 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
1524 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
1526 // Special LDR for loads from non-pc-relative constpools.
1527 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
1528 isReMaterializable = 1 in
1529 def LDRcp : AIldst1<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1530 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
1534 let Inst{23} = addr{12}; // U (add = ('U' == 1))
1535 let Inst{19-16} = 0b1111;
1536 let Inst{15-12} = Rt;
1537 let Inst{11-0} = addr{11-0}; // imm12
1540 // Loads with zero extension
1541 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1542 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr",
1543 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
1545 // Loads with sign extension
1546 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1547 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr",
1548 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
1550 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
1551 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr",
1552 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
1554 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
1555 isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring?
1557 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
1558 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr",
1559 []>, Requires<[IsARM, HasV5TE]>;
1562 multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
1563 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1564 (ins addrmode2:$addr), IndexModePre, LdFrm, itin,
1565 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
1567 // {13} 1 == Rm, 0 == imm12
1571 let Inst{25} = addr{13};
1572 let Inst{23} = addr{12};
1573 let Inst{19-16} = addr{17-14};
1574 let Inst{11-0} = addr{11-0};
1576 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1577 (ins GPR:$Rn, am2offset:$offset),
1578 IndexModePost, LdFrm, itin,
1579 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
1580 // {13} 1 == Rm, 0 == imm12
1585 let Inst{25} = offset{13};
1586 let Inst{23} = offset{12};
1587 let Inst{19-16} = Rn;
1588 let Inst{11-0} = offset{11-0};
1592 defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
1593 defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
1595 def LDRH_PRE : AI3ldhpr<(outs GPR:$Rt, GPR:$Rn_wb),
1596 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1597 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1599 def LDRH_POST : AI3ldhpo<(outs GPR:$Rt, GPR:$Rn_wb),
1600 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1601 "ldrh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1603 def LDRSH_PRE : AI3ldshpr<(outs GPR:$Rt, GPR:$Rn_wb),
1604 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1605 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1607 def LDRSH_POST: AI3ldshpo<(outs GPR:$Rt, GPR:$Rn_wb),
1608 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1609 "ldrsh", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1611 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$Rt, GPR:$Rn_wb),
1612 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru,
1613 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1615 def LDRSB_POST: AI3ldsbpo<(outs GPR:$Rt, GPR:$Rn_wb),
1616 (ins GPR:$Rn,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru,
1617 "ldrsb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
1619 // For disassembly only
1620 def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1621 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru,
1622 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
1623 Requires<[IsARM, HasV5TE]>;
1625 // For disassembly only
1626 def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
1627 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru,
1628 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
1629 Requires<[IsARM, HasV5TE]>;
1631 } // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
1633 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
1635 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1636 (ins GPR:$base, am2offset:$offset), IndexModeNone,
1637 LdFrm, IIC_iLoad_ru,
1638 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1639 let Inst{21} = 1; // overwrite
1642 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1643 (ins GPR:$base,am2offset:$offset), IndexModeNone,
1644 LdFrm, IIC_iLoad_bh_ru,
1645 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1646 let Inst{21} = 1; // overwrite
1649 def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
1650 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1651 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1652 let Inst{21} = 1; // overwrite
1655 def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
1656 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1657 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1658 let Inst{21} = 1; // overwrite
1661 def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
1662 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru,
1663 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1664 let Inst{21} = 1; // overwrite
1669 // Stores with truncate
1670 def STRH : AI3sth<(outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
1671 IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
1672 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
1675 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
1676 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
1677 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
1678 StMiscFrm, IIC_iStore_d_r,
1679 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
1682 def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$Rn_wb),
1683 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1684 IndexModePre, StFrm, IIC_iStore_ru,
1685 "str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1687 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
1688 // {13} 1 == Rm, 0 == imm12
1693 let Inst{25} = offset{13};
1694 let Inst{23} = offset{12};
1695 let Inst{19-16} = Rn;
1696 let Inst{11-0} = offset{11-0};
1699 def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
1700 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1701 IndexModePost, StFrm, IIC_iStore_ru,
1702 "str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1704 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
1705 // {13} 1 == Rm, 0 == imm12
1710 let Inst{25} = offset{13};
1711 let Inst{23} = offset{12};
1712 let Inst{19-16} = Rn;
1713 let Inst{11-0} = offset{11-0};
1716 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
1717 (ins GPR:$src, GPR:$base,am3offset:$offset),
1718 StMiscFrm, IIC_iStore_ru,
1719 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
1721 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
1723 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
1724 (ins GPR:$src, GPR:$base,am3offset:$offset),
1725 StMiscFrm, IIC_iStore_bh_ru,
1726 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
1727 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
1728 GPR:$base, am3offset:$offset))]>;
1730 def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$Rn_wb),
1731 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1732 IndexModePre, StFrm, IIC_iStore_bh_ru,
1733 "strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
1734 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
1735 GPR:$Rn, am2offset:$offset))]> {
1736 // {13} 1 == Rm, 0 == imm12
1741 let Inst{25} = offset{13};
1742 let Inst{23} = offset{12};
1743 let Inst{19-16} = Rn;
1744 let Inst{11-0} = offset{11-0};
1747 def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
1748 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1749 IndexModePost, StFrm, IIC_iStore_bh_ru,
1750 "strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1751 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
1752 GPR:$Rn, am2offset:$offset))]> {
1753 // {13} 1 == Rm, 0 == imm12
1758 let Inst{25} = offset{13};
1759 let Inst{23} = offset{12};
1760 let Inst{19-16} = Rn;
1761 let Inst{11-0} = offset{11-0};
1764 // For disassembly only
1765 def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
1766 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1767 StMiscFrm, IIC_iStore_d_ru,
1768 "strd", "\t$src1, $src2, [$base, $offset]!",
1769 "$base = $base_wb", []>;
1771 // For disassembly only
1772 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
1773 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
1774 StMiscFrm, IIC_iStore_d_ru,
1775 "strd", "\t$src1, $src2, [$base], $offset",
1776 "$base = $base_wb", []>;
1778 // STRT, STRBT, and STRHT are for disassembly only.
1780 def STRT : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
1781 (ins GPR:$src, GPR:$base,am2offset:$offset),
1782 IndexModeNone, StFrm, IIC_iStore_ru,
1783 "strt", "\t$src, [$base], $offset", "$base = $base_wb",
1784 [/* For disassembly only; pattern left blank */]> {
1785 let Inst{21} = 1; // overwrite
1788 def STRBT : AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
1789 (ins GPR:$src, GPR:$base,am2offset:$offset),
1790 IndexModeNone, StFrm, IIC_iStore_bh_ru,
1791 "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
1792 [/* For disassembly only; pattern left blank */]> {
1793 let Inst{21} = 1; // overwrite
1796 def STRHT: AI3sthpo<(outs GPR:$base_wb),
1797 (ins GPR:$src, GPR:$base,am3offset:$offset),
1798 StMiscFrm, IIC_iStore_bh_ru,
1799 "strht", "\t$src, [$base], $offset", "$base = $base_wb",
1800 [/* For disassembly only; pattern left blank */]> {
1801 let Inst{21} = 1; // overwrite
1804 //===----------------------------------------------------------------------===//
1805 // Load / store multiple Instructions.
1808 multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
1809 InstrItinClass itin, InstrItinClass itin_upd> {
1811 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1812 IndexModeNone, f, itin,
1813 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
1814 let Inst{24-23} = 0b01; // Increment After
1815 let Inst{21} = 0; // No writeback
1816 let Inst{20} = L_bit;
1819 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1820 IndexModeUpd, f, itin_upd,
1821 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1822 let Inst{24-23} = 0b01; // Increment After
1823 let Inst{21} = 1; // Writeback
1824 let Inst{20} = L_bit;
1827 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1828 IndexModeNone, f, itin,
1829 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> {
1830 let Inst{24-23} = 0b00; // Decrement After
1831 let Inst{21} = 0; // No writeback
1832 let Inst{20} = L_bit;
1835 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1836 IndexModeUpd, f, itin_upd,
1837 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1838 let Inst{24-23} = 0b00; // Decrement After
1839 let Inst{21} = 1; // Writeback
1840 let Inst{20} = L_bit;
1843 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1844 IndexModeNone, f, itin,
1845 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
1846 let Inst{24-23} = 0b10; // Decrement Before
1847 let Inst{21} = 0; // No writeback
1848 let Inst{20} = L_bit;
1851 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1852 IndexModeUpd, f, itin_upd,
1853 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1854 let Inst{24-23} = 0b10; // Decrement Before
1855 let Inst{21} = 1; // Writeback
1856 let Inst{20} = L_bit;
1859 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1860 IndexModeNone, f, itin,
1861 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> {
1862 let Inst{24-23} = 0b11; // Increment Before
1863 let Inst{21} = 0; // No writeback
1864 let Inst{20} = L_bit;
1867 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1868 IndexModeUpd, f, itin_upd,
1869 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1870 let Inst{24-23} = 0b11; // Increment Before
1871 let Inst{21} = 1; // Writeback
1872 let Inst{20} = L_bit;
1876 let neverHasSideEffects = 1 in {
1878 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1879 defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>;
1881 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1882 defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>;
1884 } // neverHasSideEffects
1886 // Load / Store Multiple Mnemnoic Aliases
1887 def : MnemonicAlias<"ldm", "ldmia">;
1888 def : MnemonicAlias<"stm", "stmia">;
1890 // FIXME: remove when we have a way to marking a MI with these properties.
1891 // FIXME: Should pc be an implicit operand like PICADD, etc?
1892 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1893 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
1894 def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
1895 reglist:$regs, variable_ops),
1896 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
1897 "ldmia${p}\t$Rn!, $regs",
1899 let Inst{24-23} = 0b01; // Increment After
1900 let Inst{21} = 1; // Writeback
1901 let Inst{20} = 1; // Load
1904 //===----------------------------------------------------------------------===//
1905 // Move Instructions.
1908 let neverHasSideEffects = 1 in
1909 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
1910 "mov", "\t$Rd, $Rm", []>, UnaryDP {
1914 let Inst{11-4} = 0b00000000;
1917 let Inst{15-12} = Rd;
1920 // A version for the smaller set of tail call registers.
1921 let neverHasSideEffects = 1 in
1922 def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
1923 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP {
1927 let Inst{11-4} = 0b00000000;
1930 let Inst{15-12} = Rd;
1933 def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
1934 DPSoRegFrm, IIC_iMOVsr,
1935 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
1939 let Inst{15-12} = Rd;
1940 let Inst{11-0} = src;
1944 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1945 def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
1946 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
1950 let Inst{15-12} = Rd;
1951 let Inst{19-16} = 0b0000;
1952 let Inst{11-0} = imm;
1955 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1956 def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
1958 "movw", "\t$Rd, $imm",
1959 [(set GPR:$Rd, imm0_65535:$imm)]>,
1960 Requires<[IsARM, HasV6T2]>, UnaryDP {
1963 let Inst{15-12} = Rd;
1964 let Inst{11-0} = imm{11-0};
1965 let Inst{19-16} = imm{15-12};
1970 let Constraints = "$src = $Rd" in
1971 def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
1973 "movt", "\t$Rd, $imm",
1975 (or (and GPR:$src, 0xffff),
1976 lo16AllZero:$imm))]>, UnaryDP,
1977 Requires<[IsARM, HasV6T2]> {
1980 let Inst{15-12} = Rd;
1981 let Inst{11-0} = imm{11-0};
1982 let Inst{19-16} = imm{15-12};
1987 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
1988 Requires<[IsARM, HasV6T2]>;
1990 let Uses = [CPSR] in
1991 def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "",
1992 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
1995 // These aren't really mov instructions, but we have to define them this way
1996 // due to flag operands.
1998 let Defs = [CPSR] in {
1999 def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
2000 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
2002 def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "",
2003 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
2007 //===----------------------------------------------------------------------===//
2008 // Extend Instructions.
2013 defm SXTB : AI_ext_rrot<0b01101010,
2014 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
2015 defm SXTH : AI_ext_rrot<0b01101011,
2016 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
2018 defm SXTAB : AI_exta_rrot<0b01101010,
2019 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
2020 defm SXTAH : AI_exta_rrot<0b01101011,
2021 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
2023 // For disassembly only
2024 defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
2026 // For disassembly only
2027 defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
2031 let AddedComplexity = 16 in {
2032 defm UXTB : AI_ext_rrot<0b01101110,
2033 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
2034 defm UXTH : AI_ext_rrot<0b01101111,
2035 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2036 defm UXTB16 : AI_ext_rrot<0b01101100,
2037 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2039 // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2040 // The transformation should probably be done as a combiner action
2041 // instead so we can include a check for masking back in the upper
2042 // eight bits of the source into the lower eight bits of the result.
2043 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
2044 // (UXTB16r_rot GPR:$Src, 24)>;
2045 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
2046 (UXTB16r_rot GPR:$Src, 8)>;
2048 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
2049 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2050 defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
2051 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2054 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
2055 // For disassembly only
2056 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
2059 def SBFX : I<(outs GPR:$Rd),
2060 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2061 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2062 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2063 Requires<[IsARM, HasV6T2]> {
2068 let Inst{27-21} = 0b0111101;
2069 let Inst{6-4} = 0b101;
2070 let Inst{20-16} = width;
2071 let Inst{15-12} = Rd;
2072 let Inst{11-7} = lsb;
2076 def UBFX : I<(outs GPR:$Rd),
2077 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
2078 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2079 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
2080 Requires<[IsARM, HasV6T2]> {
2085 let Inst{27-21} = 0b0111111;
2086 let Inst{6-4} = 0b101;
2087 let Inst{20-16} = width;
2088 let Inst{15-12} = Rd;
2089 let Inst{11-7} = lsb;
2093 //===----------------------------------------------------------------------===//
2094 // Arithmetic Instructions.
2097 defm ADD : AsI1_bin_irs<0b0100, "add",
2098 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2099 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
2100 defm SUB : AsI1_bin_irs<0b0010, "sub",
2101 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2102 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
2104 // ADD and SUB with 's' bit set.
2105 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
2106 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2107 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
2108 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
2109 IIC_iALUi, IIC_iALUr, IIC_iALUsr,
2110 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
2112 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
2113 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
2114 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
2115 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
2116 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
2117 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
2118 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
2119 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
2121 def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2122 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm",
2123 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> {
2128 let Inst{15-12} = Rd;
2129 let Inst{19-16} = Rn;
2130 let Inst{11-0} = imm;
2133 // The reg/reg form is only defined for the disassembler; for codegen it is
2134 // equivalent to SUBrr.
2135 def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
2136 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm",
2137 [/* For disassembly only; pattern left blank */]> {
2141 let Inst{11-4} = 0b00000000;
2144 let Inst{15-12} = Rd;
2145 let Inst{19-16} = Rn;
2148 def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2149 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
2150 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
2155 let Inst{11-0} = shift;
2156 let Inst{15-12} = Rd;
2157 let Inst{19-16} = Rn;
2160 // RSB with 's' bit set.
2161 let Defs = [CPSR] in {
2162 def RSBSri : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
2163 IIC_iALUi, "rsbs", "\t$Rd, $Rn, $imm",
2164 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]> {
2170 let Inst{15-12} = Rd;
2171 let Inst{19-16} = Rn;
2172 let Inst{11-0} = imm;
2174 def RSBSrs : AI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2175 DPSoRegFrm, IIC_iALUsr, "rsbs", "\t$Rd, $Rn, $shift",
2176 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]> {
2182 let Inst{11-0} = shift;
2183 let Inst{15-12} = Rd;
2184 let Inst{19-16} = Rn;
2188 let Uses = [CPSR] in {
2189 def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2190 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm",
2191 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2197 let Inst{15-12} = Rd;
2198 let Inst{19-16} = Rn;
2199 let Inst{11-0} = imm;
2201 // The reg/reg form is only defined for the disassembler; for codegen it is
2202 // equivalent to SUBrr.
2203 def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2204 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm",
2205 [/* For disassembly only; pattern left blank */]> {
2209 let Inst{11-4} = 0b00000000;
2212 let Inst{15-12} = Rd;
2213 let Inst{19-16} = Rn;
2215 def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2216 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
2217 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2223 let Inst{11-0} = shift;
2224 let Inst{15-12} = Rd;
2225 let Inst{19-16} = Rn;
2229 // FIXME: Allow these to be predicated.
2230 let Defs = [CPSR], Uses = [CPSR] in {
2231 def RSCSri : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
2232 DPFrm, IIC_iALUi, "rscs\t$Rd, $Rn, $imm",
2233 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>,
2240 let Inst{15-12} = Rd;
2241 let Inst{19-16} = Rn;
2242 let Inst{11-0} = imm;
2244 def RSCSrs : AXI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
2245 DPSoRegFrm, IIC_iALUsr, "rscs\t$Rd, $Rn, $shift",
2246 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
2253 let Inst{11-0} = shift;
2254 let Inst{15-12} = Rd;
2255 let Inst{19-16} = Rn;
2259 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
2260 // The assume-no-carry-in form uses the negation of the input since add/sub
2261 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
2262 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2264 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
2265 (SUBri GPR:$src, so_imm_neg:$imm)>;
2266 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
2267 (SUBSri GPR:$src, so_imm_neg:$imm)>;
2268 // The with-carry-in form matches bitwise not instead of the negation.
2269 // Effectively, the inverse interpretation of the carry flag already accounts
2270 // for part of the negation.
2271 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
2272 (SBCri GPR:$src, so_imm_not:$imm)>;
2274 // Note: These are implemented in C++ code, because they have to generate
2275 // ADD/SUBrs instructions, which use a complex pattern that a xform function
2277 // (mul X, 2^n+1) -> (add (X << n), X)
2278 // (mul X, 2^n-1) -> (rsb X, (X << n))
2280 // ARM Arithmetic Instruction -- for disassembly only
2281 // GPR:$dst = GPR:$a op GPR:$b
2282 class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
2283 list<dag> pattern = [/* For disassembly only; pattern left blank */]>
2284 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iALUr,
2285 opc, "\t$Rd, $Rn, $Rm", pattern> {
2289 let Inst{27-20} = op27_20;
2290 let Inst{11-4} = op11_4;
2291 let Inst{19-16} = Rn;
2292 let Inst{15-12} = Rd;
2296 // Saturating add/subtract -- for disassembly only
2298 def QADD : AAI<0b00010000, 0b00000101, "qadd",
2299 [(set GPR:$Rd, (int_arm_qadd GPR:$Rn, GPR:$Rm))]>;
2300 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
2301 [(set GPR:$Rd, (int_arm_qsub GPR:$Rn, GPR:$Rm))]>;
2302 def QDADD : AAI<0b00010100, 0b00000101, "qdadd">;
2303 def QDSUB : AAI<0b00010110, 0b00000101, "qdsub">;
2305 def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">;
2306 def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">;
2307 def QASX : AAI<0b01100010, 0b11110011, "qasx">;
2308 def QSAX : AAI<0b01100010, 0b11110101, "qsax">;
2309 def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">;
2310 def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">;
2311 def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">;
2312 def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">;
2313 def UQASX : AAI<0b01100110, 0b11110011, "uqasx">;
2314 def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">;
2315 def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">;
2316 def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">;
2318 // Signed/Unsigned add/subtract -- for disassembly only
2320 def SASX : AAI<0b01100001, 0b11110011, "sasx">;
2321 def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">;
2322 def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">;
2323 def SSAX : AAI<0b01100001, 0b11110101, "ssax">;
2324 def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">;
2325 def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">;
2326 def UASX : AAI<0b01100101, 0b11110011, "uasx">;
2327 def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">;
2328 def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">;
2329 def USAX : AAI<0b01100101, 0b11110101, "usax">;
2330 def USUB16 : AAI<0b01100101, 0b11110111, "usub16">;
2331 def USUB8 : AAI<0b01100101, 0b11111111, "usub8">;
2333 // Signed/Unsigned halving add/subtract -- for disassembly only
2335 def SHASX : AAI<0b01100011, 0b11110011, "shasx">;
2336 def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">;
2337 def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">;
2338 def SHSAX : AAI<0b01100011, 0b11110101, "shsax">;
2339 def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">;
2340 def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">;
2341 def UHASX : AAI<0b01100111, 0b11110011, "uhasx">;
2342 def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">;
2343 def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">;
2344 def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">;
2345 def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">;
2346 def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">;
2348 // Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
2350 def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2351 MulFrm /* for convenience */, NoItinerary, "usad8",
2352 "\t$Rd, $Rn, $Rm", []>,
2353 Requires<[IsARM, HasV6]> {
2357 let Inst{27-20} = 0b01111000;
2358 let Inst{15-12} = 0b1111;
2359 let Inst{7-4} = 0b0001;
2360 let Inst{19-16} = Rd;
2361 let Inst{11-8} = Rm;
2364 def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2365 MulFrm /* for convenience */, NoItinerary, "usada8",
2366 "\t$Rd, $Rn, $Rm, $Ra", []>,
2367 Requires<[IsARM, HasV6]> {
2372 let Inst{27-20} = 0b01111000;
2373 let Inst{7-4} = 0b0001;
2374 let Inst{19-16} = Rd;
2375 let Inst{15-12} = Ra;
2376 let Inst{11-8} = Rm;
2380 // Signed/Unsigned saturate -- for disassembly only
2382 def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2383 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
2384 [/* For disassembly only; pattern left blank */]> {
2389 let Inst{27-21} = 0b0110101;
2390 let Inst{5-4} = 0b01;
2391 let Inst{20-16} = sat_imm;
2392 let Inst{15-12} = Rd;
2393 let Inst{11-7} = sh{7-3};
2394 let Inst{6} = sh{0};
2398 def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm,
2399 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
2400 [/* For disassembly only; pattern left blank */]> {
2404 let Inst{27-20} = 0b01101010;
2405 let Inst{11-4} = 0b11110011;
2406 let Inst{15-12} = Rd;
2407 let Inst{19-16} = sat_imm;
2411 def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh),
2412 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh",
2413 [/* For disassembly only; pattern left blank */]> {
2418 let Inst{27-21} = 0b0110111;
2419 let Inst{5-4} = 0b01;
2420 let Inst{15-12} = Rd;
2421 let Inst{11-7} = sh{7-3};
2422 let Inst{6} = sh{0};
2423 let Inst{20-16} = sat_imm;
2427 def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm,
2428 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a",
2429 [/* For disassembly only; pattern left blank */]> {
2433 let Inst{27-20} = 0b01101110;
2434 let Inst{11-4} = 0b11110011;
2435 let Inst{15-12} = Rd;
2436 let Inst{19-16} = sat_imm;
2440 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
2441 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
2443 //===----------------------------------------------------------------------===//
2444 // Bitwise Instructions.
2447 defm AND : AsI1_bin_irs<0b0000, "and",
2448 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2449 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
2450 defm ORR : AsI1_bin_irs<0b1100, "orr",
2451 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2452 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
2453 defm EOR : AsI1_bin_irs<0b0001, "eor",
2454 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2455 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
2456 defm BIC : AsI1_bin_irs<0b1110, "bic",
2457 IIC_iBITi, IIC_iBITr, IIC_iBITsr,
2458 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2460 def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
2461 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2462 "bfc", "\t$Rd, $imm", "$src = $Rd",
2463 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
2464 Requires<[IsARM, HasV6T2]> {
2467 let Inst{27-21} = 0b0111110;
2468 let Inst{6-0} = 0b0011111;
2469 let Inst{15-12} = Rd;
2470 let Inst{11-7} = imm{4-0}; // lsb
2471 let Inst{20-16} = imm{9-5}; // width
2474 // A8.6.18 BFI - Bitfield insert (Encoding A1)
2475 def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
2476 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
2477 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
2478 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn,
2479 bf_inv_mask_imm:$imm))]>,
2480 Requires<[IsARM, HasV6T2]> {
2484 let Inst{27-21} = 0b0111110;
2485 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
2486 let Inst{15-12} = Rd;
2487 let Inst{11-7} = imm{4-0}; // lsb
2488 let Inst{20-16} = imm{9-5}; // width
2492 def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
2493 "mvn", "\t$Rd, $Rm",
2494 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {
2498 let Inst{19-16} = 0b0000;
2499 let Inst{11-4} = 0b00000000;
2500 let Inst{15-12} = Rd;
2503 def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
2504 IIC_iMVNsr, "mvn", "\t$Rd, $shift",
2505 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
2509 let Inst{19-16} = 0b0000;
2510 let Inst{15-12} = Rd;
2511 let Inst{11-0} = shift;
2513 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
2514 def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
2515 IIC_iMVNi, "mvn", "\t$Rd, $imm",
2516 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP {
2520 let Inst{19-16} = 0b0000;
2521 let Inst{15-12} = Rd;
2522 let Inst{11-0} = imm;
2525 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
2526 (BICri GPR:$src, so_imm_not:$imm)>;
2528 //===----------------------------------------------------------------------===//
2529 // Multiply Instructions.
2531 class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2532 string opc, string asm, list<dag> pattern>
2533 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2537 let Inst{19-16} = Rd;
2538 let Inst{11-8} = Rm;
2541 class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
2542 string opc, string asm, list<dag> pattern>
2543 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
2548 let Inst{19-16} = RdHi;
2549 let Inst{15-12} = RdLo;
2550 let Inst{11-8} = Rm;
2554 let isCommutable = 1 in
2555 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2556 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
2557 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
2559 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2560 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
2561 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
2563 let Inst{15-12} = Ra;
2566 def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
2567 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
2568 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
2569 Requires<[IsARM, HasV6T2]> {
2573 let Inst{19-16} = Rd;
2574 let Inst{11-8} = Rm;
2578 // Extra precision multiplies with low / high results
2580 let neverHasSideEffects = 1 in {
2581 let isCommutable = 1 in {
2582 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2583 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2584 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2586 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2587 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2588 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2591 // Multiply + accumulate
2592 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
2593 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2594 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2596 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
2597 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2598 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2600 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
2601 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
2602 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2603 Requires<[IsARM, HasV6]> {
2608 let Inst{19-16} = RdLo;
2609 let Inst{15-12} = RdHi;
2610 let Inst{11-8} = Rm;
2613 } // neverHasSideEffects
2615 // Most significant word multiply
2616 def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2617 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
2618 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
2619 Requires<[IsARM, HasV6]> {
2620 let Inst{15-12} = 0b1111;
2623 def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2624 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
2625 [/* For disassembly only; pattern left blank */]>,
2626 Requires<[IsARM, HasV6]> {
2627 let Inst{15-12} = 0b1111;
2630 def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
2631 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2632 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2633 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2634 Requires<[IsARM, HasV6]>;
2636 def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
2637 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2638 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
2639 [/* For disassembly only; pattern left blank */]>,
2640 Requires<[IsARM, HasV6]>;
2642 def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
2643 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2644 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2645 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>,
2646 Requires<[IsARM, HasV6]>;
2648 def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
2649 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2650 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
2651 [/* For disassembly only; pattern left blank */]>,
2652 Requires<[IsARM, HasV6]>;
2654 multiclass AI_smul<string opc, PatFrag opnode> {
2655 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2656 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2657 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2658 (sext_inreg GPR:$Rm, i16)))]>,
2659 Requires<[IsARM, HasV5TE]>;
2661 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2662 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2663 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
2664 (sra GPR:$Rm, (i32 16))))]>,
2665 Requires<[IsARM, HasV5TE]>;
2667 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2668 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2669 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2670 (sext_inreg GPR:$Rm, i16)))]>,
2671 Requires<[IsARM, HasV5TE]>;
2673 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2674 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2675 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
2676 (sra GPR:$Rm, (i32 16))))]>,
2677 Requires<[IsARM, HasV5TE]>;
2679 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2680 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2681 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2682 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
2683 Requires<[IsARM, HasV5TE]>;
2685 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2686 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2687 [(set GPR:$Rd, (sra (opnode GPR:$Rn,
2688 (sra GPR:$Rm, (i32 16))), (i32 16)))]>,
2689 Requires<[IsARM, HasV5TE]>;
2693 multiclass AI_smla<string opc, PatFrag opnode> {
2694 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
2695 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2696 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2697 [(set GPR:$Rd, (add GPR:$Ra,
2698 (opnode (sext_inreg GPR:$Rn, i16),
2699 (sext_inreg GPR:$Rm, i16))))]>,
2700 Requires<[IsARM, HasV5TE]>;
2702 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd),
2703 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2704 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2705 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
2706 (sra GPR:$Rm, (i32 16)))))]>,
2707 Requires<[IsARM, HasV5TE]>;
2709 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd),
2710 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2711 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2712 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2713 (sext_inreg GPR:$Rm, i16))))]>,
2714 Requires<[IsARM, HasV5TE]>;
2716 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd),
2717 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2718 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2719 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
2720 (sra GPR:$Rm, (i32 16)))))]>,
2721 Requires<[IsARM, HasV5TE]>;
2723 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd),
2724 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2725 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2726 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2727 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
2728 Requires<[IsARM, HasV5TE]>;
2730 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd),
2731 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2732 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2733 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
2734 (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
2735 Requires<[IsARM, HasV5TE]>;
2738 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2739 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2741 // Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
2742 def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
2743 (ins GPR:$Rn, GPR:$Rm),
2744 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
2745 [/* For disassembly only; pattern left blank */]>,
2746 Requires<[IsARM, HasV5TE]>;
2748 def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
2749 (ins GPR:$Rn, GPR:$Rm),
2750 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
2751 [/* For disassembly only; pattern left blank */]>,
2752 Requires<[IsARM, HasV5TE]>;
2754 def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
2755 (ins GPR:$Rn, GPR:$Rm),
2756 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
2757 [/* For disassembly only; pattern left blank */]>,
2758 Requires<[IsARM, HasV5TE]>;
2760 def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
2761 (ins GPR:$Rn, GPR:$Rm),
2762 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
2763 [/* For disassembly only; pattern left blank */]>,
2764 Requires<[IsARM, HasV5TE]>;
2766 // Helper class for AI_smld -- for disassembly only
2767 class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
2768 InstrItinClass itin, string opc, string asm>
2769 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
2776 let Inst{21-20} = 0b00;
2777 let Inst{22} = long;
2778 let Inst{27-23} = 0b01110;
2779 let Inst{11-8} = Rm;
2782 class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
2783 InstrItinClass itin, string opc, string asm>
2784 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2786 let Inst{15-12} = 0b1111;
2787 let Inst{19-16} = Rd;
2789 class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
2790 InstrItinClass itin, string opc, string asm>
2791 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2793 let Inst{15-12} = Ra;
2795 class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
2796 InstrItinClass itin, string opc, string asm>
2797 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
2800 let Inst{19-16} = RdHi;
2801 let Inst{15-12} = RdLo;
2804 multiclass AI_smld<bit sub, string opc> {
2806 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2807 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">;
2809 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
2810 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">;
2812 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi),
2813 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2814 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">;
2816 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi),
2817 (ins GPR:$Rn, GPR:$Rm), NoItinerary,
2818 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">;
2822 defm SMLA : AI_smld<0, "smla">;
2823 defm SMLS : AI_smld<1, "smls">;
2825 multiclass AI_sdml<bit sub, string opc> {
2827 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2828 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">;
2829 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2830 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">;
2833 defm SMUA : AI_sdml<0, "smua">;
2834 defm SMUS : AI_sdml<1, "smus">;
2836 //===----------------------------------------------------------------------===//
2837 // Misc. Arithmetic Instructions.
2840 def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
2841 IIC_iUNAr, "clz", "\t$Rd, $Rm",
2842 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
2844 def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2845 IIC_iUNAr, "rbit", "\t$Rd, $Rm",
2846 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
2847 Requires<[IsARM, HasV6T2]>;
2849 def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
2850 IIC_iUNAr, "rev", "\t$Rd, $Rm",
2851 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
2853 def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2854 IIC_iUNAr, "rev16", "\t$Rd, $Rm",
2856 (or (and (srl GPR:$Rm, (i32 8)), 0xFF),
2857 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
2858 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
2859 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
2860 Requires<[IsARM, HasV6]>;
2862 def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
2863 IIC_iUNAr, "revsh", "\t$Rd, $Rm",
2866 (or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
2867 (shl GPR:$Rm, (i32 8))), i16))]>,
2868 Requires<[IsARM, HasV6]>;
2870 def lsl_shift_imm : SDNodeXForm<imm, [{
2871 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
2872 return CurDAG->getTargetConstant(Sh, MVT::i32);
2875 def lsl_amt : PatLeaf<(i32 imm), [{
2876 return (N->getZExtValue() < 32);
2879 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
2880 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2881 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2882 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
2883 (and (shl GPR:$Rm, lsl_amt:$sh),
2885 Requires<[IsARM, HasV6]>;
2887 // Alternate cases for PKHBT where identities eliminate some nodes.
2888 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
2889 (PKHBT GPR:$Rn, GPR:$Rm, 0)>;
2890 def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
2891 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
2893 def asr_shift_imm : SDNodeXForm<imm, [{
2894 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
2895 return CurDAG->getTargetConstant(Sh, MVT::i32);
2898 def asr_amt : PatLeaf<(i32 imm), [{
2899 return (N->getZExtValue() <= 32);
2902 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
2903 // will match the pattern below.
2904 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
2905 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
2906 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
2907 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
2908 (and (sra GPR:$Rm, asr_amt:$sh),
2910 Requires<[IsARM, HasV6]>;
2912 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
2913 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
2914 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
2915 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
2916 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
2917 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
2918 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
2920 //===----------------------------------------------------------------------===//
2921 // Comparison Instructions...
2924 defm CMP : AI1_cmp_irs<0b1010, "cmp",
2925 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2926 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
2928 // FIXME: We have to be careful when using the CMN instruction and comparison
2929 // with 0. One would expect these two pieces of code should give identical
2945 // However, the CMN gives the *opposite* result when r1 is 0. This is because
2946 // the carry flag is set in the CMP case but not in the CMN case. In short, the
2947 // CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
2948 // value of r0 and the carry bit (because the "carry bit" parameter to
2949 // AddWithCarry is defined as 1 in this case, the carry flag will always be set
2950 // when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
2951 // never a "carry" when this AddWithCarry is performed (because the "carry bit"
2952 // parameter to AddWithCarry is defined as 0).
2954 // When x is 0 and unsigned:
2958 // ~x + 1 = 0x1 0000 0000
2959 // (-x = 0) != (0x1 0000 0000 = ~x + 1)
2961 // Therefore, we should disable CMN when comparing against zero, until we can
2962 // limit when the CMN instruction is used (when we know that the RHS is not 0 or
2963 // when it's a comparison which doesn't look at the 'carry' flag).
2965 // (See the ARM docs for the "AddWithCarry" pseudo-code.)
2967 // This is related to <rdar://problem/7569620>.
2969 //defm CMN : AI1_cmp_irs<0b1011, "cmn",
2970 // BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
2972 // Note that TST/TEQ don't set all the same flags that CMP does!
2973 defm TST : AI1_cmp_irs<0b1000, "tst",
2974 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2975 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
2976 defm TEQ : AI1_cmp_irs<0b1001, "teq",
2977 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
2978 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
2980 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
2981 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2982 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
2983 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
2984 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr,
2985 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
2987 //def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
2988 // (CMNri GPR:$src, so_imm_neg:$imm)>;
2990 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
2991 (CMNzri GPR:$src, so_imm_neg:$imm)>;
2993 // Pseudo i64 compares for some floating point compares.
2994 let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
2996 def BCCi64 : PseudoInst<(outs),
2997 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
2999 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
3001 def BCCZi64 : PseudoInst<(outs),
3002 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "",
3003 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
3004 } // usesCustomInserter
3007 // Conditional moves
3008 // FIXME: should be able to write a pattern for ARMcmov, but can't use
3009 // a two-value operand where a dag node expects two operands. :(
3010 // FIXME: These should all be pseudo-instructions that get expanded to
3011 // the normal MOV instructions. That would fix the dependency on
3012 // special casing them in tblgen.
3013 let neverHasSideEffects = 1 in {
3014 def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
3015 IIC_iCMOVr, "mov", "\t$Rd, $Rm",
3016 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
3017 RegConstraint<"$false = $Rd">, UnaryDP {
3022 let Inst{15-12} = Rd;
3023 let Inst{11-4} = 0b00000000;
3027 def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
3028 (ins GPR:$false, so_reg:$shift), DPSoRegFrm, IIC_iCMOVsr,
3029 "mov", "\t$Rd, $shift",
3030 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
3031 RegConstraint<"$false = $Rd">, UnaryDP {
3036 let Inst{19-16} = 0;
3037 let Inst{15-12} = Rd;
3038 let Inst{11-0} = shift;
3041 def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
3043 "movw", "\t$Rd, $imm",
3045 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
3051 let Inst{19-16} = imm{15-12};
3052 let Inst{15-12} = Rd;
3053 let Inst{11-0} = imm{11-0};
3056 def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
3057 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3058 "mov", "\t$Rd, $imm",
3059 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>,
3060 RegConstraint<"$false = $Rd">, UnaryDP {
3065 let Inst{19-16} = 0b0000;
3066 let Inst{15-12} = Rd;
3067 let Inst{11-0} = imm;
3070 // Two instruction predicate mov immediate.
3071 def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
3072 (ins GPR:$false, i32imm:$src, pred:$p),
3073 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $Rd">;
3075 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
3076 (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
3077 "mvn", "\t$Rd, $imm",
3078 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
3079 RegConstraint<"$false = $Rd">, UnaryDP {
3084 let Inst{19-16} = 0b0000;
3085 let Inst{15-12} = Rd;
3086 let Inst{11-0} = imm;
3088 } // neverHasSideEffects
3090 //===----------------------------------------------------------------------===//
3091 // Atomic operations intrinsics
3094 def memb_opt : Operand<i32> {
3095 let PrintMethod = "printMemBOption";
3098 // memory barriers protect the atomic sequences
3099 let hasSideEffects = 1 in {
3100 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3101 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3102 Requires<[IsARM, HasDB]> {
3104 let Inst{31-4} = 0xf57ff05;
3105 let Inst{3-0} = opt;
3108 def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
3109 "mcr", "\tp15, 0, $zero, c7, c10, 5",
3110 [(ARMMemBarrierMCR GPR:$zero)]>,
3111 Requires<[IsARM, HasV6]> {
3112 // FIXME: add encoding
3116 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
3118 [/* For disassembly only; pattern left blank */]>,
3119 Requires<[IsARM, HasDB]> {
3121 let Inst{31-4} = 0xf57ff04;
3122 let Inst{3-0} = opt;
3125 // ISB has only full system option -- for disassembly only
3126 def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
3127 Requires<[IsARM, HasDB]> {
3128 let Inst{31-4} = 0xf57ff06;
3129 let Inst{3-0} = 0b1111;
3132 let usesCustomInserter = 1 in {
3133 let Uses = [CPSR] in {
3134 def ATOMIC_LOAD_ADD_I8 : PseudoInst<
3135 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3136 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
3137 def ATOMIC_LOAD_SUB_I8 : PseudoInst<
3138 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3139 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
3140 def ATOMIC_LOAD_AND_I8 : PseudoInst<
3141 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3142 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
3143 def ATOMIC_LOAD_OR_I8 : PseudoInst<
3144 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3145 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
3146 def ATOMIC_LOAD_XOR_I8 : PseudoInst<
3147 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3148 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
3149 def ATOMIC_LOAD_NAND_I8 : PseudoInst<
3150 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3151 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
3152 def ATOMIC_LOAD_ADD_I16 : PseudoInst<
3153 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3154 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
3155 def ATOMIC_LOAD_SUB_I16 : PseudoInst<
3156 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3157 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
3158 def ATOMIC_LOAD_AND_I16 : PseudoInst<
3159 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3160 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
3161 def ATOMIC_LOAD_OR_I16 : PseudoInst<
3162 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3163 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
3164 def ATOMIC_LOAD_XOR_I16 : PseudoInst<
3165 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3166 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
3167 def ATOMIC_LOAD_NAND_I16 : PseudoInst<
3168 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3169 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
3170 def ATOMIC_LOAD_ADD_I32 : PseudoInst<
3171 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3172 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
3173 def ATOMIC_LOAD_SUB_I32 : PseudoInst<
3174 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3175 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
3176 def ATOMIC_LOAD_AND_I32 : PseudoInst<
3177 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3178 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
3179 def ATOMIC_LOAD_OR_I32 : PseudoInst<
3180 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3181 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
3182 def ATOMIC_LOAD_XOR_I32 : PseudoInst<
3183 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3184 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
3185 def ATOMIC_LOAD_NAND_I32 : PseudoInst<
3186 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "",
3187 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
3189 def ATOMIC_SWAP_I8 : PseudoInst<
3190 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3191 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
3192 def ATOMIC_SWAP_I16 : PseudoInst<
3193 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3194 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
3195 def ATOMIC_SWAP_I32 : PseudoInst<
3196 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "",
3197 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
3199 def ATOMIC_CMP_SWAP_I8 : PseudoInst<
3200 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3201 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
3202 def ATOMIC_CMP_SWAP_I16 : PseudoInst<
3203 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3204 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
3205 def ATOMIC_CMP_SWAP_I32 : PseudoInst<
3206 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "",
3207 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
3211 let mayLoad = 1 in {
3212 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3213 "ldrexb", "\t$Rt, [$Rn]",
3215 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3216 "ldrexh", "\t$Rt, [$Rn]",
3218 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3219 "ldrex", "\t$Rt, [$Rn]",
3221 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3223 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3227 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3228 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3230 "strexb", "\t$Rd, $src, [$Rn]",
3232 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3234 "strexh", "\t$Rd, $Rt, [$Rn]",
3236 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3238 "strex", "\t$Rd, $Rt, [$Rn]",
3240 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3241 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3243 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3247 // Clear-Exclusive is for disassembly only.
3248 def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
3249 [/* For disassembly only; pattern left blank */]>,
3250 Requires<[IsARM, HasV7]> {
3251 let Inst{31-0} = 0b11110101011111111111000000011111;
3254 // SWP/SWPB are deprecated in V6/V7 and for disassembly only.
3255 let mayLoad = 1 in {
3256 def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp",
3257 [/* For disassembly only; pattern left blank */]>;
3258 def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
3259 [/* For disassembly only; pattern left blank */]>;
3262 //===----------------------------------------------------------------------===//
3266 // __aeabi_read_tp preserves the registers r1-r3.
3267 // FIXME: This needs to be a pseudo of some sort so that we can get the
3268 // encoding right, complete with fixup for the aeabi_read_tp function.
3270 Defs = [R0, R12, LR, CPSR] in {
3271 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
3272 "bl\t__aeabi_read_tp",
3273 [(set R0, ARMthread_pointer)]>;
3276 //===----------------------------------------------------------------------===//
3277 // SJLJ Exception handling intrinsics
3278 // eh_sjlj_setjmp() is an instruction sequence to store the return
3279 // address and save #0 in R0 for the non-longjmp case.
3280 // Since by its nature we may be coming from some other function to get
3281 // here, and we're using the stack frame for the containing function to
3282 // save/restore registers, we can't keep anything live in regs across
3283 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3284 // when we get here from a longjmp(). We force everthing out of registers
3285 // except for our own input by listing the relevant registers in Defs. By
3286 // doing so, we also cause the prologue/epilogue code to actively preserve
3287 // all of the callee-saved resgisters, which is exactly what we want.
3288 // A constant value is passed in $val, and we use the location as a scratch.
3290 // These are pseudo-instructions and are lowered to individual MC-insts, so
3291 // no encoding information is necessary.
3293 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
3294 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
3295 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
3296 D31 ], hasSideEffects = 1, isBarrier = 1 in {
3297 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
3298 AddrModeNone, SizeSpecial, IndexModeNone,
3299 Pseudo, NoItinerary, "", "",
3300 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3301 Requires<[IsARM, HasVFP2]>;
3305 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
3306 hasSideEffects = 1, isBarrier = 1 in {
3307 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
3308 AddrModeNone, SizeSpecial, IndexModeNone,
3309 Pseudo, NoItinerary, "", "",
3310 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
3311 Requires<[IsARM, NoVFP]>;
3314 // FIXME: Non-Darwin version(s)
3315 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
3316 Defs = [ R7, LR, SP ] in {
3317 def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
3318 AddrModeNone, SizeSpecial, IndexModeNone,
3319 Pseudo, NoItinerary, "", "",
3320 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
3321 Requires<[IsARM, IsDarwin]>;
3324 // eh.sjlj.dispatchsetup pseudo-instruction.
3325 // This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are
3326 // handled when the pseudo is expanded (which happens before any passes
3327 // that need the instruction size).
3328 let isBarrier = 1, hasSideEffects = 1 in
3329 def Int_eh_sjlj_dispatchsetup :
3330 PseudoInst<(outs), (ins GPR:$src), NoItinerary, "",
3331 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>,
3332 Requires<[IsDarwin]>;
3334 //===----------------------------------------------------------------------===//
3335 // Non-Instruction Patterns
3338 // Large immediate handling.
3340 // FIXME: Folding immediates into these logical operations aren't necessary
3341 // good ideas. If it's in a loop machine licm could have hoisted the immediate
3342 // computation out of the loop.
3343 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
3344 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3345 (so_imm2part_2 imm:$RHS))>;
3346 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
3347 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3348 (so_imm2part_2 imm:$RHS))>;
3349 def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
3350 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
3351 (so_imm2part_2 imm:$RHS))>;
3352 def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
3353 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
3354 (so_neg_imm2part_2 imm:$RHS))>;
3356 // 32-bit immediate using two piece so_imms or movw + movt.
3357 // This is a single pseudo instruction, the benefit is that it can be remat'd
3358 // as a single unit instead of having to handle reg inputs.
3359 // FIXME: Remove this when we can do generalized remat.
3360 let isReMaterializable = 1 in
3361 def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "",
3362 [(set GPR:$dst, (arm_i32imm:$src))]>,
3365 // ConstantPool, GlobalAddress, and JumpTable
3366 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
3367 Requires<[IsARM, DontUseMovt]>;
3368 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
3369 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
3370 Requires<[IsARM, UseMovt]>;
3371 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
3372 (LEApcrelJT tjumptable:$dst, imm:$id)>;
3374 // TODO: add,sub,and, 3-instr forms?
3377 def : ARMPat<(ARMtcret tcGPR:$dst),
3378 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
3380 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3381 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3383 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3384 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
3386 def : ARMPat<(ARMtcret tcGPR:$dst),
3387 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
3389 def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
3390 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3392 def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
3393 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
3396 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
3397 Requires<[IsARM, IsNotDarwin]>;
3398 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
3399 Requires<[IsARM, IsDarwin]>;
3401 // zextload i1 -> zextload i8
3402 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3403 def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3405 // extload -> zextload
3406 def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3407 def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3408 def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
3409 def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
3411 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
3413 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
3414 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
3417 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3418 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3419 (SMULBB GPR:$a, GPR:$b)>;
3420 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
3421 (SMULBB GPR:$a, GPR:$b)>;
3422 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3423 (sra GPR:$b, (i32 16))),
3424 (SMULBT GPR:$a, GPR:$b)>;
3425 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
3426 (SMULBT GPR:$a, GPR:$b)>;
3427 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
3428 (sra (shl GPR:$b, (i32 16)), (i32 16))),
3429 (SMULTB GPR:$a, GPR:$b)>;
3430 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
3431 (SMULTB GPR:$a, GPR:$b)>;
3432 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3434 (SMULWB GPR:$a, GPR:$b)>;
3435 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
3436 (SMULWB GPR:$a, GPR:$b)>;
3438 def : ARMV5TEPat<(add GPR:$acc,
3439 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3440 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3441 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3442 def : ARMV5TEPat<(add GPR:$acc,
3443 (mul sext_16_node:$a, sext_16_node:$b)),
3444 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
3445 def : ARMV5TEPat<(add GPR:$acc,
3446 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
3447 (sra GPR:$b, (i32 16)))),
3448 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3449 def : ARMV5TEPat<(add GPR:$acc,
3450 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
3451 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
3452 def : ARMV5TEPat<(add GPR:$acc,
3453 (mul (sra GPR:$a, (i32 16)),
3454 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
3455 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3456 def : ARMV5TEPat<(add GPR:$acc,
3457 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
3458 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
3459 def : ARMV5TEPat<(add GPR:$acc,
3460 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
3462 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3463 def : ARMV5TEPat<(add GPR:$acc,
3464 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
3465 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
3467 //===----------------------------------------------------------------------===//
3471 include "ARMInstrThumb.td"
3473 //===----------------------------------------------------------------------===//
3477 include "ARMInstrThumb2.td"
3479 //===----------------------------------------------------------------------===//
3480 // Floating Point Support
3483 include "ARMInstrVFP.td"
3485 //===----------------------------------------------------------------------===//
3486 // Advanced SIMD (NEON) Support
3489 include "ARMInstrNEON.td"
3491 //===----------------------------------------------------------------------===//
3492 // Coprocessor Instructions. For disassembly only.
3495 def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3496 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3497 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3498 [/* For disassembly only; pattern left blank */]> {
3502 def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3503 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3504 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
3505 [/* For disassembly only; pattern left blank */]> {
3506 let Inst{31-28} = 0b1111;
3510 class ACI<dag oops, dag iops, string opc, string asm>
3511 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
3512 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
3513 let Inst{27-25} = 0b110;
3516 multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
3518 def _OFFSET : ACI<(outs),
3519 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3520 opc, "\tp$cop, cr$CRd, $addr"> {
3521 let Inst{31-28} = op31_28;
3522 let Inst{24} = 1; // P = 1
3523 let Inst{21} = 0; // W = 0
3524 let Inst{22} = 0; // D = 0
3525 let Inst{20} = load;
3528 def _PRE : ACI<(outs),
3529 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3530 opc, "\tp$cop, cr$CRd, $addr!"> {
3531 let Inst{31-28} = op31_28;
3532 let Inst{24} = 1; // P = 1
3533 let Inst{21} = 1; // W = 1
3534 let Inst{22} = 0; // D = 0
3535 let Inst{20} = load;
3538 def _POST : ACI<(outs),
3539 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3540 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3541 let Inst{31-28} = op31_28;
3542 let Inst{24} = 0; // P = 0
3543 let Inst{21} = 1; // W = 1
3544 let Inst{22} = 0; // D = 0
3545 let Inst{20} = load;
3548 def _OPTION : ACI<(outs),
3549 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
3550 opc, "\tp$cop, cr$CRd, [$base], $option"> {
3551 let Inst{31-28} = op31_28;
3552 let Inst{24} = 0; // P = 0
3553 let Inst{23} = 1; // U = 1
3554 let Inst{21} = 0; // W = 0
3555 let Inst{22} = 0; // D = 0
3556 let Inst{20} = load;
3559 def L_OFFSET : ACI<(outs),
3560 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3561 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
3562 let Inst{31-28} = op31_28;
3563 let Inst{24} = 1; // P = 1
3564 let Inst{21} = 0; // W = 0
3565 let Inst{22} = 1; // D = 1
3566 let Inst{20} = load;
3569 def L_PRE : ACI<(outs),
3570 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3571 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3572 let Inst{31-28} = op31_28;
3573 let Inst{24} = 1; // P = 1
3574 let Inst{21} = 1; // W = 1
3575 let Inst{22} = 1; // D = 1
3576 let Inst{20} = load;
3579 def L_POST : ACI<(outs),
3580 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3581 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3582 let Inst{31-28} = op31_28;
3583 let Inst{24} = 0; // P = 0
3584 let Inst{21} = 1; // W = 1
3585 let Inst{22} = 1; // D = 1
3586 let Inst{20} = load;
3589 def L_OPTION : ACI<(outs),
3590 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
3591 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
3592 let Inst{31-28} = op31_28;
3593 let Inst{24} = 0; // P = 0
3594 let Inst{23} = 1; // U = 1
3595 let Inst{21} = 0; // W = 0
3596 let Inst{22} = 1; // D = 1
3597 let Inst{20} = load;
3601 defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
3602 defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
3603 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
3604 defm STC2 : LdStCop<0b1111, 0, "stc2">;
3606 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3607 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3608 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3609 [/* For disassembly only; pattern left blank */]> {
3614 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3615 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3616 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3617 [/* For disassembly only; pattern left blank */]> {
3618 let Inst{31-28} = 0b1111;
3623 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3624 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3625 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3626 [/* For disassembly only; pattern left blank */]> {
3631 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3632 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3633 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3634 [/* For disassembly only; pattern left blank */]> {
3635 let Inst{31-28} = 0b1111;
3640 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3641 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3642 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3643 [/* For disassembly only; pattern left blank */]> {
3644 let Inst{23-20} = 0b0100;
3647 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3648 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3649 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3650 [/* For disassembly only; pattern left blank */]> {
3651 let Inst{31-28} = 0b1111;
3652 let Inst{23-20} = 0b0100;
3655 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3656 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3657 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3658 [/* For disassembly only; pattern left blank */]> {
3659 let Inst{23-20} = 0b0101;
3662 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3663 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3664 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3665 [/* For disassembly only; pattern left blank */]> {
3666 let Inst{31-28} = 0b1111;
3667 let Inst{23-20} = 0b0101;
3670 //===----------------------------------------------------------------------===//
3671 // Move between special register and ARM core register -- for disassembly only
3674 def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
3675 [/* For disassembly only; pattern left blank */]> {
3676 let Inst{23-20} = 0b0000;
3677 let Inst{7-4} = 0b0000;
3680 def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
3681 [/* For disassembly only; pattern left blank */]> {
3682 let Inst{23-20} = 0b0100;
3683 let Inst{7-4} = 0b0000;
3686 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3687 "msr", "\tcpsr$mask, $src",
3688 [/* For disassembly only; pattern left blank */]> {
3689 let Inst{23-20} = 0b0010;
3690 let Inst{7-4} = 0b0000;
3693 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3694 "msr", "\tcpsr$mask, $a",
3695 [/* For disassembly only; pattern left blank */]> {
3696 let Inst{23-20} = 0b0010;
3697 let Inst{7-4} = 0b0000;
3700 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3701 "msr", "\tspsr$mask, $src",
3702 [/* For disassembly only; pattern left blank */]> {
3703 let Inst{23-20} = 0b0110;
3704 let Inst{7-4} = 0b0000;
3707 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3708 "msr", "\tspsr$mask, $a",
3709 [/* For disassembly only; pattern left blank */]> {
3710 let Inst{23-20} = 0b0110;
3711 let Inst{7-4} = 0b0000;